aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig50
-rw-r--r--drivers/media/video/Makefile14
-rw-r--r--drivers/media/video/au0828/Kconfig2
-rw-r--r--drivers/media/video/au0828/Makefile2
-rw-r--r--drivers/media/video/bt8xx/Kconfig2
-rw-r--r--drivers/media/video/bt8xx/Makefile1
-rw-r--r--drivers/media/video/cx18/Kconfig20
-rw-r--r--drivers/media/video/cx18/Makefile11
-rw-r--r--drivers/media/video/cx18/cx18-audio.c73
-rw-r--r--drivers/media/video/cx18/cx18-audio.h26
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c361
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c879
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h318
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c120
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c413
-rw-r--r--drivers/media/video/cx18/cx18-cards.c277
-rw-r--r--drivers/media/video/cx18/cx18-cards.h170
-rw-r--r--drivers/media/video/cx18/cx18-controls.c306
-rw-r--r--drivers/media/video/cx18/cx18-controls.h24
-rw-r--r--drivers/media/video/cx18/cx18-driver.c971
-rw-r--r--drivers/media/video/cx18/cx18-driver.h500
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c288
-rw-r--r--drivers/media/video/cx18/cx18-dvb.h25
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c711
-rw-r--r--drivers/media/video/cx18/cx18-fileops.h45
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c373
-rw-r--r--drivers/media/video/cx18/cx18-firmware.h25
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c74
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h24
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c431
-rw-r--r--drivers/media/video/cx18/cx18-i2c.h33
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c851
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.h30
-rw-r--r--drivers/media/video/cx18/cx18-irq.c179
-rw-r--r--drivers/media/video/cx18/cx18-irq.h37
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c372
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h73
-rw-r--r--drivers/media/video/cx18/cx18-queue.c282
-rw-r--r--drivers/media/video/cx18/cx18-queue.h59
-rw-r--r--drivers/media/video/cx18/cx18-scb.c121
-rw-r--r--drivers/media/video/cx18/cx18-scb.h285
-rw-r--r--drivers/media/video/cx18/cx18-streams.c566
-rw-r--r--drivers/media/video/cx18/cx18-streams.h33
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c208
-rw-r--r--drivers/media/video/cx18/cx18-vbi.h26
-rw-r--r--drivers/media/video/cx18/cx18-version.h34
-rw-r--r--drivers/media/video/cx18/cx18-video.c45
-rw-r--r--drivers/media/video/cx18/cx18-video.h22
-rw-r--r--drivers/media/video/cx18/cx23418.h458
-rw-r--r--drivers/media/video/cx23885/Kconfig12
-rw-r--r--drivers/media/video/cx23885/Makefile1
-rw-r--r--drivers/media/video/cx88/Kconfig4
-rw-r--r--drivers/media/video/cx88/Makefile1
-rw-r--r--drivers/media/video/cx88/cx88-cards.c50
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c30
-rw-r--r--drivers/media/video/em28xx/Kconfig2
-rw-r--r--drivers/media/video/em28xx/Makefile1
-rw-r--r--drivers/media/video/ivtv/Kconfig2
-rw-r--r--drivers/media/video/ivtv/Makefile1
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c98
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h5
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c43
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c3
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c44
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-version.h2
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c2
-rw-r--r--drivers/media/video/mt20xx.c670
-rw-r--r--drivers/media/video/mt20xx.h37
-rw-r--r--drivers/media/video/mt9m001.c2
-rw-r--r--drivers/media/video/mt9v022.c2
-rw-r--r--drivers/media/video/pvrusb2/Kconfig55
-rw-r--r--drivers/media/video/pvrusb2/Makefile1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debug.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c8
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.c42
-rw-r--r--drivers/media/video/saa7134/Kconfig6
-rw-r--r--drivers/media/video/saa7134/Makefile1
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c260
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c42
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c1
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/tda8290.c804
-rw-r--r--drivers/media/video/tda8290.h57
-rw-r--r--drivers/media/video/tda9887.c717
-rw-r--r--drivers/media/video/tda9887.h38
-rw-r--r--drivers/media/video/tea5761.c324
-rw-r--r--drivers/media/video/tea5761.h47
-rw-r--r--drivers/media/video/tea5767.c474
-rw-r--r--drivers/media/video/tea5767.h66
-rw-r--r--drivers/media/video/tuner-core.c124
-rw-r--r--drivers/media/video/tuner-i2c.h173
-rw-r--r--drivers/media/video/tuner-simple.c1093
-rw-r--r--drivers/media/video/tuner-simple.h39
-rw-r--r--drivers/media/video/tuner-types.c1652
-rw-r--r--drivers/media/video/tuner-xc2028-types.h141
-rw-r--r--drivers/media/video/tuner-xc2028.c1227
-rw-r--r--drivers/media/video/tuner-xc2028.h63
-rw-r--r--drivers/media/video/usbvision/Kconfig2
-rw-r--r--drivers/media/video/usbvision/Makefile1
101 files changed, 10719 insertions, 8016 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index fe9a4cc14141..fe743aa7f645 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1,4 +1,50 @@
1# 1#
2# Generic video config states
3#
4
5config VIDEO_V4L2
6 tristate
7 depends on VIDEO_DEV && VIDEO_V4L2_COMMON
8 default VIDEO_DEV && VIDEO_V4L2_COMMON
9
10config VIDEO_V4L1
11 tristate
12 depends on VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
13 default VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
14
15config VIDEOBUF_GEN
16 tristate
17
18config VIDEOBUF_DMA_SG
19 depends on HAS_DMA
20 select VIDEOBUF_GEN
21 tristate
22
23config VIDEOBUF_VMALLOC
24 select VIDEOBUF_GEN
25 tristate
26
27config VIDEOBUF_DVB
28 tristate
29 select VIDEOBUF_GEN
30 select VIDEOBUF_DMA_SG
31
32config VIDEO_BTCX
33 tristate
34
35config VIDEO_IR_I2C
36 tristate
37
38config VIDEO_IR
39 tristate
40 depends on INPUT
41 select VIDEO_IR_I2C if I2C
42
43config VIDEO_TVEEPROM
44 tristate
45 depends on I2C
46
47#
2# Multimedia Video device configuration 48# Multimedia Video device configuration
3# 49#
4 50
@@ -644,7 +690,7 @@ config VIDEO_MXB
644 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" 690 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
645 depends on PCI && VIDEO_V4L1 && I2C 691 depends on PCI && VIDEO_V4L1 && I2C
646 select VIDEO_SAA7146_VV 692 select VIDEO_SAA7146_VV
647 select VIDEO_TUNER 693 select MEDIA_TUNER
648 select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO 694 select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
649 select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO 695 select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
650 select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO 696 select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
@@ -702,6 +748,8 @@ source "drivers/media/video/au0828/Kconfig"
702 748
703source "drivers/media/video/ivtv/Kconfig" 749source "drivers/media/video/ivtv/Kconfig"
704 750
751source "drivers/media/video/cx18/Kconfig"
752
705config VIDEO_M32R_AR 753config VIDEO_M32R_AR
706 tristate "AR devices" 754 tristate "AR devices"
707 depends on M32R && VIDEO_V4L1 755 depends on M32R && VIDEO_V4L1
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index be14227f3726..a352c6e31f0c 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -84,17 +84,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
84obj-$(CONFIG_VIDEO_DPC) += dpc7146.o 84obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
85obj-$(CONFIG_TUNER_3036) += tuner-3036.o 85obj-$(CONFIG_TUNER_3036) += tuner-3036.o
86 86
87obj-$(CONFIG_VIDEO_TUNER) += tuner.o 87obj-$(CONFIG_MEDIA_TUNER) += tuner.o
88
89obj-$(CONFIG_TUNER_XC2028) += tuner-xc2028.o
90obj-$(CONFIG_TUNER_SIMPLE) += tuner-simple.o
91# tuner-types will be merged into tuner-simple, in the future
92obj-$(CONFIG_TUNER_SIMPLE) += tuner-types.o
93obj-$(CONFIG_TUNER_MT20XX) += mt20xx.o
94obj-$(CONFIG_TUNER_TDA8290) += tda8290.o
95obj-$(CONFIG_TUNER_TEA5767) += tea5767.o
96obj-$(CONFIG_TUNER_TEA5761) += tea5761.o
97obj-$(CONFIG_TUNER_TDA9887) += tda9887.o
98 88
99obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o 89obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
100obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o 90obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
@@ -134,6 +124,7 @@ obj-$(CONFIG_USB_VICAM) += usbvideo/
134obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/ 124obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/
135 125
136obj-$(CONFIG_VIDEO_IVTV) += ivtv/ 126obj-$(CONFIG_VIDEO_IVTV) += ivtv/
127obj-$(CONFIG_VIDEO_CX18) += cx18/
137 128
138obj-$(CONFIG_VIDEO_VIVI) += vivi.o 129obj-$(CONFIG_VIDEO_VIVI) += vivi.o
139obj-$(CONFIG_VIDEO_CX23885) += cx23885/ 130obj-$(CONFIG_VIDEO_CX23885) += cx23885/
@@ -147,3 +138,4 @@ obj-$(CONFIG_VIDEO_AU0828) += au0828/
147 138
148EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 139EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
149EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 140EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
141EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index 41708267e7a4..cab277fafa63 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -4,7 +4,7 @@ config VIDEO_AU0828
4 depends on VIDEO_DEV && I2C && INPUT && DVB_CORE 4 depends on VIDEO_DEV && I2C && INPUT && DVB_CORE
5 select I2C_ALGOBIT 5 select I2C_ALGOBIT
6 select DVB_AU8522 if !DVB_FE_CUSTOMIZE 6 select DVB_AU8522 if !DVB_FE_CUSTOMIZE
7 select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE 7 select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
8 ---help--- 8 ---help---
9 This is a video4linux driver for Auvitek's USB device. 9 This is a video4linux driver for Auvitek's USB device.
10 10
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile
index 9f4f572c89c5..cd2c58281b4e 100644
--- a/drivers/media/video/au0828/Makefile
+++ b/drivers/media/video/au0828/Makefile
@@ -2,7 +2,7 @@ au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o
2 2
3obj-$(CONFIG_VIDEO_AU0828) += au0828.o 3obj-$(CONFIG_VIDEO_AU0828) += au0828.o
4 4
5EXTRA_CFLAGS += -Idrivers/media/video 5EXTRA_CFLAGS += -Idrivers/media/common/tuners
6EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 6EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
7EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 7EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
8 8
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index cfc822bb502a..7431ef6de9f1 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -6,7 +6,7 @@ config VIDEO_BT848
6 select VIDEO_BTCX 6 select VIDEO_BTCX
7 select VIDEOBUF_DMA_SG 7 select VIDEOBUF_DMA_SG
8 select VIDEO_IR 8 select VIDEO_IR
9 select VIDEO_TUNER 9 select MEDIA_TUNER
10 select VIDEO_TVEEPROM 10 select VIDEO_TVEEPROM
11 select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO 11 select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
12 select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO 12 select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile
index 924d216d9570..e415f6fc447c 100644
--- a/drivers/media/video/bt8xx/Makefile
+++ b/drivers/media/video/bt8xx/Makefile
@@ -9,4 +9,5 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
9obj-$(CONFIG_VIDEO_BT848) += bttv.o 9obj-$(CONFIG_VIDEO_BT848) += bttv.o
10 10
11EXTRA_CFLAGS += -Idrivers/media/video 11EXTRA_CFLAGS += -Idrivers/media/video
12EXTRA_CFLAGS += -Idrivers/media/common/tuners
12EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 13EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
new file mode 100644
index 000000000000..be654a27bd3c
--- /dev/null
+++ b/drivers/media/video/cx18/Kconfig
@@ -0,0 +1,20 @@
1config VIDEO_CX18
2 tristate "Conexant cx23418 MPEG encoder support"
3 depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_IR
7 select VIDEO_TUNER
8 select VIDEO_TVEEPROM
9 select VIDEO_CX2341X
10 select VIDEO_CS5345
11 select DVB_S5H1409
12 ---help---
13 This is a video4linux driver for Conexant cx23418 based
14 PCI combo video recorder devices.
15
16 This is used in devices such as the Hauppauge HVR-1600
17 cards.
18
19 To compile this driver as a module, choose M here: the
20 module will be called cx18.
diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/video/cx18/Makefile
new file mode 100644
index 000000000000..b23d2e26120f
--- /dev/null
+++ b/drivers/media/video/cx18/Makefile
@@ -0,0 +1,11 @@
1cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.o \
2 cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \
3 cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \
4 cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \
5 cx18-dvb.o
6
7obj-$(CONFIG_VIDEO_CX18) += cx18.o
8
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
11EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
new file mode 100644
index 000000000000..1adc404d955e
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -0,0 +1,73 @@
1/*
2 * cx18 audio-related functions
3 *
4 * Derived from ivtv-audio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-i2c.h"
26#include "cx18-cards.h"
27#include "cx18-audio.h"
28
29/* Selects the audio input and output according to the current
30 settings. */
31int cx18_audio_set_io(struct cx18 *cx)
32{
33 struct v4l2_routing route;
34 u32 audio_input;
35 int mux_input;
36
37 /* Determine which input to use */
38 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
39 audio_input = cx->card->radio_input.audio_input;
40 mux_input = cx->card->radio_input.muxer_input;
41 } else {
42 audio_input =
43 cx->card->audio_inputs[cx->audio_input].audio_input;
44 mux_input =
45 cx->card->audio_inputs[cx->audio_input].muxer_input;
46 }
47
48 /* handle muxer chips */
49 route.input = mux_input;
50 route.output = 0;
51 cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
52
53 route.input = audio_input;
54 return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
55 VIDIOC_INT_S_AUDIO_ROUTING, &route);
56}
57
58void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route)
59{
60 cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
61 VIDIOC_INT_S_AUDIO_ROUTING, route);
62}
63
64void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq)
65{
66 static u32 freqs[3] = { 44100, 48000, 32000 };
67
68 /* The audio clock of the digitizer must match the codec sample
69 rate otherwise you get some very strange effects. */
70 if (freq > 2)
71 return;
72 cx18_call_i2c_clients(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]);
73}
diff --git a/drivers/media/video/cx18/cx18-audio.h b/drivers/media/video/cx18/cx18-audio.h
new file mode 100644
index 000000000000..cb569a69379c
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-audio.h
@@ -0,0 +1,26 @@
1/*
2 * cx18 audio-related functions
3 *
4 * Derived from ivtv-audio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24int cx18_audio_set_io(struct cx18 *cx);
25void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route);
26void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq);
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
new file mode 100644
index 000000000000..2dc3a5dd170e
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -0,0 +1,361 @@
1/*
2 * cx18 ADEC audio functions
3 *
4 * Derived from cx25840-audio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#include "cx18-driver.h"
25
26static int set_audclk_freq(struct cx18 *cx, u32 freq)
27{
28 struct cx18_av_state *state = &cx->av_state;
29
30 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL;
32
33 /* common for all inputs and rates */
34 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
35 cx18_av_write(cx, 0x127, 0x50);
36
37 if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
38 switch (freq) {
39 case 32000:
40 /* VID_PLL and AUX_PLL */
41 cx18_av_write4(cx, 0x108, 0x1006040f);
42
43 /* AUX_PLL_FRAC */
44 cx18_av_write4(cx, 0x110, 0x01bb39ee);
45
46 /* src3/4/6_ctl = 0x0801f77f */
47 cx18_av_write4(cx, 0x900, 0x0801f77f);
48 cx18_av_write4(cx, 0x904, 0x0801f77f);
49 cx18_av_write4(cx, 0x90c, 0x0801f77f);
50 break;
51
52 case 44100:
53 /* VID_PLL and AUX_PLL */
54 cx18_av_write4(cx, 0x108, 0x1009040f);
55
56 /* AUX_PLL_FRAC */
57 cx18_av_write4(cx, 0x110, 0x00ec6bd6);
58
59 /* src3/4/6_ctl = 0x08016d59 */
60 cx18_av_write4(cx, 0x900, 0x08016d59);
61 cx18_av_write4(cx, 0x904, 0x08016d59);
62 cx18_av_write4(cx, 0x90c, 0x08016d59);
63 break;
64
65 case 48000:
66 /* VID_PLL and AUX_PLL */
67 cx18_av_write4(cx, 0x108, 0x100a040f);
68
69 /* AUX_PLL_FRAC */
70 cx18_av_write4(cx, 0x110, 0x0098d6e5);
71
72 /* src3/4/6_ctl = 0x08014faa */
73 cx18_av_write4(cx, 0x900, 0x08014faa);
74 cx18_av_write4(cx, 0x904, 0x08014faa);
75 cx18_av_write4(cx, 0x90c, 0x08014faa);
76 break;
77 }
78 } else {
79 switch (freq) {
80 case 32000:
81 /* VID_PLL and AUX_PLL */
82 cx18_av_write4(cx, 0x108, 0x1e08040f);
83
84 /* AUX_PLL_FRAC */
85 cx18_av_write4(cx, 0x110, 0x012a0869);
86
87 /* src1_ctl = 0x08010000 */
88 cx18_av_write4(cx, 0x8f8, 0x08010000);
89
90 /* src3/4/6_ctl = 0x08020000 */
91 cx18_av_write4(cx, 0x900, 0x08020000);
92 cx18_av_write4(cx, 0x904, 0x08020000);
93 cx18_av_write4(cx, 0x90c, 0x08020000);
94
95 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
96 cx18_av_write(cx, 0x127, 0x54);
97 break;
98
99 case 44100:
100 /* VID_PLL and AUX_PLL */
101 cx18_av_write4(cx, 0x108, 0x1809040f);
102
103 /* AUX_PLL_FRAC */
104 cx18_av_write4(cx, 0x110, 0x00ec6bd6);
105
106 /* src1_ctl = 0x08010000 */
107 cx18_av_write4(cx, 0x8f8, 0x080160cd);
108
109 /* src3/4/6_ctl = 0x08020000 */
110 cx18_av_write4(cx, 0x900, 0x08017385);
111 cx18_av_write4(cx, 0x904, 0x08017385);
112 cx18_av_write4(cx, 0x90c, 0x08017385);
113 break;
114
115 case 48000:
116 /* VID_PLL and AUX_PLL */
117 cx18_av_write4(cx, 0x108, 0x180a040f);
118
119 /* AUX_PLL_FRAC */
120 cx18_av_write4(cx, 0x110, 0x0098d6e5);
121
122 /* src1_ctl = 0x08010000 */
123 cx18_av_write4(cx, 0x8f8, 0x08018000);
124
125 /* src3/4/6_ctl = 0x08020000 */
126 cx18_av_write4(cx, 0x900, 0x08015555);
127 cx18_av_write4(cx, 0x904, 0x08015555);
128 cx18_av_write4(cx, 0x90c, 0x08015555);
129 break;
130 }
131 }
132
133 state->audclk_freq = freq;
134
135 return 0;
136}
137
138void cx18_av_audio_set_path(struct cx18 *cx)
139{
140 struct cx18_av_state *state = &cx->av_state;
141
142 /* stop microcontroller */
143 cx18_av_and_or(cx, 0x803, ~0x10, 0);
144
145 /* assert soft reset */
146 cx18_av_and_or(cx, 0x810, ~0x1, 0x01);
147
148 /* Mute everything to prevent the PFFT! */
149 cx18_av_write(cx, 0x8d3, 0x1f);
150
151 if (state->aud_input == CX18_AV_AUDIO_SERIAL) {
152 /* Set Path1 to Serial Audio Input */
153 cx18_av_write4(cx, 0x8d0, 0x01011012);
154
155 /* The microcontroller should not be started for the
156 * non-tuner inputs: autodetection is specific for
157 * TV audio. */
158 } else {
159 /* Set Path1 to Analog Demod Main Channel */
160 cx18_av_write4(cx, 0x8d0, 0x1f063870);
161 }
162
163 set_audclk_freq(cx, state->audclk_freq);
164
165 /* deassert soft reset */
166 cx18_av_and_or(cx, 0x810, ~0x1, 0x00);
167
168 if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
169 /* When the microcontroller detects the
170 * audio format, it will unmute the lines */
171 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
172 }
173}
174
175static int get_volume(struct cx18 *cx)
176{
177 /* Volume runs +18dB to -96dB in 1/2dB steps
178 * change to fit the msp3400 -114dB to +12dB range */
179
180 /* check PATH1_VOLUME */
181 int vol = 228 - cx18_av_read(cx, 0x8d4);
182 vol = (vol / 2) + 23;
183 return vol << 9;
184}
185
186static void set_volume(struct cx18 *cx, int volume)
187{
188 /* First convert the volume to msp3400 values (0-127) */
189 int vol = volume >> 9;
190 /* now scale it up to cx18_av values
191 * -114dB to -96dB maps to 0
192 * this should be 19, but in my testing that was 4dB too loud */
193 if (vol <= 23)
194 vol = 0;
195 else
196 vol -= 23;
197
198 /* PATH1_VOLUME */
199 cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
200}
201
202static int get_bass(struct cx18 *cx)
203{
204 /* bass is 49 steps +12dB to -12dB */
205
206 /* check PATH1_EQ_BASS_VOL */
207 int bass = cx18_av_read(cx, 0x8d9) & 0x3f;
208 bass = (((48 - bass) * 0xffff) + 47) / 48;
209 return bass;
210}
211
212static void set_bass(struct cx18 *cx, int bass)
213{
214 /* PATH1_EQ_BASS_VOL */
215 cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
216}
217
218static int get_treble(struct cx18 *cx)
219{
220 /* treble is 49 steps +12dB to -12dB */
221
222 /* check PATH1_EQ_TREBLE_VOL */
223 int treble = cx18_av_read(cx, 0x8db) & 0x3f;
224 treble = (((48 - treble) * 0xffff) + 47) / 48;
225 return treble;
226}
227
228static void set_treble(struct cx18 *cx, int treble)
229{
230 /* PATH1_EQ_TREBLE_VOL */
231 cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
232}
233
234static int get_balance(struct cx18 *cx)
235{
236 /* balance is 7 bit, 0 to -96dB */
237
238 /* check PATH1_BAL_LEVEL */
239 int balance = cx18_av_read(cx, 0x8d5) & 0x7f;
240 /* check PATH1_BAL_LEFT */
241 if ((cx18_av_read(cx, 0x8d5) & 0x80) == 0)
242 balance = 0x80 - balance;
243 else
244 balance = 0x80 + balance;
245 return balance << 8;
246}
247
248static void set_balance(struct cx18 *cx, int balance)
249{
250 int bal = balance >> 8;
251 if (bal > 0x80) {
252 /* PATH1_BAL_LEFT */
253 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80);
254 /* PATH1_BAL_LEVEL */
255 cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f);
256 } else {
257 /* PATH1_BAL_LEFT */
258 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00);
259 /* PATH1_BAL_LEVEL */
260 cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal);
261 }
262}
263
264static int get_mute(struct cx18 *cx)
265{
266 /* check SRC1_MUTE_EN */
267 return cx18_av_read(cx, 0x8d3) & 0x2 ? 1 : 0;
268}
269
270static void set_mute(struct cx18 *cx, int mute)
271{
272 struct cx18_av_state *state = &cx->av_state;
273
274 if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
275 /* Must turn off microcontroller in order to mute sound.
276 * Not sure if this is the best method, but it does work.
277 * If the microcontroller is running, then it will undo any
278 * changes to the mute register. */
279 if (mute) {
280 /* disable microcontroller */
281 cx18_av_and_or(cx, 0x803, ~0x10, 0x00);
282 cx18_av_write(cx, 0x8d3, 0x1f);
283 } else {
284 /* enable microcontroller */
285 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
286 }
287 } else {
288 /* SRC1_MUTE_EN */
289 cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
290 }
291}
292
293int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
294{
295 struct cx18_av_state *state = &cx->av_state;
296 struct v4l2_control *ctrl = arg;
297 int retval;
298
299 switch (cmd) {
300 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
301 if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
302 cx18_av_and_or(cx, 0x803, ~0x10, 0);
303 cx18_av_write(cx, 0x8d3, 0x1f);
304 }
305 cx18_av_and_or(cx, 0x810, ~0x1, 1);
306 retval = set_audclk_freq(cx, *(u32 *)arg);
307 cx18_av_and_or(cx, 0x810, ~0x1, 0);
308 if (state->aud_input != CX18_AV_AUDIO_SERIAL)
309 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
310 return retval;
311
312 case VIDIOC_G_CTRL:
313 switch (ctrl->id) {
314 case V4L2_CID_AUDIO_VOLUME:
315 ctrl->value = get_volume(cx);
316 break;
317 case V4L2_CID_AUDIO_BASS:
318 ctrl->value = get_bass(cx);
319 break;
320 case V4L2_CID_AUDIO_TREBLE:
321 ctrl->value = get_treble(cx);
322 break;
323 case V4L2_CID_AUDIO_BALANCE:
324 ctrl->value = get_balance(cx);
325 break;
326 case V4L2_CID_AUDIO_MUTE:
327 ctrl->value = get_mute(cx);
328 break;
329 default:
330 return -EINVAL;
331 }
332 break;
333
334 case VIDIOC_S_CTRL:
335 switch (ctrl->id) {
336 case V4L2_CID_AUDIO_VOLUME:
337 set_volume(cx, ctrl->value);
338 break;
339 case V4L2_CID_AUDIO_BASS:
340 set_bass(cx, ctrl->value);
341 break;
342 case V4L2_CID_AUDIO_TREBLE:
343 set_treble(cx, ctrl->value);
344 break;
345 case V4L2_CID_AUDIO_BALANCE:
346 set_balance(cx, ctrl->value);
347 break;
348 case V4L2_CID_AUDIO_MUTE:
349 set_mute(cx, ctrl->value);
350 break;
351 default:
352 return -EINVAL;
353 }
354 break;
355
356 default:
357 return -EINVAL;
358 }
359
360 return 0;
361}
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
new file mode 100644
index 000000000000..66864904c99b
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -0,0 +1,879 @@
1/*
2 * cx18 ADEC audio functions
3 *
4 * Derived from cx25840-core.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#include "cx18-driver.h"
25
26int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
27{
28 u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3));
29 u32 mask = 0xff;
30 int shift = (addr & 3) * 8;
31
32 x = (x & ~(mask << shift)) | ((u32)value << shift);
33 writel(x, cx->reg_mem + 0xc40000 + (addr & ~3));
34 return 0;
35}
36
37int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value)
38{
39 writel(value, cx->reg_mem + 0xc40000 + addr);
40 return 0;
41}
42
43u8 cx18_av_read(struct cx18 *cx, u16 addr)
44{
45 u32 x = readl(cx->reg_mem + 0xc40000 + (addr & ~3));
46 int shift = (addr & 3) * 8;
47
48 return (x >> shift) & 0xff;
49}
50
51u32 cx18_av_read4(struct cx18 *cx, u16 addr)
52{
53 return readl(cx->reg_mem + 0xc40000 + addr);
54}
55
56int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
57 u8 or_value)
58{
59 return cx18_av_write(cx, addr,
60 (cx18_av_read(cx, addr) & and_mask) |
61 or_value);
62}
63
64int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
65 u32 or_value)
66{
67 return cx18_av_write4(cx, addr,
68 (cx18_av_read4(cx, addr) & and_mask) |
69 or_value);
70}
71
72/* ----------------------------------------------------------------------- */
73
74static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
75 enum cx18_av_audio_input aud_input);
76static void log_audio_status(struct cx18 *cx);
77static void log_video_status(struct cx18 *cx);
78
79/* ----------------------------------------------------------------------- */
80
81static void cx18_av_initialize(struct cx18 *cx)
82{
83 u32 v;
84
85 cx18_av_loadfw(cx);
86 /* Stop 8051 code execution */
87 cx18_av_write4(cx, CXADEC_DL_CTL, 0x03000000);
88
89 /* initallize the PLL by toggling sleep bit */
90 v = cx18_av_read4(cx, CXADEC_HOST_REG1);
91 /* enable sleep mode */
92 cx18_av_write4(cx, CXADEC_HOST_REG1, v | 1);
93 /* disable sleep mode */
94 cx18_av_write4(cx, CXADEC_HOST_REG1, v & 0xfffe);
95
96 /* initialize DLLs */
97 v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF;
98 /* disable FLD */
99 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v);
100 /* enable FLD */
101 cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100);
102
103 v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF;
104 /* disable FLD */
105 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v);
106 /* enable FLD */
107 cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100);
108
109 /* set analog bias currents. Set Vreg to 1.20V. */
110 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802);
111
112 v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1;
113 /* enable TUNE_FIL_RST */
114 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v);
115 /* disable TUNE_FIL_RST */
116 cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL3, v & 0xFFFFFFFE);
117
118 /* enable 656 output */
119 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00);
120
121 /* video output drive strength */
122 cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2);
123
124 /* reset video */
125 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000);
126 cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0);
127
128 /* set video to auto-detect */
129 /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */
130 /* set the comb notch = 1 */
131 cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800);
132
133 /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */
134 /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */
135 cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000);
136
137 /* Set VGA_TRACK_RANGE to 0x20 */
138 cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
139
140 /* Enable VBI capture */
141 cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F);
142 /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
143
144 /* Set the video input.
145 The setting in MODE_CTRL gets lost when we do the above setup */
146 /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */
147 /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */
148
149 v = cx18_av_read4(cx, CXADEC_AFE_CTRL);
150 v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */
151 v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */
152 v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */
153 /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */
154 cx18_av_write4(cx, CXADEC_AFE_CTRL, v);
155
156/* if(dwEnable && dw3DCombAvailable) { */
157/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
158/* } else { */
159/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
160/* } */
161 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
162}
163
164/* ----------------------------------------------------------------------- */
165
166static void input_change(struct cx18 *cx)
167{
168 struct cx18_av_state *state = &cx->av_state;
169 v4l2_std_id std = state->std;
170
171 /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
172 if (std & V4L2_STD_SECAM)
173 cx18_av_write(cx, 0x402, 0);
174 else {
175 cx18_av_write(cx, 0x402, 0x04);
176 cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
177 }
178 cx18_av_and_or(cx, 0x401, ~0x60, 0);
179 cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
180
181 if (std & V4L2_STD_525_60) {
182 if (std == V4L2_STD_NTSC_M_JP) {
183 /* Japan uses EIAJ audio standard */
184 cx18_av_write(cx, 0x808, 0xf7);
185 } else if (std == V4L2_STD_NTSC_M_KR) {
186 /* South Korea uses A2 audio standard */
187 cx18_av_write(cx, 0x808, 0xf8);
188 } else {
189 /* Others use the BTSC audio standard */
190 cx18_av_write(cx, 0x808, 0xf6);
191 }
192 cx18_av_write(cx, 0x80b, 0x00);
193 } else if (std & V4L2_STD_PAL) {
194 /* Follow tuner change procedure for PAL */
195 cx18_av_write(cx, 0x808, 0xff);
196 cx18_av_write(cx, 0x80b, 0x03);
197 } else if (std & V4L2_STD_SECAM) {
198 /* Select autodetect for SECAM */
199 cx18_av_write(cx, 0x808, 0xff);
200 cx18_av_write(cx, 0x80b, 0x03);
201 }
202
203 if (cx18_av_read(cx, 0x803) & 0x10) {
204 /* restart audio decoder microcontroller */
205 cx18_av_and_or(cx, 0x803, ~0x10, 0x00);
206 cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
207 }
208}
209
210static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
211 enum cx18_av_audio_input aud_input)
212{
213 struct cx18_av_state *state = &cx->av_state;
214 u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
215 vid_input <= CX18_AV_COMPOSITE8);
216 u8 reg;
217
218 CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
219 vid_input, aud_input);
220
221 if (is_composite) {
222 reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
223 } else {
224 int luma = vid_input & 0xf0;
225 int chroma = vid_input & 0xf00;
226
227 if ((vid_input & ~0xff0) ||
228 luma < CX18_AV_SVIDEO_LUMA1 ||
229 luma > CX18_AV_SVIDEO_LUMA4 ||
230 chroma < CX18_AV_SVIDEO_CHROMA4 ||
231 chroma > CX18_AV_SVIDEO_CHROMA8) {
232 CX18_ERR("0x%04x is not a valid video input!\n",
233 vid_input);
234 return -EINVAL;
235 }
236 reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
237 if (chroma >= CX18_AV_SVIDEO_CHROMA7) {
238 reg &= 0x3f;
239 reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2;
240 } else {
241 reg &= 0xcf;
242 reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4;
243 }
244 }
245
246 switch (aud_input) {
247 case CX18_AV_AUDIO_SERIAL:
248 /* do nothing, use serial audio input */
249 break;
250 case CX18_AV_AUDIO4: reg &= ~0x30; break;
251 case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
252 case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
253 case CX18_AV_AUDIO7: reg &= ~0xc0; break;
254 case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
255
256 default:
257 CX18_ERR("0x%04x is not a valid audio input!\n", aud_input);
258 return -EINVAL;
259 }
260
261 cx18_av_write(cx, 0x103, reg);
262 /* Set INPUT_MODE to Composite (0) or S-Video (1) */
263 cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
264 /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
265 cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
266 /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
267 if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
268 cx18_av_and_or(cx, 0x102, ~0x4, 4);
269 else
270 cx18_av_and_or(cx, 0x102, ~0x4, 0);
271 /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/
272
273 state->vid_input = vid_input;
274 state->aud_input = aud_input;
275 cx18_av_audio_set_path(cx);
276 input_change(cx);
277 return 0;
278}
279
280/* ----------------------------------------------------------------------- */
281
282static int set_v4lstd(struct cx18 *cx)
283{
284 struct cx18_av_state *state = &cx->av_state;
285 u8 fmt = 0; /* zero is autodetect */
286 u8 pal_m = 0;
287
288 /* First tests should be against specific std */
289 if (state->std == V4L2_STD_NTSC_M_JP) {
290 fmt = 0x2;
291 } else if (state->std == V4L2_STD_NTSC_443) {
292 fmt = 0x3;
293 } else if (state->std == V4L2_STD_PAL_M) {
294 pal_m = 1;
295 fmt = 0x5;
296 } else if (state->std == V4L2_STD_PAL_N) {
297 fmt = 0x6;
298 } else if (state->std == V4L2_STD_PAL_Nc) {
299 fmt = 0x7;
300 } else if (state->std == V4L2_STD_PAL_60) {
301 fmt = 0x8;
302 } else {
303 /* Then, test against generic ones */
304 if (state->std & V4L2_STD_NTSC)
305 fmt = 0x1;
306 else if (state->std & V4L2_STD_PAL)
307 fmt = 0x4;
308 else if (state->std & V4L2_STD_SECAM)
309 fmt = 0xc;
310 }
311
312 CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt);
313
314 /* Follow step 9 of section 3.16 in the cx18_av datasheet.
315 Without this PAL may display a vertical ghosting effect.
316 This happens for example with the Yuan MPC622. */
317 if (fmt >= 4 && fmt < 8) {
318 /* Set format to NTSC-M */
319 cx18_av_and_or(cx, 0x400, ~0xf, 1);
320 /* Turn off LCOMB */
321 cx18_av_and_or(cx, 0x47b, ~6, 0);
322 }
323 cx18_av_and_or(cx, 0x400, ~0xf, fmt);
324 cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
325 cx18_av_vbi_setup(cx);
326 input_change(cx);
327 return 0;
328}
329
330/* ----------------------------------------------------------------------- */
331
332static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
333{
334 switch (ctrl->id) {
335 case V4L2_CID_BRIGHTNESS:
336 if (ctrl->value < 0 || ctrl->value > 255) {
337 CX18_ERR("invalid brightness setting %d\n",
338 ctrl->value);
339 return -ERANGE;
340 }
341
342 cx18_av_write(cx, 0x414, ctrl->value - 128);
343 break;
344
345 case V4L2_CID_CONTRAST:
346 if (ctrl->value < 0 || ctrl->value > 127) {
347 CX18_ERR("invalid contrast setting %d\n",
348 ctrl->value);
349 return -ERANGE;
350 }
351
352 cx18_av_write(cx, 0x415, ctrl->value << 1);
353 break;
354
355 case V4L2_CID_SATURATION:
356 if (ctrl->value < 0 || ctrl->value > 127) {
357 CX18_ERR("invalid saturation setting %d\n",
358 ctrl->value);
359 return -ERANGE;
360 }
361
362 cx18_av_write(cx, 0x420, ctrl->value << 1);
363 cx18_av_write(cx, 0x421, ctrl->value << 1);
364 break;
365
366 case V4L2_CID_HUE:
367 if (ctrl->value < -127 || ctrl->value > 127) {
368 CX18_ERR("invalid hue setting %d\n", ctrl->value);
369 return -ERANGE;
370 }
371
372 cx18_av_write(cx, 0x422, ctrl->value);
373 break;
374
375 case V4L2_CID_AUDIO_VOLUME:
376 case V4L2_CID_AUDIO_BASS:
377 case V4L2_CID_AUDIO_TREBLE:
378 case V4L2_CID_AUDIO_BALANCE:
379 case V4L2_CID_AUDIO_MUTE:
380 return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl);
381
382 default:
383 return -EINVAL;
384 }
385
386 return 0;
387}
388
389static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
390{
391 switch (ctrl->id) {
392 case V4L2_CID_BRIGHTNESS:
393 ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128;
394 break;
395 case V4L2_CID_CONTRAST:
396 ctrl->value = cx18_av_read(cx, 0x415) >> 1;
397 break;
398 case V4L2_CID_SATURATION:
399 ctrl->value = cx18_av_read(cx, 0x420) >> 1;
400 break;
401 case V4L2_CID_HUE:
402 ctrl->value = (s8)cx18_av_read(cx, 0x422);
403 break;
404 case V4L2_CID_AUDIO_VOLUME:
405 case V4L2_CID_AUDIO_BASS:
406 case V4L2_CID_AUDIO_TREBLE:
407 case V4L2_CID_AUDIO_BALANCE:
408 case V4L2_CID_AUDIO_MUTE:
409 return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl);
410 default:
411 return -EINVAL;
412 }
413
414 return 0;
415}
416
417/* ----------------------------------------------------------------------- */
418
419static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
420{
421 switch (fmt->type) {
422 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
423 return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt);
424 default:
425 return -EINVAL;
426 }
427
428 return 0;
429}
430
431static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
432{
433 struct cx18_av_state *state = &cx->av_state;
434 struct v4l2_pix_format *pix;
435 int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
436 int is_50Hz = !(state->std & V4L2_STD_525_60);
437
438 switch (fmt->type) {
439 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
440 pix = &(fmt->fmt.pix);
441
442 Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4;
443 Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4;
444
445 Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
446 Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
447
448 Vlines = pix->height + (is_50Hz ? 4 : 7);
449
450 if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
451 (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
452 CX18_ERR("%dx%d is not a valid size!\n",
453 pix->width, pix->height);
454 return -ERANGE;
455 }
456
457 HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
458 VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
459 VSC &= 0x1fff;
460
461 if (pix->width >= 385)
462 filter = 0;
463 else if (pix->width > 192)
464 filter = 1;
465 else if (pix->width > 96)
466 filter = 2;
467 else
468 filter = 3;
469
470 CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n",
471 pix->width, pix->height, HSC, VSC);
472
473 /* HSCALE=HSC */
474 cx18_av_write(cx, 0x418, HSC & 0xff);
475 cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff);
476 cx18_av_write(cx, 0x41a, HSC >> 16);
477 /* VSCALE=VSC */
478 cx18_av_write(cx, 0x41c, VSC & 0xff);
479 cx18_av_write(cx, 0x41d, VSC >> 8);
480 /* VS_INTRLACE=1 VFILT=filter */
481 cx18_av_write(cx, 0x41e, 0x8 | filter);
482 break;
483
484 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
485 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
486
487 case V4L2_BUF_TYPE_VBI_CAPTURE:
488 return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
489
490 default:
491 return -EINVAL;
492 }
493
494 return 0;
495}
496
497/* ----------------------------------------------------------------------- */
498
499int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
500{
501 struct cx18_av_state *state = &cx->av_state;
502 struct v4l2_tuner *vt = arg;
503 struct v4l2_routing *route = arg;
504
505 /* ignore these commands */
506 switch (cmd) {
507 case TUNER_SET_TYPE_ADDR:
508 return 0;
509 }
510
511 if (!state->is_initialized) {
512 CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd);
513 /* initialize on first use */
514 state->is_initialized = 1;
515 cx18_av_initialize(cx);
516 }
517
518 switch (cmd) {
519 case VIDIOC_INT_DECODE_VBI_LINE:
520 return cx18_av_vbi(cx, cmd, arg);
521
522 case VIDIOC_INT_AUDIO_CLOCK_FREQ:
523 return cx18_av_audio(cx, cmd, arg);
524
525 case VIDIOC_STREAMON:
526 CX18_DEBUG_INFO("enable output\n");
527 cx18_av_write(cx, 0x115, 0x8c);
528 cx18_av_write(cx, 0x116, 0x07);
529 break;
530
531 case VIDIOC_STREAMOFF:
532 CX18_DEBUG_INFO("disable output\n");
533 cx18_av_write(cx, 0x115, 0x00);
534 cx18_av_write(cx, 0x116, 0x00);
535 break;
536
537 case VIDIOC_LOG_STATUS:
538 log_video_status(cx);
539 log_audio_status(cx);
540 break;
541
542 case VIDIOC_G_CTRL:
543 return get_v4lctrl(cx, (struct v4l2_control *)arg);
544
545 case VIDIOC_S_CTRL:
546 return set_v4lctrl(cx, (struct v4l2_control *)arg);
547
548 case VIDIOC_QUERYCTRL:
549 {
550 struct v4l2_queryctrl *qc = arg;
551
552 switch (qc->id) {
553 case V4L2_CID_BRIGHTNESS:
554 case V4L2_CID_CONTRAST:
555 case V4L2_CID_SATURATION:
556 case V4L2_CID_HUE:
557 return v4l2_ctrl_query_fill_std(qc);
558 default:
559 break;
560 }
561
562 switch (qc->id) {
563 case V4L2_CID_AUDIO_VOLUME:
564 case V4L2_CID_AUDIO_MUTE:
565 case V4L2_CID_AUDIO_BALANCE:
566 case V4L2_CID_AUDIO_BASS:
567 case V4L2_CID_AUDIO_TREBLE:
568 return v4l2_ctrl_query_fill_std(qc);
569 default:
570 return -EINVAL;
571 }
572 return -EINVAL;
573 }
574
575 case VIDIOC_G_STD:
576 *(v4l2_std_id *)arg = state->std;
577 break;
578
579 case VIDIOC_S_STD:
580 if (state->radio == 0 && state->std == *(v4l2_std_id *)arg)
581 return 0;
582 state->radio = 0;
583 state->std = *(v4l2_std_id *)arg;
584 return set_v4lstd(cx);
585
586 case AUDC_SET_RADIO:
587 state->radio = 1;
588 break;
589
590 case VIDIOC_INT_G_VIDEO_ROUTING:
591 route->input = state->vid_input;
592 route->output = 0;
593 break;
594
595 case VIDIOC_INT_S_VIDEO_ROUTING:
596 return set_input(cx, route->input, state->aud_input);
597
598 case VIDIOC_INT_G_AUDIO_ROUTING:
599 route->input = state->aud_input;
600 route->output = 0;
601 break;
602
603 case VIDIOC_INT_S_AUDIO_ROUTING:
604 return set_input(cx, state->vid_input, route->input);
605
606 case VIDIOC_S_FREQUENCY:
607 input_change(cx);
608 break;
609
610 case VIDIOC_G_TUNER:
611 {
612 u8 vpres = cx18_av_read(cx, 0x40e) & 0x20;
613 u8 mode;
614 int val = 0;
615
616 if (state->radio)
617 break;
618
619 vt->signal = vpres ? 0xffff : 0x0;
620
621 vt->capability |=
622 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
623 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
624
625 mode = cx18_av_read(cx, 0x804);
626
627 /* get rxsubchans and audmode */
628 if ((mode & 0xf) == 1)
629 val |= V4L2_TUNER_SUB_STEREO;
630 else
631 val |= V4L2_TUNER_SUB_MONO;
632
633 if (mode == 2 || mode == 4)
634 val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
635
636 if (mode & 0x10)
637 val |= V4L2_TUNER_SUB_SAP;
638
639 vt->rxsubchans = val;
640 vt->audmode = state->audmode;
641 break;
642 }
643
644 case VIDIOC_S_TUNER:
645 if (state->radio)
646 break;
647
648 switch (vt->audmode) {
649 case V4L2_TUNER_MODE_MONO:
650 /* mono -> mono
651 stereo -> mono
652 bilingual -> lang1 */
653 cx18_av_and_or(cx, 0x809, ~0xf, 0x00);
654 break;
655 case V4L2_TUNER_MODE_STEREO:
656 case V4L2_TUNER_MODE_LANG1:
657 /* mono -> mono
658 stereo -> stereo
659 bilingual -> lang1 */
660 cx18_av_and_or(cx, 0x809, ~0xf, 0x04);
661 break;
662 case V4L2_TUNER_MODE_LANG1_LANG2:
663 /* mono -> mono
664 stereo -> stereo
665 bilingual -> lang1/lang2 */
666 cx18_av_and_or(cx, 0x809, ~0xf, 0x07);
667 break;
668 case V4L2_TUNER_MODE_LANG2:
669 /* mono -> mono
670 stereo -> stereo
671 bilingual -> lang2 */
672 cx18_av_and_or(cx, 0x809, ~0xf, 0x01);
673 break;
674 default:
675 return -EINVAL;
676 }
677 state->audmode = vt->audmode;
678 break;
679
680 case VIDIOC_G_FMT:
681 return get_v4lfmt(cx, (struct v4l2_format *)arg);
682
683 case VIDIOC_S_FMT:
684 return set_v4lfmt(cx, (struct v4l2_format *)arg);
685
686 case VIDIOC_INT_RESET:
687 cx18_av_initialize(cx);
688 break;
689
690 default:
691 return -EINVAL;
692 }
693
694 return 0;
695}
696
697/* ----------------------------------------------------------------------- */
698
699/* ----------------------------------------------------------------------- */
700
701static void log_video_status(struct cx18 *cx)
702{
703 static const char *const fmt_strs[] = {
704 "0x0",
705 "NTSC-M", "NTSC-J", "NTSC-4.43",
706 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
707 "0x9", "0xA", "0xB",
708 "SECAM",
709 "0xD", "0xE", "0xF"
710 };
711
712 struct cx18_av_state *state = &cx->av_state;
713 u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
714 u8 gen_stat1 = cx18_av_read(cx, 0x40d);
715 u8 gen_stat2 = cx18_av_read(cx, 0x40e);
716 int vid_input = state->vid_input;
717
718 CX18_INFO("Video signal: %spresent\n",
719 (gen_stat2 & 0x20) ? "" : "not ");
720 CX18_INFO("Detected format: %s\n",
721 fmt_strs[gen_stat1 & 0xf]);
722
723 CX18_INFO("Specified standard: %s\n",
724 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
725
726 if (vid_input >= CX18_AV_COMPOSITE1 &&
727 vid_input <= CX18_AV_COMPOSITE8) {
728 CX18_INFO("Specified video input: Composite %d\n",
729 vid_input - CX18_AV_COMPOSITE1 + 1);
730 } else {
731 CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
732 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
733 }
734
735 CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq);
736}
737
738/* ----------------------------------------------------------------------- */
739
740static void log_audio_status(struct cx18 *cx)
741{
742 struct cx18_av_state *state = &cx->av_state;
743 u8 download_ctl = cx18_av_read(cx, 0x803);
744 u8 mod_det_stat0 = cx18_av_read(cx, 0x805);
745 u8 mod_det_stat1 = cx18_av_read(cx, 0x804);
746 u8 audio_config = cx18_av_read(cx, 0x808);
747 u8 pref_mode = cx18_av_read(cx, 0x809);
748 u8 afc0 = cx18_av_read(cx, 0x80b);
749 u8 mute_ctl = cx18_av_read(cx, 0x8d3);
750 int aud_input = state->aud_input;
751 char *p;
752
753 switch (mod_det_stat0) {
754 case 0x00: p = "mono"; break;
755 case 0x01: p = "stereo"; break;
756 case 0x02: p = "dual"; break;
757 case 0x04: p = "tri"; break;
758 case 0x10: p = "mono with SAP"; break;
759 case 0x11: p = "stereo with SAP"; break;
760 case 0x12: p = "dual with SAP"; break;
761 case 0x14: p = "tri with SAP"; break;
762 case 0xfe: p = "forced mode"; break;
763 default: p = "not defined";
764 }
765 CX18_INFO("Detected audio mode: %s\n", p);
766
767 switch (mod_det_stat1) {
768 case 0x00: p = "BTSC"; break;
769 case 0x01: p = "EIAJ"; break;
770 case 0x02: p = "A2-M"; break;
771 case 0x03: p = "A2-BG"; break;
772 case 0x04: p = "A2-DK1"; break;
773 case 0x05: p = "A2-DK2"; break;
774 case 0x06: p = "A2-DK3"; break;
775 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
776 case 0x08: p = "AM-L"; break;
777 case 0x09: p = "NICAM-BG"; break;
778 case 0x0a: p = "NICAM-DK"; break;
779 case 0x0b: p = "NICAM-I"; break;
780 case 0x0c: p = "NICAM-L"; break;
781 case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
782 case 0xff: p = "no detected audio standard"; break;
783 default: p = "not defined";
784 }
785 CX18_INFO("Detected audio standard: %s\n", p);
786 CX18_INFO("Audio muted: %s\n",
787 (mute_ctl & 0x2) ? "yes" : "no");
788 CX18_INFO("Audio microcontroller: %s\n",
789 (download_ctl & 0x10) ? "running" : "stopped");
790
791 switch (audio_config >> 4) {
792 case 0x00: p = "BTSC"; break;
793 case 0x01: p = "EIAJ"; break;
794 case 0x02: p = "A2-M"; break;
795 case 0x03: p = "A2-BG"; break;
796 case 0x04: p = "A2-DK1"; break;
797 case 0x05: p = "A2-DK2"; break;
798 case 0x06: p = "A2-DK3"; break;
799 case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
800 case 0x08: p = "AM-L"; break;
801 case 0x09: p = "NICAM-BG"; break;
802 case 0x0a: p = "NICAM-DK"; break;
803 case 0x0b: p = "NICAM-I"; break;
804 case 0x0c: p = "NICAM-L"; break;
805 case 0x0d: p = "FM radio"; break;
806 case 0x0f: p = "automatic detection"; break;
807 default: p = "undefined";
808 }
809 CX18_INFO("Configured audio standard: %s\n", p);
810
811 if ((audio_config >> 4) < 0xF) {
812 switch (audio_config & 0xF) {
813 case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
814 case 0x01: p = "MONO2 (LANGUAGE B)"; break;
815 case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
816 case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
817 case 0x04: p = "STEREO"; break;
818 case 0x05: p = "DUAL1 (AB)"; break;
819 case 0x06: p = "DUAL2 (AC) (FM)"; break;
820 case 0x07: p = "DUAL3 (BC) (FM)"; break;
821 case 0x08: p = "DUAL4 (AC) (AM)"; break;
822 case 0x09: p = "DUAL5 (BC) (AM)"; break;
823 case 0x0a: p = "SAP"; break;
824 default: p = "undefined";
825 }
826 CX18_INFO("Configured audio mode: %s\n", p);
827 } else {
828 switch (audio_config & 0xF) {
829 case 0x00: p = "BG"; break;
830 case 0x01: p = "DK1"; break;
831 case 0x02: p = "DK2"; break;
832 case 0x03: p = "DK3"; break;
833 case 0x04: p = "I"; break;
834 case 0x05: p = "L"; break;
835 case 0x06: p = "BTSC"; break;
836 case 0x07: p = "EIAJ"; break;
837 case 0x08: p = "A2-M"; break;
838 case 0x09: p = "FM Radio"; break;
839 case 0x0f: p = "automatic standard and mode detection"; break;
840 default: p = "undefined";
841 }
842 CX18_INFO("Configured audio system: %s\n", p);
843 }
844
845 if (aud_input)
846 CX18_INFO("Specified audio input: Tuner (In%d)\n",
847 aud_input);
848 else
849 CX18_INFO("Specified audio input: External\n");
850
851 switch (pref_mode & 0xf) {
852 case 0: p = "mono/language A"; break;
853 case 1: p = "language B"; break;
854 case 2: p = "language C"; break;
855 case 3: p = "analog fallback"; break;
856 case 4: p = "stereo"; break;
857 case 5: p = "language AC"; break;
858 case 6: p = "language BC"; break;
859 case 7: p = "language AB"; break;
860 default: p = "undefined";
861 }
862 CX18_INFO("Preferred audio mode: %s\n", p);
863
864 if ((audio_config & 0xf) == 0xf) {
865 switch ((afc0 >> 2) & 0x1) {
866 case 0: p = "system DK"; break;
867 case 1: p = "system L"; break;
868 }
869 CX18_INFO("Selected 65 MHz format: %s\n", p);
870
871 switch (afc0 & 0x3) {
872 case 0: p = "BTSC"; break;
873 case 1: p = "EIAJ"; break;
874 case 2: p = "A2-M"; break;
875 default: p = "undefined";
876 }
877 CX18_INFO("Selected 45 MHz format: %s\n", p);
878 }
879}
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
new file mode 100644
index 000000000000..786901d72e9a
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -0,0 +1,318 @@
1/*
2 * cx18 ADEC header
3 *
4 * Derived from cx25840-core.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24#ifndef _CX18_AV_CORE_H_
25#define _CX18_AV_CORE_H_
26
27struct cx18;
28
29enum cx18_av_video_input {
30 /* Composite video inputs In1-In8 */
31 CX18_AV_COMPOSITE1 = 1,
32 CX18_AV_COMPOSITE2,
33 CX18_AV_COMPOSITE3,
34 CX18_AV_COMPOSITE4,
35 CX18_AV_COMPOSITE5,
36 CX18_AV_COMPOSITE6,
37 CX18_AV_COMPOSITE7,
38 CX18_AV_COMPOSITE8,
39
40 /* S-Video inputs consist of one luma input (In1-In4) ORed with one
41 chroma input (In5-In8) */
42 CX18_AV_SVIDEO_LUMA1 = 0x10,
43 CX18_AV_SVIDEO_LUMA2 = 0x20,
44 CX18_AV_SVIDEO_LUMA3 = 0x30,
45 CX18_AV_SVIDEO_LUMA4 = 0x40,
46 CX18_AV_SVIDEO_CHROMA4 = 0x400,
47 CX18_AV_SVIDEO_CHROMA5 = 0x500,
48 CX18_AV_SVIDEO_CHROMA6 = 0x600,
49 CX18_AV_SVIDEO_CHROMA7 = 0x700,
50 CX18_AV_SVIDEO_CHROMA8 = 0x800,
51
52 /* S-Video aliases for common luma/chroma combinations */
53 CX18_AV_SVIDEO1 = 0x510,
54 CX18_AV_SVIDEO2 = 0x620,
55 CX18_AV_SVIDEO3 = 0x730,
56 CX18_AV_SVIDEO4 = 0x840,
57};
58
59enum cx18_av_audio_input {
60 /* Audio inputs: serial or In4-In8 */
61 CX18_AV_AUDIO_SERIAL,
62 CX18_AV_AUDIO4 = 4,
63 CX18_AV_AUDIO5,
64 CX18_AV_AUDIO6,
65 CX18_AV_AUDIO7,
66 CX18_AV_AUDIO8,
67};
68
69struct cx18_av_state {
70 int radio;
71 v4l2_std_id std;
72 enum cx18_av_video_input vid_input;
73 enum cx18_av_audio_input aud_input;
74 u32 audclk_freq;
75 int audmode;
76 int vbi_line_offset;
77 u32 id;
78 u32 rev;
79 int is_initialized;
80};
81
82
83/* Registers */
84#define CXADEC_CHIP_TYPE_TIGER 0x837
85#define CXADEC_CHIP_TYPE_MAKO 0x843
86
87#define CXADEC_HOST_REG1 0x000
88#define CXADEC_HOST_REG2 0x001
89
90#define CXADEC_CHIP_CTRL 0x100
91#define CXADEC_AFE_CTRL 0x104
92#define CXADEC_PLL_CTRL1 0x108
93#define CXADEC_VID_PLL_FRAC 0x10C
94#define CXADEC_AUX_PLL_FRAC 0x110
95#define CXADEC_PIN_CTRL1 0x114
96#define CXADEC_PIN_CTRL2 0x118
97#define CXADEC_PIN_CFG1 0x11C
98#define CXADEC_PIN_CFG2 0x120
99
100#define CXADEC_PIN_CFG3 0x124
101#define CXADEC_I2S_MCLK 0x127
102
103#define CXADEC_AUD_LOCK1 0x128
104#define CXADEC_AUD_LOCK2 0x12C
105#define CXADEC_POWER_CTRL 0x130
106#define CXADEC_AFE_DIAG_CTRL1 0x134
107#define CXADEC_AFE_DIAG_CTRL2 0x138
108#define CXADEC_AFE_DIAG_CTRL3 0x13C
109#define CXADEC_PLL_DIAG_CTRL 0x140
110#define CXADEC_TEST_CTRL1 0x144
111#define CXADEC_TEST_CTRL2 0x148
112#define CXADEC_BIST_STAT 0x14C
113#define CXADEC_DLL1_DIAG_CTRL 0x158
114#define CXADEC_DLL2_DIAG_CTRL 0x15C
115
116/* IR registers */
117#define CXADEC_IR_CTRL_REG 0x200
118#define CXADEC_IR_TXCLK_REG 0x204
119#define CXADEC_IR_RXCLK_REG 0x208
120#define CXADEC_IR_CDUTY_REG 0x20C
121#define CXADEC_IR_STAT_REG 0x210
122#define CXADEC_IR_IRQEN_REG 0x214
123#define CXADEC_IR_FILTER_REG 0x218
124#define CXADEC_IR_FIFO_REG 0x21C
125
126/* Video Registers */
127#define CXADEC_MODE_CTRL 0x400
128#define CXADEC_OUT_CTRL1 0x404
129#define CXADEC_OUT_CTRL2 0x408
130#define CXADEC_GEN_STAT 0x40C
131#define CXADEC_INT_STAT_MASK 0x410
132#define CXADEC_LUMA_CTRL 0x414
133
134#define CXADEC_BRIGHTNESS_CTRL_BYTE 0x414
135#define CXADEC_CONTRAST_CTRL_BYTE 0x415
136#define CXADEC_LUMA_CTRL_BYTE_3 0x416
137
138#define CXADEC_HSCALE_CTRL 0x418
139#define CXADEC_VSCALE_CTRL 0x41C
140
141#define CXADEC_CHROMA_CTRL 0x420
142
143#define CXADEC_USAT_CTRL_BYTE 0x420
144#define CXADEC_VSAT_CTRL_BYTE 0x421
145#define CXADEC_HUE_CTRL_BYTE 0x422
146
147#define CXADEC_VBI_LINE_CTRL1 0x424
148#define CXADEC_VBI_LINE_CTRL2 0x428
149#define CXADEC_VBI_LINE_CTRL3 0x42C
150#define CXADEC_VBI_LINE_CTRL4 0x430
151#define CXADEC_VBI_LINE_CTRL5 0x434
152#define CXADEC_VBI_FC_CFG 0x438
153#define CXADEC_VBI_MISC_CFG1 0x43C
154#define CXADEC_VBI_MISC_CFG2 0x440
155#define CXADEC_VBI_PAY1 0x444
156#define CXADEC_VBI_PAY2 0x448
157#define CXADEC_VBI_CUST1_CFG1 0x44C
158#define CXADEC_VBI_CUST1_CFG2 0x450
159#define CXADEC_VBI_CUST1_CFG3 0x454
160#define CXADEC_VBI_CUST2_CFG1 0x458
161#define CXADEC_VBI_CUST2_CFG2 0x45C
162#define CXADEC_VBI_CUST2_CFG3 0x460
163#define CXADEC_VBI_CUST3_CFG1 0x464
164#define CXADEC_VBI_CUST3_CFG2 0x468
165#define CXADEC_VBI_CUST3_CFG3 0x46C
166#define CXADEC_HORIZ_TIM_CTRL 0x470
167#define CXADEC_VERT_TIM_CTRL 0x474
168#define CXADEC_SRC_COMB_CFG 0x478
169#define CXADEC_CHROMA_VBIOFF_CFG 0x47C
170#define CXADEC_FIELD_COUNT 0x480
171#define CXADEC_MISC_TIM_CTRL 0x484
172#define CXADEC_DFE_CTRL1 0x488
173#define CXADEC_DFE_CTRL2 0x48C
174#define CXADEC_DFE_CTRL3 0x490
175#define CXADEC_PLL_CTRL2 0x494
176#define CXADEC_HTL_CTRL 0x498
177#define CXADEC_COMB_CTRL 0x49C
178#define CXADEC_CRUSH_CTRL 0x4A0
179#define CXADEC_SOFT_RST_CTRL 0x4A4
180#define CXADEC_MV_DT_CTRL2 0x4A8
181#define CXADEC_MV_DT_CTRL3 0x4AC
182#define CXADEC_MISC_DIAG_CTRL 0x4B8
183
184#define CXADEC_DL_CTL 0x800
185#define CXADEC_DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */
186#define CXADEC_DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */
187#define CXADEC_DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */
188#define CXADEC_DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */
189
190#define CXADEC_STD_DET_STATUS 0x804
191
192#define CXADEC_STD_DET_CTL 0x808
193#define CXADEC_STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */
194#define CXADEC_STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */
195
196#define CXADEC_DW8051_INT 0x80C
197#define CXADEC_GENERAL_CTL 0x810
198#define CXADEC_AAGC_CTL 0x814
199#define CXADEC_IF_SRC_CTL 0x818
200#define CXADEC_ANLOG_DEMOD_CTL 0x81C
201#define CXADEC_ROT_FREQ_CTL 0x820
202#define CXADEC_FM1_CTL 0x824
203#define CXADEC_PDF_CTL 0x828
204#define CXADEC_DFT1_CTL1 0x82C
205#define CXADEC_DFT1_CTL2 0x830
206#define CXADEC_DFT_STATUS 0x834
207#define CXADEC_DFT2_CTL1 0x838
208#define CXADEC_DFT2_CTL2 0x83C
209#define CXADEC_DFT2_STATUS 0x840
210#define CXADEC_DFT3_CTL1 0x844
211#define CXADEC_DFT3_CTL2 0x848
212#define CXADEC_DFT3_STATUS 0x84C
213#define CXADEC_DFT4_CTL1 0x850
214#define CXADEC_DFT4_CTL2 0x854
215#define CXADEC_DFT4_STATUS 0x858
216#define CXADEC_AM_MTS_DET 0x85C
217#define CXADEC_ANALOG_MUX_CTL 0x860
218#define CXADEC_DIG_PLL_CTL1 0x864
219#define CXADEC_DIG_PLL_CTL2 0x868
220#define CXADEC_DIG_PLL_CTL3 0x86C
221#define CXADEC_DIG_PLL_CTL4 0x870
222#define CXADEC_DIG_PLL_CTL5 0x874
223#define CXADEC_DEEMPH_GAIN_CTL 0x878
224#define CXADEC_DEEMPH_COEF1 0x87C
225#define CXADEC_DEEMPH_COEF2 0x880
226#define CXADEC_DBX1_CTL1 0x884
227#define CXADEC_DBX1_CTL2 0x888
228#define CXADEC_DBX1_STATUS 0x88C
229#define CXADEC_DBX2_CTL1 0x890
230#define CXADEC_DBX2_CTL2 0x894
231#define CXADEC_DBX2_STATUS 0x898
232#define CXADEC_AM_FM_DIFF 0x89C
233
234/* NICAM registers go here */
235#define CXADEC_NICAM_STATUS 0x8C8
236#define CXADEC_DEMATRIX_CTL 0x8CC
237
238#define CXADEC_PATH1_CTL1 0x8D0
239#define CXADEC_PATH1_VOL_CTL 0x8D4
240#define CXADEC_PATH1_EQ_CTL 0x8D8
241#define CXADEC_PATH1_SC_CTL 0x8DC
242
243#define CXADEC_PATH2_CTL1 0x8E0
244#define CXADEC_PATH2_VOL_CTL 0x8E4
245#define CXADEC_PATH2_EQ_CTL 0x8E8
246#define CXADEC_PATH2_SC_CTL 0x8EC
247
248#define CXADEC_SRC_CTL 0x8F0
249#define CXADEC_SRC_LF_COEF 0x8F4
250#define CXADEC_SRC1_CTL 0x8F8
251#define CXADEC_SRC2_CTL 0x8FC
252#define CXADEC_SRC3_CTL 0x900
253#define CXADEC_SRC4_CTL 0x904
254#define CXADEC_SRC5_CTL 0x908
255#define CXADEC_SRC6_CTL 0x90C
256
257#define CXADEC_BASEBAND_OUT_SEL 0x910
258#define CXADEC_I2S_IN_CTL 0x914
259#define CXADEC_I2S_OUT_CTL 0x918
260#define CXADEC_AC97_CTL 0x91C
261#define CXADEC_QAM_PDF 0x920
262#define CXADEC_QAM_CONST_DEC 0x924
263#define CXADEC_QAM_ROTATOR_FREQ 0x948
264
265/* Bit defintions / settings used in Mako Audio */
266#define CXADEC_PREF_MODE_MONO_LANGA 0
267#define CXADEC_PREF_MODE_MONO_LANGB 1
268#define CXADEC_PREF_MODE_MONO_LANGC 2
269#define CXADEC_PREF_MODE_FALLBACK 3
270#define CXADEC_PREF_MODE_STEREO 4
271#define CXADEC_PREF_MODE_DUAL_LANG_AC 5
272#define CXADEC_PREF_MODE_DUAL_LANG_BC 6
273#define CXADEC_PREF_MODE_DUAL_LANG_AB 7
274
275
276#define CXADEC_DETECT_STEREO 1
277#define CXADEC_DETECT_DUAL 2
278#define CXADEC_DETECT_TRI 4
279#define CXADEC_DETECT_SAP 0x10
280#define CXADEC_DETECT_NO_SIGNAL 0xFF
281
282#define CXADEC_SELECT_AUDIO_STANDARD_BG 0xF0 /* NICAM BG and A2 BG */
283#define CXADEC_SELECT_AUDIO_STANDARD_DK1 0xF1 /* NICAM DK and A2 DK */
284#define CXADEC_SELECT_AUDIO_STANDARD_DK2 0xF2
285#define CXADEC_SELECT_AUDIO_STANDARD_DK3 0xF3
286#define CXADEC_SELECT_AUDIO_STANDARD_I 0xF4 /* NICAM I and A1 */
287#define CXADEC_SELECT_AUDIO_STANDARD_L 0xF5 /* NICAM L and System L AM */
288#define CXADEC_SELECT_AUDIO_STANDARD_BTSC 0xF6
289#define CXADEC_SELECT_AUDIO_STANDARD_EIAJ 0xF7
290#define CXADEC_SELECT_AUDIO_STANDARD_A2_M 0xF8 /* A2 M */
291#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
292#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
293
294/* ----------------------------------------------------------------------- */
295/* cx18_av-core.c */
296int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
297int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
298u8 cx18_av_read(struct cx18 *cx, u16 addr);
299u32 cx18_av_read4(struct cx18 *cx, u16 addr);
300int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
301int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
302int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
303
304/* ----------------------------------------------------------------------- */
305/* cx18_av-firmware.c */
306int cx18_av_loadfw(struct cx18 *cx);
307
308/* ----------------------------------------------------------------------- */
309/* cx18_av-audio.c */
310int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg);
311void cx18_av_audio_set_path(struct cx18 *cx);
312
313/* ----------------------------------------------------------------------- */
314/* cx18_av-vbi.c */
315void cx18_av_vbi_setup(struct cx18 *cx);
316int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg);
317
318#endif
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
new file mode 100644
index 000000000000..526e142156cd
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -0,0 +1,120 @@
1/*
2 * cx18 ADEC firmware functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA.
20 */
21
22#include "cx18-driver.h"
23#include <linux/firmware.h>
24
25#define FWFILE "v4l-cx23418-dig.fw"
26
27int cx18_av_loadfw(struct cx18 *cx)
28{
29 const struct firmware *fw = NULL;
30 u32 size;
31 u32 v;
32 u8 *ptr;
33 int i;
34
35 if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
36 CX18_ERR("unable to open firmware %s\n", FWFILE);
37 return -EINVAL;
38 }
39
40 cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
41 cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); /* Byte 0 */
42
43 /* Reset the Mako core (Register is undocumented.) */
44 cx18_av_write4(cx, 0x8100, 0x00010000);
45
46 /* Put the 8051 in reset and enable firmware upload */
47 cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000);
48
49 ptr = fw->data;
50 size = fw->size;
51
52 for (i = 0; i < size; i++) {
53 u32 dl_control = 0x0F000000 | ((u32)ptr[i] << 16);
54 u32 value = 0;
55 int retries;
56
57 for (retries = 0; retries < 5; retries++) {
58 cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
59 value = cx18_av_read4(cx, CXADEC_DL_CTL);
60 if ((value & 0x3F00) == (dl_control & 0x3F00))
61 break;
62 }
63 if (retries >= 5) {
64 CX18_ERR("unable to load firmware %s\n", FWFILE);
65 release_firmware(fw);
66 return -EIO;
67 }
68 }
69
70 cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size);
71
72 /* Output to the 416 */
73 cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
74
75 /* Audio input control 1 set to Sony mode */
76 /* Audio output input 2 is 0 for slave operation input */
77 /* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
78 /* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
79 after WS transition for first bit of audio word. */
80 cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0);
81
82 /* Audio output control 1 is set to Sony mode */
83 /* Audio output control 2 is set to 1 for master mode */
84 /* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */
85 /* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge
86 after WS transition for first bit of audio word. */
87 /* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT
88 are generated) */
89 cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
90
91 /* set alt I2s master clock to /16 and enable alt divider i2s
92 passthrough */
93 cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
94
95 cx18_av_write4(cx, CXADEC_STD_DET_CTL, 0x000000F6);
96 /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */
97
98 /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */
99 /* Register 0x09CC is defined by the Merlin firmware, and doesn't
100 have a name in the spec. */
101 cx18_av_write4(cx, 0x09CC, 1);
102
103#define CX18_AUDIO_ENABLE 0xc72014
104 v = read_reg(CX18_AUDIO_ENABLE);
105 /* If bit 11 is 1 */
106 if (v & 0x800)
107 write_reg(v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); /* Clear bit 10 */
108
109 /* Enable WW auto audio standard detection */
110 v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
111 v |= 0xFF; /* Auto by default */
112 v |= 0x400; /* Stereo by default */
113 v |= 0x14000000;
114 cx18_av_write4(cx, CXADEC_STD_DET_CTL, v);
115
116 release_firmware(fw);
117
118 CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size);
119 return 0;
120}
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
new file mode 100644
index 000000000000..d09f1daf4ebf
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -0,0 +1,413 @@
1/*
2 * cx18 ADEC VBI functions
3 *
4 * Derived from cx25840-vbi.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 */
23
24
25#include "cx18-driver.h"
26
27static int odd_parity(u8 c)
28{
29 c ^= (c >> 4);
30 c ^= (c >> 2);
31 c ^= (c >> 1);
32
33 return c & 1;
34}
35
36static int decode_vps(u8 *dst, u8 *p)
37{
38 static const u8 biphase_tbl[] = {
39 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
40 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
41 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
42 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
43 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
44 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
45 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
46 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
47 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
48 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
49 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
50 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
51 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
52 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
53 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
54 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
55 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
56 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
57 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
58 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
59 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
60 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
61 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
62 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
63 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
64 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
65 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
66 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
67 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
68 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
69 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
70 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
71 };
72
73 u8 c, err = 0;
74 int i;
75
76 for (i = 0; i < 2 * 13; i += 2) {
77 err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
78 c = (biphase_tbl[p[i + 1]] & 0xf) |
79 ((biphase_tbl[p[i]] & 0xf) << 4);
80 dst[i / 2] = c;
81 }
82
83 return err & 0xf0;
84}
85
86void cx18_av_vbi_setup(struct cx18 *cx)
87{
88 struct cx18_av_state *state = &cx->av_state;
89 v4l2_std_id std = state->std;
90 int hblank, hactive, burst, vblank, vactive, sc;
91 int vblank656, src_decimation;
92 int luma_lpf, uv_lpf, comb;
93 u32 pll_int, pll_frac, pll_post;
94
95 /* datasheet startup, step 8d */
96 if (std & ~V4L2_STD_NTSC)
97 cx18_av_write(cx, 0x49f, 0x11);
98 else
99 cx18_av_write(cx, 0x49f, 0x14);
100
101 if (std & V4L2_STD_625_50) {
102 hblank = 0x084;
103 hactive = 0x2d0;
104 burst = 0x5d;
105 vblank = 0x024;
106 vactive = 0x244;
107 vblank656 = 0x28;
108 src_decimation = 0x21f;
109
110 luma_lpf = 2;
111 if (std & V4L2_STD_SECAM) {
112 uv_lpf = 0;
113 comb = 0;
114 sc = 0x0a425f;
115 } else if (std == V4L2_STD_PAL_Nc) {
116 uv_lpf = 1;
117 comb = 0x20;
118 sc = 556453;
119 } else {
120 uv_lpf = 1;
121 comb = 0x20;
122 sc = 0x0a8263;
123 }
124 } else {
125 hactive = 720;
126 hblank = 122;
127 vactive = 487;
128 luma_lpf = 1;
129 uv_lpf = 1;
130
131 src_decimation = 0x21f;
132 if (std == V4L2_STD_PAL_60) {
133 vblank = 26;
134 vblank656 = 26;
135 burst = 0x5b;
136 luma_lpf = 2;
137 comb = 0x20;
138 sc = 0x0a8263;
139 } else if (std == V4L2_STD_PAL_M) {
140 vblank = 20;
141 vblank656 = 24;
142 burst = 0x61;
143 comb = 0x20;
144
145 sc = 555452;
146 } else {
147 vblank = 26;
148 vblank656 = 26;
149 burst = 0x5b;
150 comb = 0x66;
151 sc = 556063;
152 }
153 }
154
155 /* DEBUG: Displays configured PLL frequency */
156 pll_int = cx18_av_read(cx, 0x108);
157 pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
158 pll_post = cx18_av_read(cx, 0x109);
159 CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n",
160 pll_int, pll_frac, pll_post);
161
162 if (pll_post) {
163 int fin, fsc;
164 int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac);
165
166 pll >>= 25;
167 pll /= pll_post;
168 CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
169 pll / 1000000, pll % 1000000);
170 CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n",
171 pll / 8000000, (pll / 8) % 1000000);
172
173 fin = ((u64)src_decimation * pll) >> 12;
174 CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n",
175 fin / 1000000, fin % 1000000);
176
177 fsc = (((u64)sc) * pll) >> 24L;
178 CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n",
179 fsc / 1000000, fsc % 1000000);
180
181 CX18_DEBUG_INFO("hblank %i, hactive %i, "
182 "vblank %i , vactive %i, vblank656 %i, src_dec %i,"
183 "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
184 " sc 0x%06x\n",
185 hblank, hactive, vblank, vactive, vblank656,
186 src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
187 }
188
189 /* Sets horizontal blanking delay and active lines */
190 cx18_av_write(cx, 0x470, hblank);
191 cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) |
192 (hactive << 4)));
193 cx18_av_write(cx, 0x472, hactive >> 4);
194
195 /* Sets burst gate delay */
196 cx18_av_write(cx, 0x473, burst);
197
198 /* Sets vertical blanking delay and active duration */
199 cx18_av_write(cx, 0x474, vblank);
200 cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) |
201 (vactive << 4)));
202 cx18_av_write(cx, 0x476, vactive >> 4);
203 cx18_av_write(cx, 0x477, vblank656);
204
205 /* Sets src decimation rate */
206 cx18_av_write(cx, 0x478, 0xff & src_decimation);
207 cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8));
208
209 /* Sets Luma and UV Low pass filters */
210 cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
211
212 /* Enables comb filters */
213 cx18_av_write(cx, 0x47b, comb);
214
215 /* Sets SC Step*/
216 cx18_av_write(cx, 0x47c, sc);
217 cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
218 cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
219
220 /* Sets VBI parameters */
221 if (std & V4L2_STD_625_50) {
222 cx18_av_write(cx, 0x47f, 0x01);
223 state->vbi_line_offset = 5;
224 } else {
225 cx18_av_write(cx, 0x47f, 0x00);
226 state->vbi_line_offset = 8;
227 }
228}
229
230int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
231{
232 struct cx18_av_state *state = &cx->av_state;
233 struct v4l2_format *fmt;
234 struct v4l2_sliced_vbi_format *svbi;
235
236 switch (cmd) {
237 case VIDIOC_G_FMT:
238 {
239 static u16 lcr2vbi[] = {
240 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
241 0, V4L2_SLICED_WSS_625, 0, /* 4 */
242 V4L2_SLICED_CAPTION_525, /* 6 */
243 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
244 0, 0, 0, 0
245 };
246 int is_pal = !(state->std & V4L2_STD_525_60);
247 int i;
248
249 fmt = arg;
250 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
251 return -EINVAL;
252 svbi = &fmt->fmt.sliced;
253 memset(svbi, 0, sizeof(*svbi));
254 /* we're done if raw VBI is active */
255 if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
256 break;
257
258 if (is_pal) {
259 for (i = 7; i <= 23; i++) {
260 u8 v = cx18_av_read(cx, 0x424 + i - 7);
261
262 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
263 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
264 svbi->service_set |= svbi->service_lines[0][i] |
265 svbi->service_lines[1][i];
266 }
267 } else {
268 for (i = 10; i <= 21; i++) {
269 u8 v = cx18_av_read(cx, 0x424 + i - 10);
270
271 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
272 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
273 svbi->service_set |= svbi->service_lines[0][i] |
274 svbi->service_lines[1][i];
275 }
276 }
277 break;
278 }
279
280 case VIDIOC_S_FMT:
281 {
282 int is_pal = !(state->std & V4L2_STD_525_60);
283 int vbi_offset = is_pal ? 1 : 0;
284 int i, x;
285 u8 lcr[24];
286
287 fmt = arg;
288 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
289 return -EINVAL;
290 svbi = &fmt->fmt.sliced;
291 if (svbi->service_set == 0) {
292 /* raw VBI */
293 memset(svbi, 0, sizeof(*svbi));
294
295 /* Setup VBI */
296 cx18_av_vbi_setup(cx);
297
298 /* VBI Offset */
299 cx18_av_write(cx, 0x47f, vbi_offset);
300 cx18_av_write(cx, 0x404, 0x2e);
301 break;
302 }
303
304 for (x = 0; x <= 23; x++)
305 lcr[x] = 0x00;
306
307 /* Setup VBI */
308 cx18_av_vbi_setup(cx);
309
310 /* Sliced VBI */
311 cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
312 cx18_av_write(cx, 0x406, 0x13);
313 cx18_av_write(cx, 0x47f, vbi_offset);
314
315 if (is_pal) {
316 for (i = 0; i <= 6; i++)
317 svbi->service_lines[0][i] =
318 svbi->service_lines[1][i] = 0;
319 } else {
320 for (i = 0; i <= 9; i++)
321 svbi->service_lines[0][i] =
322 svbi->service_lines[1][i] = 0;
323
324 for (i = 22; i <= 23; i++)
325 svbi->service_lines[0][i] =
326 svbi->service_lines[1][i] = 0;
327 }
328
329 for (i = 7; i <= 23; i++) {
330 for (x = 0; x <= 1; x++) {
331 switch (svbi->service_lines[1-x][i]) {
332 case V4L2_SLICED_TELETEXT_B:
333 lcr[i] |= 1 << (4 * x);
334 break;
335 case V4L2_SLICED_WSS_625:
336 lcr[i] |= 4 << (4 * x);
337 break;
338 case V4L2_SLICED_CAPTION_525:
339 lcr[i] |= 6 << (4 * x);
340 break;
341 case V4L2_SLICED_VPS:
342 lcr[i] |= 9 << (4 * x);
343 break;
344 }
345 }
346 }
347
348 if (is_pal) {
349 for (x = 1, i = 0x424; i <= 0x434; i++, x++)
350 cx18_av_write(cx, i, lcr[6 + x]);
351 } else {
352 for (x = 1, i = 0x424; i <= 0x430; i++, x++)
353 cx18_av_write(cx, i, lcr[9 + x]);
354 for (i = 0x431; i <= 0x434; i++)
355 cx18_av_write(cx, i, 0);
356 }
357
358 cx18_av_write(cx, 0x43c, 0x16);
359 cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22);
360 break;
361 }
362
363 case VIDIOC_INT_DECODE_VBI_LINE:
364 {
365 struct v4l2_decode_vbi_line *vbi = arg;
366 u8 *p = vbi->p;
367 int id1, id2, l, err = 0;
368
369 if (p[0] || p[1] != 0xff || p[2] != 0xff ||
370 (p[3] != 0x55 && p[3] != 0x91)) {
371 vbi->line = vbi->type = 0;
372 break;
373 }
374
375 p += 4;
376 id1 = p[-1];
377 id2 = p[0] & 0xf;
378 l = p[2] & 0x3f;
379 l += state->vbi_line_offset;
380 p += 4;
381
382 switch (id2) {
383 case 1:
384 id2 = V4L2_SLICED_TELETEXT_B;
385 break;
386 case 4:
387 id2 = V4L2_SLICED_WSS_625;
388 break;
389 case 6:
390 id2 = V4L2_SLICED_CAPTION_525;
391 err = !odd_parity(p[0]) || !odd_parity(p[1]);
392 break;
393 case 9:
394 id2 = V4L2_SLICED_VPS;
395 if (decode_vps(p, p) != 0)
396 err = 1;
397 break;
398 default:
399 id2 = 0;
400 err = 1;
401 break;
402 }
403
404 vbi->type = err ? 0 : id2;
405 vbi->line = err ? 0 : l;
406 vbi->is_second_field = err ? 0 : (id1 == 0x55);
407 vbi->p = p;
408 break;
409 }
410 }
411
412 return 0;
413}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
new file mode 100644
index 000000000000..f5e3ba1f5354
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -0,0 +1,277 @@
1/*
2 * cx18 functions to query card hardware
3 *
4 * Derived from ivtv-cards.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-cards.h"
26#include "cx18-i2c.h"
27#include <media/cs5345.h>
28
29/********************** card configuration *******************************/
30
31/* usual i2c tuner addresses to probe */
32static struct cx18_card_tuner_i2c cx18_i2c_std = {
33 .radio = { I2C_CLIENT_END },
34 .demod = { 0x43, I2C_CLIENT_END },
35 .tv = { 0x61, 0x60, I2C_CLIENT_END },
36};
37
38/* Please add new PCI IDs to: http://pci-ids.ucw.cz/iii
39 This keeps the PCI ID database up to date. Note that the entries
40 must be added under vendor 0x4444 (Conexant) as subsystem IDs.
41 New vendor IDs should still be added to the vendor ID list. */
42
43/* Hauppauge HVR-1600 cards */
44
45/* Note: for Hauppauge cards the tveeprom information is used instead
46 of PCI IDs */
47static const struct cx18_card cx18_card_hvr1600_esmt = {
48 .type = CX18_CARD_HVR_1600_ESMT,
49 .name = "Hauppauge HVR-1600",
50 .comment = "DVB & VBI are not yet supported\n",
51 .v4l2_capabilities = CX18_CAP_ENCODER,
52 .hw_audio_ctrl = CX18_HW_CX23418,
53 .hw_muxer = CX18_HW_CS5345,
54 .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
55 .video_inputs = {
56 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
57 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
58 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
59 { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 },
60 { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
61 },
62 .audio_inputs = {
63 { CX18_CARD_INPUT_AUD_TUNER,
64 CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
65 { CX18_CARD_INPUT_LINE_IN1,
66 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
67 { CX18_CARD_INPUT_LINE_IN2,
68 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
69 },
70 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
71 CX23418_AUDIO_SERIAL, 0 },
72 .ddr = {
73 /* ESMT M13S128324A-5B memory */
74 .chip_config = 0x003,
75 .refresh = 0x30c,
76 .timing1 = 0x44220e82,
77 .timing2 = 0x08,
78 .tune_lane = 0,
79 .initial_emrs = 0,
80 },
81 .gpio_init.initial_value = 0x3001,
82 .gpio_init.direction = 0x3001,
83 .i2c = &cx18_i2c_std,
84};
85
86static const struct cx18_card cx18_card_hvr1600_samsung = {
87 .type = CX18_CARD_HVR_1600_SAMSUNG,
88 .name = "Hauppauge HVR-1600 (Preproduction)",
89 .comment = "DVB & VBI are not yet supported\n",
90 .v4l2_capabilities = CX18_CAP_ENCODER,
91 .hw_audio_ctrl = CX18_HW_CX23418,
92 .hw_muxer = CX18_HW_CS5345,
93 .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
94 .video_inputs = {
95 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
96 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
97 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
98 { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 },
99 { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
100 },
101 .audio_inputs = {
102 { CX18_CARD_INPUT_AUD_TUNER,
103 CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
104 { CX18_CARD_INPUT_LINE_IN1,
105 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
106 { CX18_CARD_INPUT_LINE_IN2,
107 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
108 },
109 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
110 CX23418_AUDIO_SERIAL, 0 },
111 .ddr = {
112 /* Samsung K4D263238G-VC33 memory */
113 .chip_config = 0x003,
114 .refresh = 0x30c,
115 .timing1 = 0x23230b73,
116 .timing2 = 0x08,
117 .tune_lane = 0,
118 .initial_emrs = 2,
119 },
120 .gpio_init.initial_value = 0x3001,
121 .gpio_init.direction = 0x3001,
122 .i2c = &cx18_i2c_std,
123};
124
125/* ------------------------------------------------------------------------- */
126
127/* Compro VideoMate H900: not working at the moment! */
128
129static const struct cx18_card_pci_info cx18_pci_h900[] = {
130 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 },
131 { 0, 0, 0 }
132};
133
134static const struct cx18_card cx18_card_h900 = {
135 .type = CX18_CARD_COMPRO_H900,
136 .name = "Compro VideoMate H900",
137 .comment = "Not yet supported!\n",
138 .v4l2_capabilities = 0,
139 .hw_audio_ctrl = CX18_HW_CX23418,
140 .hw_all = CX18_HW_TUNER,
141 .video_inputs = {
142 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
143 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
144 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
145 },
146 .audio_inputs = {
147 { CX18_CARD_INPUT_AUD_TUNER,
148 CX23418_AUDIO8, 0 },
149 { CX18_CARD_INPUT_LINE_IN1,
150 CX23418_AUDIO_SERIAL, 0 },
151 },
152 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
153 CX23418_AUDIO_SERIAL, 0 },
154 .tuners = {
155 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
156 },
157 .ddr = {
158 /* EtronTech EM6A9160TS-5G memory */
159 .chip_config = 0x50003,
160 .refresh = 0x753,
161 .timing1 = 0x24330e84,
162 .timing2 = 0x1f,
163 .tune_lane = 0,
164 .initial_emrs = 0,
165 },
166 .pci_list = cx18_pci_h900,
167 .i2c = &cx18_i2c_std,
168};
169
170/* ------------------------------------------------------------------------- */
171
172/* Yuan MPC718: not working at the moment! */
173
174static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
175 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_YUAN, 0x0718 },
176 { 0, 0, 0 }
177};
178
179static const struct cx18_card cx18_card_mpc718 = {
180 .type = CX18_CARD_YUAN_MPC718,
181 .name = "Yuan MPC718",
182 .comment = "Not yet supported!\n",
183 .v4l2_capabilities = 0,
184 .hw_audio_ctrl = CX18_HW_CX23418,
185 .hw_all = CX18_HW_TUNER,
186 .video_inputs = {
187 { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
188 { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
189 { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
190 },
191 .audio_inputs = {
192 { CX18_CARD_INPUT_AUD_TUNER,
193 CX23418_AUDIO8, 0 },
194 { CX18_CARD_INPUT_LINE_IN1,
195 CX23418_AUDIO_SERIAL, 0 },
196 },
197 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
198 CX23418_AUDIO_SERIAL, 0 },
199 .tuners = {
200 /* XC3028 tuner */
201 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
202 },
203 /* tuner reset */
204 .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 },
205 .ddr = {
206 /* Probably Samsung K4D263238G-VC33 memory */
207 .chip_config = 0x003,
208 .refresh = 0x30c,
209 .timing1 = 0x23230b73,
210 .timing2 = 0x08,
211 .tune_lane = 0,
212 .initial_emrs = 2,
213 },
214 .pci_list = cx18_pci_mpc718,
215 .i2c = &cx18_i2c_std,
216};
217
218static const struct cx18_card *cx18_card_list[] = {
219 &cx18_card_hvr1600_esmt,
220 &cx18_card_hvr1600_samsung,
221 &cx18_card_h900,
222 &cx18_card_mpc718,
223};
224
225const struct cx18_card *cx18_get_card(u16 index)
226{
227 if (index >= ARRAY_SIZE(cx18_card_list))
228 return NULL;
229 return cx18_card_list[index];
230}
231
232int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input)
233{
234 const struct cx18_card_video_input *card_input =
235 cx->card->video_inputs + index;
236 static const char * const input_strs[] = {
237 "Tuner 1",
238 "S-Video 1",
239 "S-Video 2",
240 "Composite 1",
241 "Composite 2",
242 "Composite 3"
243 };
244
245 memset(input, 0, sizeof(*input));
246 if (index >= cx->nof_inputs)
247 return -EINVAL;
248 input->index = index;
249 strlcpy(input->name, input_strs[card_input->video_type - 1],
250 sizeof(input->name));
251 input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ?
252 V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
253 input->audioset = (1 << cx->nof_audio_inputs) - 1;
254 input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ?
255 cx->tuner_std : V4L2_STD_ALL;
256 return 0;
257}
258
259int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio)
260{
261 const struct cx18_card_audio_input *aud_input =
262 cx->card->audio_inputs + index;
263 static const char * const input_strs[] = {
264 "Tuner 1",
265 "Line In 1",
266 "Line In 2"
267 };
268
269 memset(audio, 0, sizeof(*audio));
270 if (index >= cx->nof_audio_inputs)
271 return -EINVAL;
272 strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
273 sizeof(audio->name));
274 audio->index = index;
275 audio->capability = V4L2_AUDCAP_STEREO;
276 return 0;
277}
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
new file mode 100644
index 000000000000..bca249bdd337
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -0,0 +1,170 @@
1/*
2 * cx18 functions to query card hardware
3 *
4 * Derived from ivtv-cards.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23/* hardware flags */
24#define CX18_HW_TUNER (1 << 0)
25#define CX18_HW_TVEEPROM (1 << 1)
26#define CX18_HW_CS5345 (1 << 2)
27#define CX18_HW_GPIO (1 << 3)
28#define CX18_HW_CX23418 (1 << 4)
29#define CX18_HW_DVB (1 << 5)
30
31/* video inputs */
32#define CX18_CARD_INPUT_VID_TUNER 1
33#define CX18_CARD_INPUT_SVIDEO1 2
34#define CX18_CARD_INPUT_SVIDEO2 3
35#define CX18_CARD_INPUT_COMPOSITE1 4
36#define CX18_CARD_INPUT_COMPOSITE2 5
37#define CX18_CARD_INPUT_COMPOSITE3 6
38
39enum cx34180_video_input {
40 /* Composite video inputs In1-In8 */
41 CX23418_COMPOSITE1 = 1,
42 CX23418_COMPOSITE2,
43 CX23418_COMPOSITE3,
44 CX23418_COMPOSITE4,
45 CX23418_COMPOSITE5,
46 CX23418_COMPOSITE6,
47 CX23418_COMPOSITE7,
48 CX23418_COMPOSITE8,
49
50 /* S-Video inputs consist of one luma input (In1-In4) ORed with one
51 chroma input (In5-In8) */
52 CX23418_SVIDEO_LUMA1 = 0x10,
53 CX23418_SVIDEO_LUMA2 = 0x20,
54 CX23418_SVIDEO_LUMA3 = 0x30,
55 CX23418_SVIDEO_LUMA4 = 0x40,
56 CX23418_SVIDEO_CHROMA4 = 0x400,
57 CX23418_SVIDEO_CHROMA5 = 0x500,
58 CX23418_SVIDEO_CHROMA6 = 0x600,
59 CX23418_SVIDEO_CHROMA7 = 0x700,
60 CX23418_SVIDEO_CHROMA8 = 0x800,
61
62 /* S-Video aliases for common luma/chroma combinations */
63 CX23418_SVIDEO1 = 0x510,
64 CX23418_SVIDEO2 = 0x620,
65 CX23418_SVIDEO3 = 0x730,
66 CX23418_SVIDEO4 = 0x840,
67};
68
69/* audio inputs */
70#define CX18_CARD_INPUT_AUD_TUNER 1
71#define CX18_CARD_INPUT_LINE_IN1 2
72#define CX18_CARD_INPUT_LINE_IN2 3
73
74#define CX18_CARD_MAX_VIDEO_INPUTS 6
75#define CX18_CARD_MAX_AUDIO_INPUTS 3
76#define CX18_CARD_MAX_TUNERS 2
77
78enum cx23418_audio_input {
79 /* Audio inputs: serial or In4-In8 */
80 CX23418_AUDIO_SERIAL,
81 CX23418_AUDIO4 = 4,
82 CX23418_AUDIO5,
83 CX23418_AUDIO6,
84 CX23418_AUDIO7,
85 CX23418_AUDIO8,
86};
87
88/* V4L2 capability aliases */
89#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
90 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE)
91/* | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */
92
93struct cx18_card_video_input {
94 u8 video_type; /* video input type */
95 u8 audio_index; /* index in cx18_card_audio_input array */
96 u16 video_input; /* hardware video input */
97};
98
99struct cx18_card_audio_input {
100 u8 audio_type; /* audio input type */
101 u32 audio_input; /* hardware audio input */
102 u16 muxer_input; /* hardware muxer input for boards with a
103 multiplexer chip */
104};
105
106struct cx18_card_pci_info {
107 u16 device;
108 u16 subsystem_vendor;
109 u16 subsystem_device;
110};
111
112/* GPIO definitions */
113
114/* The mask is the set of bits used by the operation */
115
116struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
117 u16 direction; /* DIR setting. Leave to 0 if no init is needed */
118 u16 initial_value;
119};
120
121struct cx18_card_tuner {
122 v4l2_std_id std; /* standard for which the tuner is suitable */
123 int tuner; /* tuner ID (from tuner.h) */
124};
125
126struct cx18_card_tuner_i2c {
127 unsigned short radio[2];/* radio tuner i2c address to probe */
128 unsigned short demod[2];/* demodulator i2c address to probe */
129 unsigned short tv[4]; /* tv tuner i2c addresses to probe */
130};
131
132struct cx18_ddr { /* DDR config data */
133 u32 chip_config;
134 u32 refresh;
135 u32 timing1;
136 u32 timing2;
137 u32 tune_lane;
138 u32 initial_emrs;
139};
140
141/* for card information/parameters */
142struct cx18_card {
143 int type;
144 char *name;
145 char *comment;
146 u32 v4l2_capabilities;
147 u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only
148 1 dev allowed) */
149 u32 hw_muxer; /* hardware used to multiplex audio input */
150 u32 hw_all; /* all hardware used by the board */
151 struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS];
152 struct cx18_card_audio_input audio_inputs[CX18_CARD_MAX_AUDIO_INPUTS];
153 struct cx18_card_audio_input radio_input;
154
155 /* GPIO card-specific settings */
156 struct cx18_gpio_init gpio_init;
157
158 struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
159 struct cx18_card_tuner_i2c *i2c;
160
161 struct cx18_ddr ddr;
162
163 /* list of device and subsystem vendor/devices that
164 correspond to this card type. */
165 const struct cx18_card_pci_info *pci_list;
166};
167
168int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input);
169int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *input);
170const struct cx18_card *cx18_get_card(u16 index);
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
new file mode 100644
index 000000000000..2bdac5ebbb0d
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -0,0 +1,306 @@
1/*
2 * cx18 ioctl control functions
3 *
4 * Derived from ivtv-controls.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-av-core.h"
26#include "cx18-cards.h"
27#include "cx18-ioctl.h"
28#include "cx18-audio.h"
29#include "cx18-i2c.h"
30#include "cx18-mailbox.h"
31#include "cx18-controls.h"
32
33static const u32 user_ctrls[] = {
34 V4L2_CID_USER_CLASS,
35 V4L2_CID_BRIGHTNESS,
36 V4L2_CID_CONTRAST,
37 V4L2_CID_SATURATION,
38 V4L2_CID_HUE,
39 V4L2_CID_AUDIO_VOLUME,
40 V4L2_CID_AUDIO_BALANCE,
41 V4L2_CID_AUDIO_BASS,
42 V4L2_CID_AUDIO_TREBLE,
43 V4L2_CID_AUDIO_MUTE,
44 V4L2_CID_AUDIO_LOUDNESS,
45 0
46};
47
48static const u32 *ctrl_classes[] = {
49 user_ctrls,
50 cx2341x_mpeg_ctrls,
51 NULL
52};
53
54static int cx18_queryctrl(struct cx18 *cx, struct v4l2_queryctrl *qctrl)
55{
56 const char *name;
57
58 CX18_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
59
60 qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
61 if (qctrl->id == 0)
62 return -EINVAL;
63
64 switch (qctrl->id) {
65 /* Standard V4L2 controls */
66 case V4L2_CID_BRIGHTNESS:
67 case V4L2_CID_HUE:
68 case V4L2_CID_SATURATION:
69 case V4L2_CID_CONTRAST:
70 if (cx18_av_cmd(cx, VIDIOC_QUERYCTRL, qctrl))
71 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
72 return 0;
73
74 case V4L2_CID_AUDIO_VOLUME:
75 case V4L2_CID_AUDIO_MUTE:
76 case V4L2_CID_AUDIO_BALANCE:
77 case V4L2_CID_AUDIO_BASS:
78 case V4L2_CID_AUDIO_TREBLE:
79 case V4L2_CID_AUDIO_LOUDNESS:
80 if (cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_QUERYCTRL, qctrl))
81 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
82 return 0;
83
84 default:
85 if (cx2341x_ctrl_query(&cx->params, qctrl))
86 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
87 return 0;
88 }
89 strncpy(qctrl->name, name, sizeof(qctrl->name) - 1);
90 qctrl->name[sizeof(qctrl->name) - 1] = 0;
91 return 0;
92}
93
94static int cx18_querymenu(struct cx18 *cx, struct v4l2_querymenu *qmenu)
95{
96 struct v4l2_queryctrl qctrl;
97
98 qctrl.id = qmenu->id;
99 cx18_queryctrl(cx, &qctrl);
100 return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
101}
102
103static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
104{
105 s32 v = vctrl->value;
106
107 CX18_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
108
109 switch (vctrl->id) {
110 /* Standard V4L2 controls */
111 case V4L2_CID_BRIGHTNESS:
112 case V4L2_CID_HUE:
113 case V4L2_CID_SATURATION:
114 case V4L2_CID_CONTRAST:
115 return cx18_av_cmd(cx, VIDIOC_S_CTRL, vctrl);
116
117 case V4L2_CID_AUDIO_VOLUME:
118 case V4L2_CID_AUDIO_MUTE:
119 case V4L2_CID_AUDIO_BALANCE:
120 case V4L2_CID_AUDIO_BASS:
121 case V4L2_CID_AUDIO_TREBLE:
122 case V4L2_CID_AUDIO_LOUDNESS:
123 return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
124
125 default:
126 CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
127 return -EINVAL;
128 }
129 return 0;
130}
131
132static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
133{
134 CX18_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
135
136 switch (vctrl->id) {
137 /* Standard V4L2 controls */
138 case V4L2_CID_BRIGHTNESS:
139 case V4L2_CID_HUE:
140 case V4L2_CID_SATURATION:
141 case V4L2_CID_CONTRAST:
142 return cx18_av_cmd(cx, VIDIOC_G_CTRL, vctrl);
143
144 case V4L2_CID_AUDIO_VOLUME:
145 case V4L2_CID_AUDIO_MUTE:
146 case V4L2_CID_AUDIO_BALANCE:
147 case V4L2_CID_AUDIO_BASS:
148 case V4L2_CID_AUDIO_TREBLE:
149 case V4L2_CID_AUDIO_LOUDNESS:
150 return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
151 default:
152 CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
153 return -EINVAL;
154 }
155 return 0;
156}
157
158static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt)
159{
160 if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
161 return -EINVAL;
162 if (atomic_read(&cx->capturing) > 0)
163 return -EBUSY;
164
165 /* First try to allocate sliced VBI buffers if needed. */
166 if (fmt && cx->vbi.sliced_mpeg_data[0] == NULL) {
167 int i;
168
169 for (i = 0; i < CX18_VBI_FRAMES; i++) {
170 /* Yuck, hardcoded. Needs to be a define */
171 cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL);
172 if (cx->vbi.sliced_mpeg_data[i] == NULL) {
173 while (--i >= 0) {
174 kfree(cx->vbi.sliced_mpeg_data[i]);
175 cx->vbi.sliced_mpeg_data[i] = NULL;
176 }
177 return -ENOMEM;
178 }
179 }
180 }
181
182 cx->vbi.insert_mpeg = fmt;
183
184 if (cx->vbi.insert_mpeg == 0)
185 return 0;
186 /* Need sliced data for mpeg insertion */
187 if (cx18_get_service_set(cx->vbi.sliced_in) == 0) {
188 if (cx->is_60hz)
189 cx->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
190 else
191 cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
192 cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz);
193 }
194 return 0;
195}
196
197int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg)
198{
199 struct v4l2_control ctrl;
200
201 switch (cmd) {
202 case VIDIOC_QUERYMENU:
203 CX18_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
204 return cx18_querymenu(cx, arg);
205
206 case VIDIOC_QUERYCTRL:
207 return cx18_queryctrl(cx, arg);
208
209 case VIDIOC_S_CTRL:
210 return cx18_s_ctrl(cx, arg);
211
212 case VIDIOC_G_CTRL:
213 return cx18_g_ctrl(cx, arg);
214
215 case VIDIOC_S_EXT_CTRLS:
216 {
217 struct v4l2_ext_controls *c = arg;
218
219 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
220 int i;
221 int err = 0;
222
223 for (i = 0; i < c->count; i++) {
224 ctrl.id = c->controls[i].id;
225 ctrl.value = c->controls[i].value;
226 err = cx18_s_ctrl(cx, &ctrl);
227 c->controls[i].value = ctrl.value;
228 if (err) {
229 c->error_idx = i;
230 break;
231 }
232 }
233 return err;
234 }
235 CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
236 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
237 struct cx2341x_mpeg_params p = cx->params;
238 int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->capturing), arg, cmd);
239
240 if (err)
241 return err;
242
243 if (p.video_encoding != cx->params.video_encoding) {
244 int is_mpeg1 = p.video_encoding ==
245 V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
246 struct v4l2_format fmt;
247
248 /* fix videodecoder resolution */
249 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
250 fmt.fmt.pix.width = cx->params.width / (is_mpeg1 ? 2 : 1);
251 fmt.fmt.pix.height = cx->params.height;
252 cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
253 }
254 err = cx2341x_update(cx, cx18_api_func, &cx->params, &p);
255 if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
256 err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
257 cx->params = p;
258 cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
259 cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03);
260 return err;
261 }
262 return -EINVAL;
263 }
264
265 case VIDIOC_G_EXT_CTRLS:
266 {
267 struct v4l2_ext_controls *c = arg;
268
269 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
270 int i;
271 int err = 0;
272
273 for (i = 0; i < c->count; i++) {
274 ctrl.id = c->controls[i].id;
275 ctrl.value = c->controls[i].value;
276 err = cx18_g_ctrl(cx, &ctrl);
277 c->controls[i].value = ctrl.value;
278 if (err) {
279 c->error_idx = i;
280 break;
281 }
282 }
283 return err;
284 }
285 CX18_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n");
286 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
287 return cx2341x_ext_ctrls(&cx->params, 0, arg, cmd);
288 return -EINVAL;
289 }
290
291 case VIDIOC_TRY_EXT_CTRLS:
292 {
293 struct v4l2_ext_controls *c = arg;
294
295 CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
296 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
297 return cx2341x_ext_ctrls(&cx->params,
298 atomic_read(&cx->capturing), arg, cmd);
299 return -EINVAL;
300 }
301
302 default:
303 return -EINVAL;
304 }
305 return 0;
306}
diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h
new file mode 100644
index 000000000000..6e985cf422a0
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-controls.h
@@ -0,0 +1,24 @@
1/*
2 * cx18 ioctl control functions
3 *
4 * Derived from ivtv-controls.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
new file mode 100644
index 000000000000..9f31befc3139
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -0,0 +1,971 @@
1/*
2 * cx18 driver initialization and card probing
3 *
4 * Derived from ivtv-driver.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-version.h"
26#include "cx18-cards.h"
27#include "cx18-i2c.h"
28#include "cx18-irq.h"
29#include "cx18-gpio.h"
30#include "cx18-firmware.h"
31#include "cx18-streams.h"
32#include "cx18-av-core.h"
33#include "cx18-scb.h"
34#include "cx18-mailbox.h"
35#include "cx18-ioctl.h"
36#include "tuner-xc2028.h"
37
38#include <media/tveeprom.h>
39
40
41/* var to keep track of the number of array elements in use */
42int cx18_cards_active;
43
44/* If you have already X v4l cards, then set this to X. This way
45 the device numbers stay matched. Example: you have a WinTV card
46 without radio and a Compro H900 with. Normally this would give a
47 video1 device together with a radio0 device for the Compro. By
48 setting this to 1 you ensure that radio0 is now also radio1. */
49int cx18_first_minor;
50
51/* Master variable for all cx18 info */
52struct cx18 *cx18_cards[CX18_MAX_CARDS];
53
54/* Protects cx18_cards_active */
55DEFINE_SPINLOCK(cx18_cards_lock);
56
57/* add your revision and whatnot here */
58static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
59 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
60 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
61 {0,}
62};
63
64MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
65
66/* Parameter declarations */
67static int cardtype[CX18_MAX_CARDS];
68static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
69 -1, -1, -1, -1, -1, -1, -1, -1,
70 -1, -1, -1, -1, -1, -1, -1, -1,
71 -1, -1, -1, -1, -1, -1, -1, -1 };
72static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
73 -1, -1, -1, -1, -1, -1, -1, -1,
74 -1, -1, -1, -1, -1, -1, -1, -1,
75 -1, -1, -1, -1, -1, -1, -1, -1 };
76
77static int cardtype_c = 1;
78static int tuner_c = 1;
79static int radio_c = 1;
80static char pal[] = "--";
81static char secam[] = "--";
82static char ntsc[] = "-";
83
84/* Buffers */
85static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS;
86static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS;
87static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS;
88static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS;
89static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
90
91static int cx18_pci_latency = 1;
92
93int cx18_debug;
94
95module_param_array(tuner, int, &tuner_c, 0644);
96module_param_array(radio, bool, &radio_c, 0644);
97module_param_array(cardtype, int, &cardtype_c, 0644);
98module_param_string(pal, pal, sizeof(pal), 0644);
99module_param_string(secam, secam, sizeof(secam), 0644);
100module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
101module_param_named(debug, cx18_debug, int, 0644);
102module_param(cx18_pci_latency, int, 0644);
103module_param(cx18_first_minor, int, 0644);
104
105module_param(enc_mpg_buffers, int, 0644);
106module_param(enc_ts_buffers, int, 0644);
107module_param(enc_yuv_buffers, int, 0644);
108module_param(enc_vbi_buffers, int, 0644);
109module_param(enc_pcm_buffers, int, 0644);
110
111MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
112 "\t\t\tsee tuner.h for values");
113MODULE_PARM_DESC(radio,
114 "Enable or disable the radio. Use only if autodetection\n"
115 "\t\t\tfails. 0 = disable, 1 = enable");
116MODULE_PARM_DESC(cardtype,
117 "Only use this option if your card is not detected properly.\n"
118 "\t\tSpecify card type:\n"
119 "\t\t\t 1 = Hauppauge HVR 1600 (ESMT memory)\n"
120 "\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n"
121 "\t\t\t 3 = Compro VideoMate H900\n"
122 "\t\t\t 4 = Yuan MPC718\n"
123 "\t\t\t 0 = Autodetect (default)\n"
124 "\t\t\t-1 = Ignore this card\n\t\t");
125MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
126MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC");
127MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K");
128MODULE_PARM_DESC(debug,
129 "Debug level (bitmask). Default: 0\n"
130 "\t\t\t 1/0x0001: warning\n"
131 "\t\t\t 2/0x0002: info\n"
132 "\t\t\t 4/0x0004: mailbox\n"
133 "\t\t\t 8/0x0008: dma\n"
134 "\t\t\t 16/0x0010: ioctl\n"
135 "\t\t\t 32/0x0020: file\n"
136 "\t\t\t 64/0x0040: i2c\n"
137 "\t\t\t128/0x0080: irq\n"
138 "\t\t\t256/0x0100: high volume\n");
139MODULE_PARM_DESC(cx18_pci_latency,
140 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
141 "\t\t\tDefault: Yes");
142MODULE_PARM_DESC(enc_mpg_buffers,
143 "Encoder MPG Buffers (in MB)\n"
144 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
145MODULE_PARM_DESC(enc_ts_buffers,
146 "Encoder TS Buffers (in MB)\n"
147 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS));
148MODULE_PARM_DESC(enc_yuv_buffers,
149 "Encoder YUV Buffers (in MB)\n"
150 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
151MODULE_PARM_DESC(enc_vbi_buffers,
152 "Encoder VBI Buffers (in MB)\n"
153 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS));
154MODULE_PARM_DESC(enc_pcm_buffers,
155 "Encoder PCM buffers (in MB)\n"
156 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS));
157
158MODULE_PARM_DESC(cx18_first_minor, "Set minor assigned to first card");
159
160MODULE_AUTHOR("Hans Verkuil");
161MODULE_DESCRIPTION("CX23418 driver");
162MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder");
163MODULE_LICENSE("GPL");
164
165MODULE_VERSION(CX18_VERSION);
166
167int cx18_waitq(wait_queue_head_t *waitq)
168{
169 DEFINE_WAIT(wait);
170
171 prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
172 schedule();
173 finish_wait(waitq, &wait);
174 return signal_pending(current) ? -EINTR : 0;
175}
176
177/* Generic utility functions */
178int cx18_msleep_timeout(unsigned int msecs, int intr)
179{
180 int timeout = msecs_to_jiffies(msecs);
181 int sig;
182
183 do {
184 set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
185 timeout = schedule_timeout(timeout);
186 sig = intr ? signal_pending(current) : 0;
187 } while (!sig && timeout);
188 return sig;
189}
190
191/* Release ioremapped memory */
192static void cx18_iounmap(struct cx18 *cx)
193{
194 if (cx == NULL)
195 return;
196
197 /* Release io memory */
198 if (cx->enc_mem != NULL) {
199 CX18_DEBUG_INFO("releasing enc_mem\n");
200 iounmap(cx->enc_mem);
201 cx->enc_mem = NULL;
202 }
203}
204
205/* Hauppauge card? get values from tveeprom */
206void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
207{
208 u8 eedata[256];
209
210 cx->i2c_client[0].addr = 0xA0 >> 1;
211 tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata));
212 tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata);
213}
214
215static void cx18_process_eeprom(struct cx18 *cx)
216{
217 struct tveeprom tv;
218
219 cx18_read_eeprom(cx, &tv);
220
221 /* Many thanks to Steven Toth from Hauppauge for providing the
222 model numbers */
223 switch (tv.model) {
224 case 74000 ... 74099:
225 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
226 break;
227 case 74700 ... 74799:
228 cx->card = cx18_get_card(CX18_CARD_HVR_1600_SAMSUNG);
229 break;
230 case 0:
231 CX18_ERR("Invalid EEPROM\n");
232 return;
233 default:
234 CX18_ERR("Unknown model %d, defaulting to HVR-1600\n", tv.model);
235 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
236 break;
237 }
238
239 cx->v4l2_cap = cx->card->v4l2_capabilities;
240 cx->card_name = cx->card->name;
241 cx->card_i2c = cx->card->i2c;
242
243 CX18_INFO("Autodetected %s\n", cx->card_name);
244
245 if (tv.tuner_type == TUNER_ABSENT)
246 CX18_ERR("tveeprom cannot autodetect tuner!");
247
248 if (cx->options.tuner == -1)
249 cx->options.tuner = tv.tuner_type;
250 if (cx->options.radio == -1)
251 cx->options.radio = (tv.has_radio != 0);
252
253 if (cx->std != 0)
254 /* user specified tuner standard */
255 return;
256
257 /* autodetect tuner standard */
258 if (tv.tuner_formats & V4L2_STD_PAL) {
259 CX18_DEBUG_INFO("PAL tuner detected\n");
260 cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
261 } else if (tv.tuner_formats & V4L2_STD_NTSC) {
262 CX18_DEBUG_INFO("NTSC tuner detected\n");
263 cx->std |= V4L2_STD_NTSC_M;
264 } else if (tv.tuner_formats & V4L2_STD_SECAM) {
265 CX18_DEBUG_INFO("SECAM tuner detected\n");
266 cx->std |= V4L2_STD_SECAM_L;
267 } else {
268 CX18_INFO("No tuner detected, default to NTSC-M\n");
269 cx->std |= V4L2_STD_NTSC_M;
270 }
271}
272
273static v4l2_std_id cx18_parse_std(struct cx18 *cx)
274{
275 switch (pal[0]) {
276 case '6':
277 return V4L2_STD_PAL_60;
278 case 'b':
279 case 'B':
280 case 'g':
281 case 'G':
282 return V4L2_STD_PAL_BG;
283 case 'h':
284 case 'H':
285 return V4L2_STD_PAL_H;
286 case 'n':
287 case 'N':
288 if (pal[1] == 'c' || pal[1] == 'C')
289 return V4L2_STD_PAL_Nc;
290 return V4L2_STD_PAL_N;
291 case 'i':
292 case 'I':
293 return V4L2_STD_PAL_I;
294 case 'd':
295 case 'D':
296 case 'k':
297 case 'K':
298 return V4L2_STD_PAL_DK;
299 case 'M':
300 case 'm':
301 return V4L2_STD_PAL_M;
302 case '-':
303 break;
304 default:
305 CX18_WARN("pal= argument not recognised\n");
306 return 0;
307 }
308
309 switch (secam[0]) {
310 case 'b':
311 case 'B':
312 case 'g':
313 case 'G':
314 case 'h':
315 case 'H':
316 return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
317 case 'd':
318 case 'D':
319 case 'k':
320 case 'K':
321 return V4L2_STD_SECAM_DK;
322 case 'l':
323 case 'L':
324 if (secam[1] == 'C' || secam[1] == 'c')
325 return V4L2_STD_SECAM_LC;
326 return V4L2_STD_SECAM_L;
327 case '-':
328 break;
329 default:
330 CX18_WARN("secam= argument not recognised\n");
331 return 0;
332 }
333
334 switch (ntsc[0]) {
335 case 'm':
336 case 'M':
337 return V4L2_STD_NTSC_M;
338 case 'j':
339 case 'J':
340 return V4L2_STD_NTSC_M_JP;
341 case 'k':
342 case 'K':
343 return V4L2_STD_NTSC_M_KR;
344 case '-':
345 break;
346 default:
347 CX18_WARN("ntsc= argument not recognised\n");
348 return 0;
349 }
350
351 /* no match found */
352 return 0;
353}
354
355static void cx18_process_options(struct cx18 *cx)
356{
357 int i, j;
358
359 cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
360 cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers;
361 cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
362 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
363 cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
364 cx->options.cardtype = cardtype[cx->num];
365 cx->options.tuner = tuner[cx->num];
366 cx->options.radio = radio[cx->num];
367
368 cx->std = cx18_parse_std(cx);
369 if (cx->options.cardtype == -1) {
370 CX18_INFO("Ignore card\n");
371 return;
372 }
373 cx->card = cx18_get_card(cx->options.cardtype - 1);
374 if (cx->card)
375 CX18_INFO("User specified %s card\n", cx->card->name);
376 else if (cx->options.cardtype != 0)
377 CX18_ERR("Unknown user specified type, trying to autodetect card\n");
378 if (cx->card == NULL) {
379 if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
380 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
381 CX18_INFO("Autodetected Hauppauge card\n");
382 }
383 }
384 if (cx->card == NULL) {
385 for (i = 0; (cx->card = cx18_get_card(i)); i++) {
386 if (cx->card->pci_list == NULL)
387 continue;
388 for (j = 0; cx->card->pci_list[j].device; j++) {
389 if (cx->dev->device !=
390 cx->card->pci_list[j].device)
391 continue;
392 if (cx->dev->subsystem_vendor !=
393 cx->card->pci_list[j].subsystem_vendor)
394 continue;
395 if (cx->dev->subsystem_device !=
396 cx->card->pci_list[j].subsystem_device)
397 continue;
398 CX18_INFO("Autodetected %s card\n", cx->card->name);
399 goto done;
400 }
401 }
402 }
403done:
404
405 if (cx->card == NULL) {
406 cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
407 CX18_ERR("Unknown card: vendor/device: %04x/%04x\n",
408 cx->dev->vendor, cx->dev->device);
409 CX18_ERR(" subsystem vendor/device: %04x/%04x\n",
410 cx->dev->subsystem_vendor, cx->dev->subsystem_device);
411 CX18_ERR("Defaulting to %s card\n", cx->card->name);
412 CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
413 CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
414 CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
415 }
416 cx->v4l2_cap = cx->card->v4l2_capabilities;
417 cx->card_name = cx->card->name;
418 cx->card_i2c = cx->card->i2c;
419}
420
421/* Precondition: the cx18 structure has been memset to 0. Only
422 the dev and num fields have been filled in.
423 No assumptions on the card type may be made here (see cx18_init_struct2
424 for that).
425 */
426static int __devinit cx18_init_struct1(struct cx18 *cx)
427{
428 cx->base_addr = pci_resource_start(cx->dev, 0);
429
430 mutex_init(&cx->serialize_lock);
431 mutex_init(&cx->i2c_bus_lock[0]);
432 mutex_init(&cx->i2c_bus_lock[1]);
433
434 spin_lock_init(&cx->lock);
435 spin_lock_init(&cx->dma_reg_lock);
436
437 /* start counting open_id at 1 */
438 cx->open_id = 1;
439
440 /* Initial settings */
441 cx2341x_fill_defaults(&cx->params);
442 cx->temporal_strength = cx->params.video_temporal_filter;
443 cx->spatial_strength = cx->params.video_spatial_filter;
444 cx->filter_mode = cx->params.video_spatial_filter_mode |
445 (cx->params.video_temporal_filter_mode << 1) |
446 (cx->params.video_median_filter_type << 2);
447 cx->params.port = CX2341X_PORT_MEMORY;
448 cx->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
449 init_waitqueue_head(&cx->cap_w);
450 init_waitqueue_head(&cx->mb_apu_waitq);
451 init_waitqueue_head(&cx->mb_cpu_waitq);
452 init_waitqueue_head(&cx->mb_epu_waitq);
453 init_waitqueue_head(&cx->mb_hpu_waitq);
454 init_waitqueue_head(&cx->dma_waitq);
455
456 /* VBI */
457 cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
458 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
459 cx->vbi.raw_size = 1456;
460 cx->vbi.raw_decoder_line_size = 1456;
461 cx->vbi.raw_decoder_sav_odd_field = 0x20;
462 cx->vbi.raw_decoder_sav_even_field = 0x60;
463 cx->vbi.sliced_decoder_line_size = 272;
464 cx->vbi.sliced_decoder_sav_odd_field = 0xB0;
465 cx->vbi.sliced_decoder_sav_even_field = 0xF0;
466 return 0;
467}
468
469/* Second initialization part. Here the card type has been
470 autodetected. */
471static void __devinit cx18_init_struct2(struct cx18 *cx)
472{
473 int i;
474
475 for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS; i++)
476 if (cx->card->video_inputs[i].video_type == 0)
477 break;
478 cx->nof_inputs = i;
479 for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS; i++)
480 if (cx->card->audio_inputs[i].audio_type == 0)
481 break;
482 cx->nof_audio_inputs = i;
483
484 /* Find tuner input */
485 for (i = 0; i < cx->nof_inputs; i++) {
486 if (cx->card->video_inputs[i].video_type ==
487 CX18_CARD_INPUT_VID_TUNER)
488 break;
489 }
490 if (i == cx->nof_inputs)
491 i = 0;
492 cx->active_input = i;
493 cx->audio_input = cx->card->video_inputs[i].audio_index;
494 cx->av_state.vid_input = CX18_AV_COMPOSITE7;
495 cx->av_state.aud_input = CX18_AV_AUDIO8;
496 cx->av_state.audclk_freq = 48000;
497 cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
498 cx->av_state.vbi_line_offset = 8;
499}
500
501static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
502 const struct pci_device_id *pci_id)
503{
504 u16 cmd;
505 unsigned char pci_latency;
506
507 CX18_DEBUG_INFO("Enabling pci device\n");
508
509 if (pci_enable_device(dev)) {
510 CX18_ERR("Can't enable device %d!\n", cx->num);
511 return -EIO;
512 }
513 if (pci_set_dma_mask(dev, 0xffffffff)) {
514 CX18_ERR("No suitable DMA available on card %d.\n", cx->num);
515 return -EIO;
516 }
517 if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
518 CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num);
519 return -EIO;
520 }
521
522 /* Check for bus mastering */
523 pci_read_config_word(dev, PCI_COMMAND, &cmd);
524 cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
525 pci_write_config_word(dev, PCI_COMMAND, cmd);
526
527 pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev);
528 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
529
530 if (pci_latency < 64 && cx18_pci_latency) {
531 CX18_INFO("Unreasonably low latency timer, "
532 "setting to 64 (was %d)\n", pci_latency);
533 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
534 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
535 }
536 /* This config space value relates to DMA latencies. The
537 default value 0x8080 is too low however and will lead
538 to DMA errors. 0xffff is the max value which solves
539 these problems. */
540 pci_write_config_dword(dev, 0x40, 0xffff);
541
542 CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
543 "irq: %d, latency: %d, memory: 0x%lx\n",
544 cx->dev->device, cx->card_rev, dev->bus->number,
545 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
546 cx->dev->irq, pci_latency, (unsigned long)cx->base_addr);
547
548 return 0;
549}
550
551static u32 cx18_request_module(struct cx18 *cx, u32 hw,
552 const char *name, u32 id)
553{
554 if ((hw & id) == 0)
555 return hw;
556 if (request_module(name) != 0) {
557 CX18_ERR("Failed to load module %s\n", name);
558 return hw & ~id;
559 }
560 CX18_DEBUG_INFO("Loaded module %s\n", name);
561 return hw;
562}
563
564static void cx18_load_and_init_modules(struct cx18 *cx)
565{
566 u32 hw = cx->card->hw_all;
567 int i;
568
569 /* load modules */
570#ifndef CONFIG_VIDEO_TUNER
571 hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
572#endif
573#ifndef CONFIG_VIDEO_CS5345
574 hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
575#endif
576
577 /* check which i2c devices are actually found */
578 for (i = 0; i < 32; i++) {
579 u32 device = 1 << i;
580
581 if (!(device & hw))
582 continue;
583 if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM ||
584 device == CX18_HW_CX23418 || device == CX18_HW_DVB) {
585 /* These 'devices' do not use i2c probing */
586 cx->hw_flags |= device;
587 continue;
588 }
589 cx18_i2c_register(cx, i);
590 if (cx18_i2c_hw_addr(cx, device) > 0)
591 cx->hw_flags |= device;
592 }
593
594 hw = cx->hw_flags;
595}
596
597static int __devinit cx18_probe(struct pci_dev *dev,
598 const struct pci_device_id *pci_id)
599{
600 int retval = 0;
601 int vbi_buf_size;
602 u32 devtype;
603 struct cx18 *cx;
604
605 spin_lock(&cx18_cards_lock);
606
607 /* Make sure we've got a place for this card */
608 if (cx18_cards_active == CX18_MAX_CARDS) {
609 printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n",
610 cx18_cards_active);
611 spin_unlock(&cx18_cards_lock);
612 return -ENOMEM;
613 }
614
615 cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
616 if (cx == 0) {
617 spin_unlock(&cx18_cards_lock);
618 return -ENOMEM;
619 }
620 cx18_cards[cx18_cards_active] = cx;
621 cx->dev = dev;
622 cx->num = cx18_cards_active++;
623 snprintf(cx->name, sizeof(cx->name) - 1, "cx18-%d", cx->num);
624 CX18_INFO("Initializing card #%d\n", cx->num);
625
626 spin_unlock(&cx18_cards_lock);
627
628 cx18_process_options(cx);
629 if (cx->options.cardtype == -1) {
630 retval = -ENODEV;
631 goto err;
632 }
633 if (cx18_init_struct1(cx)) {
634 retval = -ENOMEM;
635 goto err;
636 }
637
638 CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
639
640 /* PCI Device Setup */
641 retval = cx18_setup_pci(cx, dev, pci_id);
642 if (retval != 0) {
643 if (retval == -EIO)
644 goto free_workqueue;
645 else if (retval == -ENXIO)
646 goto free_mem;
647 }
648 /* save cx in the pci struct for later use */
649 pci_set_drvdata(dev, cx);
650
651 /* map io memory */
652 CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
653 cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
654 cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET,
655 CX18_MEM_SIZE);
656 if (!cx->enc_mem) {
657 CX18_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n");
658 CX18_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n");
659 retval = -ENOMEM;
660 goto free_mem;
661 }
662 cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET;
663 devtype = read_reg(0xC72028);
664 switch (devtype & 0xff000000) {
665 case 0xff000000:
666 CX18_INFO("cx23418 revision %08x (A)\n", devtype);
667 break;
668 case 0x01000000:
669 CX18_INFO("cx23418 revision %08x (B)\n", devtype);
670 break;
671 default:
672 CX18_INFO("cx23418 revision %08x (Unknown)\n", devtype);
673 break;
674 }
675
676 cx18_init_power(cx, 1);
677 cx18_init_memory(cx);
678
679 cx->scb = (struct cx18_scb *)(cx->enc_mem + SCB_OFFSET);
680 cx18_init_scb(cx);
681
682 cx18_gpio_init(cx);
683
684 /* active i2c */
685 CX18_DEBUG_INFO("activating i2c...\n");
686 if (init_cx18_i2c(cx)) {
687 CX18_ERR("Could not initialize i2c\n");
688 goto free_map;
689 }
690
691 CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active);
692
693 if (cx->card->hw_all & CX18_HW_TVEEPROM) {
694 /* Based on the model number the cardtype may be changed.
695 The PCI IDs are not always reliable. */
696 cx18_process_eeprom(cx);
697 }
698 if (cx->card->comment)
699 CX18_INFO("%s", cx->card->comment);
700 if (cx->card->v4l2_capabilities == 0) {
701 retval = -ENODEV;
702 goto free_i2c;
703 }
704 cx18_init_memory(cx);
705
706 /* Register IRQ */
707 retval = request_irq(cx->dev->irq, cx18_irq_handler,
708 IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx);
709 if (retval) {
710 CX18_ERR("Failed to register irq %d\n", retval);
711 goto free_i2c;
712 }
713
714 if (cx->std == 0)
715 cx->std = V4L2_STD_NTSC_M;
716
717 if (cx->options.tuner == -1) {
718 int i;
719
720 for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) {
721 if ((cx->std & cx->card->tuners[i].std) == 0)
722 continue;
723 cx->options.tuner = cx->card->tuners[i].tuner;
724 break;
725 }
726 }
727 /* if no tuner was found, then pick the first tuner in the card list */
728 if (cx->options.tuner == -1 && cx->card->tuners[0].std) {
729 cx->std = cx->card->tuners[0].std;
730 cx->options.tuner = cx->card->tuners[0].tuner;
731 }
732 if (cx->options.radio == -1)
733 cx->options.radio = (cx->card->radio_input.audio_type != 0);
734
735 /* The card is now fully identified, continue with card-specific
736 initialization. */
737 cx18_init_struct2(cx);
738
739 cx18_load_and_init_modules(cx);
740
741 if (cx->std & V4L2_STD_525_60) {
742 cx->is_60hz = 1;
743 cx->is_out_60hz = 1;
744 } else {
745 cx->is_50hz = 1;
746 cx->is_out_50hz = 1;
747 }
748 cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
749
750 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = 0x08000;
751 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = 0x08000;
752 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = 0x01200;
753 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = 0x20000;
754 vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
755 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
756
757 if (cx->options.radio > 0)
758 cx->v4l2_cap |= V4L2_CAP_RADIO;
759
760 retval = cx18_streams_setup(cx);
761 if (retval) {
762 CX18_ERR("Error %d setting up streams\n", retval);
763 goto free_irq;
764 }
765 retval = cx18_streams_register(cx);
766 if (retval) {
767 CX18_ERR("Error %d registering devices\n", retval);
768 goto free_streams;
769 }
770
771 if (cx->options.tuner > -1) {
772 struct tuner_setup setup;
773
774 setup.addr = ADDR_UNSET;
775 setup.type = cx->options.tuner;
776 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
777 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
778 cx18_reset_tuner_gpio : NULL;
779 cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup);
780 if (setup.type == TUNER_XC2028) {
781 static struct xc2028_ctrl ctrl = {
782 .fname = XC2028_DEFAULT_FIRMWARE,
783 .max_len = 64,
784 };
785 struct v4l2_priv_tun_config cfg = {
786 .tuner = cx->options.tuner,
787 .priv = &ctrl,
788 };
789 cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg);
790 }
791 }
792
793 /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
794 are not. */
795 cx->tuner_std = cx->std;
796
797 cx18_init_on_first_open(cx);
798
799 CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name);
800
801 return 0;
802
803free_streams:
804 cx18_streams_cleanup(cx);
805free_irq:
806 free_irq(cx->dev->irq, (void *)cx);
807free_i2c:
808 exit_cx18_i2c(cx);
809free_map:
810 cx18_iounmap(cx);
811free_mem:
812 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
813free_workqueue:
814err:
815 if (retval == 0)
816 retval = -ENODEV;
817 CX18_ERR("Error %d on initialization\n", retval);
818
819 kfree(cx18_cards[cx18_cards_active]);
820 cx18_cards[cx18_cards_active] = NULL;
821 return retval;
822}
823
824int cx18_init_on_first_open(struct cx18 *cx)
825{
826 int video_input;
827 int fw_retry_count = 3;
828 struct v4l2_frequency vf;
829
830 if (test_bit(CX18_F_I_FAILED, &cx->i_flags))
831 return -ENXIO;
832
833 if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags))
834 return 0;
835
836 while (--fw_retry_count > 0) {
837 /* load firmware */
838 if (cx18_firmware_init(cx) == 0)
839 break;
840 if (fw_retry_count > 1)
841 CX18_WARN("Retry loading firmware\n");
842 }
843
844 if (fw_retry_count == 0) {
845 set_bit(CX18_F_I_FAILED, &cx->i_flags);
846 return -ENXIO;
847 }
848 set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
849
850 /* Init the firmware twice to work around a silicon bug
851 * transport related. */
852
853 fw_retry_count = 3;
854 while (--fw_retry_count > 0) {
855 /* load firmware */
856 if (cx18_firmware_init(cx) == 0)
857 break;
858 if (fw_retry_count > 1)
859 CX18_WARN("Retry loading firmware\n");
860 }
861
862 if (fw_retry_count == 0) {
863 set_bit(CX18_F_I_FAILED, &cx->i_flags);
864 return -ENXIO;
865 }
866
867 vf.tuner = 0;
868 vf.type = V4L2_TUNER_ANALOG_TV;
869 vf.frequency = 6400; /* the tuner 'baseline' frequency */
870
871 /* Set initial frequency. For PAL/SECAM broadcasts no
872 'default' channel exists AFAIK. */
873 if (cx->std == V4L2_STD_NTSC_M_JP)
874 vf.frequency = 1460; /* ch. 1 91250*16/1000 */
875 else if (cx->std & V4L2_STD_NTSC_M)
876 vf.frequency = 1076; /* ch. 4 67250*16/1000 */
877
878 video_input = cx->active_input;
879 cx->active_input++; /* Force update of input */
880 cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_INPUT, &video_input);
881
882 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
883 in one place. */
884 cx->std++; /* Force full standard initialization */
885 cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_STD, &cx->tuner_std);
886 cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_FREQUENCY, &vf);
887 return 0;
888}
889
890static void cx18_remove(struct pci_dev *pci_dev)
891{
892 struct cx18 *cx = pci_get_drvdata(pci_dev);
893
894 CX18_DEBUG_INFO("Removing Card #%d\n", cx->num);
895
896 /* Stop all captures */
897 CX18_DEBUG_INFO("Stopping all streams\n");
898 if (atomic_read(&cx->capturing) > 0)
899 cx18_stop_all_captures(cx);
900
901 /* Interrupts */
902 sw1_irq_disable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
903 sw2_irq_disable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
904
905 cx18_halt_firmware(cx);
906
907 cx18_streams_cleanup(cx);
908
909 exit_cx18_i2c(cx);
910
911 free_irq(cx->dev->irq, (void *)cx);
912
913 if (cx->dev)
914 cx18_iounmap(cx);
915
916 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
917
918 pci_disable_device(cx->dev);
919
920 CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
921}
922
923/* define a pci_driver for card detection */
924static struct pci_driver cx18_pci_driver = {
925 .name = "cx18",
926 .id_table = cx18_pci_tbl,
927 .probe = cx18_probe,
928 .remove = cx18_remove,
929};
930
931static int module_start(void)
932{
933 printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION);
934
935 memset(cx18_cards, 0, sizeof(cx18_cards));
936
937 /* Validate parameters */
938 if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
939 printk(KERN_ERR "cx18: Exiting, ivtv_first_minor must be between 0 and %d\n",
940 CX18_MAX_CARDS - 1);
941 return -1;
942 }
943
944 if (cx18_debug < 0 || cx18_debug > 511) {
945 cx18_debug = 0;
946 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
947 }
948
949 if (pci_register_driver(&cx18_pci_driver)) {
950 printk(KERN_ERR "cx18: Error detecting PCI card\n");
951 return -ENODEV;
952 }
953 printk(KERN_INFO "cx18: End initialization\n");
954 return 0;
955}
956
957static void module_cleanup(void)
958{
959 int i;
960
961 pci_unregister_driver(&cx18_pci_driver);
962
963 for (i = 0; i < cx18_cards_active; i++) {
964 if (cx18_cards[i] == NULL)
965 continue;
966 kfree(cx18_cards[i]);
967 }
968}
969
970module_init(module_start);
971module_exit(module_cleanup);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
new file mode 100644
index 000000000000..2ee939193bb7
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -0,0 +1,500 @@
1/*
2 * cx18 driver internal defines and structures
3 *
4 * Derived from ivtv-driver.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#ifndef CX18_DRIVER_H
25#define CX18_DRIVER_H
26
27#include <linux/version.h>
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <linux/sched.h>
33#include <linux/fs.h>
34#include <linux/pci.h>
35#include <linux/interrupt.h>
36#include <linux/spinlock.h>
37#include <linux/i2c.h>
38#include <linux/i2c-algo-bit.h>
39#include <linux/list.h>
40#include <linux/unistd.h>
41#include <linux/byteorder/swab.h>
42#include <linux/pagemap.h>
43#include <linux/workqueue.h>
44#include <linux/mutex.h>
45
46#include <linux/dvb/video.h>
47#include <linux/dvb/audio.h>
48#include <media/v4l2-common.h>
49#include <media/tuner.h>
50#include "cx18-mailbox.h"
51#include "cx18-av-core.h"
52#include "cx23418.h"
53
54/* DVB */
55#include "demux.h"
56#include "dmxdev.h"
57#include "dvb_demux.h"
58#include "dvb_frontend.h"
59#include "dvb_net.h"
60#include "dvbdev.h"
61
62#ifndef CONFIG_PCI
63# error "This driver requires kernel PCI support."
64#endif
65
66#define CX18_MEM_OFFSET 0x00000000
67#define CX18_MEM_SIZE 0x04000000
68#define CX18_REG_OFFSET 0x02000000
69
70/* Maximum cx18 driver instances. */
71#define CX18_MAX_CARDS 32
72
73/* Supported cards */
74#define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */
75#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
76#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
77#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
78#define CX18_CARD_LAST 3
79
80#define CX18_ENC_STREAM_TYPE_MPG 0
81#define CX18_ENC_STREAM_TYPE_TS 1
82#define CX18_ENC_STREAM_TYPE_YUV 2
83#define CX18_ENC_STREAM_TYPE_VBI 3
84#define CX18_ENC_STREAM_TYPE_PCM 4
85#define CX18_ENC_STREAM_TYPE_IDX 5
86#define CX18_ENC_STREAM_TYPE_RAD 6
87#define CX18_MAX_STREAMS 7
88
89/* system vendor and device IDs */
90#define PCI_VENDOR_ID_CX 0x14f1
91#define PCI_DEVICE_ID_CX23418 0x5b7a
92
93/* subsystem vendor ID */
94#define CX18_PCI_ID_HAUPPAUGE 0x0070
95#define CX18_PCI_ID_COMPRO 0x185b
96#define CX18_PCI_ID_YUAN 0x12ab
97
98/* ======================================================================== */
99/* ========================== START USER SETTABLE DMA VARIABLES =========== */
100/* ======================================================================== */
101
102/* DMA Buffers, Default size in MB allocated */
103#define CX18_DEFAULT_ENC_TS_BUFFERS 1
104#define CX18_DEFAULT_ENC_MPG_BUFFERS 2
105#define CX18_DEFAULT_ENC_IDX_BUFFERS 1
106#define CX18_DEFAULT_ENC_YUV_BUFFERS 2
107#define CX18_DEFAULT_ENC_VBI_BUFFERS 1
108#define CX18_DEFAULT_ENC_PCM_BUFFERS 1
109
110/* i2c stuff */
111#define I2C_CLIENTS_MAX 16
112
113/* debugging */
114
115/* Flag to turn on high volume debugging */
116#define CX18_DBGFLG_WARN (1 << 0)
117#define CX18_DBGFLG_INFO (1 << 1)
118#define CX18_DBGFLG_API (1 << 2)
119#define CX18_DBGFLG_DMA (1 << 3)
120#define CX18_DBGFLG_IOCTL (1 << 4)
121#define CX18_DBGFLG_FILE (1 << 5)
122#define CX18_DBGFLG_I2C (1 << 6)
123#define CX18_DBGFLG_IRQ (1 << 7)
124/* Flag to turn on high volume debugging */
125#define CX18_DBGFLG_HIGHVOL (1 << 8)
126
127/* NOTE: extra space before comma in 'cx->num , ## args' is required for
128 gcc-2.95, otherwise it won't compile. */
129#define CX18_DEBUG(x, type, fmt, args...) \
130 do { \
131 if ((x) & cx18_debug) \
132 printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \
133 } while (0)
134#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
135#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
136#define CX18_DEBUG_API(fmt, args...) CX18_DEBUG(CX18_DBGFLG_API, "api", fmt , ## args)
137#define CX18_DEBUG_DMA(fmt, args...) CX18_DEBUG(CX18_DBGFLG_DMA, "dma", fmt , ## args)
138#define CX18_DEBUG_IOCTL(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
139#define CX18_DEBUG_FILE(fmt, args...) CX18_DEBUG(CX18_DBGFLG_FILE, "file", fmt , ## args)
140#define CX18_DEBUG_I2C(fmt, args...) CX18_DEBUG(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
141#define CX18_DEBUG_IRQ(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
142
143#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
144 do { \
145 if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
146 printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \
147 } while (0)
148#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
149#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
150#define CX18_DEBUG_HI_API(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_API, "api", fmt , ## args)
151#define CX18_DEBUG_HI_DMA(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_DMA, "dma", fmt , ## args)
152#define CX18_DEBUG_HI_IOCTL(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args)
153#define CX18_DEBUG_HI_FILE(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_FILE, "file", fmt , ## args)
154#define CX18_DEBUG_HI_I2C(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_I2C, "i2c", fmt , ## args)
155#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
156
157/* Standard kernel messages */
158#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args)
159#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args)
160#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args)
161
162/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
163#define MPEG_FRAME_TYPE_IFRAME 1
164#define MPEG_FRAME_TYPE_IFRAME_PFRAME 3
165#define MPEG_FRAME_TYPE_ALL 7
166
167#define CX18_MAX_PGM_INDEX (400)
168
169extern int cx18_debug;
170
171
172struct cx18_options {
173 int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */
174 int cardtype; /* force card type on load */
175 int tuner; /* set tuner on load */
176 int radio; /* enable/disable radio */
177};
178
179/* per-buffer bit flags */
180#define CX18_F_B_NEED_BUF_SWAP 0 /* this buffer should be byte swapped */
181
182/* per-stream, s_flags */
183#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
184#define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
185#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
186#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
187#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */
188
189/* per-cx18, i_flags */
190#define CX18_F_I_LOADED_FW 0 /* Loaded the firmware the first time */
191#define CX18_F_I_EOS 4 /* End of encoder stream reached */
192#define CX18_F_I_RADIO_USER 5 /* The radio tuner is selected */
193#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
194#define CX18_F_I_INITED 21 /* set after first open */
195#define CX18_F_I_FAILED 22 /* set if first open failed */
196
197/* These are the VBI types as they appear in the embedded VBI private packets. */
198#define CX18_SLICED_TYPE_TELETEXT_B (1)
199#define CX18_SLICED_TYPE_CAPTION_525 (4)
200#define CX18_SLICED_TYPE_WSS_625 (5)
201#define CX18_SLICED_TYPE_VPS (7)
202
203struct cx18_buffer {
204 struct list_head list;
205 dma_addr_t dma_handle;
206 u32 id;
207 unsigned long b_flags;
208 char *buf;
209
210 u32 bytesused;
211 u32 readpos;
212};
213
214struct cx18_queue {
215 struct list_head list;
216 u32 buffers;
217 u32 length;
218 u32 bytesused;
219};
220
221struct cx18_dvb {
222 struct dmx_frontend hw_frontend;
223 struct dmx_frontend mem_frontend;
224 struct dmxdev dmxdev;
225 struct dvb_adapter dvb_adapter;
226 struct dvb_demux demux;
227 struct dvb_frontend *fe;
228 struct dvb_net dvbnet;
229 int enabled;
230 int feeding;
231
232 struct mutex feedlock;
233
234};
235
236struct cx18; /* forward reference */
237struct cx18_scb; /* forward reference */
238
239struct cx18_stream {
240 /* These first four fields are always set, even if the stream
241 is not actually created. */
242 struct video_device *v4l2dev; /* NULL when stream not created */
243 struct cx18 *cx; /* for ease of use */
244 const char *name; /* name of the stream */
245 int type; /* stream type */
246 u32 handle; /* task handle */
247 unsigned mdl_offset;
248
249 u32 id;
250 spinlock_t qlock; /* locks access to the queues */
251 unsigned long s_flags; /* status flags, see above */
252 int dma; /* can be PCI_DMA_TODEVICE,
253 PCI_DMA_FROMDEVICE or
254 PCI_DMA_NONE */
255 u64 dma_pts;
256 wait_queue_head_t waitq;
257
258 /* Buffer Stats */
259 u32 buffers;
260 u32 buf_size;
261 u32 buffers_stolen;
262
263 /* Buffer Queues */
264 struct cx18_queue q_free; /* free buffers */
265 struct cx18_queue q_full; /* full buffers */
266 struct cx18_queue q_io; /* waiting for I/O */
267
268 /* DVB / Digital Transport */
269 struct cx18_dvb dvb;
270};
271
272struct cx18_open_id {
273 u32 open_id;
274 int type;
275 enum v4l2_priority prio;
276 struct cx18 *cx;
277};
278
279/* forward declaration of struct defined in cx18-cards.h */
280struct cx18_card;
281
282
283#define CX18_VBI_FRAMES 32
284
285/* VBI data */
286struct vbi_info {
287 u32 enc_size;
288 u32 frame;
289 u8 cc_data_odd[256];
290 u8 cc_data_even[256];
291 int cc_pos;
292 u8 cc_no_update;
293 u8 vps[5];
294 u8 vps_found;
295 int wss;
296 u8 wss_found;
297 u8 wss_no_update;
298 u32 raw_decoder_line_size;
299 u8 raw_decoder_sav_odd_field;
300 u8 raw_decoder_sav_even_field;
301 u32 sliced_decoder_line_size;
302 u8 sliced_decoder_sav_odd_field;
303 u8 sliced_decoder_sav_even_field;
304 struct v4l2_format in;
305 /* convenience pointer to sliced struct in vbi_in union */
306 struct v4l2_sliced_vbi_format *sliced_in;
307 u32 service_set_in;
308 int insert_mpeg;
309
310 /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
311 One for /dev/vbi0 and one for /dev/vbi8 */
312 struct v4l2_sliced_vbi_data sliced_data[36];
313
314 /* Buffer for VBI data inserted into MPEG stream.
315 The first byte is a dummy byte that's never used.
316 The next 16 bytes contain the MPEG header for the VBI data,
317 the remainder is the actual VBI data.
318 The max size accepted by the MPEG VBI reinsertion turns out
319 to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
320 where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
321 a single line header byte and 2 * 18 is the number of VBI lines per frame.
322
323 However, it seems that the data must be 1K aligned, so we have to
324 pad the data until the 1 or 2 K boundary.
325
326 This pointer array will allocate 2049 bytes to store each VBI frame. */
327 u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
328 u32 sliced_mpeg_size[CX18_VBI_FRAMES];
329 struct cx18_buffer sliced_mpeg_buf;
330 u32 inserted_frame;
331
332 u32 start[2], count;
333 u32 raw_size;
334 u32 sliced_size;
335};
336
337/* Per cx23418, per I2C bus private algo callback data */
338struct cx18_i2c_algo_callback_data {
339 struct cx18 *cx;
340 int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */
341};
342
343/* Struct to hold info about cx18 cards */
344struct cx18 {
345 int num; /* board number, -1 during init! */
346 char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */
347 struct pci_dev *dev; /* PCI device */
348 const struct cx18_card *card; /* card information */
349 const char *card_name; /* full name of the card */
350 const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
351 u8 is_50hz;
352 u8 is_60hz;
353 u8 is_out_50hz;
354 u8 is_out_60hz;
355 u8 nof_inputs; /* number of video inputs */
356 u8 nof_audio_inputs; /* number of audio inputs */
357 u16 buffer_id; /* buffer ID counter */
358 u32 v4l2_cap; /* V4L2 capabilities of card */
359 u32 hw_flags; /* Hardware description of the board */
360 unsigned mdl_offset;
361 struct cx18_scb *scb; /* pointer to SCB */
362
363 struct cx18_av_state av_state;
364
365 /* codec settings */
366 struct cx2341x_mpeg_params params;
367 u32 filter_mode;
368 u32 temporal_strength;
369 u32 spatial_strength;
370
371 /* dualwatch */
372 unsigned long dualwatch_jiffies;
373 u16 dualwatch_stereo_mode;
374
375 /* Digitizer type */
376 int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
377
378 struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
379 struct cx18_options options; /* User options */
380 int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
381 struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
382 unsigned long i_flags; /* global cx18 flags */
383 atomic_t capturing; /* count number of active capture streams */
384 spinlock_t lock; /* lock access to this struct */
385 int search_pack_header;
386
387 spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
388
389 int open_id; /* incremented each time an open occurs, used as
390 unique ID. Starts at 1, so 0 can be used as
391 uninitialized value in the stream->id. */
392
393 u32 base_addr;
394 struct v4l2_prio_state prio;
395
396 u8 card_rev;
397 void __iomem *enc_mem, *reg_mem;
398
399 struct vbi_info vbi;
400
401 u32 pgm_info_offset;
402 u32 pgm_info_num;
403 u32 pgm_info_write_idx;
404 u32 pgm_info_read_idx;
405 struct v4l2_enc_idx_entry pgm_info[CX18_MAX_PGM_INDEX];
406
407 u64 mpg_data_received;
408 u64 vbi_data_inserted;
409
410 wait_queue_head_t mb_apu_waitq;
411 wait_queue_head_t mb_cpu_waitq;
412 wait_queue_head_t mb_epu_waitq;
413 wait_queue_head_t mb_hpu_waitq;
414 wait_queue_head_t cap_w;
415 /* when the current DMA is finished this queue is woken up */
416 wait_queue_head_t dma_waitq;
417
418 /* i2c */
419 struct i2c_adapter i2c_adap[2];
420 struct i2c_algo_bit_data i2c_algo[2];
421 struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
422 struct i2c_client i2c_client[2];
423 struct mutex i2c_bus_lock[2];
424 struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
425
426 /* v4l2 and User settings */
427
428 /* codec settings */
429 u32 audio_input;
430 u32 active_input;
431 u32 active_output;
432 v4l2_std_id std;
433 v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
434};
435
436/* Globals */
437extern struct cx18 *cx18_cards[];
438extern int cx18_cards_active;
439extern int cx18_first_minor;
440extern spinlock_t cx18_cards_lock;
441
442/*==============Prototypes==================*/
443
444/* Return non-zero if a signal is pending */
445int cx18_msleep_timeout(unsigned int msecs, int intr);
446
447/* Wait on queue, returns -EINTR if interrupted */
448int cx18_waitq(wait_queue_head_t *waitq);
449
450/* Read Hauppauge eeprom */
451struct tveeprom; /* forward reference */
452void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
453
454/* First-open initialization: load firmware, etc. */
455int cx18_init_on_first_open(struct cx18 *cx);
456
457/* This is a PCI post thing, where if the pci register is not read, then
458 the write doesn't always take effect right away. By reading back the
459 register any pending PCI writes will be performed (in order), and so
460 you can be sure that the writes are guaranteed to be done.
461
462 Rarely needed, only in some timing sensitive cases.
463 Apparently if this is not done some motherboards seem
464 to kill the firmware and get into the broken state until computer is
465 rebooted. */
466#define write_sync(val, reg) \
467 do { writel(val, reg); readl(reg); } while (0)
468
469#define read_reg(reg) readl(cx->reg_mem + (reg))
470#define write_reg(val, reg) writel(val, cx->reg_mem + (reg))
471#define write_reg_sync(val, reg) \
472 do { write_reg(val, reg); read_reg(reg); } while (0)
473
474#define read_enc(addr) readl(cx->enc_mem + (u32)(addr))
475#define write_enc(val, addr) writel(val, cx->enc_mem + (u32)(addr))
476#define write_enc_sync(val, addr) \
477 do { write_enc(val, addr); read_enc(addr); } while (0)
478
479#define sw1_irq_enable(val) do { \
480 write_reg(val, SW1_INT_STATUS); \
481 write_reg(read_reg(SW1_INT_ENABLE_PCI) | (val), SW1_INT_ENABLE_PCI); \
482} while (0)
483
484#define sw1_irq_disable(val) \
485 write_reg(read_reg(SW1_INT_ENABLE_PCI) & ~(val), SW1_INT_ENABLE_PCI);
486
487#define sw2_irq_enable(val) do { \
488 write_reg(val, SW2_INT_STATUS); \
489 write_reg(read_reg(SW2_INT_ENABLE_PCI) | (val), SW2_INT_ENABLE_PCI); \
490} while (0)
491
492#define sw2_irq_disable(val) \
493 write_reg(read_reg(SW2_INT_ENABLE_PCI) & ~(val), SW2_INT_ENABLE_PCI);
494
495#define setup_page(addr) do { \
496 u32 val = read_reg(0xD000F8) & ~0x1f00; \
497 write_reg(val | (((addr) >> 17) & 0x1f00), 0xD000F8); \
498} while (0)
499
500#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
new file mode 100644
index 000000000000..65efe69d939a
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -0,0 +1,288 @@
1/*
2 * cx18 functions for DVB support
3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "cx18-version.h"
23#include "cx18-dvb.h"
24#include "cx18-streams.h"
25#include "cx18-cards.h"
26#include "s5h1409.h"
27
28/* Wait until the MXL500X driver is merged */
29#ifdef HAVE_MXL500X
30#include "mxl500x.h"
31#endif
32
33DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
34
35#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
36
37#ifdef HAVE_MXL500X
38static struct mxl500x_config hauppauge_hvr1600_tuner = {
39 .delsys = MXL500x_MODE_ATSC,
40 .octf = MXL500x_OCTF_CH,
41 .xtal_freq = 16000000,
42 .iflo_freq = 5380000,
43 .ref_freq = 322800000,
44 .rssi_ena = MXL_RSSI_ENABLE,
45 .addr = 0xC6 >> 1,
46};
47
48static struct s5h1409_config hauppauge_hvr1600_config = {
49 .demod_address = 0x32 >> 1,
50 .output_mode = S5H1409_SERIAL_OUTPUT,
51 .gpio = S5H1409_GPIO_ON,
52 .qam_if = 44000,
53 .inversion = S5H1409_INVERSION_OFF,
54 .status_mode = S5H1409_DEMODLOCKING,
55 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
56
57};
58#endif
59
60static int dvb_register(struct cx18_stream *stream);
61
62/* Kernel DVB framework calls this when the feed needs to start.
63 * The CX18 framework should enable the transport DMA handling
64 * and queue processing.
65 */
66static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
67{
68 struct dvb_demux *demux = feed->demux;
69 struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
70 struct cx18 *cx = stream->cx;
71 int ret = -EINVAL;
72 u32 v;
73
74 CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
75 feed->pid, feed->index);
76 switch (cx->card->type) {
77 case CX18_CARD_HVR_1600_ESMT:
78 case CX18_CARD_HVR_1600_SAMSUNG:
79 v = read_reg(CX18_REG_DMUX_NUM_PORT_0_CONTROL);
80 v |= 0x00400000; /* Serial Mode */
81 v |= 0x00002000; /* Data Length - Byte */
82 v |= 0x00010000; /* Error - Polarity */
83 v |= 0x00020000; /* Error - Passthru */
84 v |= 0x000c0000; /* Error - Ignore */
85 write_reg(v, CX18_REG_DMUX_NUM_PORT_0_CONTROL);
86 break;
87
88 default:
89 /* Assumption - Parallel transport - Signalling
90 * undefined or default.
91 */
92 break;
93 }
94
95 if (!demux->dmx.frontend)
96 return -EINVAL;
97
98 if (stream) {
99 mutex_lock(&stream->dvb.feedlock);
100 if (stream->dvb.feeding++ == 0) {
101 CX18_DEBUG_INFO("Starting Transport DMA\n");
102 ret = cx18_start_v4l2_encode_stream(stream);
103 } else
104 ret = 0;
105 mutex_unlock(&stream->dvb.feedlock);
106 }
107
108 return ret;
109}
110
111/* Kernel DVB framework calls this when the feed needs to stop. */
112static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed)
113{
114 struct dvb_demux *demux = feed->demux;
115 struct cx18_stream *stream = (struct cx18_stream *)demux->priv;
116 struct cx18 *cx = stream->cx;
117 int ret = -EINVAL;
118
119 CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n",
120 feed->pid, feed->index);
121
122 if (stream) {
123 mutex_lock(&stream->dvb.feedlock);
124 if (--stream->dvb.feeding == 0) {
125 CX18_DEBUG_INFO("Stopping Transport DMA\n");
126 ret = cx18_stop_v4l2_encode_stream(stream, 0);
127 } else
128 ret = 0;
129 mutex_unlock(&stream->dvb.feedlock);
130 }
131
132 return ret;
133}
134
135int cx18_dvb_register(struct cx18_stream *stream)
136{
137 struct cx18 *cx = stream->cx;
138 struct cx18_dvb *dvb = &stream->dvb;
139 struct dvb_adapter *dvb_adapter;
140 struct dvb_demux *dvbdemux;
141 struct dmx_demux *dmx;
142 int ret;
143
144 if (!dvb)
145 return -EINVAL;
146
147 ret = dvb_register_adapter(&dvb->dvb_adapter,
148 CX18_DRIVER_NAME,
149 THIS_MODULE, &cx->dev->dev, adapter_nr);
150 if (ret < 0)
151 goto err_out;
152
153 dvb_adapter = &dvb->dvb_adapter;
154
155 dvbdemux = &dvb->demux;
156
157 dvbdemux->priv = (void *)stream;
158
159 dvbdemux->filternum = 256;
160 dvbdemux->feednum = 256;
161 dvbdemux->start_feed = cx18_dvb_start_feed;
162 dvbdemux->stop_feed = cx18_dvb_stop_feed;
163 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
164 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
165 ret = dvb_dmx_init(dvbdemux);
166 if (ret < 0)
167 goto err_dvb_unregister_adapter;
168
169 dmx = &dvbdemux->dmx;
170
171 dvb->hw_frontend.source = DMX_FRONTEND_0;
172 dvb->mem_frontend.source = DMX_MEMORY_FE;
173 dvb->dmxdev.filternum = 256;
174 dvb->dmxdev.demux = dmx;
175
176 ret = dvb_dmxdev_init(&dvb->dmxdev, dvb_adapter);
177 if (ret < 0)
178 goto err_dvb_dmx_release;
179
180 ret = dmx->add_frontend(dmx, &dvb->hw_frontend);
181 if (ret < 0)
182 goto err_dvb_dmxdev_release;
183
184 ret = dmx->add_frontend(dmx, &dvb->mem_frontend);
185 if (ret < 0)
186 goto err_remove_hw_frontend;
187
188 ret = dmx->connect_frontend(dmx, &dvb->hw_frontend);
189 if (ret < 0)
190 goto err_remove_mem_frontend;
191
192 ret = dvb_register(stream);
193 if (ret < 0)
194 goto err_disconnect_frontend;
195
196 dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
197
198 CX18_INFO("DVB Frontend registered\n");
199 mutex_init(&dvb->feedlock);
200 dvb->enabled = 1;
201 return ret;
202
203err_disconnect_frontend:
204 dmx->disconnect_frontend(dmx);
205err_remove_mem_frontend:
206 dmx->remove_frontend(dmx, &dvb->mem_frontend);
207err_remove_hw_frontend:
208 dmx->remove_frontend(dmx, &dvb->hw_frontend);
209err_dvb_dmxdev_release:
210 dvb_dmxdev_release(&dvb->dmxdev);
211err_dvb_dmx_release:
212 dvb_dmx_release(dvbdemux);
213err_dvb_unregister_adapter:
214 dvb_unregister_adapter(dvb_adapter);
215err_out:
216 return ret;
217}
218
219void cx18_dvb_unregister(struct cx18_stream *stream)
220{
221 struct cx18 *cx = stream->cx;
222 struct cx18_dvb *dvb = &stream->dvb;
223 struct dvb_adapter *dvb_adapter;
224 struct dvb_demux *dvbdemux;
225 struct dmx_demux *dmx;
226
227 CX18_INFO("unregister DVB\n");
228
229 dvb_adapter = &dvb->dvb_adapter;
230 dvbdemux = &dvb->demux;
231 dmx = &dvbdemux->dmx;
232
233 dmx->close(dmx);
234 dvb_net_release(&dvb->dvbnet);
235 dmx->remove_frontend(dmx, &dvb->mem_frontend);
236 dmx->remove_frontend(dmx, &dvb->hw_frontend);
237 dvb_dmxdev_release(&dvb->dmxdev);
238 dvb_dmx_release(dvbdemux);
239 dvb_unregister_frontend(dvb->fe);
240 dvb_frontend_detach(dvb->fe);
241 dvb_unregister_adapter(dvb_adapter);
242}
243
244/* All the DVB attach calls go here, this function get's modified
245 * for each new card. No other function in this file needs
246 * to change.
247 */
248static int dvb_register(struct cx18_stream *stream)
249{
250 struct cx18_dvb *dvb = &stream->dvb;
251 struct cx18 *cx = stream->cx;
252 int ret = 0;
253
254 switch (cx->card->type) {
255/* Wait until the MXL500X driver is merged */
256#ifdef HAVE_MXL500X
257 case CX18_CARD_HVR_1600_ESMT:
258 case CX18_CARD_HVR_1600_SAMSUNG:
259 dvb->fe = dvb_attach(s5h1409_attach,
260 &hauppauge_hvr1600_config,
261 &cx->i2c_adap[0]);
262 if (dvb->fe != NULL) {
263 dvb_attach(mxl500x_attach, dvb->fe,
264 &hauppauge_hvr1600_tuner,
265 &cx->i2c_adap[0]);
266 ret = 0;
267 }
268 break;
269#endif
270 default:
271 /* No Digital Tv Support */
272 break;
273 }
274
275 if (dvb->fe == NULL) {
276 CX18_ERR("frontend initialization failed\n");
277 return -1;
278 }
279
280 ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe);
281 if (ret < 0) {
282 if (dvb->fe->ops.release)
283 dvb->fe->ops.release(dvb->fe);
284 return ret;
285 }
286
287 return ret;
288}
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h
new file mode 100644
index 000000000000..d6a6ccda79a9
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-dvb.h
@@ -0,0 +1,25 @@
1/*
2 * cx18 functions for DVB support
3 *
4 * Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "cx18-driver.h"
23
24int cx18_dvb_register(struct cx18_stream *stream);
25void cx18_dvb_unregister(struct cx18_stream *stream);
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
new file mode 100644
index 000000000000..69303065a294
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -0,0 +1,711 @@
1/*
2 * cx18 file operation functions
3 *
4 * Derived from ivtv-fileops.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-fileops.h"
26#include "cx18-i2c.h"
27#include "cx18-queue.h"
28#include "cx18-vbi.h"
29#include "cx18-audio.h"
30#include "cx18-mailbox.h"
31#include "cx18-scb.h"
32#include "cx18-streams.h"
33#include "cx18-controls.h"
34#include "cx18-ioctl.h"
35#include "cx18-cards.h"
36
37/* This function tries to claim the stream for a specific file descriptor.
38 If no one else is using this stream then the stream is claimed and
39 associated VBI streams are also automatically claimed.
40 Possible error returns: -EBUSY if someone else has claimed
41 the stream or 0 on success. */
42int cx18_claim_stream(struct cx18_open_id *id, int type)
43{
44 struct cx18 *cx = id->cx;
45 struct cx18_stream *s = &cx->streams[type];
46 struct cx18_stream *s_vbi;
47 int vbi_type;
48
49 if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
50 /* someone already claimed this stream */
51 if (s->id == id->open_id) {
52 /* yes, this file descriptor did. So that's OK. */
53 return 0;
54 }
55 if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) {
56 /* VBI is handled already internally, now also assign
57 the file descriptor to this stream for external
58 reading of the stream. */
59 s->id = id->open_id;
60 CX18_DEBUG_INFO("Start Read VBI\n");
61 return 0;
62 }
63 /* someone else is using this stream already */
64 CX18_DEBUG_INFO("Stream %d is busy\n", type);
65 return -EBUSY;
66 }
67 s->id = id->open_id;
68
69 /* CX18_DEC_STREAM_TYPE_MPG needs to claim CX18_DEC_STREAM_TYPE_VBI,
70 CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI
71 (provided VBI insertion is on and sliced VBI is selected), for all
72 other streams we're done */
73 if (type == CX18_ENC_STREAM_TYPE_MPG &&
74 cx->vbi.insert_mpeg && cx->vbi.sliced_in->service_set) {
75 vbi_type = CX18_ENC_STREAM_TYPE_VBI;
76 } else {
77 return 0;
78 }
79 s_vbi = &cx->streams[vbi_type];
80
81 set_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
82
83 /* mark that it is used internally */
84 set_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags);
85 return 0;
86}
87
88/* This function releases a previously claimed stream. It will take into
89 account associated VBI streams. */
90void cx18_release_stream(struct cx18_stream *s)
91{
92 struct cx18 *cx = s->cx;
93 struct cx18_stream *s_vbi;
94
95 s->id = -1;
96 if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
97 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) {
98 /* this stream is still in use internally */
99 return;
100 }
101 if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) {
102 CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name);
103 return;
104 }
105
106 cx18_flush_queues(s);
107
108 /* CX18_ENC_STREAM_TYPE_MPG needs to release CX18_ENC_STREAM_TYPE_VBI,
109 for all other streams we're done */
110 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
111 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
112 else
113 return;
114
115 /* clear internal use flag */
116 if (!test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags)) {
117 /* was already cleared */
118 return;
119 }
120 if (s_vbi->id != -1) {
121 /* VBI stream still claimed by a file descriptor */
122 return;
123 }
124 clear_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags);
125 cx18_flush_queues(s_vbi);
126}
127
128static void cx18_dualwatch(struct cx18 *cx)
129{
130 struct v4l2_tuner vt;
131 u16 new_bitmap;
132 u16 new_stereo_mode;
133 const u16 stereo_mask = 0x0300;
134 const u16 dual = 0x0200;
135
136 new_stereo_mode = cx->params.audio_properties & stereo_mask;
137 memset(&vt, 0, sizeof(vt));
138 cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, &vt);
139 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
140 (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
141 new_stereo_mode = dual;
142
143 if (new_stereo_mode == cx->dualwatch_stereo_mode)
144 return;
145
146 new_bitmap = new_stereo_mode | (cx->params.audio_properties & ~stereo_mask);
147
148 CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. new audio_bitmask=0x%ux\n",
149 cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap);
150
151 if (cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2,
152 cx18_find_handle(cx), new_bitmap) == 0) {
153 cx->dualwatch_stereo_mode = new_stereo_mode;
154 return;
155 }
156 CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
157}
158
159
160static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, int *err)
161{
162 struct cx18 *cx = s->cx;
163 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
164 struct cx18_buffer *buf;
165 DEFINE_WAIT(wait);
166
167 *err = 0;
168 while (1) {
169 if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
170
171 if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
172 cx->dualwatch_jiffies = jiffies;
173 cx18_dualwatch(cx);
174 }
175 if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
176 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
177 while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
178 /* byteswap and process VBI data */
179/* cx18_process_vbi_data(cx, buf, s_vbi->dma_pts, s_vbi->type); */
180 cx18_enqueue(s_vbi, buf, &s_vbi->q_free);
181 }
182 }
183 buf = &cx->vbi.sliced_mpeg_buf;
184 if (buf->readpos != buf->bytesused)
185 return buf;
186 }
187
188 /* do we have leftover data? */
189 buf = cx18_dequeue(s, &s->q_io);
190 if (buf)
191 return buf;
192
193 /* do we have new data? */
194 buf = cx18_dequeue(s, &s->q_full);
195 if (buf) {
196 if (!test_and_clear_bit(CX18_F_B_NEED_BUF_SWAP,
197 &buf->b_flags))
198 return buf;
199 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
200 /* byteswap MPG data */
201 cx18_buf_swap(buf);
202 else {
203 /* byteswap and process VBI data */
204 cx18_process_vbi_data(cx, buf,
205 s->dma_pts, s->type);
206 }
207 return buf;
208 }
209
210 /* return if end of stream */
211 if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
212 CX18_DEBUG_INFO("EOS %s\n", s->name);
213 return NULL;
214 }
215
216 /* return if file was opened with O_NONBLOCK */
217 if (non_block) {
218 *err = -EAGAIN;
219 return NULL;
220 }
221
222 /* wait for more data to arrive */
223 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
224 /* New buffers might have become available before we were added
225 to the waitqueue */
226 if (!s->q_full.buffers)
227 schedule();
228 finish_wait(&s->waitq, &wait);
229 if (signal_pending(current)) {
230 /* return if a signal was received */
231 CX18_DEBUG_INFO("User stopped %s\n", s->name);
232 *err = -EINTR;
233 return NULL;
234 }
235 }
236}
237
238static void cx18_setup_sliced_vbi_buf(struct cx18 *cx)
239{
240 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
241
242 cx->vbi.sliced_mpeg_buf.buf = cx->vbi.sliced_mpeg_data[idx];
243 cx->vbi.sliced_mpeg_buf.bytesused = cx->vbi.sliced_mpeg_size[idx];
244 cx->vbi.sliced_mpeg_buf.readpos = 0;
245}
246
247static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
248 struct cx18_buffer *buf, char __user *ubuf, size_t ucount)
249{
250 struct cx18 *cx = s->cx;
251 size_t len = buf->bytesused - buf->readpos;
252
253 if (len > ucount)
254 len = ucount;
255 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
256 cx->vbi.sliced_in->service_set && buf != &cx->vbi.sliced_mpeg_buf) {
257 const char *start = buf->buf + buf->readpos;
258 const char *p = start + 1;
259 const u8 *q;
260 u8 ch = cx->search_pack_header ? 0xba : 0xe0;
261 int stuffing, i;
262
263 while (start + len > p) {
264 q = memchr(p, 0, start + len - p);
265 if (q == NULL)
266 break;
267 p = q + 1;
268 if ((char *)q + 15 >= buf->buf + buf->bytesused ||
269 q[1] != 0 || q[2] != 1 || q[3] != ch)
270 continue;
271 if (!cx->search_pack_header) {
272 if ((q[6] & 0xc0) != 0x80)
273 continue;
274 if (((q[7] & 0xc0) == 0x80 &&
275 (q[9] & 0xf0) == 0x20) ||
276 ((q[7] & 0xc0) == 0xc0 &&
277 (q[9] & 0xf0) == 0x30)) {
278 ch = 0xba;
279 cx->search_pack_header = 1;
280 p = q + 9;
281 }
282 continue;
283 }
284 stuffing = q[13] & 7;
285 /* all stuffing bytes must be 0xff */
286 for (i = 0; i < stuffing; i++)
287 if (q[14 + i] != 0xff)
288 break;
289 if (i == stuffing &&
290 (q[4] & 0xc4) == 0x44 &&
291 (q[12] & 3) == 3 &&
292 q[14 + stuffing] == 0 &&
293 q[15 + stuffing] == 0 &&
294 q[16 + stuffing] == 1) {
295 cx->search_pack_header = 0;
296 len = (char *)q - start;
297 cx18_setup_sliced_vbi_buf(cx);
298 break;
299 }
300 }
301 }
302 if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
303 CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n",
304 len, s->name);
305 return -EFAULT;
306 }
307 buf->readpos += len;
308 if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
309 buf != &cx->vbi.sliced_mpeg_buf)
310 cx->mpg_data_received += len;
311 return len;
312}
313
314static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
315 size_t tot_count, int non_block)
316{
317 struct cx18 *cx = s->cx;
318 size_t tot_written = 0;
319 int single_frame = 0;
320
321 if (atomic_read(&cx->capturing) == 0 && s->id == -1) {
322 /* shouldn't happen */
323 CX18_DEBUG_WARN("Stream %s not initialized before read\n",
324 s->name);
325 return -EIO;
326 }
327
328 /* Each VBI buffer is one frame, the v4l2 API says that for VBI the
329 frames should arrive one-by-one, so make sure we never output more
330 than one VBI frame at a time */
331 if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
332 cx->vbi.sliced_in->service_set)
333 single_frame = 1;
334
335 for (;;) {
336 struct cx18_buffer *buf;
337 int rc;
338
339 buf = cx18_get_buffer(s, non_block, &rc);
340 /* if there is no data available... */
341 if (buf == NULL) {
342 /* if we got data, then return that regardless */
343 if (tot_written)
344 break;
345 /* EOS condition */
346 if (rc == 0) {
347 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
348 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
349 cx18_release_stream(s);
350 }
351 /* set errno */
352 return rc;
353 }
354
355 rc = cx18_copy_buf_to_user(s, buf, ubuf + tot_written,
356 tot_count - tot_written);
357
358 if (buf != &cx->vbi.sliced_mpeg_buf) {
359 if (buf->readpos == buf->bytesused) {
360 cx18_buf_sync_for_device(s, buf);
361 cx18_enqueue(s, buf, &s->q_free);
362 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5,
363 s->handle,
364 (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
365 1, buf->id, s->buf_size);
366 } else
367 cx18_enqueue(s, buf, &s->q_io);
368 } else if (buf->readpos == buf->bytesused) {
369 int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES;
370
371 cx->vbi.sliced_mpeg_size[idx] = 0;
372 cx->vbi.inserted_frame++;
373 cx->vbi_data_inserted += buf->bytesused;
374 }
375 if (rc < 0)
376 return rc;
377 tot_written += rc;
378
379 if (tot_written == tot_count || single_frame)
380 break;
381 }
382 return tot_written;
383}
384
385static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf,
386 size_t count, loff_t *pos, int non_block)
387{
388 ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0;
389 struct cx18 *cx = s->cx;
390
391 CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
392 if (rc > 0)
393 pos += rc;
394 return rc;
395}
396
397int cx18_start_capture(struct cx18_open_id *id)
398{
399 struct cx18 *cx = id->cx;
400 struct cx18_stream *s = &cx->streams[id->type];
401 struct cx18_stream *s_vbi;
402
403 if (s->type == CX18_ENC_STREAM_TYPE_RAD) {
404 /* you cannot read from these stream types. */
405 return -EPERM;
406 }
407
408 /* Try to claim this stream. */
409 if (cx18_claim_stream(id, s->type))
410 return -EBUSY;
411
412 /* If capture is already in progress, then we also have to
413 do nothing extra. */
414 if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) ||
415 test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
416 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
417 return 0;
418 }
419
420 /* Start VBI capture if required */
421 s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
422 if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
423 test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
424 !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
425 /* Note: the CX18_ENC_STREAM_TYPE_VBI is claimed
426 automatically when the MPG stream is claimed.
427 We only need to start the VBI capturing. */
428 if (cx18_start_v4l2_encode_stream(s_vbi)) {
429 CX18_DEBUG_WARN("VBI capture start failed\n");
430
431 /* Failure, clean up and return an error */
432 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
433 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
434 /* also releases the associated VBI stream */
435 cx18_release_stream(s);
436 return -EIO;
437 }
438 CX18_DEBUG_INFO("VBI insertion started\n");
439 }
440
441 /* Tell the card to start capturing */
442 if (!cx18_start_v4l2_encode_stream(s)) {
443 /* We're done */
444 set_bit(CX18_F_S_APPL_IO, &s->s_flags);
445 /* Resume a possibly paused encoder */
446 if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
447 cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle);
448 return 0;
449 }
450
451 /* failure, clean up */
452 CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
453
454 /* Note: the CX18_ENC_STREAM_TYPE_VBI is released
455 automatically when the MPG stream is released.
456 We only need to stop the VBI capturing. */
457 if (s->type == CX18_ENC_STREAM_TYPE_MPG &&
458 test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) {
459 cx18_stop_v4l2_encode_stream(s_vbi, 0);
460 clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
461 }
462 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
463 cx18_release_stream(s);
464 return -EIO;
465}
466
467ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
468 loff_t *pos)
469{
470 struct cx18_open_id *id = filp->private_data;
471 struct cx18 *cx = id->cx;
472 struct cx18_stream *s = &cx->streams[id->type];
473 int rc;
474
475 CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
476
477 mutex_lock(&cx->serialize_lock);
478 rc = cx18_start_capture(id);
479 mutex_unlock(&cx->serialize_lock);
480 if (rc)
481 return rc;
482 return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
483}
484
485unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
486{
487 struct cx18_open_id *id = filp->private_data;
488 struct cx18 *cx = id->cx;
489 struct cx18_stream *s = &cx->streams[id->type];
490 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
491
492 /* Start a capture if there is none */
493 if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
494 int rc;
495
496 mutex_lock(&cx->serialize_lock);
497 rc = cx18_start_capture(id);
498 mutex_unlock(&cx->serialize_lock);
499 if (rc) {
500 CX18_DEBUG_INFO("Could not start capture for %s (%d)\n",
501 s->name, rc);
502 return POLLERR;
503 }
504 CX18_DEBUG_FILE("Encoder poll started capture\n");
505 }
506
507 /* add stream's waitq to the poll list */
508 CX18_DEBUG_HI_FILE("Encoder poll\n");
509 poll_wait(filp, &s->waitq, wait);
510
511 if (s->q_full.length || s->q_io.length)
512 return POLLIN | POLLRDNORM;
513 if (eof)
514 return POLLHUP;
515 return 0;
516}
517
518void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
519{
520 struct cx18 *cx = id->cx;
521 struct cx18_stream *s = &cx->streams[id->type];
522
523 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
524
525 /* 'Unclaim' this stream */
526
527 /* Stop capturing */
528 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
529 struct cx18_stream *s_vbi =
530 &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
531
532 CX18_DEBUG_INFO("close stopping capture\n");
533 /* Special case: a running VBI capture for VBI insertion
534 in the mpeg stream. Need to stop that too. */
535 if (id->type == CX18_ENC_STREAM_TYPE_MPG &&
536 test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) &&
537 !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) {
538 CX18_DEBUG_INFO("close stopping embedded VBI capture\n");
539 cx18_stop_v4l2_encode_stream(s_vbi, 0);
540 }
541 if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
542 test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags))
543 /* Also used internally, don't stop capturing */
544 s->id = -1;
545 else
546 cx18_stop_v4l2_encode_stream(s, gop_end);
547 }
548 if (!gop_end) {
549 clear_bit(CX18_F_S_APPL_IO, &s->s_flags);
550 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
551 cx18_release_stream(s);
552 }
553}
554
555int cx18_v4l2_close(struct inode *inode, struct file *filp)
556{
557 struct cx18_open_id *id = filp->private_data;
558 struct cx18 *cx = id->cx;
559 struct cx18_stream *s = &cx->streams[id->type];
560
561 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
562
563 v4l2_prio_close(&cx->prio, &id->prio);
564
565 /* Easy case first: this stream was never claimed by us */
566 if (s->id != id->open_id) {
567 kfree(id);
568 return 0;
569 }
570
571 /* 'Unclaim' this stream */
572
573 /* Stop radio */
574 mutex_lock(&cx->serialize_lock);
575 if (id->type == CX18_ENC_STREAM_TYPE_RAD) {
576 /* Closing radio device, return to TV mode */
577 cx18_mute(cx);
578 /* Mark that the radio is no longer in use */
579 clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
580 /* Switch tuner to TV */
581 cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
582 /* Select correct audio input (i.e. TV tuner or Line in) */
583 cx18_audio_set_io(cx);
584 if (atomic_read(&cx->capturing) > 0) {
585 /* Undo video mute */
586 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
587 cx->params.video_mute |
588 (cx->params.video_mute_yuv << 8));
589 }
590 /* Done! Unmute and continue. */
591 cx18_unmute(cx);
592 cx18_release_stream(s);
593 } else {
594 cx18_stop_capture(id, 0);
595 }
596 kfree(id);
597 mutex_unlock(&cx->serialize_lock);
598 return 0;
599}
600
601static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
602{
603 struct cx18 *cx = s->cx;
604 struct cx18_open_id *item;
605
606 CX18_DEBUG_FILE("open %s\n", s->name);
607
608 /* Allocate memory */
609 item = kmalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
610 if (NULL == item) {
611 CX18_DEBUG_WARN("nomem on v4l2 open\n");
612 return -ENOMEM;
613 }
614 item->cx = cx;
615 item->type = s->type;
616 v4l2_prio_open(&cx->prio, &item->prio);
617
618 item->open_id = cx->open_id++;
619 filp->private_data = item;
620
621 if (item->type == CX18_ENC_STREAM_TYPE_RAD) {
622 /* Try to claim this stream */
623 if (cx18_claim_stream(item, item->type)) {
624 /* No, it's already in use */
625 kfree(item);
626 return -EBUSY;
627 }
628
629 if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
630 if (atomic_read(&cx->capturing) > 0) {
631 /* switching to radio while capture is
632 in progress is not polite */
633 cx18_release_stream(s);
634 kfree(item);
635 return -EBUSY;
636 }
637 }
638
639 /* Mark that the radio is being used. */
640 set_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
641 /* We have the radio */
642 cx18_mute(cx);
643 /* Switch tuner to radio */
644 cx18_call_i2c_clients(cx, AUDC_SET_RADIO, NULL);
645 /* Select the correct audio input (i.e. radio tuner) */
646 cx18_audio_set_io(cx);
647 /* Done! Unmute and continue. */
648 cx18_unmute(cx);
649 }
650 return 0;
651}
652
653int cx18_v4l2_open(struct inode *inode, struct file *filp)
654{
655 int res, x, y = 0;
656 struct cx18 *cx = NULL;
657 struct cx18_stream *s = NULL;
658 int minor = iminor(inode);
659
660 /* Find which card this open was on */
661 spin_lock(&cx18_cards_lock);
662 for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
663 /* find out which stream this open was on */
664 for (y = 0; y < CX18_MAX_STREAMS; y++) {
665 s = &cx18_cards[x]->streams[y];
666 if (s->v4l2dev && s->v4l2dev->minor == minor) {
667 cx = cx18_cards[x];
668 break;
669 }
670 }
671 }
672 spin_unlock(&cx18_cards_lock);
673
674 if (cx == NULL) {
675 /* Couldn't find a device registered
676 on that minor, shouldn't happen! */
677 printk(KERN_WARNING "No cx18 device found on minor %d\n",
678 minor);
679 return -ENXIO;
680 }
681
682 mutex_lock(&cx->serialize_lock);
683 if (cx18_init_on_first_open(cx)) {
684 CX18_ERR("Failed to initialize on minor %d\n", minor);
685 mutex_unlock(&cx->serialize_lock);
686 return -ENXIO;
687 }
688 res = cx18_serialized_open(s, filp);
689 mutex_unlock(&cx->serialize_lock);
690 return res;
691}
692
693void cx18_mute(struct cx18 *cx)
694{
695 if (atomic_read(&cx->capturing))
696 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
697 cx18_find_handle(cx), 1);
698 CX18_DEBUG_INFO("Mute\n");
699}
700
701void cx18_unmute(struct cx18 *cx)
702{
703 if (atomic_read(&cx->capturing)) {
704 cx18_msleep_timeout(100, 0);
705 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
706 cx18_find_handle(cx), 12);
707 cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
708 cx18_find_handle(cx), 0);
709 }
710 CX18_DEBUG_INFO("Unmute\n");
711}
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
new file mode 100644
index 000000000000..16cdafbd24c5
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -0,0 +1,45 @@
1/*
2 * cx18 file operation functions
3 *
4 * Derived from ivtv-fileops.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24/* Testing/Debugging */
25int cx18_v4l2_open(struct inode *inode, struct file *filp);
26ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
27 loff_t *pos);
28ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count,
29 loff_t *pos);
30int cx18_v4l2_close(struct inode *inode, struct file *filp);
31unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait);
32int cx18_start_capture(struct cx18_open_id *id);
33void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
34void cx18_mute(struct cx18 *cx);
35void cx18_unmute(struct cx18 *cx);
36
37/* Utilities */
38
39/* Try to claim a stream for the filehandle. Return 0 on success,
40 -EBUSY if stream already claimed. Once a stream is claimed, it
41 remains claimed until the associated filehandle is closed. */
42int cx18_claim_stream(struct cx18_open_id *id, int type);
43
44/* Release a previously claimed stream. */
45void cx18_release_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
new file mode 100644
index 000000000000..2694ce350631
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -0,0 +1,373 @@
1/*
2 * cx18 firmware functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include "cx18-driver.h"
23#include "cx18-scb.h"
24#include "cx18-irq.h"
25#include "cx18-firmware.h"
26#include "cx18-cards.h"
27#include <linux/firmware.h>
28
29#define CX18_PROC_SOFT_RESET 0xc70010
30#define CX18_DDR_SOFT_RESET 0xc70014
31#define CX18_CLOCK_SELECT1 0xc71000
32#define CX18_CLOCK_SELECT2 0xc71004
33#define CX18_HALF_CLOCK_SELECT1 0xc71008
34#define CX18_HALF_CLOCK_SELECT2 0xc7100C
35#define CX18_CLOCK_POLARITY1 0xc71010
36#define CX18_CLOCK_POLARITY2 0xc71014
37#define CX18_ADD_DELAY_ENABLE1 0xc71018
38#define CX18_ADD_DELAY_ENABLE2 0xc7101C
39#define CX18_CLOCK_ENABLE1 0xc71020
40#define CX18_CLOCK_ENABLE2 0xc71024
41
42#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
43
44#define CX18_AUDIO_ENABLE 0xc72014
45#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
46
47#define CX18_FAST_CLOCK_PLL_INT 0xc78000
48#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004
49#define CX18_FAST_CLOCK_PLL_POST 0xc78008
50#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C
51#define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010
52
53#define CX18_SLOW_CLOCK_PLL_INT 0xc78014
54#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018
55#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C
56#define CX18_MPEG_CLOCK_PLL_INT 0xc78040
57#define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044
58#define CX18_MPEG_CLOCK_PLL_POST 0xc78048
59#define CX18_PLL_POWER_DOWN 0xc78088
60#define CX18_SW1_INT_STATUS 0xc73104
61#define CX18_SW1_INT_ENABLE_PCI 0xc7311C
62#define CX18_SW2_INT_SET 0xc73140
63#define CX18_SW2_INT_STATUS 0xc73144
64#define CX18_ADEC_CONTROL 0xc78120
65
66#define CX18_DDR_REQUEST_ENABLE 0xc80000
67#define CX18_DDR_CHIP_CONFIG 0xc80004
68#define CX18_DDR_REFRESH 0xc80008
69#define CX18_DDR_TIMING1 0xc8000C
70#define CX18_DDR_TIMING2 0xc80010
71#define CX18_DDR_POWER_REG 0xc8001C
72
73#define CX18_DDR_TUNE_LANE 0xc80048
74#define CX18_DDR_INITIAL_EMRS 0xc80054
75#define CX18_DDR_MB_PER_ROW_7 0xc8009C
76#define CX18_DDR_BASE_63_ADDR 0xc804FC
77
78#define CX18_WMB_CLIENT02 0xc90108
79#define CX18_WMB_CLIENT05 0xc90114
80#define CX18_WMB_CLIENT06 0xc90118
81#define CX18_WMB_CLIENT07 0xc9011C
82#define CX18_WMB_CLIENT08 0xc90120
83#define CX18_WMB_CLIENT09 0xc90124
84#define CX18_WMB_CLIENT10 0xc90128
85#define CX18_WMB_CLIENT11 0xc9012C
86#define CX18_WMB_CLIENT12 0xc90130
87#define CX18_WMB_CLIENT13 0xc90134
88#define CX18_WMB_CLIENT14 0xc90138
89
90#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
91
92/* Encoder/decoder firmware sizes */
93#define CX18_FW_CPU_SIZE (174716)
94#define CX18_FW_APU_SIZE (141200)
95
96#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
97#define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
98
99struct cx18_apu_rom_seghdr {
100 u32 sync1;
101 u32 sync2;
102 u32 addr;
103 u32 size;
104};
105
106static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx, long size)
107{
108 const struct firmware *fw = NULL;
109 int retries = 3;
110 int i, j;
111 u32 __iomem *dst = (u32 __iomem *)mem;
112 const u32 *src;
113
114retry:
115 if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) {
116 CX18_ERR("Unable to open firmware %s (must be %ld bytes)\n",
117 fn, size);
118 CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
119 return -ENOMEM;
120 }
121
122 src = (const u32 *)fw->data;
123
124 if (fw->size != size) {
125 /* Due to race conditions in firmware loading (esp. with
126 udev <0.95) the wrong file was sometimes loaded. So we check
127 filesizes to see if at least the right-sized file was
128 loaded. If not, then we retry. */
129 CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n",
130 fn, size, fw->size);
131 release_firmware(fw);
132 retries--;
133 goto retry;
134 }
135 for (i = 0; i < fw->size; i += 4096) {
136 setup_page(i);
137 for (j = i; j < fw->size && j < i + 4096; j += 4) {
138 /* no need for endianness conversion on the ppc */
139 __raw_writel(*src, dst);
140 if (__raw_readl(dst) != *src) {
141 CX18_ERR("Mismatch at offset %x\n", i);
142 release_firmware(fw);
143 return -EIO;
144 }
145 dst++;
146 src++;
147 }
148 }
149 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
150 CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size);
151 release_firmware(fw);
152 return size;
153}
154
155static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, long size)
156{
157 const struct firmware *fw = NULL;
158 int retries = 3;
159 int i, j;
160 const u32 *src;
161 struct cx18_apu_rom_seghdr seghdr;
162 const u8 *vers;
163 u32 offset = 0;
164 u32 apu_version = 0;
165 int sz;
166
167retry:
168 if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) {
169 CX18_ERR("unable to open firmware %s (must be %ld bytes)\n",
170 fn, size);
171 CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
172 return -ENOMEM;
173 }
174
175 src = (const u32 *)fw->data;
176 vers = fw->data + sizeof(seghdr);
177 sz = fw->size;
178
179 if (fw->size != size) {
180 /* Due to race conditions in firmware loading (esp. with
181 udev <0.95) the wrong file was sometimes loaded. So we check
182 filesizes to see if at least the right-sized file was
183 loaded. If not, then we retry. */
184 CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n",
185 fn, size, fw->size);
186 release_firmware(fw);
187 retries--;
188 goto retry;
189 }
190 apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
191 while (offset + sizeof(seghdr) < size) {
192 /* TODO: byteswapping */
193 memcpy(&seghdr, src + offset / 4, sizeof(seghdr));
194 offset += sizeof(seghdr);
195 if (seghdr.sync1 != APU_ROM_SYNC1 ||
196 seghdr.sync2 != APU_ROM_SYNC2) {
197 offset += seghdr.size;
198 continue;
199 }
200 CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
201 seghdr.addr + seghdr.size - 1);
202 if (offset + seghdr.size > sz)
203 break;
204 for (i = 0; i < seghdr.size; i += 4096) {
205 setup_page(offset + i);
206 for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
207 /* no need for endianness conversion on the ppc */
208 __raw_writel(src[(offset + j) / 4], dst + seghdr.addr + j);
209 if (__raw_readl(dst + seghdr.addr + j) != src[(offset + j) / 4]) {
210 CX18_ERR("Mismatch at offset %x\n", offset + j);
211 release_firmware(fw);
212 return -EIO;
213 }
214 }
215 }
216 offset += seghdr.size;
217 }
218 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
219 CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n",
220 fn, apu_version, fw->size);
221 release_firmware(fw);
222 /* Clear bit0 for APU to start from 0 */
223 write_reg(read_reg(0xc72030) & ~1, 0xc72030);
224 return size;
225}
226
227void cx18_halt_firmware(struct cx18 *cx)
228{
229 CX18_DEBUG_INFO("Preparing for firmware halt.\n");
230 write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
231 write_reg(0x00020002, CX18_ADEC_CONTROL);
232}
233
234void cx18_init_power(struct cx18 *cx, int lowpwr)
235{
236 /* power-down Spare and AOM PLLs */
237 /* power-up fast, slow and mpeg PLLs */
238 write_reg(0x00000008, CX18_PLL_POWER_DOWN);
239
240 /* ADEC out of sleep */
241 write_reg(0x00020000, CX18_ADEC_CONTROL);
242
243 /* The fast clock is at 200/245 MHz */
244 write_reg(lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
245 write_reg(lowpwr ? 0x1EFBF37 : 0x038E3D7, CX18_FAST_CLOCK_PLL_FRAC);
246
247 write_reg(2, CX18_FAST_CLOCK_PLL_POST);
248 write_reg(1, CX18_FAST_CLOCK_PLL_PRESCALE);
249 write_reg(4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);
250
251 /* set slow clock to 125/120 MHz */
252 write_reg(lowpwr ? 0x11 : 0x10, CX18_SLOW_CLOCK_PLL_INT);
253 write_reg(lowpwr ? 0xEBAF05 : 0x18618A8, CX18_SLOW_CLOCK_PLL_FRAC);
254 write_reg(4, CX18_SLOW_CLOCK_PLL_POST);
255
256 /* mpeg clock pll 54MHz */
257 write_reg(0xF, CX18_MPEG_CLOCK_PLL_INT);
258 write_reg(0x2BCFEF, CX18_MPEG_CLOCK_PLL_FRAC);
259 write_reg(8, CX18_MPEG_CLOCK_PLL_POST);
260
261 /* Defaults */
262 /* APU = SC or SC/2 = 125/62.5 */
263 /* EPU = SC = 125 */
264 /* DDR = FC = 180 */
265 /* ENC = SC = 125 */
266 /* AI1 = SC = 125 */
267 /* VIM2 = disabled */
268 /* PCI = FC/2 = 90 */
269 /* AI2 = disabled */
270 /* DEMUX = disabled */
271 /* AO = SC/2 = 62.5 */
272 /* SER = 54MHz */
273 /* VFC = disabled */
274 /* USB = disabled */
275
276 write_reg(lowpwr ? 0xFFFF0020 : 0x00060004, CX18_CLOCK_SELECT1);
277 write_reg(lowpwr ? 0xFFFF0004 : 0x00060006, CX18_CLOCK_SELECT2);
278
279 write_reg(0xFFFF0002, CX18_HALF_CLOCK_SELECT1);
280 write_reg(0xFFFF0104, CX18_HALF_CLOCK_SELECT2);
281
282 write_reg(0xFFFF9026, CX18_CLOCK_ENABLE1);
283 write_reg(0xFFFF3105, CX18_CLOCK_ENABLE2);
284}
285
286void cx18_init_memory(struct cx18 *cx)
287{
288 cx18_msleep_timeout(10, 0);
289 write_reg(0x10000, CX18_DDR_SOFT_RESET);
290 cx18_msleep_timeout(10, 0);
291
292 write_reg(cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);
293
294 cx18_msleep_timeout(10, 0);
295
296 write_reg(cx->card->ddr.refresh, CX18_DDR_REFRESH);
297 write_reg(cx->card->ddr.timing1, CX18_DDR_TIMING1);
298 write_reg(cx->card->ddr.timing2, CX18_DDR_TIMING2);
299
300 cx18_msleep_timeout(10, 0);
301
302 /* Initialize DQS pad time */
303 write_reg(cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
304 write_reg(cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);
305
306 cx18_msleep_timeout(10, 0);
307
308 write_reg(0x20000, CX18_DDR_SOFT_RESET);
309 cx18_msleep_timeout(10, 0);
310
311 /* use power-down mode when idle */
312 write_reg(0x00000010, CX18_DDR_POWER_REG);
313
314 write_reg(0x10001, CX18_REG_BUS_TIMEOUT_EN);
315
316 write_reg(0x48, CX18_DDR_MB_PER_ROW_7);
317 write_reg(0xE0000, CX18_DDR_BASE_63_ADDR);
318
319 write_reg(0x00000101, CX18_WMB_CLIENT02); /* AO */
320 write_reg(0x00000101, CX18_WMB_CLIENT09); /* AI2 */
321 write_reg(0x00000101, CX18_WMB_CLIENT05); /* VIM1 */
322 write_reg(0x00000101, CX18_WMB_CLIENT06); /* AI1 */
323 write_reg(0x00000101, CX18_WMB_CLIENT07); /* 3D comb */
324 write_reg(0x00000101, CX18_WMB_CLIENT10); /* ME */
325 write_reg(0x00000101, CX18_WMB_CLIENT12); /* ENC */
326 write_reg(0x00000101, CX18_WMB_CLIENT13); /* PK */
327 write_reg(0x00000101, CX18_WMB_CLIENT11); /* RC */
328 write_reg(0x00000101, CX18_WMB_CLIENT14); /* AVO */
329}
330
331int cx18_firmware_init(struct cx18 *cx)
332{
333 /* Allow chip to control CLKRUN */
334 write_reg(0x5, CX18_DSP0_INTERRUPT_MASK);
335
336 write_reg(0x000F000F, CX18_PROC_SOFT_RESET); /* stop the fw */
337
338 cx18_msleep_timeout(1, 0);
339
340 sw1_irq_enable(IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
341 sw2_irq_enable(IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);
342
343 /* Only if the processor is not running */
344 if (read_reg(CX18_PROC_SOFT_RESET) & 8) {
345 int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
346 cx->enc_mem, cx, CX18_FW_APU_SIZE);
347
348 sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
349 cx->enc_mem, cx, CX18_FW_CPU_SIZE);
350
351 if (sz > 0) {
352 int retries = 0;
353
354 /* start the CPU */
355 write_reg(0x00080000, CX18_PROC_SOFT_RESET);
356 while (retries++ < 50) { /* Loop for max 500mS */
357 if ((read_reg(CX18_PROC_SOFT_RESET) & 1) == 0)
358 break;
359 cx18_msleep_timeout(10, 0);
360 }
361 cx18_msleep_timeout(200, 0);
362 if (retries == 51) {
363 CX18_ERR("Could not start the CPU\n");
364 return -EIO;
365 }
366 }
367 if (sz <= 0)
368 return -EIO;
369 }
370 /* initialize GPIO */
371 write_reg(0x14001400, 0xC78110);
372 return 0;
373}
diff --git a/drivers/media/video/cx18/cx18-firmware.h b/drivers/media/video/cx18/cx18-firmware.h
new file mode 100644
index 000000000000..38d4c05e8499
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-firmware.h
@@ -0,0 +1,25 @@
1/*
2 * cx18 firmware functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22int cx18_firmware_init(struct cx18 *cx);
23void cx18_halt_firmware(struct cx18 *cx);
24void cx18_init_memory(struct cx18 *cx);
25void cx18_init_power(struct cx18 *cx, int lowpwr);
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
new file mode 100644
index 000000000000..19253e6b8673
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -0,0 +1,74 @@
1/*
2 * cx18 gpio functions
3 *
4 * Derived from ivtv-gpio.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-cards.h"
26#include "cx18-gpio.h"
27#include "tuner-xc2028.h"
28
29/********************* GPIO stuffs *********************/
30
31/* GPIO registers */
32#define CX18_REG_GPIO_IN 0xc72010
33#define CX18_REG_GPIO_OUT1 0xc78100
34#define CX18_REG_GPIO_DIR1 0xc78108
35#define CX18_REG_GPIO_OUT2 0xc78104
36#define CX18_REG_GPIO_DIR2 0xc7810c
37
38/*
39 * HVR-1600 GPIO pins, courtesy of Hauppauge:
40 *
41 * gpio0: zilog ir process reset pin
42 * gpio1: zilog programming pin (you should never use this)
43 * gpio12: cx24227 reset pin
44 * gpio13: cs5345 reset pin
45*/
46
47void cx18_gpio_init(struct cx18 *cx)
48{
49 if (cx->card->gpio_init.direction == 0)
50 return;
51
52 CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
53 read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1));
54
55 /* init output data then direction */
56 write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1);
57 write_reg(0, CX18_REG_GPIO_DIR2);
58 write_reg((cx->card->gpio_init.direction << 16) |
59 cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1);
60 write_reg(0, CX18_REG_GPIO_OUT2);
61}
62
63/* Xceive tuner reset function */
64int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
65{
66 struct i2c_algo_bit_data *algo = dev;
67 struct cx18 *cx = algo->data;
68/* int curdir, curout;*/
69
70 if (cmd != XC2028_TUNER_RESET)
71 return 0;
72 CX18_DEBUG_INFO("Resetting tuner\n");
73 return 0;
74}
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
new file mode 100644
index 000000000000..41bac8856b50
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -0,0 +1,24 @@
1/*
2 * cx18 gpio functions
3 *
4 * Derived from ivtv-gpio.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23void cx18_gpio_init(struct cx18 *cx);
24int cx18_reset_tuner_gpio(void *dev, int cmd, int value);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
new file mode 100644
index 000000000000..18c88d1e4833
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -0,0 +1,431 @@
1/*
2 * cx18 I2C functions
3 *
4 * Derived from ivtv-i2c.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-cards.h"
26#include "cx18-gpio.h"
27#include "cx18-av-core.h"
28
29#include <media/ir-kbd-i2c.h>
30
31#define CX18_REG_I2C_1_WR 0xf15000
32#define CX18_REG_I2C_1_RD 0xf15008
33#define CX18_REG_I2C_2_WR 0xf25100
34#define CX18_REG_I2C_2_RD 0xf25108
35
36#define SETSCL_BIT 0x0001
37#define SETSDL_BIT 0x0002
38#define GETSCL_BIT 0x0004
39#define GETSDL_BIT 0x0008
40
41#ifndef I2C_ADAP_CLASS_TV_ANALOG
42#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG
43#endif
44
45#define CX18_CS5345_I2C_ADDR 0x4c
46
47/* This array should match the CX18_HW_ defines */
48static const u8 hw_driverids[] = {
49 I2C_DRIVERID_TUNER,
50 I2C_DRIVERID_TVEEPROM,
51 I2C_DRIVERID_CS5345,
52 0, /* CX18_HW_GPIO dummy driver ID */
53 0 /* CX18_HW_CX23418 dummy driver ID */
54};
55
56/* This array should match the CX18_HW_ defines */
57static const u8 hw_addrs[] = {
58 0,
59 0,
60 CX18_CS5345_I2C_ADDR,
61 0, /* CX18_HW_GPIO dummy driver ID */
62 0, /* CX18_HW_CX23418 dummy driver ID */
63};
64
65/* This array should match the CX18_HW_ defines */
66/* This might well become a card-specific array */
67static const u8 hw_bus[] = {
68 0,
69 0,
70 0,
71 0, /* CX18_HW_GPIO dummy driver ID */
72 0, /* CX18_HW_CX23418 dummy driver ID */
73};
74
75/* This array should match the CX18_HW_ defines */
76static const char * const hw_drivernames[] = {
77 "tuner",
78 "tveeprom",
79 "cs5345",
80 "gpio",
81 "cx23418",
82};
83
84int cx18_i2c_register(struct cx18 *cx, unsigned idx)
85{
86 struct i2c_board_info info;
87 struct i2c_client *c;
88 u8 id, bus;
89 int i;
90
91 CX18_DEBUG_I2C("i2c client register\n");
92 if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
93 return -1;
94 id = hw_driverids[idx];
95 bus = hw_bus[idx];
96 memset(&info, 0, sizeof(info));
97 strlcpy(info.driver_name, hw_drivernames[idx],
98 sizeof(info.driver_name));
99 info.addr = hw_addrs[idx];
100 for (i = 0; i < I2C_CLIENTS_MAX; i++)
101 if (cx->i2c_clients[i] == NULL)
102 break;
103
104 if (i == I2C_CLIENTS_MAX) {
105 CX18_ERR("insufficient room for new I2C client!\n");
106 return -ENOMEM;
107 }
108
109 if (id != I2C_DRIVERID_TUNER) {
110 c = i2c_new_device(&cx->i2c_adap[bus], &info);
111 if (c->driver == NULL)
112 i2c_unregister_device(c);
113 else
114 cx->i2c_clients[i] = c;
115 return cx->i2c_clients[i] ? 0 : -ENODEV;
116 }
117
118 /* special tuner handling */
119 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio);
120 if (c && c->driver == NULL)
121 i2c_unregister_device(c);
122 else if (c)
123 cx->i2c_clients[i++] = c;
124 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod);
125 if (c && c->driver == NULL)
126 i2c_unregister_device(c);
127 else if (c)
128 cx->i2c_clients[i++] = c;
129 c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv);
130 if (c && c->driver == NULL)
131 i2c_unregister_device(c);
132 else if (c)
133 cx->i2c_clients[i++] = c;
134 return 0;
135}
136
137static int attach_inform(struct i2c_client *client)
138{
139 return 0;
140}
141
142static int detach_inform(struct i2c_client *client)
143{
144 int i;
145 struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter);
146
147 CX18_DEBUG_I2C("i2c client detach\n");
148 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
149 if (cx->i2c_clients[i] == client) {
150 cx->i2c_clients[i] = NULL;
151 break;
152 }
153 }
154 CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n",
155 client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");
156
157 return 0;
158}
159
160static void cx18_setscl(void *data, int state)
161{
162 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
163 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
164 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
165 u32 r = read_reg(addr);
166
167 if (state)
168 write_reg_sync(r | SETSCL_BIT, addr);
169 else
170 write_reg_sync(r & ~SETSCL_BIT, addr);
171}
172
173static void cx18_setsda(void *data, int state)
174{
175 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
176 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
177 u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR;
178 u32 r = read_reg(addr);
179
180 if (state)
181 write_reg_sync(r | SETSDL_BIT, addr);
182 else
183 write_reg_sync(r & ~SETSDL_BIT, addr);
184}
185
186static int cx18_getscl(void *data)
187{
188 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
189 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
190 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
191
192 return read_reg(addr) & GETSCL_BIT;
193}
194
195static int cx18_getsda(void *data)
196{
197 struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
198 int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index;
199 u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD;
200
201 return read_reg(addr) & GETSDL_BIT;
202}
203
204/* template for i2c-bit-algo */
205static struct i2c_adapter cx18_i2c_adap_template = {
206 .name = "cx18 i2c driver",
207 .id = I2C_HW_B_CX2341X,
208 .algo = NULL, /* set by i2c-algo-bit */
209 .algo_data = NULL, /* filled from template */
210 .client_register = attach_inform,
211 .client_unregister = detach_inform,
212 .owner = THIS_MODULE,
213};
214
215#define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */
216#define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */
217
218static struct i2c_algo_bit_data cx18_i2c_algo_template = {
219 .setsda = cx18_setsda,
220 .setscl = cx18_setscl,
221 .getsda = cx18_getsda,
222 .getscl = cx18_getscl,
223 .udelay = CX18_SCL_PERIOD/2, /* 1/2 clock period in usec*/
224 .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
225};
226
227static struct i2c_client cx18_i2c_client_template = {
228 .name = "cx18 internal",
229};
230
231int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg)
232{
233 struct i2c_client *client;
234 int retval;
235 int i;
236
237 CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
238 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
239 client = cx->i2c_clients[i];
240 if (client == NULL || client->driver == NULL ||
241 client->driver->command == NULL)
242 continue;
243 if (addr == client->addr) {
244 retval = client->driver->command(client, cmd, arg);
245 return retval;
246 }
247 }
248 if (cmd != VIDIOC_G_CHIP_IDENT)
249 CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n",
250 addr, cmd);
251 return -ENODEV;
252}
253
254/* Find the i2c device based on the driver ID and return
255 its i2c address or -ENODEV if no matching device was found. */
256static int cx18_i2c_id_addr(struct cx18 *cx, u32 id)
257{
258 struct i2c_client *client;
259 int retval = -ENODEV;
260 int i;
261
262 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
263 client = cx->i2c_clients[i];
264 if (client == NULL || client->driver == NULL)
265 continue;
266 if (id == client->driver->id) {
267 retval = client->addr;
268 break;
269 }
270 }
271 return retval;
272}
273
274/* Find the i2c device name matching the DRIVERID */
275static const char *cx18_i2c_id_name(u32 id)
276{
277 int i;
278
279 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
280 if (hw_driverids[i] == id)
281 return hw_drivernames[i];
282 return "unknown device";
283}
284
285/* Find the i2c device name matching the CX18_HW_ flag */
286static const char *cx18_i2c_hw_name(u32 hw)
287{
288 int i;
289
290 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
291 if (1 << i == hw)
292 return hw_drivernames[i];
293 return "unknown device";
294}
295
296/* Find the i2c device matching the CX18_HW_ flag and return
297 its i2c address or -ENODEV if no matching device was found. */
298int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw)
299{
300 int i;
301
302 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
303 if (1 << i == hw)
304 return cx18_i2c_id_addr(cx, hw_driverids[i]);
305 return -ENODEV;
306}
307
308/* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing.
309 If hw == CX18_HW_GPIO then call the gpio handler. */
310int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
311{
312 int addr;
313
314 if (hw == CX18_HW_GPIO || hw == 0)
315 return 0;
316 if (hw == CX18_HW_CX23418)
317 return cx18_av_cmd(cx, cmd, arg);
318
319 addr = cx18_i2c_hw_addr(cx, hw);
320 if (addr < 0) {
321 CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n",
322 hw, cx18_i2c_hw_name(hw), cmd);
323 return addr;
324 }
325 return cx18_call_i2c_client(cx, addr, cmd, arg);
326}
327
328/* Calls i2c device based on I2C driver ID. */
329int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg)
330{
331 int addr;
332
333 addr = cx18_i2c_id_addr(cx, id);
334 if (addr < 0) {
335 if (cmd != VIDIOC_G_CHIP_IDENT)
336 CX18_ERR("i2c ID 0x%08x (%s) not found for cmd 0x%x!\n",
337 id, cx18_i2c_id_name(id), cmd);
338 return addr;
339 }
340 return cx18_call_i2c_client(cx, addr, cmd, arg);
341}
342
343/* broadcast cmd for all I2C clients and for the gpio subsystem */
344void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
345{
346 if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) {
347 CX18_ERR("adapter is not set\n");
348 return;
349 }
350 cx18_av_cmd(cx, cmd, arg);
351 i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
352 i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
353}
354
355/* init + register i2c algo-bit adapter */
356int init_cx18_i2c(struct cx18 *cx)
357{
358 int i;
359 CX18_DEBUG_I2C("i2c init\n");
360
361 for (i = 0; i < 2; i++) {
362 memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
363 sizeof(struct i2c_adapter));
364 memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
365 sizeof(struct i2c_algo_bit_data));
366 cx->i2c_algo_cb_data[i].cx = cx;
367 cx->i2c_algo_cb_data[i].bus_index = i;
368 cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
369 cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
370
371 sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
372 " #%d-%d", cx->num, i);
373 i2c_set_adapdata(&cx->i2c_adap[i], cx);
374
375 memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
376 sizeof(struct i2c_client));
377 sprintf(cx->i2c_client[i].name +
378 strlen(cx->i2c_client[i].name), "%d", i);
379 cx->i2c_client[i].adapter = &cx->i2c_adap[i];
380 cx->i2c_adap[i].dev.parent = &cx->dev->dev;
381 }
382
383 if (read_reg(CX18_REG_I2C_2_WR) != 0x0003c02f) {
384 /* Reset/Unreset I2C hardware block */
385 write_reg(0x10000000, 0xc71004); /* Clock select 220MHz */
386 write_reg_sync(0x10001000, 0xc71024); /* Clock Enable */
387 }
388 /* courtesy of Steven Toth <stoth@hauppauge.com> */
389 write_reg_sync(0x00c00000, 0xc7001c);
390 mdelay(10);
391 write_reg_sync(0x00c000c0, 0xc7001c);
392 mdelay(10);
393 write_reg_sync(0x00c00000, 0xc7001c);
394
395 write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */
396 write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */
397
398 /* Hw I2C1 Clock Freq ~100kHz */
399 write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_1_WR);
400 cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
401 cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
402
403 /* Hw I2C2 Clock Freq ~100kHz */
404 write_reg_sync(0x00021c0f & ~4, CX18_REG_I2C_2_WR);
405 cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
406 cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
407
408 return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
409 i2c_bit_add_bus(&cx->i2c_adap[1]);
410}
411
412void exit_cx18_i2c(struct cx18 *cx)
413{
414 int i;
415 CX18_DEBUG_I2C("i2c exit\n");
416 write_reg(read_reg(CX18_REG_I2C_1_WR) | 4, CX18_REG_I2C_1_WR);
417 write_reg(read_reg(CX18_REG_I2C_2_WR) | 4, CX18_REG_I2C_2_WR);
418
419 for (i = 0; i < 2; i++) {
420 i2c_del_adapter(&cx->i2c_adap[i]);
421 }
422}
423
424/*
425 Hauppauge HVR1600 should have:
426 32 cx24227
427 98 unknown
428 a0 eeprom
429 c2 tuner
430 e? zilog ir
431 */
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h
new file mode 100644
index 000000000000..113c3f9a2cc0
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-i2c.h
@@ -0,0 +1,33 @@
1/*
2 * cx18 I2C functions
3 *
4 * Derived from ivtv-i2c.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw);
25int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg);
26int cx18_i2c_id(struct cx18 *cx, u32 id, unsigned int cmd, void *arg);
27int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg);
28void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg);
29int cx18_i2c_register(struct cx18 *cx, unsigned idx);
30
31/* init + register i2c algo-bit adapter */
32int init_cx18_i2c(struct cx18 *cx);
33void exit_cx18_i2c(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
new file mode 100644
index 000000000000..dbdcb86ec5aa
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -0,0 +1,851 @@
1/*
2 * cx18 ioctl system call
3 *
4 * Derived from ivtv-ioctl.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-version.h"
26#include "cx18-mailbox.h"
27#include "cx18-i2c.h"
28#include "cx18-queue.h"
29#include "cx18-fileops.h"
30#include "cx18-vbi.h"
31#include "cx18-audio.h"
32#include "cx18-video.h"
33#include "cx18-streams.h"
34#include "cx18-ioctl.h"
35#include "cx18-gpio.h"
36#include "cx18-controls.h"
37#include "cx18-cards.h"
38#include "cx18-av-core.h"
39#include <media/tveeprom.h>
40#include <media/v4l2-chip-ident.h>
41#include <linux/i2c-id.h>
42
43u16 cx18_service2vbi(int type)
44{
45 switch (type) {
46 case V4L2_SLICED_TELETEXT_B:
47 return CX18_SLICED_TYPE_TELETEXT_B;
48 case V4L2_SLICED_CAPTION_525:
49 return CX18_SLICED_TYPE_CAPTION_525;
50 case V4L2_SLICED_WSS_625:
51 return CX18_SLICED_TYPE_WSS_625;
52 case V4L2_SLICED_VPS:
53 return CX18_SLICED_TYPE_VPS;
54 default:
55 return 0;
56 }
57}
58
59static int valid_service_line(int field, int line, int is_pal)
60{
61 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
62 (!is_pal && line >= 10 && line < 22);
63}
64
65static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
66{
67 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
68 int i;
69
70 set = set & valid_set;
71 if (set == 0 || !valid_service_line(field, line, is_pal))
72 return 0;
73 if (!is_pal) {
74 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
75 return V4L2_SLICED_CAPTION_525;
76 } else {
77 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
78 return V4L2_SLICED_VPS;
79 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
80 return V4L2_SLICED_WSS_625;
81 if (line == 23)
82 return 0;
83 }
84 for (i = 0; i < 32; i++) {
85 if ((1 << i) & set)
86 return 1 << i;
87 }
88 return 0;
89}
90
91void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
92{
93 u16 set = fmt->service_set;
94 int f, l;
95
96 fmt->service_set = 0;
97 for (f = 0; f < 2; f++) {
98 for (l = 0; l < 24; l++)
99 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
100 }
101}
102
103static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
104{
105 int f, l;
106 u16 set = 0;
107
108 for (f = 0; f < 2; f++) {
109 for (l = 0; l < 24; l++) {
110 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
111 set |= fmt->service_lines[f][l];
112 }
113 }
114 return set != 0;
115}
116
117u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
118{
119 int f, l;
120 u16 set = 0;
121
122 for (f = 0; f < 2; f++) {
123 for (l = 0; l < 24; l++)
124 set |= fmt->service_lines[f][l];
125 }
126 return set;
127}
128
129static const struct {
130 v4l2_std_id std;
131 char *name;
132} enum_stds[] = {
133 { V4L2_STD_PAL_BG | V4L2_STD_PAL_H, "PAL-BGH" },
134 { V4L2_STD_PAL_DK, "PAL-DK" },
135 { V4L2_STD_PAL_I, "PAL-I" },
136 { V4L2_STD_PAL_M, "PAL-M" },
137 { V4L2_STD_PAL_N, "PAL-N" },
138 { V4L2_STD_PAL_Nc, "PAL-Nc" },
139 { V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, "SECAM-BGH" },
140 { V4L2_STD_SECAM_DK, "SECAM-DK" },
141 { V4L2_STD_SECAM_L, "SECAM-L" },
142 { V4L2_STD_SECAM_LC, "SECAM-L'" },
143 { V4L2_STD_NTSC_M, "NTSC-M" },
144 { V4L2_STD_NTSC_M_JP, "NTSC-J" },
145 { V4L2_STD_NTSC_M_KR, "NTSC-K" },
146};
147
148static const struct v4l2_standard cx18_std_60hz = {
149 .frameperiod = {.numerator = 1001, .denominator = 30000},
150 .framelines = 525,
151};
152
153static const struct v4l2_standard cx18_std_50hz = {
154 .frameperiod = { .numerator = 1, .denominator = 25 },
155 .framelines = 625,
156};
157
158static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
159{
160 struct v4l2_register *regs = arg;
161 unsigned long flags;
162
163 if (!capable(CAP_SYS_ADMIN))
164 return -EPERM;
165 if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
166 return -EINVAL;
167
168 spin_lock_irqsave(&cx18_cards_lock, flags);
169 if (cmd == VIDIOC_DBG_G_REGISTER)
170 regs->val = read_enc(regs->reg);
171 else
172 write_enc(regs->val, regs->reg);
173 spin_unlock_irqrestore(&cx18_cards_lock, flags);
174 return 0;
175}
176
177static int cx18_get_fmt(struct cx18 *cx, int streamtype, struct v4l2_format *fmt)
178{
179 switch (fmt->type) {
180 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
181 fmt->fmt.pix.width = cx->params.width;
182 fmt->fmt.pix.height = cx->params.height;
183 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
184 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
185 if (streamtype == CX18_ENC_STREAM_TYPE_YUV) {
186 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
187 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
188 fmt->fmt.pix.sizeimage =
189 fmt->fmt.pix.height * fmt->fmt.pix.width +
190 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
191 } else {
192 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
193 fmt->fmt.pix.sizeimage = 128 * 1024;
194 }
195 break;
196
197 case V4L2_BUF_TYPE_VBI_CAPTURE:
198 fmt->fmt.vbi.sampling_rate = 27000000;
199 fmt->fmt.vbi.offset = 248;
200 fmt->fmt.vbi.samples_per_line = cx->vbi.raw_decoder_line_size - 4;
201 fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
202 fmt->fmt.vbi.start[0] = cx->vbi.start[0];
203 fmt->fmt.vbi.start[1] = cx->vbi.start[1];
204 fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = cx->vbi.count;
205 break;
206
207 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
208 {
209 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
210
211 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
212 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
213 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
214
215 cx18_av_cmd(cx, VIDIOC_G_FMT, fmt);
216 vbifmt->service_set = cx18_get_service_set(vbifmt);
217 break;
218 }
219 default:
220 return -EINVAL;
221 }
222 return 0;
223}
224
225static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype,
226 struct v4l2_format *fmt, int set_fmt)
227{
228 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
229 u16 set;
230
231 /* set window size */
232 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
233 int w = fmt->fmt.pix.width;
234 int h = fmt->fmt.pix.height;
235
236 if (w > 720)
237 w = 720;
238 else if (w < 1)
239 w = 1;
240 if (h > (cx->is_50hz ? 576 : 480))
241 h = (cx->is_50hz ? 576 : 480);
242 else if (h < 2)
243 h = 2;
244 cx18_get_fmt(cx, streamtype, fmt);
245 fmt->fmt.pix.width = w;
246 fmt->fmt.pix.height = h;
247
248 if (!set_fmt || (cx->params.width == w && cx->params.height == h))
249 return 0;
250 if (atomic_read(&cx->capturing) > 0)
251 return -EBUSY;
252
253 cx->params.width = w;
254 cx->params.height = h;
255 if (w != 720 || h != (cx->is_50hz ? 576 : 480))
256 cx->params.video_temporal_filter = 0;
257 else
258 cx->params.video_temporal_filter = 8;
259 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
260 return cx18_get_fmt(cx, streamtype, fmt);
261 }
262
263 /* set raw VBI format */
264 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
265 if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI &&
266 cx->vbi.sliced_in->service_set &&
267 atomic_read(&cx->capturing) > 0)
268 return -EBUSY;
269 if (set_fmt) {
270 cx->vbi.sliced_in->service_set = 0;
271 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
272 }
273 return cx18_get_fmt(cx, streamtype, fmt);
274 }
275
276 /* any else but sliced VBI capture is an error */
277 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
278 return -EINVAL;
279
280 /* TODO: implement sliced VBI, for now silently return 0 */
281 return 0;
282
283 /* set sliced VBI capture format */
284 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
285 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
286
287 if (vbifmt->service_set)
288 cx18_expand_service_set(vbifmt, cx->is_50hz);
289 set = check_service_set(vbifmt, cx->is_50hz);
290 vbifmt->service_set = cx18_get_service_set(vbifmt);
291
292 if (!set_fmt)
293 return 0;
294 if (set == 0)
295 return -EINVAL;
296 if (atomic_read(&cx->capturing) > 0 && cx->vbi.sliced_in->service_set == 0)
297 return -EBUSY;
298 cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
299 memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
300 return 0;
301}
302
303static int cx18_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
304{
305 struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
306 struct cx18 *cx = id->cx;
307 struct v4l2_register *reg = arg;
308
309 switch (cmd) {
310 /* ioctls to allow direct access to the encoder registers for testing */
311 case VIDIOC_DBG_G_REGISTER:
312 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
313 return cx18_cxc(cx, cmd, arg);
314 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
315 return cx18_i2c_id(cx, reg->match_chip, cmd, arg);
316 return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg);
317
318 case VIDIOC_DBG_S_REGISTER:
319 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
320 return cx18_cxc(cx, cmd, arg);
321 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
322 return cx18_i2c_id(cx, reg->match_chip, cmd, arg);
323 return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg);
324
325 case VIDIOC_G_CHIP_IDENT: {
326 struct v4l2_chip_ident *chip = arg;
327
328 chip->ident = V4L2_IDENT_NONE;
329 chip->revision = 0;
330 if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
331 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) {
332 struct v4l2_chip_ident *chip = arg;
333
334 chip->ident = V4L2_IDENT_CX23418;
335 }
336 return 0;
337 }
338 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
339 return cx18_i2c_id(cx, reg->match_chip, cmd, arg);
340 if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
341 return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg);
342 return -EINVAL;
343 }
344
345 case VIDIOC_INT_S_AUDIO_ROUTING: {
346 struct v4l2_routing *route = arg;
347
348 cx18_audio_set_route(cx, route);
349 break;
350 }
351
352 default:
353 return -EINVAL;
354 }
355 return 0;
356}
357
358int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg)
359{
360 struct cx18_open_id *id = NULL;
361
362 if (filp)
363 id = (struct cx18_open_id *)filp->private_data;
364
365 switch (cmd) {
366 case VIDIOC_G_PRIORITY:
367 {
368 enum v4l2_priority *p = arg;
369
370 *p = v4l2_prio_max(&cx->prio);
371 break;
372 }
373
374 case VIDIOC_S_PRIORITY:
375 {
376 enum v4l2_priority *prio = arg;
377
378 return v4l2_prio_change(&cx->prio, &id->prio, *prio);
379 }
380
381 case VIDIOC_QUERYCAP:{
382 struct v4l2_capability *vcap = arg;
383
384 memset(vcap, 0, sizeof(*vcap));
385 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
386 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
387 strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info));
388 vcap->version = CX18_DRIVER_VERSION; /* version */
389 vcap->capabilities = cx->v4l2_cap; /* capabilities */
390
391 /* reserved.. must set to 0! */
392 vcap->reserved[0] = vcap->reserved[1] =
393 vcap->reserved[2] = vcap->reserved[3] = 0;
394 break;
395 }
396
397 case VIDIOC_ENUMAUDIO:{
398 struct v4l2_audio *vin = arg;
399
400 return cx18_get_audio_input(cx, vin->index, vin);
401 }
402
403 case VIDIOC_G_AUDIO:{
404 struct v4l2_audio *vin = arg;
405
406 vin->index = cx->audio_input;
407 return cx18_get_audio_input(cx, vin->index, vin);
408 }
409
410 case VIDIOC_S_AUDIO:{
411 struct v4l2_audio *vout = arg;
412
413 if (vout->index >= cx->nof_audio_inputs)
414 return -EINVAL;
415 cx->audio_input = vout->index;
416 cx18_audio_set_io(cx);
417 break;
418 }
419
420 case VIDIOC_ENUMINPUT:{
421 struct v4l2_input *vin = arg;
422
423 /* set it to defaults from our table */
424 return cx18_get_input(cx, vin->index, vin);
425 }
426
427 case VIDIOC_TRY_FMT:
428 case VIDIOC_S_FMT: {
429 struct v4l2_format *fmt = arg;
430
431 return cx18_try_or_set_fmt(cx, id->type, fmt, cmd == VIDIOC_S_FMT);
432 }
433
434 case VIDIOC_G_FMT: {
435 struct v4l2_format *fmt = arg;
436 int type = fmt->type;
437
438 memset(fmt, 0, sizeof(*fmt));
439 fmt->type = type;
440 return cx18_get_fmt(cx, id->type, fmt);
441 }
442
443 case VIDIOC_CROPCAP: {
444 struct v4l2_cropcap *cropcap = arg;
445
446 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
447 return -EINVAL;
448 cropcap->bounds.top = cropcap->bounds.left = 0;
449 cropcap->bounds.width = 720;
450 cropcap->bounds.height = cx->is_50hz ? 576 : 480;
451 cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
452 cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
453 cropcap->defrect = cropcap->bounds;
454 return 0;
455 }
456
457 case VIDIOC_S_CROP: {
458 struct v4l2_crop *crop = arg;
459
460 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
461 return -EINVAL;
462 return cx18_av_cmd(cx, VIDIOC_S_CROP, arg);
463 }
464
465 case VIDIOC_G_CROP: {
466 struct v4l2_crop *crop = arg;
467
468 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
469 return -EINVAL;
470 return cx18_av_cmd(cx, VIDIOC_G_CROP, arg);
471 }
472
473 case VIDIOC_ENUM_FMT: {
474 static struct v4l2_fmtdesc formats[] = {
475 { 0, 0, 0,
476 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12,
477 { 0, 0, 0, 0 }
478 },
479 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
480 "MPEG", V4L2_PIX_FMT_MPEG,
481 { 0, 0, 0, 0 }
482 }
483 };
484 struct v4l2_fmtdesc *fmt = arg;
485 enum v4l2_buf_type type = fmt->type;
486
487 switch (type) {
488 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
489 break;
490 default:
491 return -EINVAL;
492 }
493 if (fmt->index > 1)
494 return -EINVAL;
495 *fmt = formats[fmt->index];
496 fmt->type = type;
497 return 0;
498 }
499
500 case VIDIOC_G_INPUT:{
501 *(int *)arg = cx->active_input;
502 break;
503 }
504
505 case VIDIOC_S_INPUT:{
506 int inp = *(int *)arg;
507
508 if (inp < 0 || inp >= cx->nof_inputs)
509 return -EINVAL;
510
511 if (inp == cx->active_input) {
512 CX18_DEBUG_INFO("Input unchanged\n");
513 break;
514 }
515 CX18_DEBUG_INFO("Changing input from %d to %d\n",
516 cx->active_input, inp);
517
518 cx->active_input = inp;
519 /* Set the audio input to whatever is appropriate for the
520 input type. */
521 cx->audio_input = cx->card->video_inputs[inp].audio_index;
522
523 /* prevent others from messing with the streams until
524 we're finished changing inputs. */
525 cx18_mute(cx);
526 cx18_video_set_io(cx);
527 cx18_audio_set_io(cx);
528 cx18_unmute(cx);
529 break;
530 }
531
532 case VIDIOC_G_FREQUENCY:{
533 struct v4l2_frequency *vf = arg;
534
535 if (vf->tuner != 0)
536 return -EINVAL;
537 cx18_call_i2c_clients(cx, cmd, arg);
538 break;
539 }
540
541 case VIDIOC_S_FREQUENCY:{
542 struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
543
544 if (vf.tuner != 0)
545 return -EINVAL;
546
547 cx18_mute(cx);
548 CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
549 cx18_call_i2c_clients(cx, cmd, &vf);
550 cx18_unmute(cx);
551 break;
552 }
553
554 case VIDIOC_ENUMSTD:{
555 struct v4l2_standard *vs = arg;
556 int idx = vs->index;
557
558 if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
559 return -EINVAL;
560
561 *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
562 cx18_std_60hz : cx18_std_50hz;
563 vs->index = idx;
564 vs->id = enum_stds[idx].std;
565 strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name));
566 break;
567 }
568
569 case VIDIOC_G_STD:{
570 *(v4l2_std_id *) arg = cx->std;
571 break;
572 }
573
574 case VIDIOC_S_STD: {
575 v4l2_std_id std = *(v4l2_std_id *) arg;
576
577 if ((std & V4L2_STD_ALL) == 0)
578 return -EINVAL;
579
580 if (std == cx->std)
581 break;
582
583 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
584 atomic_read(&cx->capturing) > 0) {
585 /* Switching standard would turn off the radio or mess
586 with already running streams, prevent that by
587 returning EBUSY. */
588 return -EBUSY;
589 }
590
591 cx->std = std;
592 cx->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
593 cx->params.is_50hz = cx->is_50hz = !cx->is_60hz;
594 cx->params.width = 720;
595 cx->params.height = cx->is_50hz ? 576 : 480;
596 cx->vbi.count = cx->is_50hz ? 18 : 12;
597 cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
598 cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
599 cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
600 CX18_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)cx->std);
601
602 /* Tuner */
603 cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
604 break;
605 }
606
607 case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */
608 struct v4l2_tuner *vt = arg;
609
610 if (vt->index != 0)
611 return -EINVAL;
612
613 cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt);
614 break;
615 }
616
617 case VIDIOC_G_TUNER: {
618 struct v4l2_tuner *vt = arg;
619
620 if (vt->index != 0)
621 return -EINVAL;
622
623 memset(vt, 0, sizeof(*vt));
624 cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt);
625
626 if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
627 strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
628 vt->type = V4L2_TUNER_RADIO;
629 } else {
630 strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
631 vt->type = V4L2_TUNER_ANALOG_TV;
632 }
633 break;
634 }
635
636 case VIDIOC_G_SLICED_VBI_CAP: {
637 struct v4l2_sliced_vbi_cap *cap = arg;
638 int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
639 int f, l;
640 enum v4l2_buf_type type = cap->type;
641
642 memset(cap, 0, sizeof(*cap));
643 cap->type = type;
644 if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
645 for (f = 0; f < 2; f++) {
646 for (l = 0; l < 24; l++) {
647 if (valid_service_line(f, l, cx->is_50hz))
648 cap->service_lines[f][l] = set;
649 }
650 }
651 return 0;
652 }
653 return -EINVAL;
654 }
655
656 case VIDIOC_ENCODER_CMD:
657 case VIDIOC_TRY_ENCODER_CMD: {
658 struct v4l2_encoder_cmd *enc = arg;
659 int try = cmd == VIDIOC_TRY_ENCODER_CMD;
660
661 memset(&enc->raw, 0, sizeof(enc->raw));
662 switch (enc->cmd) {
663 case V4L2_ENC_CMD_START:
664 enc->flags = 0;
665 if (try)
666 return 0;
667 return cx18_start_capture(id);
668
669 case V4L2_ENC_CMD_STOP:
670 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
671 if (try)
672 return 0;
673 cx18_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
674 return 0;
675
676 case V4L2_ENC_CMD_PAUSE:
677 enc->flags = 0;
678 if (try)
679 return 0;
680 if (!atomic_read(&cx->capturing))
681 return -EPERM;
682 if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
683 return 0;
684 cx18_mute(cx);
685 cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx));
686 break;
687
688 case V4L2_ENC_CMD_RESUME:
689 enc->flags = 0;
690 if (try)
691 return 0;
692 if (!atomic_read(&cx->capturing))
693 return -EPERM;
694 if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
695 return 0;
696 cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx));
697 cx18_unmute(cx);
698 break;
699 default:
700 return -EINVAL;
701 }
702 break;
703 }
704
705 case VIDIOC_LOG_STATUS:
706 {
707 struct v4l2_input vidin;
708 struct v4l2_audio audin;
709 int i;
710
711 CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num);
712 if (cx->hw_flags & CX18_HW_TVEEPROM) {
713 struct tveeprom tv;
714
715 cx18_read_eeprom(cx, &tv);
716 }
717 cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL);
718 cx18_get_input(cx, cx->active_input, &vidin);
719 cx18_get_audio_input(cx, cx->audio_input, &audin);
720 CX18_INFO("Video Input: %s\n", vidin.name);
721 CX18_INFO("Audio Input: %s\n", audin.name);
722 CX18_INFO("Tuner: %s\n",
723 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ?
724 "Radio" : "TV");
725 cx2341x_log_status(&cx->params, cx->name);
726 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
727 for (i = 0; i < CX18_MAX_STREAMS; i++) {
728 struct cx18_stream *s = &cx->streams[i];
729
730 if (s->v4l2dev == NULL || s->buffers == 0)
731 continue;
732 CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
733 s->name, s->s_flags,
734 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
735 (s->buffers * s->buf_size) / 1024, s->buffers);
736 }
737 CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
738 (long long)cx->mpg_data_received,
739 (long long)cx->vbi_data_inserted);
740 CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num);
741 break;
742 }
743
744 default:
745 return -EINVAL;
746 }
747 return 0;
748}
749
750static int cx18_v4l2_do_ioctl(struct inode *inode, struct file *filp,
751 unsigned int cmd, void *arg)
752{
753 struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
754 struct cx18 *cx = id->cx;
755 int ret;
756
757 /* check priority */
758 switch (cmd) {
759 case VIDIOC_S_CTRL:
760 case VIDIOC_S_STD:
761 case VIDIOC_S_INPUT:
762 case VIDIOC_S_TUNER:
763 case VIDIOC_S_FREQUENCY:
764 case VIDIOC_S_FMT:
765 case VIDIOC_S_CROP:
766 case VIDIOC_S_EXT_CTRLS:
767 ret = v4l2_prio_check(&cx->prio, &id->prio);
768 if (ret)
769 return ret;
770 }
771
772 switch (cmd) {
773 case VIDIOC_DBG_G_REGISTER:
774 case VIDIOC_DBG_S_REGISTER:
775 case VIDIOC_G_CHIP_IDENT:
776 case VIDIOC_INT_S_AUDIO_ROUTING:
777 case VIDIOC_INT_RESET:
778 if (cx18_debug & CX18_DBGFLG_IOCTL) {
779 printk(KERN_INFO "cx18%d ioctl: ", cx->num);
780 v4l_printk_ioctl(cmd);
781 }
782 return cx18_debug_ioctls(filp, cmd, arg);
783
784 case VIDIOC_G_PRIORITY:
785 case VIDIOC_S_PRIORITY:
786 case VIDIOC_QUERYCAP:
787 case VIDIOC_ENUMINPUT:
788 case VIDIOC_G_INPUT:
789 case VIDIOC_S_INPUT:
790 case VIDIOC_G_FMT:
791 case VIDIOC_S_FMT:
792 case VIDIOC_TRY_FMT:
793 case VIDIOC_ENUM_FMT:
794 case VIDIOC_CROPCAP:
795 case VIDIOC_G_CROP:
796 case VIDIOC_S_CROP:
797 case VIDIOC_G_FREQUENCY:
798 case VIDIOC_S_FREQUENCY:
799 case VIDIOC_ENUMSTD:
800 case VIDIOC_G_STD:
801 case VIDIOC_S_STD:
802 case VIDIOC_S_TUNER:
803 case VIDIOC_G_TUNER:
804 case VIDIOC_ENUMAUDIO:
805 case VIDIOC_S_AUDIO:
806 case VIDIOC_G_AUDIO:
807 case VIDIOC_G_SLICED_VBI_CAP:
808 case VIDIOC_LOG_STATUS:
809 case VIDIOC_G_ENC_INDEX:
810 case VIDIOC_ENCODER_CMD:
811 case VIDIOC_TRY_ENCODER_CMD:
812 if (cx18_debug & CX18_DBGFLG_IOCTL) {
813 printk(KERN_INFO "cx18%d ioctl: ", cx->num);
814 v4l_printk_ioctl(cmd);
815 }
816 return cx18_v4l2_ioctls(cx, filp, cmd, arg);
817
818 case VIDIOC_QUERYMENU:
819 case VIDIOC_QUERYCTRL:
820 case VIDIOC_S_CTRL:
821 case VIDIOC_G_CTRL:
822 case VIDIOC_S_EXT_CTRLS:
823 case VIDIOC_G_EXT_CTRLS:
824 case VIDIOC_TRY_EXT_CTRLS:
825 if (cx18_debug & CX18_DBGFLG_IOCTL) {
826 printk(KERN_INFO "cx18%d ioctl: ", cx->num);
827 v4l_printk_ioctl(cmd);
828 }
829 return cx18_control_ioctls(cx, cmd, arg);
830
831 case 0x00005401: /* Handle isatty() calls */
832 return -EINVAL;
833 default:
834 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
835 cx18_v4l2_do_ioctl);
836 }
837 return 0;
838}
839
840int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
841 unsigned long arg)
842{
843 struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
844 struct cx18 *cx = id->cx;
845 int res;
846
847 mutex_lock(&cx->serialize_lock);
848 res = video_usercopy(inode, filp, cmd, arg, cx18_v4l2_do_ioctl);
849 mutex_unlock(&cx->serialize_lock);
850 return res;
851}
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h
new file mode 100644
index 000000000000..9f4c7eb2897f
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-ioctl.h
@@ -0,0 +1,30 @@
1/*
2 * cx18 ioctl system call
3 *
4 * Derived from ivtv-ioctl.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24u16 cx18_service2vbi(int type);
25void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
26u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt);
27int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
28 unsigned long arg);
29int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd,
30 void *arg);
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
new file mode 100644
index 000000000000..6e14f8bda559
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -0,0 +1,179 @@
1/*
2 * cx18 interrupt handling
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include "cx18-driver.h"
23#include "cx18-firmware.h"
24#include "cx18-fileops.h"
25#include "cx18-queue.h"
26#include "cx18-irq.h"
27#include "cx18-ioctl.h"
28#include "cx18-mailbox.h"
29#include "cx18-vbi.h"
30#include "cx18-scb.h"
31
32#define DMA_MAGIC_COOKIE 0x000001fe
33
34static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
35{
36 u32 handle = mb->args[0];
37 struct cx18_stream *s = NULL;
38 struct cx18_buffer *buf;
39 u32 off;
40 int i;
41 int id;
42
43 for (i = 0; i < CX18_MAX_STREAMS; i++) {
44 s = &cx->streams[i];
45 if ((handle == s->handle) && (s->dvb.enabled))
46 break;
47 if (s->v4l2dev && handle == s->handle)
48 break;
49 }
50 if (i == CX18_MAX_STREAMS) {
51 CX18_WARN("DMA done for unknown handle %d for stream %s\n",
52 handle, s->name);
53 mb->error = CXERR_NOT_OPEN;
54 mb->cmd = 0;
55 cx18_mb_ack(cx, mb);
56 return;
57 }
58
59 off = mb->args[1];
60 if (mb->args[2] != 1)
61 CX18_WARN("Ack struct = %d for %s\n",
62 mb->args[2], s->name);
63 id = read_enc(off);
64 buf = cx18_queue_find_buf(s, id, read_enc(off + 4));
65 CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
66 if (buf) {
67 cx18_buf_sync_for_cpu(s, buf);
68 if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) {
69 /* process the buffer here */
70 CX18_DEBUG_HI_DMA("TS recv and sent bytesused=%d\n",
71 buf->bytesused);
72
73 dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
74 buf->bytesused);
75
76 cx18_buf_sync_for_device(s, buf);
77 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
78 (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem,
79 1, buf->id, s->buf_size);
80 } else
81 set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags);
82 } else {
83 CX18_WARN("Could not find buf %d for stream %s\n",
84 read_enc(off), s->name);
85 }
86 mb->error = 0;
87 mb->cmd = 0;
88 cx18_mb_ack(cx, mb);
89 wake_up(&cx->dma_waitq);
90 if (s->id != -1)
91 wake_up(&s->waitq);
92}
93
94static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb)
95{
96 char str[256] = { 0 };
97 char *p;
98
99 if (mb->args[1]) {
100 setup_page(mb->args[1]);
101 memcpy_fromio(str, cx->enc_mem + mb->args[1], 252);
102 str[252] = 0;
103 }
104 cx18_mb_ack(cx, mb);
105 CX18_DEBUG_INFO("%x %s\n", mb->args[0], str);
106 p = strchr(str, '.');
107 if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str)
108 CX18_INFO("FW version: %s\n", p - 1);
109}
110
111static void hpu_cmd(struct cx18 *cx, u32 sw1)
112{
113 struct cx18_mailbox mb;
114
115 if (sw1 & IRQ_CPU_TO_EPU) {
116 memcpy_fromio(&mb, &cx->scb->cpu2epu_mb, sizeof(mb));
117 mb.error = 0;
118
119 switch (mb.cmd) {
120 case CX18_EPU_DMA_DONE:
121 epu_dma_done(cx, &mb);
122 break;
123 case CX18_EPU_DEBUG:
124 epu_debug(cx, &mb);
125 break;
126 default:
127 CX18_WARN("Unexpected mailbox command %08x\n", mb.cmd);
128 break;
129 }
130 }
131 if (sw1 & (IRQ_APU_TO_EPU | IRQ_HPU_TO_EPU))
132 CX18_WARN("Unexpected interrupt %08x\n", sw1);
133}
134
135irqreturn_t cx18_irq_handler(int irq, void *dev_id)
136{
137 struct cx18 *cx = (struct cx18 *)dev_id;
138 u32 sw1, sw1_mask;
139 u32 sw2, sw2_mask;
140 u32 hw2, hw2_mask;
141
142 spin_lock(&cx->dma_reg_lock);
143
144 hw2_mask = read_reg(HW2_INT_MASK5_PCI);
145 hw2 = read_reg(HW2_INT_CLR_STATUS) & hw2_mask;
146 sw2_mask = read_reg(SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK;
147 sw2 = read_reg(SW2_INT_STATUS) & sw2_mask;
148 sw1_mask = read_reg(SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU;
149 sw1 = read_reg(SW1_INT_STATUS) & sw1_mask;
150
151 write_reg(sw2&sw2_mask, SW2_INT_STATUS);
152 write_reg(sw1&sw1_mask, SW1_INT_STATUS);
153 write_reg(hw2&hw2_mask, HW2_INT_CLR_STATUS);
154
155 if (sw1 || sw2 || hw2)
156 CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2);
157
158 /* To do: interrupt-based I2C handling
159 if (hw2 & 0x00c00000) {
160 }
161 */
162
163 if (sw2) {
164 if (sw2 & (cx->scb->cpu2hpu_irq_ack | cx->scb->cpu2epu_irq_ack))
165 wake_up(&cx->mb_cpu_waitq);
166 if (sw2 & (cx->scb->apu2hpu_irq_ack | cx->scb->apu2epu_irq_ack))
167 wake_up(&cx->mb_apu_waitq);
168 if (sw2 & cx->scb->epu2hpu_irq_ack)
169 wake_up(&cx->mb_epu_waitq);
170 if (sw2 & cx->scb->hpu2epu_irq_ack)
171 wake_up(&cx->mb_hpu_waitq);
172 }
173
174 if (sw1)
175 hpu_cmd(cx, sw1);
176 spin_unlock(&cx->dma_reg_lock);
177
178 return (hw2 | sw1 | sw2) ? IRQ_HANDLED : IRQ_NONE;
179}
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h
new file mode 100644
index 000000000000..379f704f5cba
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-irq.h
@@ -0,0 +1,37 @@
1/*
2 * cx18 interrupt handling
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#define HW2_I2C1_INT (1 << 22)
23#define HW2_I2C2_INT (1 << 23)
24#define HW2_INT_CLR_STATUS 0xc730c4
25#define HW2_INT_MASK5_PCI 0xc730e4
26#define SW1_INT_SET 0xc73100
27#define SW1_INT_STATUS 0xc73104
28#define SW1_INT_ENABLE_PCI 0xc7311c
29#define SW2_INT_SET 0xc73140
30#define SW2_INT_STATUS 0xc73144
31#define SW2_INT_ENABLE_PCI 0xc7315c
32
33irqreturn_t cx18_irq_handler(int irq, void *dev_id);
34
35void cx18_irq_work_handler(struct work_struct *work);
36void cx18_dma_stream_dec_prepare(struct cx18_stream *s, u32 offset, int lock);
37void cx18_unfinished_dma(unsigned long arg);
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
new file mode 100644
index 000000000000..0c5f328bca54
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -0,0 +1,372 @@
1/*
2 * cx18 mailbox functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include <stdarg.h>
23
24#include "cx18-driver.h"
25#include "cx18-scb.h"
26#include "cx18-irq.h"
27#include "cx18-mailbox.h"
28
29#define API_FAST (1 << 2) /* Short timeout */
30#define API_SLOW (1 << 3) /* Additional 300ms timeout */
31
32#define APU 0
33#define CPU 1
34#define EPU 2
35#define HPU 3
36
37struct cx18_api_info {
38 u32 cmd;
39 u8 flags; /* Flags, see above */
40 u8 rpu; /* Processing unit */
41 const char *name; /* The name of the command */
42};
43
44#define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x }
45
46static const struct cx18_api_info api_info[] = {
47 /* MPEG encoder API */
48 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
49 API_ENTRY(CPU, CX18_EPU_DEBUG, 0),
50 API_ENTRY(CPU, CX18_CREATE_TASK, 0),
51 API_ENTRY(CPU, CX18_DESTROY_TASK, 0),
52 API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW),
53 API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW),
54 API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0),
55 API_ENTRY(CPU, CX18_CPU_CAPTURE_RESUME, 0),
56 API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
57 API_ENTRY(CPU, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 0),
58 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_IN, 0),
59 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RATE, 0),
60 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RESOLUTION, 0),
61 API_ENTRY(CPU, CX18_CPU_SET_FILTER_PARAM, 0),
62 API_ENTRY(CPU, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 0),
63 API_ENTRY(CPU, CX18_CPU_SET_MEDIAN_CORING, 0),
64 API_ENTRY(CPU, CX18_CPU_SET_INDEXTABLE, 0),
65 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PARAMETERS, 0),
66 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_MUTE, 0),
67 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_MUTE, 0),
68 API_ENTRY(CPU, CX18_CPU_SET_MISC_PARAMETERS, 0),
69 API_ENTRY(CPU, CX18_CPU_SET_RAW_VBI_PARAM, API_SLOW),
70 API_ENTRY(CPU, CX18_CPU_SET_CAPTURE_LINE_NO, 0),
71 API_ENTRY(CPU, CX18_CPU_SET_COPYRIGHT, 0),
72 API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PID, 0),
73 API_ENTRY(CPU, CX18_CPU_SET_VIDEO_PID, 0),
74 API_ENTRY(CPU, CX18_CPU_SET_VER_CROP_LINE, 0),
75 API_ENTRY(CPU, CX18_CPU_SET_GOP_STRUCTURE, 0),
76 API_ENTRY(CPU, CX18_CPU_SET_SCENE_CHANGE_DETECTION, 0),
77 API_ENTRY(CPU, CX18_CPU_SET_ASPECT_RATIO, 0),
78 API_ENTRY(CPU, CX18_CPU_SET_SKIP_INPUT_FRAME, 0),
79 API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0),
80 API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0),
81 API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
82 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
83 API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
84 API_ENTRY(0, 0, 0),
85};
86
87static const struct cx18_api_info *find_api_info(u32 cmd)
88{
89 int i;
90
91 for (i = 0; api_info[i].cmd; i++)
92 if (api_info[i].cmd == cmd)
93 return &api_info[i];
94 return NULL;
95}
96
97static struct cx18_mailbox *cx18_mb_is_complete(struct cx18 *cx, int rpu,
98 u32 *state, u32 *irq, u32 *req)
99{
100 struct cx18_mailbox *mb = NULL;
101 int wait_count = 0;
102 u32 ack;
103
104 switch (rpu) {
105 case APU:
106 mb = &cx->scb->epu2apu_mb;
107 *state = readl(&cx->scb->apu_state);
108 *irq = readl(&cx->scb->epu2apu_irq);
109 break;
110
111 case CPU:
112 mb = &cx->scb->epu2cpu_mb;
113 *state = readl(&cx->scb->cpu_state);
114 *irq = readl(&cx->scb->epu2cpu_irq);
115 break;
116
117 case HPU:
118 mb = &cx->scb->epu2hpu_mb;
119 *state = readl(&cx->scb->hpu_state);
120 *irq = readl(&cx->scb->epu2hpu_irq);
121 break;
122 }
123
124 if (mb == NULL)
125 return mb;
126
127 do {
128 *req = readl(&mb->request);
129 ack = readl(&mb->ack);
130 wait_count++;
131 } while (*req != ack && wait_count < 600);
132
133 if (*req == ack) {
134 (*req)++;
135 if (*req == 0 || *req == 0xffffffff)
136 *req = 1;
137 return mb;
138 }
139 return NULL;
140}
141
142long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb)
143{
144 const struct cx18_api_info *info = find_api_info(mb->cmd);
145 struct cx18_mailbox *ack_mb;
146 u32 ack_irq;
147 u8 rpu = CPU;
148
149 if (info == NULL && mb->cmd) {
150 CX18_WARN("Cannot ack unknown command %x\n", mb->cmd);
151 return -EINVAL;
152 }
153 if (info)
154 rpu = info->rpu;
155
156 switch (rpu) {
157 case HPU:
158 ack_irq = IRQ_EPU_TO_HPU_ACK;
159 ack_mb = &cx->scb->hpu2epu_mb;
160 break;
161 case APU:
162 ack_irq = IRQ_EPU_TO_APU_ACK;
163 ack_mb = &cx->scb->apu2epu_mb;
164 break;
165 case CPU:
166 ack_irq = IRQ_EPU_TO_CPU_ACK;
167 ack_mb = &cx->scb->cpu2epu_mb;
168 break;
169 default:
170 CX18_WARN("Unknown RPU for command %x\n", mb->cmd);
171 return -EINVAL;
172 }
173
174 setup_page(SCB_OFFSET);
175 write_sync(mb->request, &ack_mb->ack);
176 write_reg(ack_irq, SW2_INT_SET);
177 return 0;
178}
179
180
181static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
182{
183 const struct cx18_api_info *info = find_api_info(cmd);
184 u32 state = 0, irq = 0, req, oldreq, err;
185 struct cx18_mailbox *mb;
186 wait_queue_head_t *waitq;
187 int timeout = 100;
188 int cnt = 0;
189 int sig = 0;
190 int i;
191
192 if (info == NULL) {
193 CX18_WARN("unknown cmd %x\n", cmd);
194 return -EINVAL;
195 }
196
197 if (cmd == CX18_CPU_DE_SET_MDL)
198 CX18_DEBUG_HI_API("%s\n", info->name);
199 else
200 CX18_DEBUG_API("%s\n", info->name);
201 setup_page(SCB_OFFSET);
202 mb = cx18_mb_is_complete(cx, info->rpu, &state, &irq, &req);
203
204 if (mb == NULL) {
205 CX18_ERR("mb %s busy\n", info->name);
206 return -EBUSY;
207 }
208
209 oldreq = req - 1;
210 writel(cmd, &mb->cmd);
211 for (i = 0; i < args; i++)
212 writel(data[i], &mb->args[i]);
213 writel(0, &mb->error);
214 writel(req, &mb->request);
215
216 switch (info->rpu) {
217 case APU: waitq = &cx->mb_apu_waitq; break;
218 case CPU: waitq = &cx->mb_cpu_waitq; break;
219 case EPU: waitq = &cx->mb_epu_waitq; break;
220 case HPU: waitq = &cx->mb_hpu_waitq; break;
221 default: return -EINVAL;
222 }
223 if (info->flags & API_FAST)
224 timeout /= 2;
225 write_reg(irq, SW1_INT_SET);
226
227 while (!sig && readl(&mb->ack) != readl(&mb->request) && cnt < 660) {
228 if (cnt > 200 && !in_atomic())
229 sig = cx18_msleep_timeout(10, 1);
230 cnt++;
231 }
232 if (sig)
233 return -EINTR;
234 if (cnt == 660) {
235 writel(oldreq, &mb->request);
236 CX18_ERR("mb %s failed\n", info->name);
237 return -EINVAL;
238 }
239 for (i = 0; i < MAX_MB_ARGUMENTS; i++)
240 data[i] = readl(&mb->args[i]);
241 err = readl(&mb->error);
242 if (!in_atomic() && (info->flags & API_SLOW))
243 cx18_msleep_timeout(300, 0);
244 if (err)
245 CX18_DEBUG_API("mailbox error %08x for command %s\n", err,
246 info->name);
247 return err ? -EIO : 0;
248}
249
250int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[])
251{
252 int res = cx18_api_call(cx, cmd, args, data);
253
254 /* Allow a single retry, probably already too late though.
255 If there is no free mailbox then that is usually an indication
256 of a more serious problem. */
257 return (res == -EBUSY) ? cx18_api_call(cx, cmd, args, data) : res;
258}
259
260static int cx18_set_filter_param(struct cx18_stream *s)
261{
262 struct cx18 *cx = s->cx;
263 u32 mode;
264 int ret;
265
266 mode = (cx->filter_mode & 1) ? 2 : (cx->spatial_strength ? 1 : 0);
267 ret = cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
268 s->handle, 1, mode, cx->spatial_strength);
269 mode = (cx->filter_mode & 2) ? 2 : (cx->temporal_strength ? 1 : 0);
270 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
271 s->handle, 0, mode, cx->temporal_strength);
272 ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4,
273 s->handle, 2, cx->filter_mode >> 2, 0);
274 return ret;
275}
276
277int cx18_api_func(void *priv, u32 cmd, int in, int out,
278 u32 data[CX2341X_MBOX_MAX_DATA])
279{
280 struct cx18 *cx = priv;
281 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
282
283 switch (cmd) {
284 case CX2341X_ENC_SET_OUTPUT_PORT:
285 return 0;
286 case CX2341X_ENC_SET_FRAME_RATE:
287 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_IN, 6,
288 s->handle, 0, 0, 0, 0, data[0]);
289 case CX2341X_ENC_SET_FRAME_SIZE:
290 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RESOLUTION, 3,
291 s->handle, data[1], data[0]);
292 case CX2341X_ENC_SET_STREAM_TYPE:
293 return cx18_vapi(cx, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 2,
294 s->handle, data[0]);
295 case CX2341X_ENC_SET_ASPECT_RATIO:
296 return cx18_vapi(cx, CX18_CPU_SET_ASPECT_RATIO, 2,
297 s->handle, data[0]);
298
299 case CX2341X_ENC_SET_GOP_PROPERTIES:
300 return cx18_vapi(cx, CX18_CPU_SET_GOP_STRUCTURE, 3,
301 s->handle, data[0], data[1]);
302 case CX2341X_ENC_SET_GOP_CLOSURE:
303 return 0;
304 case CX2341X_ENC_SET_AUDIO_PROPERTIES:
305 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2,
306 s->handle, data[0]);
307 case CX2341X_ENC_MUTE_AUDIO:
308 return cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2,
309 s->handle, data[0]);
310 case CX2341X_ENC_SET_BIT_RATE:
311 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RATE, 5,
312 s->handle, data[0], data[1], data[2], data[3]);
313 case CX2341X_ENC_MUTE_VIDEO:
314 return cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
315 s->handle, data[0]);
316 case CX2341X_ENC_SET_FRAME_DROP_RATE:
317 return cx18_vapi(cx, CX18_CPU_SET_SKIP_INPUT_FRAME, 2,
318 s->handle, data[0]);
319 case CX2341X_ENC_MISC:
320 return cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 4,
321 s->handle, data[0], data[1], data[2]);
322 case CX2341X_ENC_SET_DNR_FILTER_MODE:
323 cx->filter_mode = (data[0] & 3) | (data[1] << 2);
324 return cx18_set_filter_param(s);
325 case CX2341X_ENC_SET_DNR_FILTER_PROPS:
326 cx->spatial_strength = data[0];
327 cx->temporal_strength = data[1];
328 return cx18_set_filter_param(s);
329 case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE:
330 return cx18_vapi(cx, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 3,
331 s->handle, data[0], data[1]);
332 case CX2341X_ENC_SET_CORING_LEVELS:
333 return cx18_vapi(cx, CX18_CPU_SET_MEDIAN_CORING, 5,
334 s->handle, data[0], data[1], data[2], data[3]);
335 }
336 CX18_WARN("Unknown cmd %x\n", cmd);
337 return 0;
338}
339
340int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS],
341 u32 cmd, int args, ...)
342{
343 va_list ap;
344 int i;
345
346 va_start(ap, args);
347 for (i = 0; i < args; i++)
348 data[i] = va_arg(ap, u32);
349 va_end(ap);
350 return cx18_api(cx, cmd, args, data);
351}
352
353int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...)
354{
355 u32 data[MAX_MB_ARGUMENTS];
356 va_list ap;
357 int i;
358
359 if (cx == NULL) {
360 CX18_ERR("cx == NULL (cmd=%x)\n", cmd);
361 return 0;
362 }
363 if (args > MAX_MB_ARGUMENTS) {
364 CX18_ERR("args too big (cmd=%x)\n", cmd);
365 args = MAX_MB_ARGUMENTS;
366 }
367 va_start(ap, args);
368 for (i = 0; i < args; i++)
369 data[i] = va_arg(ap, u32);
370 va_end(ap);
371 return cx18_api(cx, cmd, args, data);
372}
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
new file mode 100644
index 000000000000..d995641536b3
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -0,0 +1,73 @@
1/*
2 * cx18 mailbox functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef _CX18_MAILBOX_H_
23#define _CX18_MAILBOX_H_
24
25/* mailbox max args */
26#define MAX_MB_ARGUMENTS 6
27/* compatibility, should be same as the define in cx2341x.h */
28#define CX2341X_MBOX_MAX_DATA 16
29
30#define MB_RESERVED_HANDLE_0 0
31#define MB_RESERVED_HANDLE_1 0xFFFFFFFF
32
33struct cx18;
34
35/* The cx18_mailbox struct is the mailbox structure which is used for passing
36 messages between processors */
37struct cx18_mailbox {
38 /* The sender sets a handle in 'request' after he fills the command. The
39 'request' should be different than 'ack'. The sender, also, generates
40 an interrupt on XPU2YPU_irq where XPU is the sender and YPU is the
41 receiver. */
42 u32 request;
43 /* The receiver detects a new command when 'req' is different than 'ack'.
44 He sets 'ack' to the same value as 'req' to clear the command. He, also,
45 generates an interrupt on YPU2XPU_irq where XPU is the sender and YPU
46 is the receiver. */
47 u32 ack;
48 u32 reserved[6];
49 /* 'cmd' identifies the command. The list of these commands are in
50 cx23418.h */
51 u32 cmd;
52 /* Each command can have up to 6 arguments */
53 u32 args[MAX_MB_ARGUMENTS];
54 /* The return code can be one of the codes in the file cx23418.h. If the
55 command is completed successfuly, the error will be ERR_SYS_SUCCESS.
56 If it is pending, the code is ERR_SYS_PENDING. If it failed, the error
57 code would indicate the task from which the error originated and will
58 be one of the errors in cx23418.h. In that case, the following
59 applies ((error & 0xff) != 0).
60 If the command is pending, the return will be passed in a MB from the
61 receiver to the sender. 'req' will be returned in args[0] */
62 u32 error;
63};
64
65int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]);
66int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd,
67 int args, ...);
68int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...);
69int cx18_api_func(void *priv, u32 cmd, int in, int out,
70 u32 data[CX2341X_MBOX_MAX_DATA]);
71long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb);
72
73#endif
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
new file mode 100644
index 000000000000..65af1bb507ca
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -0,0 +1,282 @@
1/*
2 * cx18 buffer queues
3 *
4 * Derived from ivtv-queue.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-streams.h"
26#include "cx18-queue.h"
27#include "cx18-scb.h"
28
29int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
30 const char __user *src, int copybytes)
31{
32 if (s->buf_size - buf->bytesused < copybytes)
33 copybytes = s->buf_size - buf->bytesused;
34 if (copy_from_user(buf->buf + buf->bytesused, src, copybytes))
35 return -EFAULT;
36 buf->bytesused += copybytes;
37 return copybytes;
38}
39
40void cx18_buf_swap(struct cx18_buffer *buf)
41{
42 int i;
43
44 for (i = 0; i < buf->bytesused; i += 4)
45 swab32s((u32 *)(buf->buf + i));
46}
47
48void cx18_queue_init(struct cx18_queue *q)
49{
50 INIT_LIST_HEAD(&q->list);
51 q->buffers = 0;
52 q->length = 0;
53 q->bytesused = 0;
54}
55
56void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
57 struct cx18_queue *q)
58{
59 unsigned long flags = 0;
60
61 /* clear the buffer if it is going to be enqueued to the free queue */
62 if (q == &s->q_free) {
63 buf->bytesused = 0;
64 buf->readpos = 0;
65 buf->b_flags = 0;
66 }
67 spin_lock_irqsave(&s->qlock, flags);
68 list_add_tail(&buf->list, &q->list);
69 q->buffers++;
70 q->length += s->buf_size;
71 q->bytesused += buf->bytesused - buf->readpos;
72 spin_unlock_irqrestore(&s->qlock, flags);
73}
74
75struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
76{
77 struct cx18_buffer *buf = NULL;
78 unsigned long flags = 0;
79
80 spin_lock_irqsave(&s->qlock, flags);
81 if (!list_empty(&q->list)) {
82 buf = list_entry(q->list.next, struct cx18_buffer, list);
83 list_del_init(q->list.next);
84 q->buffers--;
85 q->length -= s->buf_size;
86 q->bytesused -= buf->bytesused - buf->readpos;
87 }
88 spin_unlock_irqrestore(&s->qlock, flags);
89 return buf;
90}
91
92struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
93 u32 bytesused)
94{
95 struct cx18 *cx = s->cx;
96 struct list_head *p;
97
98 list_for_each(p, &s->q_free.list) {
99 struct cx18_buffer *buf =
100 list_entry(p, struct cx18_buffer, list);
101
102 if (buf->id != id)
103 continue;
104 buf->bytesused = bytesused;
105 /* the transport buffers are handled differently,
106 so there is no need to move them to the full queue */
107 if (s->type == CX18_ENC_STREAM_TYPE_TS)
108 return buf;
109 s->q_free.buffers--;
110 s->q_free.length -= s->buf_size;
111 s->q_full.buffers++;
112 s->q_full.length += s->buf_size;
113 s->q_full.bytesused += buf->bytesused;
114 list_move_tail(&buf->list, &s->q_full.list);
115 return buf;
116 }
117 CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name);
118 return NULL;
119}
120
121static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from,
122 struct cx18_queue *to, int clear, int full)
123{
124 struct cx18_buffer *buf =
125 list_entry(from->list.next, struct cx18_buffer, list);
126
127 list_move_tail(from->list.next, &to->list);
128 from->buffers--;
129 from->length -= s->buf_size;
130 from->bytesused -= buf->bytesused - buf->readpos;
131 /* special handling for q_free */
132 if (clear)
133 buf->bytesused = buf->readpos = buf->b_flags = 0;
134 else if (full) {
135 /* special handling for stolen buffers, assume
136 all bytes are used. */
137 buf->bytesused = s->buf_size;
138 buf->readpos = buf->b_flags = 0;
139 }
140 to->buffers++;
141 to->length += s->buf_size;
142 to->bytesused += buf->bytesused - buf->readpos;
143}
144
145/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'.
146 If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'.
147 If 'steal' != NULL, then buffers may also taken from that queue if
148 needed.
149
150 The buffer is automatically cleared if it goes to the free queue. It is
151 also cleared if buffers need to be taken from the 'steal' queue and
152 the 'from' queue is the free queue.
153
154 When 'from' is q_free, then needed_bytes is compared to the total
155 available buffer length, otherwise needed_bytes is compared to the
156 bytesused value. For the 'steal' queue the total available buffer
157 length is always used.
158
159 -ENOMEM is returned if the buffers could not be obtained, 0 if all
160 buffers where obtained from the 'from' list and if non-zero then
161 the number of stolen buffers is returned. */
162int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
163 struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes)
164{
165 unsigned long flags;
166 int rc = 0;
167 int from_free = from == &s->q_free;
168 int to_free = to == &s->q_free;
169 int bytes_available;
170
171 spin_lock_irqsave(&s->qlock, flags);
172 if (needed_bytes == 0) {
173 from_free = 1;
174 needed_bytes = from->length;
175 }
176
177 bytes_available = from_free ? from->length : from->bytesused;
178 bytes_available += steal ? steal->length : 0;
179
180 if (bytes_available < needed_bytes) {
181 spin_unlock_irqrestore(&s->qlock, flags);
182 return -ENOMEM;
183 }
184 if (from_free) {
185 u32 old_length = to->length;
186
187 while (to->length - old_length < needed_bytes) {
188 if (list_empty(&from->list))
189 from = steal;
190 if (from == steal)
191 rc++; /* keep track of 'stolen' buffers */
192 cx18_queue_move_buf(s, from, to, 1, 0);
193 }
194 } else {
195 u32 old_bytesused = to->bytesused;
196
197 while (to->bytesused - old_bytesused < needed_bytes) {
198 if (list_empty(&from->list))
199 from = steal;
200 if (from == steal)
201 rc++; /* keep track of 'stolen' buffers */
202 cx18_queue_move_buf(s, from, to, to_free, rc);
203 }
204 }
205 spin_unlock_irqrestore(&s->qlock, flags);
206 return rc;
207}
208
209void cx18_flush_queues(struct cx18_stream *s)
210{
211 cx18_queue_move(s, &s->q_io, NULL, &s->q_free, 0);
212 cx18_queue_move(s, &s->q_full, NULL, &s->q_free, 0);
213}
214
215int cx18_stream_alloc(struct cx18_stream *s)
216{
217 struct cx18 *cx = s->cx;
218 int i;
219
220 if (s->buffers == 0)
221 return 0;
222
223 CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n",
224 s->name, s->buffers, s->buf_size,
225 s->buffers * s->buf_size / 1024);
226
227 if (((char *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] -
228 (char *)cx->scb) > SCB_RESERVED_SIZE) {
229 unsigned bufsz = (((char *)cx->scb) + SCB_RESERVED_SIZE -
230 ((char *)cx->scb->cpu_mdl));
231
232 CX18_ERR("Too many buffers, cannot fit in SCB area\n");
233 CX18_ERR("Max buffers = %zd\n",
234 bufsz / sizeof(struct cx18_mdl));
235 return -ENOMEM;
236 }
237
238 s->mdl_offset = cx->mdl_offset;
239
240 /* allocate stream buffers. Initially all buffers are in q_free. */
241 for (i = 0; i < s->buffers; i++) {
242 struct cx18_buffer *buf =
243 kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL);
244
245 if (buf == NULL)
246 break;
247 buf->buf = kmalloc(s->buf_size, GFP_KERNEL);
248 if (buf->buf == NULL) {
249 kfree(buf);
250 break;
251 }
252 buf->id = cx->buffer_id++;
253 INIT_LIST_HEAD(&buf->list);
254 buf->dma_handle = pci_map_single(s->cx->dev,
255 buf->buf, s->buf_size, s->dma);
256 cx18_buf_sync_for_cpu(s, buf);
257 cx18_enqueue(s, buf, &s->q_free);
258 }
259 if (i == s->buffers) {
260 cx->mdl_offset += s->buffers;
261 return 0;
262 }
263 CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name);
264 cx18_stream_free(s);
265 return -ENOMEM;
266}
267
268void cx18_stream_free(struct cx18_stream *s)
269{
270 struct cx18_buffer *buf;
271
272 /* move all buffers to q_free */
273 cx18_flush_queues(s);
274
275 /* empty q_free */
276 while ((buf = cx18_dequeue(s, &s->q_free))) {
277 pci_unmap_single(s->cx->dev, buf->dma_handle,
278 s->buf_size, s->dma);
279 kfree(buf->buf);
280 kfree(buf);
281 }
282}
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
new file mode 100644
index 000000000000..f86c8a6fa6e7
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -0,0 +1,59 @@
1/*
2 * cx18 buffer queues
3 *
4 * Derived from ivtv-queue.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#define CX18_DMA_UNMAPPED ((u32) -1)
25
26/* cx18_buffer utility functions */
27
28static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
29 struct cx18_buffer *buf)
30{
31 pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle,
32 s->buf_size, s->dma);
33}
34
35static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
36 struct cx18_buffer *buf)
37{
38 pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle,
39 s->buf_size, s->dma);
40}
41
42int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
43 const char __user *src, int copybytes);
44void cx18_buf_swap(struct cx18_buffer *buf);
45
46/* cx18_queue utility functions */
47void cx18_queue_init(struct cx18_queue *q);
48void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
49 struct cx18_queue *q);
50struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
51int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
52 struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes);
53struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
54 u32 bytesused);
55void cx18_flush_queues(struct cx18_stream *s);
56
57/* cx18_stream utility functions */
58int cx18_stream_alloc(struct cx18_stream *s);
59void cx18_stream_free(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/video/cx18/cx18-scb.c
new file mode 100644
index 000000000000..30bc803e30da
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-scb.c
@@ -0,0 +1,121 @@
1/*
2 * cx18 System Control Block initialization
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include "cx18-driver.h"
23#include "cx18-scb.h"
24
25void cx18_init_scb(struct cx18 *cx)
26{
27 setup_page(SCB_OFFSET);
28 memset_io(cx->scb, 0, 0x10000);
29
30 writel(IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq);
31 writel(IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack);
32 writel(IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq);
33 writel(IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack);
34 writel(IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq);
35 writel(IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack);
36 writel(IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq);
37 writel(IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack);
38
39 writel(IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq);
40 writel(IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack);
41 writel(IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq);
42 writel(IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack);
43 writel(IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq);
44 writel(IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack);
45 writel(IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq);
46 writel(IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack);
47
48 writel(IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq);
49 writel(IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack);
50 writel(IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq);
51 writel(IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack);
52 writel(IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq);
53 writel(IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack);
54 writel(IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq);
55 writel(IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack);
56
57 writel(IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq);
58 writel(IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack);
59 writel(IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq);
60 writel(IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack);
61 writel(IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq);
62 writel(IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack);
63 writel(IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq);
64 writel(IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack);
65
66 writel(IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq);
67 writel(IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack);
68 writel(IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq);
69 writel(IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack);
70 writel(IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq);
71 writel(IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack);
72 writel(IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq);
73 writel(IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack);
74
75 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb),
76 &cx->scb->apu2cpu_mb_offset);
77 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb),
78 &cx->scb->hpu2cpu_mb_offset);
79 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb),
80 &cx->scb->ppu2cpu_mb_offset);
81 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb),
82 &cx->scb->epu2cpu_mb_offset);
83 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb),
84 &cx->scb->cpu2apu_mb_offset);
85 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb),
86 &cx->scb->hpu2apu_mb_offset);
87 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb),
88 &cx->scb->ppu2apu_mb_offset);
89 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb),
90 &cx->scb->epu2apu_mb_offset);
91 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb),
92 &cx->scb->cpu2hpu_mb_offset);
93 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb),
94 &cx->scb->apu2hpu_mb_offset);
95 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb),
96 &cx->scb->ppu2hpu_mb_offset);
97 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb),
98 &cx->scb->epu2hpu_mb_offset);
99 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb),
100 &cx->scb->cpu2ppu_mb_offset);
101 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb),
102 &cx->scb->apu2ppu_mb_offset);
103 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb),
104 &cx->scb->hpu2ppu_mb_offset);
105 writel(SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb),
106 &cx->scb->epu2ppu_mb_offset);
107 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb),
108 &cx->scb->cpu2epu_mb_offset);
109 writel(SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb),
110 &cx->scb->apu2epu_mb_offset);
111 writel(SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb),
112 &cx->scb->hpu2epu_mb_offset);
113 writel(SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb),
114 &cx->scb->ppu2epu_mb_offset);
115
116 writel(SCB_OFFSET + offsetof(struct cx18_scb, cpu_state),
117 &cx->scb->ipc_offset);
118
119 writel(1, &cx->scb->hpu_state);
120 writel(1, &cx->scb->epu_state);
121}
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h
new file mode 100644
index 000000000000..86b4cb15d163
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-scb.h
@@ -0,0 +1,285 @@
1/*
2 * cx18 System Control Block initialization
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef CX18_SCB_H
23#define CX18_SCB_H
24
25#include "cx18-mailbox.h"
26
27/* NOTE: All ACK interrupts are in the SW2 register. All non-ACK interrupts
28 are in the SW1 register. */
29
30#define IRQ_APU_TO_CPU 0x00000001
31#define IRQ_CPU_TO_APU_ACK 0x00000001
32#define IRQ_HPU_TO_CPU 0x00000002
33#define IRQ_CPU_TO_HPU_ACK 0x00000002
34#define IRQ_PPU_TO_CPU 0x00000004
35#define IRQ_CPU_TO_PPU_ACK 0x00000004
36#define IRQ_EPU_TO_CPU 0x00000008
37#define IRQ_CPU_TO_EPU_ACK 0x00000008
38
39#define IRQ_CPU_TO_APU 0x00000010
40#define IRQ_APU_TO_CPU_ACK 0x00000010
41#define IRQ_HPU_TO_APU 0x00000020
42#define IRQ_APU_TO_HPU_ACK 0x00000020
43#define IRQ_PPU_TO_APU 0x00000040
44#define IRQ_APU_TO_PPU_ACK 0x00000040
45#define IRQ_EPU_TO_APU 0x00000080
46#define IRQ_APU_TO_EPU_ACK 0x00000080
47
48#define IRQ_CPU_TO_HPU 0x00000100
49#define IRQ_HPU_TO_CPU_ACK 0x00000100
50#define IRQ_APU_TO_HPU 0x00000200
51#define IRQ_HPU_TO_APU_ACK 0x00000200
52#define IRQ_PPU_TO_HPU 0x00000400
53#define IRQ_HPU_TO_PPU_ACK 0x00000400
54#define IRQ_EPU_TO_HPU 0x00000800
55#define IRQ_HPU_TO_EPU_ACK 0x00000800
56
57#define IRQ_CPU_TO_PPU 0x00001000
58#define IRQ_PPU_TO_CPU_ACK 0x00001000
59#define IRQ_APU_TO_PPU 0x00002000
60#define IRQ_PPU_TO_APU_ACK 0x00002000
61#define IRQ_HPU_TO_PPU 0x00004000
62#define IRQ_PPU_TO_HPU_ACK 0x00004000
63#define IRQ_EPU_TO_PPU 0x00008000
64#define IRQ_PPU_TO_EPU_ACK 0x00008000
65
66#define IRQ_CPU_TO_EPU 0x00010000
67#define IRQ_EPU_TO_CPU_ACK 0x00010000
68#define IRQ_APU_TO_EPU 0x00020000
69#define IRQ_EPU_TO_APU_ACK 0x00020000
70#define IRQ_HPU_TO_EPU 0x00040000
71#define IRQ_EPU_TO_HPU_ACK 0x00040000
72#define IRQ_PPU_TO_EPU 0x00080000
73#define IRQ_EPU_TO_PPU_ACK 0x00080000
74
75#define SCB_OFFSET 0xDC0000
76
77/* If Firmware uses fixed memory map, it shall not allocate the area
78 between SCB_OFFSET and SCB_OFFSET+SCB_RESERVED_SIZE-1 inclusive */
79#define SCB_RESERVED_SIZE 0x10000
80
81
82/* This structure is used by EPU to provide memory descriptors in its memory */
83struct cx18_mdl {
84 u32 paddr; /* Physical address of a buffer segment */
85 u32 length; /* Length of the buffer segment */
86};
87
88/* This structure is used by CPU to provide completed buffers information */
89struct cx18_mdl_ack {
90 u32 id; /* ID of a completed MDL */
91 u32 data_used; /* Total data filled in the MDL for buffer 'id' */
92};
93
94struct cx18_scb {
95 /* These fields form the System Control Block which is used at boot time
96 for localizing the IPC data as well as the code positions for all
97 processors. The offsets are from the start of this struct. */
98
99 /* Offset where to find the Inter-Processor Communication data */
100 u32 ipc_offset;
101 u32 reserved01[7];
102 /* Offset where to find the start of the CPU code */
103 u32 cpu_code_offset;
104 u32 reserved02[3];
105 /* Offset where to find the start of the APU code */
106 u32 apu_code_offset;
107 u32 reserved03[3];
108 /* Offset where to find the start of the HPU code */
109 u32 hpu_code_offset;
110 u32 reserved04[3];
111 /* Offset where to find the start of the PPU code */
112 u32 ppu_code_offset;
113 u32 reserved05[3];
114
115 /* These fields form Inter-Processor Communication data which is used
116 by all processors to locate the information needed for communicating
117 with other processors */
118
119 /* Fields for CPU: */
120
121 /* bit 0: 1/0 processor ready/not ready. Set other bits to 0. */
122 u32 cpu_state;
123 u32 reserved1[7];
124 /* Offset to the mailbox used for sending commands from APU to CPU */
125 u32 apu2cpu_mb_offset;
126 /* Value to write to register SW1 register set (0xC7003100) after the
127 command is ready */
128 u32 apu2cpu_irq;
129 /* Value to write to register SW2 register set (0xC7003140) after the
130 command is cleared */
131 u32 apu2cpu_irq_ack;
132 u32 reserved2[13];
133
134 u32 hpu2cpu_mb_offset;
135 u32 hpu2cpu_irq;
136 u32 hpu2cpu_irq_ack;
137 u32 reserved3[13];
138
139 u32 ppu2cpu_mb_offset;
140 u32 ppu2cpu_irq;
141 u32 ppu2cpu_irq_ack;
142 u32 reserved4[13];
143
144 u32 epu2cpu_mb_offset;
145 u32 epu2cpu_irq;
146 u32 epu2cpu_irq_ack;
147 u32 reserved5[13];
148 u32 reserved6[8];
149
150 /* Fields for APU: */
151
152 u32 apu_state;
153 u32 reserved11[7];
154 u32 cpu2apu_mb_offset;
155 u32 cpu2apu_irq;
156 u32 cpu2apu_irq_ack;
157 u32 reserved12[13];
158
159 u32 hpu2apu_mb_offset;
160 u32 hpu2apu_irq;
161 u32 hpu2apu_irq_ack;
162 u32 reserved13[13];
163
164 u32 ppu2apu_mb_offset;
165 u32 ppu2apu_irq;
166 u32 ppu2apu_irq_ack;
167 u32 reserved14[13];
168
169 u32 epu2apu_mb_offset;
170 u32 epu2apu_irq;
171 u32 epu2apu_irq_ack;
172 u32 reserved15[13];
173 u32 reserved16[8];
174
175 /* Fields for HPU: */
176
177 u32 hpu_state;
178 u32 reserved21[7];
179 u32 cpu2hpu_mb_offset;
180 u32 cpu2hpu_irq;
181 u32 cpu2hpu_irq_ack;
182 u32 reserved22[13];
183
184 u32 apu2hpu_mb_offset;
185 u32 apu2hpu_irq;
186 u32 apu2hpu_irq_ack;
187 u32 reserved23[13];
188
189 u32 ppu2hpu_mb_offset;
190 u32 ppu2hpu_irq;
191 u32 ppu2hpu_irq_ack;
192 u32 reserved24[13];
193
194 u32 epu2hpu_mb_offset;
195 u32 epu2hpu_irq;
196 u32 epu2hpu_irq_ack;
197 u32 reserved25[13];
198 u32 reserved26[8];
199
200 /* Fields for PPU: */
201
202 u32 ppu_state;
203 u32 reserved31[7];
204 u32 cpu2ppu_mb_offset;
205 u32 cpu2ppu_irq;
206 u32 cpu2ppu_irq_ack;
207 u32 reserved32[13];
208
209 u32 apu2ppu_mb_offset;
210 u32 apu2ppu_irq;
211 u32 apu2ppu_irq_ack;
212 u32 reserved33[13];
213
214 u32 hpu2ppu_mb_offset;
215 u32 hpu2ppu_irq;
216 u32 hpu2ppu_irq_ack;
217 u32 reserved34[13];
218
219 u32 epu2ppu_mb_offset;
220 u32 epu2ppu_irq;
221 u32 epu2ppu_irq_ack;
222 u32 reserved35[13];
223 u32 reserved36[8];
224
225 /* Fields for EPU: */
226
227 u32 epu_state;
228 u32 reserved41[7];
229 u32 cpu2epu_mb_offset;
230 u32 cpu2epu_irq;
231 u32 cpu2epu_irq_ack;
232 u32 reserved42[13];
233
234 u32 apu2epu_mb_offset;
235 u32 apu2epu_irq;
236 u32 apu2epu_irq_ack;
237 u32 reserved43[13];
238
239 u32 hpu2epu_mb_offset;
240 u32 hpu2epu_irq;
241 u32 hpu2epu_irq_ack;
242 u32 reserved44[13];
243
244 u32 ppu2epu_mb_offset;
245 u32 ppu2epu_irq;
246 u32 ppu2epu_irq_ack;
247 u32 reserved45[13];
248 u32 reserved46[8];
249
250 u32 semaphores[8]; /* Semaphores */
251
252 u32 reserved50[32]; /* Reserved for future use */
253
254 struct cx18_mailbox apu2cpu_mb;
255 struct cx18_mailbox hpu2cpu_mb;
256 struct cx18_mailbox ppu2cpu_mb;
257 struct cx18_mailbox epu2cpu_mb;
258
259 struct cx18_mailbox cpu2apu_mb;
260 struct cx18_mailbox hpu2apu_mb;
261 struct cx18_mailbox ppu2apu_mb;
262 struct cx18_mailbox epu2apu_mb;
263
264 struct cx18_mailbox cpu2hpu_mb;
265 struct cx18_mailbox apu2hpu_mb;
266 struct cx18_mailbox ppu2hpu_mb;
267 struct cx18_mailbox epu2hpu_mb;
268
269 struct cx18_mailbox cpu2ppu_mb;
270 struct cx18_mailbox apu2ppu_mb;
271 struct cx18_mailbox hpu2ppu_mb;
272 struct cx18_mailbox epu2ppu_mb;
273
274 struct cx18_mailbox cpu2epu_mb;
275 struct cx18_mailbox apu2epu_mb;
276 struct cx18_mailbox hpu2epu_mb;
277 struct cx18_mailbox ppu2epu_mb;
278
279 struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][2];
280 struct cx18_mdl cpu_mdl[1];
281};
282
283void cx18_init_scb(struct cx18 *cx);
284
285#endif
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
new file mode 100644
index 000000000000..afb141b2027a
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -0,0 +1,566 @@
1/*
2 * cx18 init/start/stop/exit stream functions
3 *
4 * Derived from ivtv-streams.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-fileops.h"
26#include "cx18-mailbox.h"
27#include "cx18-i2c.h"
28#include "cx18-queue.h"
29#include "cx18-ioctl.h"
30#include "cx18-streams.h"
31#include "cx18-cards.h"
32#include "cx18-scb.h"
33#include "cx18-av-core.h"
34#include "cx18-dvb.h"
35
36#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
37
38static struct file_operations cx18_v4l2_enc_fops = {
39 .owner = THIS_MODULE,
40 .read = cx18_v4l2_read,
41 .open = cx18_v4l2_open,
42 .ioctl = cx18_v4l2_ioctl,
43 .release = cx18_v4l2_close,
44 .poll = cx18_v4l2_enc_poll,
45};
46
47/* offset from 0 to register ts v4l2 minors on */
48#define CX18_V4L2_ENC_TS_OFFSET 16
49/* offset from 0 to register pcm v4l2 minors on */
50#define CX18_V4L2_ENC_PCM_OFFSET 24
51/* offset from 0 to register yuv v4l2 minors on */
52#define CX18_V4L2_ENC_YUV_OFFSET 32
53
54static struct {
55 const char *name;
56 int vfl_type;
57 int minor_offset;
58 int dma;
59 enum v4l2_buf_type buf_type;
60 struct file_operations *fops;
61} cx18_stream_info[] = {
62 { /* CX18_ENC_STREAM_TYPE_MPG */
63 "encoder MPEG",
64 VFL_TYPE_GRABBER, 0,
65 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
66 &cx18_v4l2_enc_fops
67 },
68 { /* CX18_ENC_STREAM_TYPE_TS */
69 "TS",
70 VFL_TYPE_GRABBER, -1,
71 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
72 &cx18_v4l2_enc_fops
73 },
74 { /* CX18_ENC_STREAM_TYPE_YUV */
75 "encoder YUV",
76 VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET,
77 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
78 &cx18_v4l2_enc_fops
79 },
80 { /* CX18_ENC_STREAM_TYPE_VBI */
81 "encoder VBI",
82 VFL_TYPE_VBI, 0,
83 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE,
84 &cx18_v4l2_enc_fops
85 },
86 { /* CX18_ENC_STREAM_TYPE_PCM */
87 "encoder PCM audio",
88 VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET,
89 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE,
90 &cx18_v4l2_enc_fops
91 },
92 { /* CX18_ENC_STREAM_TYPE_IDX */
93 "encoder IDX",
94 VFL_TYPE_GRABBER, -1,
95 PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
96 &cx18_v4l2_enc_fops
97 },
98 { /* CX18_ENC_STREAM_TYPE_RAD */
99 "encoder radio",
100 VFL_TYPE_RADIO, 0,
101 PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE,
102 &cx18_v4l2_enc_fops
103 },
104};
105
106static void cx18_stream_init(struct cx18 *cx, int type)
107{
108 struct cx18_stream *s = &cx->streams[type];
109 struct video_device *dev = s->v4l2dev;
110 u32 max_size = cx->options.megabytes[type] * 1024 * 1024;
111
112 /* we need to keep v4l2dev, so restore it afterwards */
113 memset(s, 0, sizeof(*s));
114 s->v4l2dev = dev;
115
116 /* initialize cx18_stream fields */
117 s->cx = cx;
118 s->type = type;
119 s->name = cx18_stream_info[type].name;
120 s->handle = 0xffffffff;
121
122 s->dma = cx18_stream_info[type].dma;
123 s->buf_size = cx->stream_buf_size[type];
124 if (s->buf_size)
125 s->buffers = max_size / s->buf_size;
126 if (s->buffers > 63) {
127 /* Each stream has a maximum of 63 buffers,
128 ensure we do not exceed that. */
129 s->buffers = 63;
130 s->buf_size = (max_size / s->buffers) & ~0xfff;
131 }
132 spin_lock_init(&s->qlock);
133 init_waitqueue_head(&s->waitq);
134 s->id = -1;
135 cx18_queue_init(&s->q_free);
136 cx18_queue_init(&s->q_full);
137 cx18_queue_init(&s->q_io);
138}
139
140static int cx18_prep_dev(struct cx18 *cx, int type)
141{
142 struct cx18_stream *s = &cx->streams[type];
143 u32 cap = cx->v4l2_cap;
144 int minor_offset = cx18_stream_info[type].minor_offset;
145 int minor;
146
147 /* These four fields are always initialized. If v4l2dev == NULL, then
148 this stream is not in use. In that case no other fields but these
149 four can be used. */
150 s->v4l2dev = NULL;
151 s->cx = cx;
152 s->type = type;
153 s->name = cx18_stream_info[type].name;
154
155 /* Check whether the radio is supported */
156 if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO))
157 return 0;
158
159 /* Check whether VBI is supported */
160 if (type == CX18_ENC_STREAM_TYPE_VBI &&
161 !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)))
162 return 0;
163
164 /* card number + user defined offset + device offset */
165 minor = cx->num + cx18_first_minor + minor_offset;
166
167 /* User explicitly selected 0 buffers for these streams, so don't
168 create them. */
169 if (cx18_stream_info[type].dma != PCI_DMA_NONE &&
170 cx->options.megabytes[type] == 0) {
171 CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name);
172 return 0;
173 }
174
175 cx18_stream_init(cx, type);
176
177 if (minor_offset == -1)
178 return 0;
179
180 /* allocate and initialize the v4l2 video device structure */
181 s->v4l2dev = video_device_alloc();
182 if (s->v4l2dev == NULL) {
183 CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
184 s->name);
185 return -ENOMEM;
186 }
187
188 s->v4l2dev->type =
189 VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT |
190 VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER;
191 snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18%d %s",
192 cx->num, s->name);
193
194 s->v4l2dev->minor = minor;
195 s->v4l2dev->dev = &cx->dev->dev;
196 s->v4l2dev->fops = cx18_stream_info[type].fops;
197 s->v4l2dev->release = video_device_release;
198
199 return 0;
200}
201
202/* Initialize v4l2 variables and register v4l2 devices */
203int cx18_streams_setup(struct cx18 *cx)
204{
205 int type;
206
207 /* Setup V4L2 Devices */
208 for (type = 0; type < CX18_MAX_STREAMS; type++) {
209 /* Prepare device */
210 if (cx18_prep_dev(cx, type))
211 break;
212
213 /* Allocate Stream */
214 if (cx18_stream_alloc(&cx->streams[type]))
215 break;
216 }
217 if (type == CX18_MAX_STREAMS)
218 return 0;
219
220 /* One or more streams could not be initialized. Clean 'em all up. */
221 cx18_streams_cleanup(cx);
222 return -ENOMEM;
223}
224
225static int cx18_reg_dev(struct cx18 *cx, int type)
226{
227 struct cx18_stream *s = &cx->streams[type];
228 int vfl_type = cx18_stream_info[type].vfl_type;
229 int minor;
230
231 /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something?
232 * We need a VFL_TYPE_TS defined.
233 */
234 if (strcmp("TS", s->name) == 0) {
235 /* just return if no DVB is supported */
236 if ((cx->card->hw_all & CX18_HW_DVB) == 0)
237 return 0;
238 if (cx18_dvb_register(s) < 0) {
239 CX18_ERR("DVB failed to register\n");
240 return -EINVAL;
241 }
242 }
243
244 if (s->v4l2dev == NULL)
245 return 0;
246
247 minor = s->v4l2dev->minor;
248
249 /* Register device. First try the desired minor, then any free one. */
250 if (video_register_device(s->v4l2dev, vfl_type, minor) &&
251 video_register_device(s->v4l2dev, vfl_type, -1)) {
252 CX18_ERR("Couldn't register v4l2 device for %s minor %d\n",
253 s->name, minor);
254 video_device_release(s->v4l2dev);
255 s->v4l2dev = NULL;
256 return -ENOMEM;
257 }
258 minor = s->v4l2dev->minor;
259
260 switch (vfl_type) {
261 case VFL_TYPE_GRABBER:
262 CX18_INFO("Registered device video%d for %s (%d MB)\n",
263 minor, s->name, cx->options.megabytes[type]);
264 break;
265
266 case VFL_TYPE_RADIO:
267 CX18_INFO("Registered device radio%d for %s\n",
268 minor - MINOR_VFL_TYPE_RADIO_MIN, s->name);
269 break;
270
271 case VFL_TYPE_VBI:
272 if (cx->options.megabytes[type])
273 CX18_INFO("Registered device vbi%d for %s (%d MB)\n",
274 minor - MINOR_VFL_TYPE_VBI_MIN,
275 s->name, cx->options.megabytes[type]);
276 else
277 CX18_INFO("Registered device vbi%d for %s\n",
278 minor - MINOR_VFL_TYPE_VBI_MIN, s->name);
279 break;
280 }
281
282 return 0;
283}
284
285/* Register v4l2 devices */
286int cx18_streams_register(struct cx18 *cx)
287{
288 int type;
289 int err = 0;
290
291 /* Register V4L2 devices */
292 for (type = 0; type < CX18_MAX_STREAMS; type++)
293 err |= cx18_reg_dev(cx, type);
294
295 if (err == 0)
296 return 0;
297
298 /* One or more streams could not be initialized. Clean 'em all up. */
299 cx18_streams_cleanup(cx);
300 return -ENOMEM;
301}
302
303/* Unregister v4l2 devices */
304void cx18_streams_cleanup(struct cx18 *cx)
305{
306 struct video_device *vdev;
307 int type;
308
309 /* Teardown all streams */
310 for (type = 0; type < CX18_MAX_STREAMS; type++) {
311 if (cx->streams[type].dvb.enabled)
312 cx18_dvb_unregister(&cx->streams[type]);
313
314 vdev = cx->streams[type].v4l2dev;
315
316 cx->streams[type].v4l2dev = NULL;
317 if (vdev == NULL)
318 continue;
319
320 cx18_stream_free(&cx->streams[type]);
321
322 /* Unregister device */
323 video_unregister_device(vdev);
324 }
325}
326
327static void cx18_vbi_setup(struct cx18_stream *s)
328{
329 struct cx18 *cx = s->cx;
330 int raw = cx->vbi.sliced_in->service_set == 0;
331 u32 data[CX2341X_MBOX_MAX_DATA];
332 int lines;
333
334 if (cx->is_60hz) {
335 cx->vbi.count = 12;
336 cx->vbi.start[0] = 10;
337 cx->vbi.start[1] = 273;
338 } else { /* PAL/SECAM */
339 cx->vbi.count = 18;
340 cx->vbi.start[0] = 6;
341 cx->vbi.start[1] = 318;
342 }
343
344 /* setup VBI registers */
345 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
346
347 /* determine number of lines and total number of VBI bytes.
348 A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1
349 The '- 1' byte is probably an unused U or V byte. Or something...
350 A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
351 header, 42 data bytes + checksum (to be confirmed) */
352 if (raw) {
353 lines = cx->vbi.count * 2;
354 } else {
355 lines = cx->is_60hz ? 24 : 38;
356 if (cx->is_60hz)
357 lines += 2;
358 }
359
360 cx->vbi.enc_size = lines *
361 (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
362
363 data[0] = s->handle;
364 /* Lines per field */
365 data[1] = (lines / 2) | ((lines / 2) << 16);
366 /* bytes per line */
367 data[2] = (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
368 /* Every X number of frames a VBI interrupt arrives
369 (frames as in 25 or 30 fps) */
370 data[3] = 1;
371 /* Setup VBI for the cx25840 digitizer */
372 if (raw) {
373 data[4] = 0x20602060;
374 data[5] = 0x30703070;
375 } else {
376 data[4] = 0xB0F0B0F0;
377 data[5] = 0xA0E0A0E0;
378 }
379
380 CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
381 data[0], data[1], data[2], data[3], data[4], data[5]);
382
383 if (s->type == CX18_ENC_STREAM_TYPE_VBI)
384 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
385}
386
387int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
388{
389 u32 data[MAX_MB_ARGUMENTS];
390 struct cx18 *cx = s->cx;
391 struct list_head *p;
392 int ts = 0;
393 int captype = 0;
394
395 if (s->v4l2dev == NULL && s->dvb.enabled == 0)
396 return -EINVAL;
397
398 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
399
400 switch (s->type) {
401 case CX18_ENC_STREAM_TYPE_MPG:
402 captype = CAPTURE_CHANNEL_TYPE_MPEG;
403 cx->mpg_data_received = cx->vbi_data_inserted = 0;
404 cx->dualwatch_jiffies = jiffies;
405 cx->dualwatch_stereo_mode = cx->params.audio_properties & 0x300;
406 cx->search_pack_header = 0;
407 break;
408
409 case CX18_ENC_STREAM_TYPE_TS:
410 captype = CAPTURE_CHANNEL_TYPE_TS;
411 ts = 1;
412 break;
413 case CX18_ENC_STREAM_TYPE_YUV:
414 captype = CAPTURE_CHANNEL_TYPE_YUV;
415 break;
416 case CX18_ENC_STREAM_TYPE_PCM:
417 captype = CAPTURE_CHANNEL_TYPE_PCM;
418 break;
419 case CX18_ENC_STREAM_TYPE_VBI:
420 captype = cx->vbi.sliced_in->service_set ?
421 CAPTURE_CHANNEL_TYPE_SLICED_VBI : CAPTURE_CHANNEL_TYPE_VBI;
422 cx->vbi.frame = 0;
423 cx->vbi.inserted_frame = 0;
424 memset(cx->vbi.sliced_mpeg_size,
425 0, sizeof(cx->vbi.sliced_mpeg_size));
426 break;
427 default:
428 return -EINVAL;
429 }
430 s->buffers_stolen = 0;
431
432 /* mute/unmute video */
433 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
434 s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags));
435
436 /* Clear Streamoff flags in case left from last capture */
437 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
438
439 cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE);
440 s->handle = data[0];
441 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
442
443 if (atomic_read(&cx->capturing) == 0 && !ts) {
444 /* Stuff from Windows, we don't know what it is */
445 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
446 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
447 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
448 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
449 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12);
450
451 cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
452 s->handle, cx->digitizer, cx->digitizer);
453
454 /* Setup VBI */
455 if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
456 cx18_vbi_setup(s);
457
458 /* assign program index info.
459 Mask 7: select I/P/B, Num_req: 400 max */
460 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
461
462 /* Setup API for Stream */
463 cx2341x_update(cx, cx18_api_func, NULL, &cx->params);
464 }
465
466 if (atomic_read(&cx->capturing) == 0) {
467 clear_bit(CX18_F_I_EOS, &cx->i_flags);
468 write_reg(7, CX18_DSP0_INTERRUPT_MASK);
469 }
470
471 cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle,
472 (void *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem,
473 (void *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
474
475 list_for_each(p, &s->q_free.list) {
476 struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list);
477
478 writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr);
479 writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
480 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
481 (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 1,
482 buf->id, s->buf_size);
483 }
484 /* begin_capture */
485 if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) {
486 CX18_DEBUG_WARN("Error starting capture!\n");
487 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
488 return -EINVAL;
489 }
490
491 /* you're live! sit back and await interrupts :) */
492 atomic_inc(&cx->capturing);
493 return 0;
494}
495
496void cx18_stop_all_captures(struct cx18 *cx)
497{
498 int i;
499
500 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
501 struct cx18_stream *s = &cx->streams[i];
502
503 if (s->v4l2dev == NULL && s->dvb.enabled == 0)
504 continue;
505 if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
506 cx18_stop_v4l2_encode_stream(s, 0);
507 }
508}
509
510int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
511{
512 struct cx18 *cx = s->cx;
513 unsigned long then;
514
515 if (s->v4l2dev == NULL && s->dvb.enabled == 0)
516 return -EINVAL;
517
518 /* This function assumes that you are allowed to stop the capture
519 and that we are actually capturing */
520
521 CX18_DEBUG_INFO("Stop Capture\n");
522
523 if (atomic_read(&cx->capturing) == 0)
524 return 0;
525
526 if (s->type == CX18_ENC_STREAM_TYPE_MPG)
527 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end);
528 else
529 cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle);
530
531 then = jiffies;
532
533 if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) {
534 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
535 }
536
537 atomic_dec(&cx->capturing);
538
539 /* Clear capture and no-read bits */
540 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
541
542 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
543 s->handle = 0xffffffff;
544
545 if (atomic_read(&cx->capturing) > 0)
546 return 0;
547
548 write_reg(5, CX18_DSP0_INTERRUPT_MASK);
549 wake_up(&s->waitq);
550
551 return 0;
552}
553
554u32 cx18_find_handle(struct cx18 *cx)
555{
556 int i;
557
558 /* find first available handle to be used for global settings */
559 for (i = 0; i < CX18_MAX_STREAMS; i++) {
560 struct cx18_stream *s = &cx->streams[i];
561
562 if (s->v4l2dev && s->handle)
563 return s->handle;
564 }
565 return 0;
566}
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
new file mode 100644
index 000000000000..8c7ba7d2fa79
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -0,0 +1,33 @@
1/*
2 * cx18 init/start/stop/exit stream functions
3 *
4 * Derived from ivtv-streams.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24u32 cx18_find_handle(struct cx18 *cx);
25int cx18_streams_setup(struct cx18 *cx);
26int cx18_streams_register(struct cx18 *cx);
27void cx18_streams_cleanup(struct cx18 *cx);
28
29/* Capture related */
30int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
31int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end);
32
33void cx18_stop_all_captures(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
new file mode 100644
index 000000000000..22e76ee3f447
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -0,0 +1,208 @@
1/*
2 * cx18 Vertical Blank Interval support functions
3 *
4 * Derived from ivtv-vbi.c
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24#include "cx18-driver.h"
25#include "cx18-vbi.h"
26#include "cx18-ioctl.h"
27#include "cx18-queue.h"
28#include "cx18-av-core.h"
29
30static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
31{
32 int line = 0;
33 int i;
34 u32 linemask[2] = { 0, 0 };
35 unsigned short size;
36 static const u8 mpeg_hdr_data[] = {
37 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
38 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
39 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
40 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
41 };
42 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
43 int idx = cx->vbi.frame % CX18_VBI_FRAMES;
44 u8 *dst = &cx->vbi.sliced_mpeg_data[idx][0];
45
46 for (i = 0; i < lines; i++) {
47 struct v4l2_sliced_vbi_data *sdata = cx->vbi.sliced_data + i;
48 int f, l;
49
50 if (sdata->id == 0)
51 continue;
52
53 l = sdata->line - 6;
54 f = sdata->field;
55 if (f)
56 l += 18;
57 if (l < 32)
58 linemask[0] |= (1 << l);
59 else
60 linemask[1] |= (1 << (l - 32));
61 dst[sd + 12 + line * 43] = cx18_service2vbi(sdata->id);
62 memcpy(dst + sd + 12 + line * 43 + 1, sdata->data, 42);
63 line++;
64 }
65 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
66 if (line == 36) {
67 /* All lines are used, so there is no space for the linemask
68 (the max size of the VBI data is 36 * 43 + 4 bytes).
69 So in this case we use the magic number 'ITV0'. */
70 memcpy(dst + sd, "ITV0", 4);
71 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
72 size = 4 + ((43 * line + 3) & ~3);
73 } else {
74 memcpy(dst + sd, "cx0", 4);
75 memcpy(dst + sd + 4, &linemask[0], 8);
76 size = 12 + ((43 * line + 3) & ~3);
77 }
78 dst[4+16] = (size + 10) >> 8;
79 dst[5+16] = (size + 10) & 0xff;
80 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
81 dst[10+16] = (pts_stamp >> 22) & 0xff;
82 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
83 dst[12+16] = (pts_stamp >> 7) & 0xff;
84 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
85 cx->vbi.sliced_mpeg_size[idx] = sd + size;
86}
87
88/* Compress raw VBI format, removes leading SAV codes and surplus space
89 after the field.
90 Returns new compressed size. */
91static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
92{
93 u32 line_size = cx->vbi.raw_decoder_line_size;
94 u32 lines = cx->vbi.count;
95 u8 sav1 = cx->vbi.raw_decoder_sav_odd_field;
96 u8 sav2 = cx->vbi.raw_decoder_sav_even_field;
97 u8 *q = buf;
98 u8 *p;
99 int i;
100
101 for (i = 0; i < lines; i++) {
102 p = buf + i * line_size;
103
104 /* Look for SAV code */
105 if (p[0] != 0xff || p[1] || p[2] ||
106 (p[3] != sav1 && p[3] != sav2))
107 break;
108 memcpy(q, p + 4, line_size - 4);
109 q += line_size - 4;
110 }
111 return lines * (line_size - 4);
112}
113
114
115/* Compressed VBI format, all found sliced blocks put next to one another
116 Returns new compressed size */
117static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
118 u32 size, u8 sav)
119{
120 u32 line_size = cx->vbi.sliced_decoder_line_size;
121 struct v4l2_decode_vbi_line vbi;
122 int i;
123
124 /* find the first valid line */
125 for (i = 0; i < size; i++, buf++) {
126 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
127 break;
128 }
129
130 size -= i;
131 if (size < line_size)
132 return line;
133 for (i = 0; i < size / line_size; i++) {
134 u8 *p = buf + i * line_size;
135
136 /* Look for SAV code */
137 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav)
138 continue;
139 vbi.p = p + 4;
140 cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
141 if (vbi.type) {
142 cx->vbi.sliced_data[line].id = vbi.type;
143 cx->vbi.sliced_data[line].field = vbi.is_second_field;
144 cx->vbi.sliced_data[line].line = vbi.line;
145 memcpy(cx->vbi.sliced_data[line].data, vbi.p, 42);
146 line++;
147 }
148 }
149 return line;
150}
151
152void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
153 u64 pts_stamp, int streamtype)
154{
155 u8 *p = (u8 *) buf->buf;
156 u32 size = buf->bytesused;
157 int lines;
158
159 if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
160 return;
161
162 /* Raw VBI data */
163 if (cx->vbi.sliced_in->service_set == 0) {
164 u8 type;
165
166 cx18_buf_swap(buf);
167
168 type = p[3];
169
170 size = buf->bytesused = compress_raw_buf(cx, p, size);
171
172 /* second field of the frame? */
173 if (type == cx->vbi.raw_decoder_sav_even_field) {
174 /* Dirty hack needed for backwards
175 compatibility of old VBI software. */
176 p += size - 4;
177 memcpy(p, &cx->vbi.frame, 4);
178 cx->vbi.frame++;
179 }
180 return;
181 }
182
183 /* Sliced VBI data with data insertion */
184 cx18_buf_swap(buf);
185
186 /* first field */
187 lines = compress_sliced_buf(cx, 0, p, size / 2,
188 cx->vbi.sliced_decoder_sav_odd_field);
189 /* second field */
190 /* experimentation shows that the second half does not always
191 begin at the exact address. So start a bit earlier
192 (hence 32). */
193 lines = compress_sliced_buf(cx, lines, p + size / 2 - 32,
194 size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field);
195 /* always return at least one empty line */
196 if (lines == 0) {
197 cx->vbi.sliced_data[0].id = 0;
198 cx->vbi.sliced_data[0].line = 0;
199 cx->vbi.sliced_data[0].field = 0;
200 lines = 1;
201 }
202 buf->bytesused = size = lines * sizeof(cx->vbi.sliced_data[0]);
203 memcpy(p, &cx->vbi.sliced_data[0], size);
204
205 if (cx->vbi.insert_mpeg)
206 copy_vbi_data(cx, lines, pts_stamp);
207 cx->vbi.frame++;
208}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
new file mode 100644
index 000000000000..c56ff7d28f20
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-vbi.h
@@ -0,0 +1,26 @@
1/*
2 * cx18 Vertical Blank Interval support functions
3 *
4 * Derived from ivtv-vbi.h
5 *
6 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 * 02111-1307 USA
22 */
23
24void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
25 u64 pts_stamp, int streamtype);
26int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
new file mode 100644
index 000000000000..d5c7a6f968dd
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -0,0 +1,34 @@
1/*
2 * cx18 driver version information
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef CX18_VERSION_H
23#define CX18_VERSION_H
24
25#define CX18_DRIVER_NAME "cx18"
26#define CX18_DRIVER_VERSION_MAJOR 1
27#define CX18_DRIVER_VERSION_MINOR 0
28#define CX18_DRIVER_VERSION_PATCHLEVEL 0
29
30#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
31#define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \
32 CX18_DRIVER_VERSION_MINOR, CX18_DRIVER_VERSION_PATCHLEVEL)
33
34#endif
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c
new file mode 100644
index 000000000000..2e5c41939330
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-video.c
@@ -0,0 +1,45 @@
1/*
2 * cx18 video interface functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#include "cx18-driver.h"
23#include "cx18-video.h"
24#include "cx18-av-core.h"
25#include "cx18-cards.h"
26
27void cx18_video_set_io(struct cx18 *cx)
28{
29 struct v4l2_routing route;
30 int inp = cx->active_input;
31 u32 type;
32
33 route.input = cx->card->video_inputs[inp].video_input;
34 route.output = 0;
35 cx18_av_cmd(cx, VIDIOC_INT_S_VIDEO_ROUTING, &route);
36
37 type = cx->card->video_inputs[inp].video_type;
38
39 if (type == CX18_CARD_INPUT_VID_TUNER)
40 route.input = 0; /* Tuner */
41 else if (type < CX18_CARD_INPUT_COMPOSITE1)
42 route.input = 2; /* S-Video */
43 else
44 route.input = 1; /* Composite */
45}
diff --git a/drivers/media/video/cx18/cx18-video.h b/drivers/media/video/cx18/cx18-video.h
new file mode 100644
index 000000000000..529006a06e5c
--- /dev/null
+++ b/drivers/media/video/cx18/cx18-video.h
@@ -0,0 +1,22 @@
1/*
2 * cx18 video interface functions
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22void cx18_video_set_io(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
new file mode 100644
index 000000000000..33f78da9dba8
--- /dev/null
+++ b/drivers/media/video/cx18/cx23418.h
@@ -0,0 +1,458 @@
1/*
2 * cx18 header containing common defines.
3 *
4 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 */
21
22#ifndef CX23418_H
23#define CX23418_H
24
25#include <media/cx2341x.h>
26
27#define MGR_CMD_MASK 0x40000000
28/* The MSB of the command code indicates that this is the completion of a
29 command */
30#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000)
31
32/* Description: This command creates a new instance of a certain task
33 IN[0] - Task ID. This is one of the XPU_CMD_MASK_YYY where XPU is
34 the processor on which the task YYY will be created
35 OUT[0] - Task handle. This handle is passed along with commands to
36 dispatch to the right instance of the task
37 ReturnCode - One of the ERR_SYS_... */
38#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001)
39
40/* Description: This command destroys an instance of a task
41 IN[0] - Task handle. Hanlde of the task to destroy
42 ReturnCode - One of the ERR_SYS_... */
43#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002)
44
45/* All commands for CPU have the following mask set */
46#define CPU_CMD_MASK 0x20000000
47#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000)
48#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000)
49#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000)
50
51#define EPU_CMD_MASK 0x02000000
52#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000)
53#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000)
54
55/* Description: This command indicates that a Memory Descriptor List has been
56 filled with the requested channel type
57 IN[0] - Task handle. Handle of the task
58 IN[1] - Offset of the MDL_ACK from the beginning of the local DDR.
59 IN[2] - Number of CNXT_MDL_ACK structures in the array pointed to by IN[1]
60 ReturnCode - One of the ERR_DE_... */
61#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001)
62
63/* Something interesting happened
64 IN[0] - A value to log
65 IN[1] - An offset of a string in the MiniMe memory;
66 0/zero/NULL means "I have nothing to say" */
67#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003)
68
69/* Description: This command starts streaming with the set channel type
70 IN[0] - Task handle. Handle of the task to start
71 ReturnCode - One of the ERR_CAPTURE_... */
72#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002)
73
74/* Description: This command stops streaming with the set channel type
75 IN[0] - Task handle. Handle of the task to stop
76 IN[1] - 0 = stop at end of GOP, 1 = stop at end of frame (MPEG only)
77 ReturnCode - One of the ERR_CAPTURE_... */
78#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003)
79
80/* Description: This command pauses streaming with the set channel type
81 IN[0] - Task handle. Handle of the task to pause
82 ReturnCode - One of the ERR_CAPTURE_... */
83#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007)
84
85/* Description: This command resumes streaming with the set channel type
86 IN[0] - Task handle. Handle of the task to resume
87 ReturnCode - One of the ERR_CAPTURE_... */
88#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008)
89
90#define CAPTURE_CHANNEL_TYPE_NONE 0
91#define CAPTURE_CHANNEL_TYPE_MPEG 1
92#define CAPTURE_CHANNEL_TYPE_INDEX 2
93#define CAPTURE_CHANNEL_TYPE_YUV 3
94#define CAPTURE_CHANNEL_TYPE_PCM 4
95#define CAPTURE_CHANNEL_TYPE_VBI 5
96#define CAPTURE_CHANNEL_TYPE_SLICED_VBI 6
97#define CAPTURE_CHANNEL_TYPE_TS 7
98#define CAPTURE_CHANNEL_TYPE_MAX 15
99
100/* Description: This command sets the channel type. This can only be done
101 when stopped.
102 IN[0] - Task handle. Handle of the task to start
103 IN[1] - Channel Type. See Below.
104 ReturnCode - One of the ERR_CAPTURE_... */
105#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1)
106
107/* Description: Set stream output type
108 IN[0] - task handle. Handle of the task to start
109 IN[1] - type
110 ReturnCode - One of the ERR_CAPTURE_... */
111#define CX18_CPU_SET_STREAM_OUTPUT_TYPE (CPU_CMD_MASK_CAPTURE | 0x0012)
112
113/* Description: Set video input resolution and frame rate
114 IN[0] - task handle
115 IN[1] - reserved
116 IN[2] - reserved
117 IN[3] - reserved
118 IN[4] - reserved
119 IN[5] - frame rate, 0 - 29.97f/s, 1 - 25f/s
120 ReturnCode - One of the ERR_CAPTURE_... */
121#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004)
122
123/* Description: Set video frame rate
124 IN[0] - task handle. Handle of the task to start
125 IN[1] - video bit rate mode
126 IN[2] - video average rate
127 IN[3] - video peak rate
128 IN[4] - system mux rate
129 ReturnCode - One of the ERR_CAPTURE_... */
130#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005)
131
132/* Description: Set video output resolution
133 IN[0] - task handle
134 IN[1] - horizontal size
135 IN[2] - vertical size
136 ReturnCode - One of the ERR_CAPTURE_... */
137#define CX18_CPU_SET_VIDEO_RESOLUTION (CPU_CMD_MASK_CAPTURE | 0x0006)
138
139/* Description: This command set filter parameters
140 IN[0] - Task handle. Handle of the task
141 IN[1] - type, 0 - temporal, 1 - spatial, 2 - median
142 IN[2] - mode, temporal/spatial: 0 - disable, 1 - static, 2 - dynamic
143 median: 0 = disable, 1 = horizontal, 2 = vertical,
144 3 = horizontal/vertical, 4 = diagonal
145 IN[3] - strength, temporal 0 - 31, spatial 0 - 15
146 ReturnCode - One of the ERR_CAPTURE_... */
147#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009)
148
149/* Description: This command set spatial filter type
150 IN[0] - Task handle.
151 IN[1] - luma type: 0 = disable, 1 = 1D horizontal only, 2 = 1D vertical only,
152 3 = 2D H/V separable, 4 = 2D symmetric non-separable
153 IN[2] - chroma type: 0 - diable, 1 = 1D horizontal
154 ReturnCode - One of the ERR_CAPTURE_... */
155#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C)
156
157/* Description: This command set coring levels for median filter
158 IN[0] - Task handle.
159 IN[1] - luma_high
160 IN[2] - luma_low
161 IN[3] - chroma_high
162 IN[4] - chroma_low
163 ReturnCode - One of the ERR_CAPTURE_... */
164#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E)
165
166/* Description: This command set the picture type mask for index file
167 IN[0] - 0 = disable index file output
168 1 = output I picture
169 2 = P picture
170 4 = B picture
171 other = illegal */
172#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010)
173
174/* Description: Set audio parameters
175 IN[0] - task handle. Handle of the task to start
176 IN[1] - audio parameter
177 ReturnCode - One of the ERR_CAPTURE_... */
178#define CX18_CPU_SET_AUDIO_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0011)
179
180/* Description: Set video mute
181 IN[0] - task handle. Handle of the task to start
182 IN[1] - bit31-24: muteYvalue
183 bit23-16: muteUvalue
184 bit15-8: muteVvalue
185 bit0: 1:mute, 0: unmute
186 ReturnCode - One of the ERR_CAPTURE_... */
187#define CX18_CPU_SET_VIDEO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0013)
188
189/* Description: Set audio mute
190 IN[0] - task handle. Handle of the task to start
191 IN[1] - mute/unmute
192 ReturnCode - One of the ERR_CAPTURE_... */
193#define CX18_CPU_SET_AUDIO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0014)
194
195/* Description: Set stream output type
196 IN[0] - task handle. Handle of the task to start
197 IN[1] - subType
198 SET_INITIAL_SCR 1
199 SET_QUALITY_MODE 2
200 SET_VIM_PROTECT_MODE 3
201 SET_PTS_CORRECTION 4
202 SET_USB_FLUSH_MODE 5
203 SET_MERAQPAR_ENABLE 6
204 SET_NAV_PACK_INSERTION 7
205 SET_SCENE_CHANGE_ENABLE 8
206 IN[2] - parameter 1
207 IN[3] - parameter 2
208 ReturnCode - One of the ERR_CAPTURE_... */
209#define CX18_CPU_SET_MISC_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0015)
210
211/* Description: Set raw VBI parameters
212 IN[0] - Task handle
213 IN[1] - No. of input lines per field:
214 bit[15:0]: field 1,
215 bit[31:16]: field 2
216 IN[2] - No. of input bytes per line
217 IN[3] - No. of output frames per transfer
218 IN[4] - start code
219 IN[5] - stop code
220 ReturnCode */
221#define CX18_CPU_SET_RAW_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0016)
222
223/* Description: Set capture line No.
224 IN[0] - task handle. Handle of the task to start
225 IN[1] - height1
226 IN[2] - height2
227 ReturnCode - One of the ERR_CAPTURE_... */
228#define CX18_CPU_SET_CAPTURE_LINE_NO (CPU_CMD_MASK_CAPTURE | 0x0017)
229
230/* Description: Set copyright
231 IN[0] - task handle. Handle of the task to start
232 IN[1] - copyright
233 ReturnCode - One of the ERR_CAPTURE_... */
234#define CX18_CPU_SET_COPYRIGHT (CPU_CMD_MASK_CAPTURE | 0x0018)
235
236/* Description: Set audio PID
237 IN[0] - task handle. Handle of the task to start
238 IN[1] - PID
239 ReturnCode - One of the ERR_CAPTURE_... */
240#define CX18_CPU_SET_AUDIO_PID (CPU_CMD_MASK_CAPTURE | 0x0019)
241
242/* Description: Set video PID
243 IN[0] - task handle. Handle of the task to start
244 IN[1] - PID
245 ReturnCode - One of the ERR_CAPTURE_... */
246#define CX18_CPU_SET_VIDEO_PID (CPU_CMD_MASK_CAPTURE | 0x001A)
247
248/* Description: Set Vertical Crop Line
249 IN[0] - task handle. Handle of the task to start
250 IN[1] - Line
251 ReturnCode - One of the ERR_CAPTURE_... */
252#define CX18_CPU_SET_VER_CROP_LINE (CPU_CMD_MASK_CAPTURE | 0x001B)
253
254/* Description: Set COP structure
255 IN[0] - task handle. Handle of the task to start
256 IN[1] - M
257 IN[2] - N
258 ReturnCode - One of the ERR_CAPTURE_... */
259#define CX18_CPU_SET_GOP_STRUCTURE (CPU_CMD_MASK_CAPTURE | 0x001C)
260
261/* Description: Set Scene Change Detection
262 IN[0] - task handle. Handle of the task to start
263 IN[1] - scene change
264 ReturnCode - One of the ERR_CAPTURE_... */
265#define CX18_CPU_SET_SCENE_CHANGE_DETECTION (CPU_CMD_MASK_CAPTURE | 0x001D)
266
267/* Description: Set Aspect Ratio
268 IN[0] - task handle. Handle of the task to start
269 IN[1] - AspectRatio
270 ReturnCode - One of the ERR_CAPTURE_... */
271#define CX18_CPU_SET_ASPECT_RATIO (CPU_CMD_MASK_CAPTURE | 0x001E)
272
273/* Description: Set Skip Input Frame
274 IN[0] - task handle. Handle of the task to start
275 IN[1] - skip input frames
276 ReturnCode - One of the ERR_CAPTURE_... */
277#define CX18_CPU_SET_SKIP_INPUT_FRAME (CPU_CMD_MASK_CAPTURE | 0x001F)
278
279/* Description: Set sliced VBI parameters -
280 Note This API will only apply to MPEG and Sliced VBI Channels
281 IN[0] - Task handle
282 IN[1] - output type, 0 - CC, 1 - Moji, 2 - Teletext
283 IN[2] - start / stop line
284 bit[15:0] start line number
285 bit[31:16] stop line number
286 IN[3] - number of output frames per interrupt
287 IN[4] - VBI insertion mode
288 bit 0: output user data, 1 - enable
289 bit 1: output private stream, 1 - enable
290 bit 2: mux option, 0 - in GOP, 1 - in picture
291 bit[7:0] private stream ID
292 IN[5] - insertion period while mux option is in picture
293 ReturnCode - VBI data offset */
294#define CX18_CPU_SET_SLICED_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0020)
295
296/* Description: Set the user data place holder
297 IN[0] - type of data (0 for user)
298 IN[1] - Stuffing period
299 IN[2] - ID data size in word (less than 10)
300 IN[3] - Pointer to ID buffer */
301#define CX18_CPU_SET_USERDATA_PLACE_HOLDER (CPU_CMD_MASK_CAPTURE | 0x0021)
302
303
304/* Description:
305 In[0] Task Handle
306 return parameter:
307 Out[0] Reserved
308 Out[1] Video PTS bit[32:2] of last output video frame.
309 Out[2] Video PTS bit[ 1:0] of last output video frame.
310 Out[3] Hardware Video PTS counter bit[31:0],
311 these bits get incremented on every 90kHz clock tick.
312 Out[4] Hardware Video PTS counter bit32,
313 these bits get incremented on every 90kHz clock tick.
314 ReturnCode */
315#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022)
316
317/* Below is the list of commands related to the data exchange */
318#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000)
319
320/* Description: This command provides the physical base address of the local
321 DDR as viewed by EPU
322 IN[0] - Physical offset where EPU has the local DDR mapped
323 ReturnCode - One of the ERR_DE_... */
324#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001)
325
326/* Description: This command provides the offsets in the device memory where
327 the 2 cx18_mdl_ack blocks reside
328 IN[0] - Task handle. Handle of the task to start
329 IN[1] - Offset of the first cx18_mdl_ack from the beginning of the
330 local DDR.
331 IN[2] - Offset of the second cx18_mdl_ack from the beginning of the
332 local DDR.
333 ReturnCode - One of the ERR_DE_... */
334#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002)
335
336/* Description: This command provides the offset to a Memory Descriptor List
337 IN[0] - Task handle. Handle of the task to start
338 IN[1] - Offset of the MDL from the beginning of the local DDR.
339 IN[2] - Number of cx18_mdl structures in the array pointed to by IN[1]
340 IN[3] - Buffer ID
341 IN[4] - Total buffer length
342 ReturnCode - One of the ERR_DE_... */
343#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005)
344
345/* Description: This command requests return of all current Memory
346 Descriptor Lists to the driver
347 IN[0] - Task handle. Handle of the task to start
348 ReturnCode - One of the ERR_DE_... */
349/* #define CX18_CPU_DE_ReleaseMDL (CPU_CMD_MASK_DE | 0x0006) */
350
351/* Description: This command signals the cpu that the dat buffer has been
352 consumed and ready for re-use.
353 IN[0] - Task handle. Handle of the task
354 IN[1] - Offset of the data block from the beginning of the local DDR.
355 IN[2] - Number of bytes in the data block
356 ReturnCode - One of the ERR_DE_... */
357/* #define CX18_CPU_DE_RELEASE_BUFFER (CPU_CMD_MASK_DE | 0x0007) */
358
359/* No Error / Success */
360#define CNXT_OK 0x000000
361
362/* Received unknown command */
363#define CXERR_UNK_CMD 0x000001
364
365/* First parameter in the command is invalid */
366#define CXERR_INVALID_PARAM1 0x000002
367
368/* Second parameter in the command is invalid */
369#define CXERR_INVALID_PARAM2 0x000003
370
371/* Device interface is not open/found */
372#define CXERR_DEV_NOT_FOUND 0x000004
373
374/* Requested function is not implemented/available */
375#define CXERR_NOTSUPPORTED 0x000005
376
377/* Invalid pointer is provided */
378#define CXERR_BADPTR 0x000006
379
380/* Unable to allocate memory */
381#define CXERR_NOMEM 0x000007
382
383/* Object/Link not found */
384#define CXERR_LINK 0x000008
385
386/* Device busy, command cannot be executed */
387#define CXERR_BUSY 0x000009
388
389/* File/device/handle is not open. */
390#define CXERR_NOT_OPEN 0x00000A
391
392/* Value is out of range */
393#define CXERR_OUTOFRANGE 0x00000B
394
395/* Buffer overflow */
396#define CXERR_OVERFLOW 0x00000C
397
398/* Version mismatch */
399#define CXERR_BADVER 0x00000D
400
401/* Operation timed out */
402#define CXERR_TIMEOUT 0x00000E
403
404/* Operation aborted */
405#define CXERR_ABORT 0x00000F
406
407/* Specified I2C device not found for read/write */
408#define CXERR_I2CDEV_NOTFOUND 0x000010
409
410/* Error in I2C data xfer (but I2C device is present) */
411#define CXERR_I2CDEV_XFERERR 0x000011
412
413/* Chanel changing component not ready */
414#define CXERR_CHANNELNOTREADY 0x000012
415
416/* PPU (Presensation/Decoder) mail box is corrupted */
417#define CXERR_PPU_MB_CORRUPT 0x000013
418
419/* CPU (Capture/Encoder) mail box is corrupted */
420#define CXERR_CPU_MB_CORRUPT 0x000014
421
422/* APU (Audio) mail box is corrupted */
423#define CXERR_APU_MB_CORRUPT 0x000015
424
425/* Unable to open file for reading */
426#define CXERR_FILE_OPEN_READ 0x000016
427
428/* Unable to open file for writing */
429#define CXERR_FILE_OPEN_WRITE 0x000017
430
431/* Unable to find the I2C section specified */
432#define CXERR_I2C_BADSECTION 0x000018
433
434/* Error in I2C data xfer (but I2C device is present) */
435#define CXERR_I2CDEV_DATALOW 0x000019
436
437/* Error in I2C data xfer (but I2C device is present) */
438#define CXERR_I2CDEV_CLOCKLOW 0x00001A
439
440/* No Interrupt received from HW (for I2C access) */
441#define CXERR_NO_HW_I2C_INTR 0x00001B
442
443/* RPU is not ready to accept commands! */
444#define CXERR_RPU_NOT_READY 0x00001C
445
446/* RPU is not ready to accept commands! */
447#define CXERR_RPU_NO_ACK 0x00001D
448
449/* The are no buffers ready. Try again soon! */
450#define CXERR_NODATA_AGAIN 0x00001E
451
452/* The stream is stopping. Function not alllowed now! */
453#define CXERR_STOPPING_STATUS 0x00001F
454
455/* Trying to access hardware when the power is turned OFF */
456#define CXERR_DEVPOWER_OFF 0x000020
457
458#endif /* CX23418_H */
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index ca5fbce3a909..cadf936c3673 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -4,19 +4,19 @@ config VIDEO_CX23885
4 select I2C_ALGOBIT 4 select I2C_ALGOBIT
5 select FW_LOADER 5 select FW_LOADER
6 select VIDEO_BTCX 6 select VIDEO_BTCX
7 select VIDEO_TUNER 7 select MEDIA_TUNER
8 select VIDEO_TVEEPROM 8 select VIDEO_TVEEPROM
9 select VIDEO_IR 9 select VIDEO_IR
10 select VIDEOBUF_DVB 10 select VIDEOBUF_DVB
11 select VIDEO_CX25840 11 select VIDEO_CX25840
12 select DVB_TUNER_MT2131 if !DVB_FE_CUSTOMISE 12 select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE
13 select DVB_S5H1409 if !DVB_FE_CUSTOMISE 13 select DVB_S5H1409 if !DVB_FE_CUSTOMISE
14 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 14 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
15 select DVB_PLL if !DVB_FE_CUSTOMISE 15 select DVB_PLL if !DVB_FE_CUSTOMISE
16 select TUNER_XC2028 if !DVB_FE_CUSTOMIZE 16 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
17 select TUNER_TDA8290 if !DVB_FE_CUSTOMIZE 17 select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
18 select DVB_TDA18271 if !DVB_FE_CUSTOMIZE 18 select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
19 select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE 19 select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
20 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE 20 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
21 ---help--- 21 ---help---
22 This is a video4linux driver for Conexant 23885 based 22 This is a video4linux driver for Conexant 23885 based
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index d7b0721af062..29c23b44c13c 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -3,6 +3,7 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx2
3obj-$(CONFIG_VIDEO_CX23885) += cx23885.o 3obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
4 4
5EXTRA_CFLAGS += -Idrivers/media/video 5EXTRA_CFLAGS += -Idrivers/media/video
6EXTRA_CFLAGS += -Idrivers/media/common/tuners
6EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 7EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
7EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 8EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
8 9
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 27635cdcbaf2..b0d7d6a7a4cc 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -5,7 +5,7 @@ config VIDEO_CX88
5 select FW_LOADER 5 select FW_LOADER
6 select VIDEO_BTCX 6 select VIDEO_BTCX
7 select VIDEOBUF_DMA_SG 7 select VIDEOBUF_DMA_SG
8 select VIDEO_TUNER 8 select MEDIA_TUNER
9 select VIDEO_TVEEPROM 9 select VIDEO_TVEEPROM
10 select VIDEO_IR 10 select VIDEO_IR
11 select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO 11 select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
@@ -57,7 +57,7 @@ config VIDEO_CX88_DVB
57 select DVB_NXT200X if !DVB_FE_CUSTOMISE 57 select DVB_NXT200X if !DVB_FE_CUSTOMISE
58 select DVB_CX24123 if !DVB_FE_CUSTOMISE 58 select DVB_CX24123 if !DVB_FE_CUSTOMISE
59 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 59 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
60 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 60 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
61 select DVB_S5H1411 if !DVB_FE_CUSTOMISE 61 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
62 ---help--- 62 ---help---
63 This adds support for DVB/ATSC cards based on the 63 This adds support for DVB/ATSC cards based on the
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 532cee35eb3c..6ec30f242578 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -10,5 +10,6 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
10obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o 10obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
11 11
12EXTRA_CFLAGS += -Idrivers/media/video 12EXTRA_CFLAGS += -Idrivers/media/video
13EXTRA_CFLAGS += -Idrivers/media/common/tuners
13EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 14EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
14EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 15EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 2b6b283cda15..aeba26dc0a37 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -57,6 +57,9 @@ MODULE_PARM_DESC(latency,"pci latency timer");
57/* ------------------------------------------------------------------ */ 57/* ------------------------------------------------------------------ */
58/* board config info */ 58/* board config info */
59 59
60/* If radio_type !=UNSET, radio_addr should be specified
61 */
62
60static const struct cx88_board cx88_boards[] = { 63static const struct cx88_board cx88_boards[] = {
61 [CX88_BOARD_UNKNOWN] = { 64 [CX88_BOARD_UNKNOWN] = {
62 .name = "UNKNOWN/GENERIC", 65 .name = "UNKNOWN/GENERIC",
@@ -2446,25 +2449,31 @@ EXPORT_SYMBOL_GPL(cx88_setup_xc3028);
2446static void cx88_card_setup(struct cx88_core *core) 2449static void cx88_card_setup(struct cx88_core *core)
2447{ 2450{
2448 static u8 eeprom[256]; 2451 static u8 eeprom[256];
2452 struct tuner_setup tun_setup;
2453 unsigned int mode_mask = T_RADIO |
2454 T_ANALOG_TV |
2455 T_DIGITAL_TV;
2456
2457 memset(&tun_setup, 0, sizeof(tun_setup));
2449 2458
2450 if (0 == core->i2c_rc) { 2459 if (0 == core->i2c_rc) {
2451 core->i2c_client.addr = 0xa0 >> 1; 2460 core->i2c_client.addr = 0xa0 >> 1;
2452 tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom)); 2461 tveeprom_read(&core->i2c_client, eeprom, sizeof(eeprom));
2453 } 2462 }
2454 2463
2455 switch (core->boardnr) { 2464 switch (core->boardnr) {
2456 case CX88_BOARD_HAUPPAUGE: 2465 case CX88_BOARD_HAUPPAUGE:
2457 case CX88_BOARD_HAUPPAUGE_ROSLYN: 2466 case CX88_BOARD_HAUPPAUGE_ROSLYN:
2458 if (0 == core->i2c_rc) 2467 if (0 == core->i2c_rc)
2459 hauppauge_eeprom(core,eeprom+8); 2468 hauppauge_eeprom(core, eeprom+8);
2460 break; 2469 break;
2461 case CX88_BOARD_GDI: 2470 case CX88_BOARD_GDI:
2462 if (0 == core->i2c_rc) 2471 if (0 == core->i2c_rc)
2463 gdi_eeprom(core,eeprom); 2472 gdi_eeprom(core, eeprom);
2464 break; 2473 break;
2465 case CX88_BOARD_WINFAST2000XP_EXPERT: 2474 case CX88_BOARD_WINFAST2000XP_EXPERT:
2466 if (0 == core->i2c_rc) 2475 if (0 == core->i2c_rc)
2467 leadtek_eeprom(core,eeprom); 2476 leadtek_eeprom(core, eeprom);
2468 break; 2477 break;
2469 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 2478 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
2470 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 2479 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
@@ -2474,7 +2483,7 @@ static void cx88_card_setup(struct cx88_core *core)
2474 case CX88_BOARD_HAUPPAUGE_HVR3000: 2483 case CX88_BOARD_HAUPPAUGE_HVR3000:
2475 case CX88_BOARD_HAUPPAUGE_HVR1300: 2484 case CX88_BOARD_HAUPPAUGE_HVR1300:
2476 if (0 == core->i2c_rc) 2485 if (0 == core->i2c_rc)
2477 hauppauge_eeprom(core,eeprom); 2486 hauppauge_eeprom(core, eeprom);
2478 break; 2487 break;
2479 case CX88_BOARD_KWORLD_DVBS_100: 2488 case CX88_BOARD_KWORLD_DVBS_100:
2480 cx_write(MO_GP0_IO, 0x000007f8); 2489 cx_write(MO_GP0_IO, 0x000007f8);
@@ -2555,6 +2564,35 @@ static void cx88_card_setup(struct cx88_core *core)
2555 2564
2556 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg); 2565 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
2557 } 2566 }
2567 } /*end switch() */
2568
2569
2570 /* Setup tuners */
2571 if ((core->board.radio_type != UNSET)) {
2572 tun_setup.mode_mask = T_RADIO;
2573 tun_setup.type = core->board.radio_type;
2574 tun_setup.addr = core->board.radio_addr;
2575 tun_setup.tuner_callback = cx88_tuner_callback;
2576 cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
2577 mode_mask &= ~T_RADIO;
2578 }
2579
2580 if (core->board.tuner_type != TUNER_ABSENT) {
2581 tun_setup.mode_mask = mode_mask;
2582 tun_setup.type = core->board.tuner_type;
2583 tun_setup.addr = core->board.tuner_addr;
2584 tun_setup.tuner_callback = cx88_tuner_callback;
2585
2586 cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
2587 }
2588
2589 if (core->board.tda9887_conf) {
2590 struct v4l2_priv_tun_config tda9887_cfg;
2591
2592 tda9887_cfg.tuner = TUNER_TDA9887;
2593 tda9887_cfg.priv = &core->board.tda9887_conf;
2594
2595 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg);
2558 } 2596 }
2559 2597
2560 if (core->board.tuner_type == TUNER_XC2028) { 2598 if (core->board.tuner_type == TUNER_XC2028) {
@@ -2572,6 +2610,7 @@ static void cx88_card_setup(struct cx88_core *core)
2572 ctl.fname); 2610 ctl.fname);
2573 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg); 2611 cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
2574 } 2612 }
2613 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
2575} 2614}
2576 2615
2577/* ------------------------------------------------------------------ */ 2616/* ------------------------------------------------------------------ */
@@ -2710,7 +2749,6 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
2710 if (TUNER_ABSENT != core->board.tuner_type) 2749 if (TUNER_ABSENT != core->board.tuner_type)
2711 request_module("tuner"); 2750 request_module("tuner");
2712 2751
2713 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
2714 cx88_card_setup(core); 2752 cx88_card_setup(core);
2715 cx88_ir_init(core, pci); 2753 cx88_ir_init(core, pci);
2716 2754
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index c6b44732a082..00aa7a3f1105 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -104,37 +104,7 @@ static int attach_inform(struct i2c_client *client)
104 104
105 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", 105 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
106 client->driver->driver.name, client->addr, client->name); 106 client->driver->driver.name, client->addr, client->name);
107 if (!client->driver->command)
108 return 0;
109
110 if (core->board.radio_type != UNSET) {
111 if ((core->board.radio_addr==ADDR_UNSET)||(core->board.radio_addr==client->addr)) {
112 tun_setup.mode_mask = T_RADIO;
113 tun_setup.type = core->board.radio_type;
114 tun_setup.addr = core->board.radio_addr;
115 tun_setup.tuner_callback = cx88_tuner_callback;
116 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
117 }
118 }
119 if (core->board.tuner_type != UNSET) {
120 if ((core->board.tuner_addr==ADDR_UNSET)||(core->board.tuner_addr==client->addr)) {
121
122 tun_setup.mode_mask = T_ANALOG_TV;
123 tun_setup.type = core->board.tuner_type;
124 tun_setup.addr = core->board.tuner_addr;
125 tun_setup.tuner_callback = cx88_tuner_callback;
126 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
127 }
128 }
129
130 if (core->board.tda9887_conf) {
131 struct v4l2_priv_tun_config tda9887_cfg;
132 107
133 tda9887_cfg.tuner = TUNER_TDA9887;
134 tda9887_cfg.priv = &core->board.tda9887_conf;
135
136 client->driver->command(client, TUNER_SET_CONFIG, &tda9887_cfg);
137 }
138 return 0; 108 return 0;
139} 109}
140 110
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 9caffed2b6b8..c7c2896bbd8b 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -1,7 +1,7 @@
1config VIDEO_EM28XX 1config VIDEO_EM28XX
2 tristate "Empia EM28xx USB video capture support" 2 tristate "Empia EM28xx USB video capture support"
3 depends on VIDEO_DEV && I2C && INPUT 3 depends on VIDEO_DEV && I2C && INPUT
4 select VIDEO_TUNER 4 select MEDIA_TUNER
5 select VIDEO_TVEEPROM 5 select VIDEO_TVEEPROM
6 select VIDEO_IR 6 select VIDEO_IR
7 select VIDEOBUF_VMALLOC 7 select VIDEOBUF_VMALLOC
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
index 3d1c3cc337fe..8137a8c94bfc 100644
--- a/drivers/media/video/em28xx/Makefile
+++ b/drivers/media/video/em28xx/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o
8obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o 8obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
9 9
10EXTRA_CFLAGS += -Idrivers/media/video 10EXTRA_CFLAGS += -Idrivers/media/video
11EXTRA_CFLAGS += -Idrivers/media/common/tuners
11EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 12EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
12EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 13EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
13 14
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index b6171702c4d0..eec115bf9517 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -4,7 +4,7 @@ config VIDEO_IVTV
4 select I2C_ALGOBIT 4 select I2C_ALGOBIT
5 select FW_LOADER 5 select FW_LOADER
6 select VIDEO_IR 6 select VIDEO_IR
7 select VIDEO_TUNER 7 select MEDIA_TUNER
8 select VIDEO_TVEEPROM 8 select VIDEO_TVEEPROM
9 select VIDEO_CX2341X 9 select VIDEO_CX2341X
10 select VIDEO_CX25840 10 select VIDEO_CX25840
diff --git a/drivers/media/video/ivtv/Makefile b/drivers/media/video/ivtv/Makefile
index a0389014fa88..26ce0d6eaee1 100644
--- a/drivers/media/video/ivtv/Makefile
+++ b/drivers/media/video/ivtv/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_VIDEO_IVTV) += ivtv.o
8obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o 8obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
9 9
10EXTRA_CFLAGS += -Idrivers/media/video 10EXTRA_CFLAGS += -Idrivers/media/video
11EXTRA_CFLAGS += -Idrivers/media/common/tuners
11EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 12EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
12EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 13EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
13 14
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index e908649ea37c..4fb8faefe2ce 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -40,6 +40,8 @@
40#define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \ 40#define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \
41 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART) 41 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
42 42
43#define V4L2_STD_NOT_MN (V4L2_STD_PAL|V4L2_STD_SECAM)
44
43/* usual i2c tuner addresses to probe */ 45/* usual i2c tuner addresses to probe */
44static struct ivtv_card_tuner_i2c ivtv_i2c_std = { 46static struct ivtv_card_tuner_i2c ivtv_i2c_std = {
45 .radio = { I2C_CLIENT_END }, 47 .radio = { I2C_CLIENT_END },
@@ -298,7 +300,7 @@ static const struct ivtv_card ivtv_card_mpg600 = {
298 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 }, 300 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
299 .tuners = { 301 .tuners = {
300 /* The PAL tuner is confirmed */ 302 /* The PAL tuner is confirmed */
301 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FQ1216ME }, 303 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME },
302 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, 304 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
303 }, 305 },
304 .pci_list = ivtv_pci_mpg600, 306 .pci_list = ivtv_pci_mpg600,
@@ -339,7 +341,7 @@ static const struct ivtv_card ivtv_card_mpg160 = {
339 .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 }, 341 .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 },
340 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 }, 342 .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
341 .tuners = { 343 .tuners = {
342 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FQ1216ME }, 344 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME },
343 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, 345 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
344 }, 346 },
345 .pci_list = ivtv_pci_mpg160, 347 .pci_list = ivtv_pci_mpg160,
@@ -375,7 +377,7 @@ static const struct ivtv_card ivtv_card_pg600 = {
375 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, 377 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
376 }, 378 },
377 .tuners = { 379 .tuners = {
378 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FQ1216ME }, 380 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME },
379 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, 381 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
380 }, 382 },
381 .pci_list = ivtv_pci_pg600, 383 .pci_list = ivtv_pci_pg600,
@@ -416,7 +418,7 @@ static const struct ivtv_card ivtv_card_avc2410 = {
416 on the country/region setting of the user to decide which tuner 418 on the country/region setting of the user to decide which tuner
417 is available. */ 419 is available. */
418 .tuners = { 420 .tuners = {
419 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 421 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
420 { .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP, 422 { .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP,
421 .tuner = TUNER_PHILIPS_FM1236_MK3 }, 423 .tuner = TUNER_PHILIPS_FM1236_MK3 },
422 { .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 }, 424 { .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 },
@@ -490,7 +492,7 @@ static const struct ivtv_card ivtv_card_tg5000tv = {
490 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000, 492 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
491 .composite = 0x0010, .svideo = 0x0020 }, 493 .composite = 0x0010, .svideo = 0x0020 },
492 .tuners = { 494 .tuners = {
493 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 }, 495 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
494 }, 496 },
495 .pci_list = ivtv_pci_tg5000tv, 497 .pci_list = ivtv_pci_tg5000tv,
496 .i2c = &ivtv_i2c_std, 498 .i2c = &ivtv_i2c_std,
@@ -521,7 +523,7 @@ static const struct ivtv_card ivtv_card_va2000 = {
521 { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER }, 523 { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
522 }, 524 },
523 .tuners = { 525 .tuners = {
524 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 }, 526 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
525 }, 527 },
526 .pci_list = ivtv_pci_va2000, 528 .pci_list = ivtv_pci_va2000,
527 .i2c = &ivtv_i2c_std, 529 .i2c = &ivtv_i2c_std,
@@ -565,7 +567,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc = {
565 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, 567 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
566 .f44100 = 0x4000, .f48000 = 0x8000 }, 568 .f44100 = 0x4000, .f48000 = 0x8000 },
567 .tuners = { 569 .tuners = {
568 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 570 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
569 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 571 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
570 }, 572 },
571 .pci_list = ivtv_pci_cx23416gyc, 573 .pci_list = ivtv_pci_cx23416gyc,
@@ -597,7 +599,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogr = {
597 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, 599 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
598 .f44100 = 0x4000, .f48000 = 0x8000 }, 600 .f44100 = 0x4000, .f48000 = 0x8000 },
599 .tuners = { 601 .tuners = {
600 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 602 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
601 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 603 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
602 }, 604 },
603 .i2c = &ivtv_i2c_std, 605 .i2c = &ivtv_i2c_std,
@@ -627,7 +629,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = {
627 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, 629 .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
628 .f44100 = 0x4000, .f48000 = 0x8000 }, 630 .f44100 = 0x4000, .f48000 = 0x8000 },
629 .tuners = { 631 .tuners = {
630 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 632 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
631 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 633 { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
632 }, 634 },
633 .i2c = &ivtv_i2c_std, 635 .i2c = &ivtv_i2c_std,
@@ -667,7 +669,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx = {
667 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 }, 669 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
668 .tuners = { 670 .tuners = {
669 /* This card has the Panasonic VP27 tuner */ 671 /* This card has the Panasonic VP27 tuner */
670 { .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 }, 672 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
671 }, 673 },
672 .pci_list = ivtv_pci_gv_mvprx, 674 .pci_list = ivtv_pci_gv_mvprx,
673 .i2c = &ivtv_i2c_std, 675 .i2c = &ivtv_i2c_std,
@@ -704,7 +706,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx2e = {
704 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 }, 706 .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
705 .tuners = { 707 .tuners = {
706 /* This card has the Panasonic VP27 tuner */ 708 /* This card has the Panasonic VP27 tuner */
707 { .std = V4L2_STD_525_60, .tuner = TUNER_PANASONIC_VP27 }, 709 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
708 }, 710 },
709 .pci_list = ivtv_pci_gv_mvprx2e, 711 .pci_list = ivtv_pci_gv_mvprx2e,
710 .i2c = &ivtv_i2c_std, 712 .i2c = &ivtv_i2c_std,
@@ -739,7 +741,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd = {
739 .gpio_init = { .direction = 0xf000, .initial_value = 0xA000 }, 741 .gpio_init = { .direction = 0xf000, .initial_value = 0xA000 },
740 .tuners = { 742 .tuners = {
741 /* This card has a Philips FQ1216ME MK3 tuner */ 743 /* This card has a Philips FQ1216ME MK3 tuner */
742 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 744 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
743 }, 745 },
744 .pci_list = ivtv_pci_gotview_pci_dvd, 746 .pci_list = ivtv_pci_gotview_pci_dvd,
745 .i2c = &ivtv_i2c_std, 747 .i2c = &ivtv_i2c_std,
@@ -778,7 +780,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = {
778 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 }, 780 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
779 .tuners = { 781 .tuners = {
780 /* This card has a Philips FQ1216ME MK5 tuner */ 782 /* This card has a Philips FQ1216ME MK5 tuner */
781 { .std = V4L2_STD_625_50, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, 783 { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
782 }, 784 },
783 .pci_list = ivtv_pci_gotview_pci_dvd2, 785 .pci_list = ivtv_pci_gotview_pci_dvd2,
784 .i2c = &ivtv_i2c_std, 786 .i2c = &ivtv_i2c_std,
@@ -856,7 +858,7 @@ static const struct ivtv_card ivtv_card_dctmvtvp1 = {
856 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000, 858 .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
857 .composite = 0x0010, .svideo = 0x0020}, 859 .composite = 0x0010, .svideo = 0x0020},
858 .tuners = { 860 .tuners = {
859 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FQ1286 }, 861 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
860 }, 862 },
861 .pci_list = ivtv_pci_dctmvtvp1, 863 .pci_list = ivtv_pci_dctmvtvp1,
862 .i2c = &ivtv_i2c_std, 864 .i2c = &ivtv_i2c_std,
@@ -875,6 +877,7 @@ static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = {
875static const struct ivtv_card ivtv_card_pg600v2 = { 877static const struct ivtv_card ivtv_card_pg600v2 = {
876 .type = IVTV_CARD_PG600V2, 878 .type = IVTV_CARD_PG600V2,
877 .name = "Yuan PG600-2, GotView PCI DVD Lite", 879 .name = "Yuan PG600-2, GotView PCI DVD Lite",
880 .comment = "only Composite and S-Video inputs are supported, not the tuner\n",
878 .v4l2_capabilities = IVTV_CAP_ENCODER, 881 .v4l2_capabilities = IVTV_CAP_ENCODER,
879 .hw_video = IVTV_HW_CX25840, 882 .hw_video = IVTV_HW_CX25840,
880 .hw_audio = IVTV_HW_CX25840, 883 .hw_audio = IVTV_HW_CX25840,
@@ -921,6 +924,7 @@ static const struct ivtv_card ivtv_card_club3d = {
921 }, 924 },
922 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, 925 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
923 .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, /* tuner reset */ 926 .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, /* tuner reset */
927 .xceive_pin = 12,
924 .tuners = { 928 .tuners = {
925 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, 929 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
926 }, 930 },
@@ -944,15 +948,22 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
944 .hw_video = IVTV_HW_CX25840, 948 .hw_video = IVTV_HW_CX25840,
945 .hw_audio = IVTV_HW_CX25840, 949 .hw_audio = IVTV_HW_CX25840,
946 .hw_audio_ctrl = IVTV_HW_CX25840, 950 .hw_audio_ctrl = IVTV_HW_CX25840,
947 .hw_all = IVTV_HW_CX25840 | IVTV_HW_WM8739, 951 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
948 .video_inputs = { 952 .video_inputs = {
949 { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 }, 953 { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
950 { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 }, 954 { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
955 { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
951 }, 956 },
952 .audio_inputs = { 957 .audio_inputs = {
958 { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
953 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, 959 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
954 }, 960 },
955 .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, /* enable line-in */ 961 /* enable line-in */
962 .gpio_init = { .direction = 0xe400, .initial_value = 0x4400 },
963 .xceive_pin = 10,
964 .tuners = {
965 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
966 },
956 .pci_list = ivtv_pci_avertv_mce116, 967 .pci_list = ivtv_pci_avertv_mce116,
957 .i2c = &ivtv_i2c_std, 968 .i2c = &ivtv_i2c_std,
958}; 969};
@@ -990,7 +1001,7 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = {
990 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 }, 1001 .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
991 .tuners = { 1002 .tuners = {
992 /* This card has a Partsnic PTI-5NF05 tuner */ 1003 /* This card has a Partsnic PTI-5NF05 tuner */
993 { .std = V4L2_STD_525_60, .tuner = TUNER_TCL_2002N }, 1004 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_TCL_2002N },
994 }, 1005 },
995 .pci_list = ivtv_pci_aver_pvr150, 1006 .pci_list = ivtv_pci_aver_pvr150,
996 .i2c = &ivtv_i2c_radio, 1007 .i2c = &ivtv_i2c_radio,
@@ -1058,12 +1069,48 @@ static const struct ivtv_card ivtv_card_asus_falcon2 = {
1058 }, 1069 },
1059 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER }, 1070 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER },
1060 .tuners = { 1071 .tuners = {
1061 { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FM1236_MK3 }, 1072 { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
1062 }, 1073 },
1063 .pci_list = ivtv_pci_asus_falcon2, 1074 .pci_list = ivtv_pci_asus_falcon2,
1064 .i2c = &ivtv_i2c_std, 1075 .i2c = &ivtv_i2c_std,
1065}; 1076};
1066 1077
1078/* ------------------------------------------------------------------------- */
1079
1080/* AVerMedia M104 miniPCI card */
1081
1082static const struct ivtv_card_pci_info ivtv_pci_aver_m104[] = {
1083 { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc136 },
1084 { 0, 0, 0 }
1085};
1086
1087static const struct ivtv_card ivtv_card_aver_m104 = {
1088 .type = IVTV_CARD_AVER_M104,
1089 .name = "AVerMedia M104",
1090 .comment = "Not yet supported!\n",
1091 .v4l2_capabilities = 0, /*IVTV_CAP_ENCODER,*/
1092 .hw_video = IVTV_HW_CX25840,
1093 .hw_audio = IVTV_HW_CX25840,
1094 .hw_audio_ctrl = IVTV_HW_CX25840,
1095 .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
1096 .video_inputs = {
1097 { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 },
1098 { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
1099 },
1100 .audio_inputs = {
1101 { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
1102 },
1103 .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
1104 /* enable line-in + reset tuner */
1105 .gpio_init = { .direction = 0xe400, .initial_value = 0x4000 },
1106 .xceive_pin = 10,
1107 .tuners = {
1108 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
1109 },
1110 .pci_list = ivtv_pci_aver_m104,
1111 .i2c = &ivtv_i2c_std,
1112};
1113
1067static const struct ivtv_card *ivtv_card_list[] = { 1114static const struct ivtv_card *ivtv_card_list[] = {
1068 &ivtv_card_pvr250, 1115 &ivtv_card_pvr250,
1069 &ivtv_card_pvr350, 1116 &ivtv_card_pvr350,
@@ -1089,6 +1136,7 @@ static const struct ivtv_card *ivtv_card_list[] = {
1089 &ivtv_card_asus_falcon2, 1136 &ivtv_card_asus_falcon2,
1090 &ivtv_card_aver_pvr150, 1137 &ivtv_card_aver_pvr150,
1091 &ivtv_card_aver_ezmaker, 1138 &ivtv_card_aver_ezmaker,
1139 &ivtv_card_aver_m104,
1092 1140
1093 /* Variations of standard cards but with the same PCI IDs. 1141 /* Variations of standard cards but with the same PCI IDs.
1094 These cards must come last in this list. */ 1142 These cards must come last in this list. */
@@ -1120,7 +1168,8 @@ int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input)
1120 if (index >= itv->nof_inputs) 1168 if (index >= itv->nof_inputs)
1121 return -EINVAL; 1169 return -EINVAL;
1122 input->index = index; 1170 input->index = index;
1123 strcpy(input->name, input_strs[card_input->video_type - 1]); 1171 strlcpy(input->name, input_strs[card_input->video_type - 1],
1172 sizeof(input->name));
1124 input->type = (card_input->video_type == IVTV_CARD_INPUT_VID_TUNER ? 1173 input->type = (card_input->video_type == IVTV_CARD_INPUT_VID_TUNER ?
1125 V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA); 1174 V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
1126 input->audioset = (1 << itv->nof_audio_inputs) - 1; 1175 input->audioset = (1 << itv->nof_audio_inputs) - 1;
@@ -1137,7 +1186,7 @@ int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output)
1137 if (index >= itv->card->nof_outputs) 1186 if (index >= itv->card->nof_outputs)
1138 return -EINVAL; 1187 return -EINVAL;
1139 output->index = index; 1188 output->index = index;
1140 strcpy(output->name, card_output->name); 1189 strlcpy(output->name, card_output->name, sizeof(output->name));
1141 output->type = V4L2_OUTPUT_TYPE_ANALOG; 1190 output->type = V4L2_OUTPUT_TYPE_ANALOG;
1142 output->audioset = 1; 1191 output->audioset = 1;
1143 output->std = V4L2_STD_ALL; 1192 output->std = V4L2_STD_ALL;
@@ -1156,7 +1205,8 @@ int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *audio)
1156 memset(audio, 0, sizeof(*audio)); 1205 memset(audio, 0, sizeof(*audio));
1157 if (index >= itv->nof_audio_inputs) 1206 if (index >= itv->nof_audio_inputs)
1158 return -EINVAL; 1207 return -EINVAL;
1159 strcpy(audio->name, input_strs[aud_input->audio_type - 1]); 1208 strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
1209 sizeof(audio->name));
1160 audio->index = index; 1210 audio->index = index;
1161 audio->capability = V4L2_AUDCAP_STEREO; 1211 audio->capability = V4L2_AUDCAP_STEREO;
1162 return 0; 1212 return 0;
@@ -1167,6 +1217,6 @@ int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *aud
1167 memset(aud_output, 0, sizeof(*aud_output)); 1217 memset(aud_output, 0, sizeof(*aud_output));
1168 if (itv->card->video_outputs == NULL || index != 0) 1218 if (itv->card->video_outputs == NULL || index != 0)
1169 return -EINVAL; 1219 return -EINVAL;
1170 strcpy(aud_output->name, "A/V Audio Out"); 1220 strlcpy(aud_output->name, "A/V Audio Out", sizeof(aud_output->name));
1171 return 0; 1221 return 0;
1172} 1222}
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 9186fa2ee5fc..748485dcebbd 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -48,7 +48,8 @@
48#define IVTV_CARD_ASUS_FALCON2 21 /* ASUS Falcon2 */ 48#define IVTV_CARD_ASUS_FALCON2 21 /* ASUS Falcon2 */
49#define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */ 49#define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */
50#define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */ 50#define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */
51#define IVTV_CARD_LAST 23 51#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */
52#define IVTV_CARD_LAST 24
52 53
53/* Variants of existing cards but with the same PCI IDs. The driver 54/* Variants of existing cards but with the same PCI IDs. The driver
54 detects these based on other device information. 55 detects these based on other device information.
@@ -244,6 +245,7 @@ struct ivtv_card_tuner_i2c {
244struct ivtv_card { 245struct ivtv_card {
245 int type; 246 int type;
246 char *name; 247 char *name;
248 char *comment;
247 u32 v4l2_capabilities; 249 u32 v4l2_capabilities;
248 u32 hw_video; /* hardware used to process video */ 250 u32 hw_video; /* hardware used to process video */
249 u32 hw_audio; /* hardware used to process audio */ 251 u32 hw_audio; /* hardware used to process audio */
@@ -256,6 +258,7 @@ struct ivtv_card {
256 int nof_outputs; 258 int nof_outputs;
257 const struct ivtv_card_output *video_outputs; 259 const struct ivtv_card_output *video_outputs;
258 u8 gr_config; /* config byte for the ghost reduction device */ 260 u8 gr_config; /* config byte for the ghost reduction device */
261 u8 xceive_pin; /* XCeive tuner GPIO reset pin */
259 262
260 /* GPIO card-specific settings */ 263 /* GPIO card-specific settings */
261 struct ivtv_gpio_init gpio_init; 264 struct ivtv_gpio_init gpio_init;
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 065df53f80fd..47b5649729df 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -190,6 +190,7 @@ MODULE_PARM_DESC(cardtype,
190 "\t\t\t22 = ASUS Falcon2\n" 190 "\t\t\t22 = ASUS Falcon2\n"
191 "\t\t\t23 = AverMedia PVR-150 Plus\n" 191 "\t\t\t23 = AverMedia PVR-150 Plus\n"
192 "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n" 192 "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n"
193 "\t\t\t25 = AverMedia M104 (not yet working)\n"
193 "\t\t\t 0 = Autodetect (default)\n" 194 "\t\t\t 0 = Autodetect (default)\n"
194 "\t\t\t-1 = Ignore this card\n\t\t"); 195 "\t\t\t-1 = Ignore this card\n\t\t");
195MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60"); 196MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
@@ -871,7 +872,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
871 unsigned i; 872 unsigned i;
872 873
873 /* load modules */ 874 /* load modules */
874#ifndef CONFIG_VIDEO_TUNER 875#ifndef CONFIG_MEDIA_TUNER
875 hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER); 876 hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
876#endif 877#endif
877#ifndef CONFIG_VIDEO_CX25840 878#ifndef CONFIG_VIDEO_CX25840
@@ -1097,6 +1098,13 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1097 The PCI IDs are not always reliable. */ 1098 The PCI IDs are not always reliable. */
1098 ivtv_process_eeprom(itv); 1099 ivtv_process_eeprom(itv);
1099 } 1100 }
1101 if (itv->card->comment)
1102 IVTV_INFO("%s", itv->card->comment);
1103 if (itv->card->v4l2_capabilities == 0) {
1104 /* card was detected but is not supported */
1105 retval = -ENODEV;
1106 goto free_i2c;
1107 }
1100 1108
1101 if (itv->std == 0) { 1109 if (itv->std == 0) {
1102 itv->std = V4L2_STD_NTSC_M; 1110 itv->std = V4L2_STD_NTSC_M;
@@ -1195,13 +1203,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1195 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std); 1203 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std);
1196 } 1204 }
1197 1205
1198 retval = ivtv_streams_setup(itv);
1199 if (retval) {
1200 IVTV_ERR("Error %d setting up streams\n", retval);
1201 goto free_i2c;
1202 }
1203
1204 IVTV_DEBUG_IRQ("Masking interrupts\n");
1205 /* clear interrupt mask, effectively disabling interrupts */ 1206 /* clear interrupt mask, effectively disabling interrupts */
1206 ivtv_set_irq_mask(itv, 0xffffffff); 1207 ivtv_set_irq_mask(itv, 0xffffffff);
1207 1208
@@ -1210,32 +1211,38 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1210 IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv); 1211 IRQF_SHARED | IRQF_DISABLED, itv->name, (void *)itv);
1211 if (retval) { 1212 if (retval) {
1212 IVTV_ERR("Failed to register irq %d\n", retval); 1213 IVTV_ERR("Failed to register irq %d\n", retval);
1213 goto free_streams; 1214 goto free_i2c;
1215 }
1216
1217 retval = ivtv_streams_setup(itv);
1218 if (retval) {
1219 IVTV_ERR("Error %d setting up streams\n", retval);
1220 goto free_irq;
1214 } 1221 }
1215 retval = ivtv_streams_register(itv); 1222 retval = ivtv_streams_register(itv);
1216 if (retval) { 1223 if (retval) {
1217 IVTV_ERR("Error %d registering devices\n", retval); 1224 IVTV_ERR("Error %d registering devices\n", retval);
1218 goto free_irq; 1225 goto free_streams;
1219 } 1226 }
1220 IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); 1227 IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
1221 return 0; 1228 return 0;
1222 1229
1223 free_irq: 1230free_streams:
1224 free_irq(itv->dev->irq, (void *)itv);
1225 free_streams:
1226 ivtv_streams_cleanup(itv); 1231 ivtv_streams_cleanup(itv);
1227 free_i2c: 1232free_irq:
1233 free_irq(itv->dev->irq, (void *)itv);
1234free_i2c:
1228 exit_ivtv_i2c(itv); 1235 exit_ivtv_i2c(itv);
1229 free_io: 1236free_io:
1230 ivtv_iounmap(itv); 1237 ivtv_iounmap(itv);
1231 free_mem: 1238free_mem:
1232 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); 1239 release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
1233 release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); 1240 release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
1234 if (itv->has_cx23415) 1241 if (itv->has_cx23415)
1235 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); 1242 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
1236 free_workqueue: 1243free_workqueue:
1237 destroy_workqueue(itv->irq_work_queues); 1244 destroy_workqueue(itv->irq_work_queues);
1238 err: 1245err:
1239 if (retval == 0) 1246 if (retval == 0)
1240 retval = -ENODEV; 1247 retval = -ENODEV;
1241 IVTV_ERR("Error %d on initialization\n", retval); 1248 IVTV_ERR("Error %d on initialization\n", retval);
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index 688cd3856685..d8ac09f3cce6 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -128,20 +128,17 @@ int ivtv_reset_tuner_gpio(void *dev, int cmd, int value)
128{ 128{
129 struct i2c_algo_bit_data *algo = dev; 129 struct i2c_algo_bit_data *algo = dev;
130 struct ivtv *itv = algo->data; 130 struct ivtv *itv = algo->data;
131 int curdir, curout; 131 u32 curout;
132 132
133 if (cmd != XC2028_TUNER_RESET) 133 if (cmd != XC2028_TUNER_RESET)
134 return 0; 134 return 0;
135 IVTV_DEBUG_INFO("Resetting tuner\n"); 135 IVTV_DEBUG_INFO("Resetting tuner\n");
136 curout = read_reg(IVTV_REG_GPIO_OUT); 136 curout = read_reg(IVTV_REG_GPIO_OUT);
137 curdir = read_reg(IVTV_REG_GPIO_DIR); 137 curout &= ~(1 << itv->card->xceive_pin);
138 curdir |= (1 << 12); /* GPIO bit 12 */
139
140 curout &= ~(1 << 12);
141 write_reg(curout, IVTV_REG_GPIO_OUT); 138 write_reg(curout, IVTV_REG_GPIO_OUT);
142 schedule_timeout_interruptible(msecs_to_jiffies(1)); 139 schedule_timeout_interruptible(msecs_to_jiffies(1));
143 140
144 curout |= (1 << 12); 141 curout |= 1 << itv->card->xceive_pin;
145 write_reg(curout, IVTV_REG_GPIO_OUT); 142 write_reg(curout, IVTV_REG_GPIO_OUT);
146 schedule_timeout_interruptible(msecs_to_jiffies(1)); 143 schedule_timeout_interruptible(msecs_to_jiffies(1));
147 return 0; 144 return 0;
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 9824eafee021..771adf47e944 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -167,7 +167,8 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
167 return -1; 167 return -1;
168 id = hw_driverids[idx]; 168 id = hw_driverids[idx];
169 memset(&info, 0, sizeof(info)); 169 memset(&info, 0, sizeof(info));
170 strcpy(info.driver_name, hw_drivernames[idx]); 170 strlcpy(info.driver_name, hw_drivernames[idx],
171 sizeof(info.driver_name));
171 info.addr = hw_addrs[idx]; 172 info.addr = hw_addrs[idx];
172 for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {} 173 for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {}
173 174
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 15cac1812122..d508b5d0538c 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -243,20 +243,31 @@ static int ivtv_validate_speed(int cur_speed, int new_speed)
243 int fact = new_speed < 0 ? -1 : 1; 243 int fact = new_speed < 0 ? -1 : 1;
244 int s; 244 int s;
245 245
246 if (new_speed < 0) new_speed = -new_speed; 246 if (cur_speed == 0)
247 if (cur_speed < 0) cur_speed = -cur_speed; 247 cur_speed = 1000;
248 if (new_speed < 0)
249 new_speed = -new_speed;
250 if (cur_speed < 0)
251 cur_speed = -cur_speed;
248 252
249 if (cur_speed <= new_speed) { 253 if (cur_speed <= new_speed) {
250 if (new_speed > 1500) return fact * 2000; 254 if (new_speed > 1500)
251 if (new_speed > 1000) return fact * 1500; 255 return fact * 2000;
256 if (new_speed > 1000)
257 return fact * 1500;
252 } 258 }
253 else { 259 else {
254 if (new_speed >= 2000) return fact * 2000; 260 if (new_speed >= 2000)
255 if (new_speed >= 1500) return fact * 1500; 261 return fact * 2000;
256 if (new_speed >= 1000) return fact * 1000; 262 if (new_speed >= 1500)
257 } 263 return fact * 1500;
258 if (new_speed == 0) return 1000; 264 if (new_speed >= 1000)
259 if (new_speed == 1 || new_speed == 1000) return fact * new_speed; 265 return fact * 1000;
266 }
267 if (new_speed == 0)
268 return 1000;
269 if (new_speed == 1 || new_speed == 1000)
270 return fact * new_speed;
260 271
261 s = new_speed; 272 s = new_speed;
262 new_speed = 1000 / new_speed; 273 new_speed = 1000 / new_speed;
@@ -741,10 +752,9 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
741 struct v4l2_capability *vcap = arg; 752 struct v4l2_capability *vcap = arg;
742 753
743 memset(vcap, 0, sizeof(*vcap)); 754 memset(vcap, 0, sizeof(*vcap));
744 strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */ 755 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
745 strncpy(vcap->card, itv->card_name, 756 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
746 sizeof(vcap->card)-1); /* card type */ 757 strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info));
747 strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */
748 vcap->version = IVTV_DRIVER_VERSION; /* version */ 758 vcap->version = IVTV_DRIVER_VERSION; /* version */
749 vcap->capabilities = itv->v4l2_cap; /* capabilities */ 759 vcap->capabilities = itv->v4l2_cap; /* capabilities */
750 760
@@ -1018,7 +1028,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1018 ivtv_std_60hz : ivtv_std_50hz; 1028 ivtv_std_60hz : ivtv_std_50hz;
1019 vs->index = idx; 1029 vs->index = idx;
1020 vs->id = enum_stds[idx].std; 1030 vs->id = enum_stds[idx].std;
1021 strcpy(vs->name, enum_stds[idx].name); 1031 strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name));
1022 break; 1032 break;
1023 } 1033 }
1024 1034
@@ -1102,10 +1112,10 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1102 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt); 1112 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
1103 1113
1104 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { 1114 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1105 strcpy(vt->name, "ivtv Radio Tuner"); 1115 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
1106 vt->type = V4L2_TUNER_RADIO; 1116 vt->type = V4L2_TUNER_RADIO;
1107 } else { 1117 } else {
1108 strcpy(vt->name, "ivtv TV Tuner"); 1118 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
1109 vt->type = V4L2_TUNER_ANALOG_TV; 1119 vt->type = V4L2_TUNER_ANALOG_TV;
1110 } 1120 }
1111 break; 1121 break;
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index a329c4689dbf..d8ba3a4a8761 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -384,7 +384,7 @@ static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s)
384 ivtv_stream_sync_for_device(s); 384 ivtv_stream_sync_for_device(s);
385 write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR); 385 write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR);
386 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); 386 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
387 itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); 387 itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
388 add_timer(&itv->dma_timer); 388 add_timer(&itv->dma_timer);
389} 389}
390 390
@@ -400,7 +400,7 @@ static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s)
400 ivtv_stream_sync_for_device(s); 400 ivtv_stream_sync_for_device(s);
401 write_reg(s->sg_handle, IVTV_REG_DECDMAADDR); 401 write_reg(s->sg_handle, IVTV_REG_DECDMAADDR);
402 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); 402 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
403 itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); 403 itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
404 add_timer(&itv->dma_timer); 404 add_timer(&itv->dma_timer);
405} 405}
406 406
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
index 0f1d4cc4b4d9..02c5ab071d1b 100644
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ b/drivers/media/video/ivtv/ivtv-version.h
@@ -23,7 +23,7 @@
23#define IVTV_DRIVER_NAME "ivtv" 23#define IVTV_DRIVER_NAME "ivtv"
24#define IVTV_DRIVER_VERSION_MAJOR 1 24#define IVTV_DRIVER_VERSION_MAJOR 1
25#define IVTV_DRIVER_VERSION_MINOR 2 25#define IVTV_DRIVER_VERSION_MINOR 2
26#define IVTV_DRIVER_VERSION_PATCHLEVEL 0 26#define IVTV_DRIVER_VERSION_PATCHLEVEL 1
27 27
28#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL) 28#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
29#define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL) 29#define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 3b23fc05f7c4..df789f683e63 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -532,7 +532,7 @@ static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
532 532
533 IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n"); 533 IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
534 memset(fix, 0, sizeof(struct fb_fix_screeninfo)); 534 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
535 strcpy(fix->id, "cx23415 TV out"); 535 strlcpy(fix->id, "cx23415 TV out", sizeof(fix->id));
536 fix->smem_start = oi->video_pbase; 536 fix->smem_start = oi->video_pbase;
537 fix->smem_len = oi->video_buffer_size; 537 fix->smem_len = oi->video_buffer_size;
538 fix->type = FB_TYPE_PACKED_PIXELS; 538 fix->type = FB_TYPE_PACKED_PIXELS;
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
deleted file mode 100644
index fbcb28233737..000000000000
--- a/drivers/media/video/mt20xx.c
+++ /dev/null
@@ -1,670 +0,0 @@
1/*
2 * i2c tv tuner chip device driver
3 * controls microtune tuners, mt2032 + mt2050 at the moment.
4 *
5 * This "mt20xx" module was split apart from the original "tuner" module.
6 */
7#include <linux/delay.h>
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include "tuner-i2c.h"
11#include "mt20xx.h"
12
13static int debug;
14module_param(debug, int, 0644);
15MODULE_PARM_DESC(debug, "enable verbose debug messages");
16
17/* ---------------------------------------------------------------------- */
18
19static unsigned int optimize_vco = 1;
20module_param(optimize_vco, int, 0644);
21
22static unsigned int tv_antenna = 1;
23module_param(tv_antenna, int, 0644);
24
25static unsigned int radio_antenna;
26module_param(radio_antenna, int, 0644);
27
28/* ---------------------------------------------------------------------- */
29
30#define MT2032 0x04
31#define MT2030 0x06
32#define MT2040 0x07
33#define MT2050 0x42
34
35static char *microtune_part[] = {
36 [ MT2030 ] = "MT2030",
37 [ MT2032 ] = "MT2032",
38 [ MT2040 ] = "MT2040",
39 [ MT2050 ] = "MT2050",
40};
41
42struct microtune_priv {
43 struct tuner_i2c_props i2c_props;
44
45 unsigned int xogc;
46 //unsigned int radio_if2;
47
48 u32 frequency;
49};
50
51static int microtune_release(struct dvb_frontend *fe)
52{
53 kfree(fe->tuner_priv);
54 fe->tuner_priv = NULL;
55
56 return 0;
57}
58
59static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency)
60{
61 struct microtune_priv *priv = fe->tuner_priv;
62 *frequency = priv->frequency;
63 return 0;
64}
65
66// IsSpurInBand()?
67static int mt2032_spurcheck(struct dvb_frontend *fe,
68 int f1, int f2, int spectrum_from,int spectrum_to)
69{
70 struct microtune_priv *priv = fe->tuner_priv;
71 int n1=1,n2,f;
72
73 f1=f1/1000; //scale to kHz to avoid 32bit overflows
74 f2=f2/1000;
75 spectrum_from/=1000;
76 spectrum_to/=1000;
77
78 tuner_dbg("spurcheck f1=%d f2=%d from=%d to=%d\n",
79 f1,f2,spectrum_from,spectrum_to);
80
81 do {
82 n2=-n1;
83 f=n1*(f1-f2);
84 do {
85 n2--;
86 f=f-f2;
87 tuner_dbg("spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f);
88
89 if( (f>spectrum_from) && (f<spectrum_to))
90 tuner_dbg("mt2032 spurcheck triggered: %d\n",n1);
91 } while ( (f>(f2-spectrum_to)) || (n2>-5));
92 n1++;
93 } while (n1<5);
94
95 return 1;
96}
97
98static int mt2032_compute_freq(struct dvb_frontend *fe,
99 unsigned int rfin,
100 unsigned int if1, unsigned int if2,
101 unsigned int spectrum_from,
102 unsigned int spectrum_to,
103 unsigned char *buf,
104 int *ret_sel,
105 unsigned int xogc) //all in Hz
106{
107 struct microtune_priv *priv = fe->tuner_priv;
108 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
109 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
110
111 fref= 5250 *1000; //5.25MHz
112 desired_lo1=rfin+if1;
113
114 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
115 lo1n=lo1/8;
116 lo1a=lo1-(lo1n*8);
117
118 s=rfin/1000/1000+1090;
119
120 if(optimize_vco) {
121 if(s>1890) sel=0;
122 else if(s>1720) sel=1;
123 else if(s>1530) sel=2;
124 else if(s>1370) sel=3;
125 else sel=4; // >1090
126 }
127 else {
128 if(s>1790) sel=0; // <1958
129 else if(s>1617) sel=1;
130 else if(s>1449) sel=2;
131 else if(s>1291) sel=3;
132 else sel=4; // >1090
133 }
134 *ret_sel=sel;
135
136 lo1freq=(lo1a+8*lo1n)*fref;
137
138 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
139 rfin,lo1,lo1n,lo1a,sel,lo1freq);
140
141 desired_lo2=lo1freq-rfin-if2;
142 lo2=(desired_lo2)/fref;
143 lo2n=lo2/8;
144 lo2a=lo2-(lo2n*8);
145 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
146 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
147
148 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
149 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
150
151 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
152 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
153 lo1a, lo1n, lo2a,lo2n);
154 return(-1);
155 }
156
157 mt2032_spurcheck(fe, lo1freq, desired_lo2, spectrum_from, spectrum_to);
158 // should recalculate lo1 (one step up/down)
159
160 // set up MT2032 register map for transfer over i2c
161 buf[0]=lo1n-1;
162 buf[1]=lo1a | (sel<<4);
163 buf[2]=0x86; // LOGC
164 buf[3]=0x0f; //reserved
165 buf[4]=0x1f;
166 buf[5]=(lo2n-1) | (lo2a<<5);
167 if(rfin >400*1000*1000)
168 buf[6]=0xe4;
169 else
170 buf[6]=0xf4; // set PKEN per rev 1.2
171 buf[7]=8+xogc;
172 buf[8]=0xc3; //reserved
173 buf[9]=0x4e; //reserved
174 buf[10]=0xec; //reserved
175 buf[11]=(lo2num&0xff);
176 buf[12]=(lo2num>>8) |0x80; // Lo2RST
177
178 return 0;
179}
180
181static int mt2032_check_lo_lock(struct dvb_frontend *fe)
182{
183 struct microtune_priv *priv = fe->tuner_priv;
184 int try,lock=0;
185 unsigned char buf[2];
186
187 for(try=0;try<10;try++) {
188 buf[0]=0x0e;
189 tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
190 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
191 tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]);
192 lock=buf[0] &0x06;
193
194 if (lock==6)
195 break;
196
197 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
198 udelay(1000);
199 }
200 return lock;
201}
202
203static int mt2032_optimize_vco(struct dvb_frontend *fe,int sel,int lock)
204{
205 struct microtune_priv *priv = fe->tuner_priv;
206 unsigned char buf[2];
207 int tad1;
208
209 buf[0]=0x0f;
210 tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
211 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
212 tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]);
213 tad1=buf[0]&0x07;
214
215 if(tad1 ==0) return lock;
216 if(tad1 ==1) return lock;
217
218 if(tad1==2) {
219 if(sel==0)
220 return lock;
221 else sel--;
222 }
223 else {
224 if(sel<4)
225 sel++;
226 else
227 return lock;
228 }
229
230 tuner_dbg("mt2032 optimize_vco: sel=%d\n",sel);
231
232 buf[0]=0x0f;
233 buf[1]=sel;
234 tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
235 lock=mt2032_check_lo_lock(fe);
236 return lock;
237}
238
239
240static void mt2032_set_if_freq(struct dvb_frontend *fe, unsigned int rfin,
241 unsigned int if1, unsigned int if2,
242 unsigned int from, unsigned int to)
243{
244 unsigned char buf[21];
245 int lint_try,ret,sel,lock=0;
246 struct microtune_priv *priv = fe->tuner_priv;
247
248 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
249 rfin,if1,if2,from,to);
250
251 buf[0]=0;
252 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
253 tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
254
255 buf[0]=0;
256 ret=mt2032_compute_freq(fe,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc);
257 if (ret<0)
258 return;
259
260 // send only the relevant registers per Rev. 1.2
261 buf[0]=0;
262 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,4);
263 buf[5]=5;
264 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,4);
265 buf[11]=11;
266 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+11,3);
267 if(ret!=3)
268 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
269
270 // wait for PLLs to lock (per manual), retry LINT if not.
271 for(lint_try=0; lint_try<2; lint_try++) {
272 lock=mt2032_check_lo_lock(fe);
273
274 if(optimize_vco)
275 lock=mt2032_optimize_vco(fe,sel,lock);
276 if(lock==6) break;
277
278 tuner_dbg("mt2032: re-init PLLs by LINT\n");
279 buf[0]=7;
280 buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs
281 tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
282 mdelay(10);
283 buf[1]=8+priv->xogc;
284 tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
285 }
286
287 if (lock!=6)
288 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
289
290 buf[0]=2;
291 buf[1]=0x20; // LOGC for optimal phase noise
292 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
293 if (ret!=2)
294 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
295}
296
297
298static int mt2032_set_tv_freq(struct dvb_frontend *fe,
299 struct analog_parameters *params)
300{
301 int if2,from,to;
302
303 // signal bandwidth and picture carrier
304 if (params->std & V4L2_STD_525_60) {
305 // NTSC
306 from = 40750*1000;
307 to = 46750*1000;
308 if2 = 45750*1000;
309 } else {
310 // PAL
311 from = 32900*1000;
312 to = 39900*1000;
313 if2 = 38900*1000;
314 }
315
316 mt2032_set_if_freq(fe, params->frequency*62500,
317 1090*1000*1000, if2, from, to);
318
319 return 0;
320}
321
322static int mt2032_set_radio_freq(struct dvb_frontend *fe,
323 struct analog_parameters *params)
324{
325 struct microtune_priv *priv = fe->tuner_priv;
326 int if2;
327
328 if (params->std & V4L2_STD_525_60) {
329 tuner_dbg("pinnacle ntsc\n");
330 if2 = 41300 * 1000;
331 } else {
332 tuner_dbg("pinnacle pal\n");
333 if2 = 33300 * 1000;
334 }
335
336 // per Manual for FM tuning: first if center freq. 1085 MHz
337 mt2032_set_if_freq(fe, params->frequency * 125 / 2,
338 1085*1000*1000,if2,if2,if2);
339
340 return 0;
341}
342
343static int mt2032_set_params(struct dvb_frontend *fe,
344 struct analog_parameters *params)
345{
346 struct microtune_priv *priv = fe->tuner_priv;
347 int ret = -EINVAL;
348
349 switch (params->mode) {
350 case V4L2_TUNER_RADIO:
351 ret = mt2032_set_radio_freq(fe, params);
352 priv->frequency = params->frequency * 125 / 2;
353 break;
354 case V4L2_TUNER_ANALOG_TV:
355 case V4L2_TUNER_DIGITAL_TV:
356 ret = mt2032_set_tv_freq(fe, params);
357 priv->frequency = params->frequency * 62500;
358 break;
359 }
360
361 return ret;
362}
363
364static struct dvb_tuner_ops mt2032_tuner_ops = {
365 .set_analog_params = mt2032_set_params,
366 .release = microtune_release,
367 .get_frequency = microtune_get_frequency,
368};
369
370// Initialization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
371static int mt2032_init(struct dvb_frontend *fe)
372{
373 struct microtune_priv *priv = fe->tuner_priv;
374 unsigned char buf[21];
375 int ret,xogc,xok=0;
376
377 // Initialize Registers per spec.
378 buf[1]=2; // Index to register 2
379 buf[2]=0xff;
380 buf[3]=0x0f;
381 buf[4]=0x1f;
382 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+1,4);
383
384 buf[5]=6; // Index register 6
385 buf[6]=0xe4;
386 buf[7]=0x8f;
387 buf[8]=0xc3;
388 buf[9]=0x4e;
389 buf[10]=0xec;
390 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,6);
391
392 buf[12]=13; // Index register 13
393 buf[13]=0x32;
394 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+12,2);
395
396 // Adjust XOGC (register 7), wait for XOK
397 xogc=7;
398 do {
399 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
400 mdelay(10);
401 buf[0]=0x0e;
402 tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
403 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
404 xok=buf[0]&0x01;
405 tuner_dbg("mt2032: xok = 0x%02x\n",xok);
406 if (xok == 1) break;
407
408 xogc--;
409 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
410 if (xogc == 3) {
411 xogc=4; // min. 4 per spec
412 break;
413 }
414 buf[0]=0x07;
415 buf[1]=0x88 + xogc;
416 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
417 if (ret!=2)
418 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
419 } while (xok != 1 );
420 priv->xogc=xogc;
421
422 memcpy(&fe->ops.tuner_ops, &mt2032_tuner_ops, sizeof(struct dvb_tuner_ops));
423
424 return(1);
425}
426
427static void mt2050_set_antenna(struct dvb_frontend *fe, unsigned char antenna)
428{
429 struct microtune_priv *priv = fe->tuner_priv;
430 unsigned char buf[2];
431 int ret;
432
433 buf[0] = 6;
434 buf[1] = antenna ? 0x11 : 0x10;
435 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
436 tuner_dbg("mt2050: enabled antenna connector %d\n", antenna);
437}
438
439static void mt2050_set_if_freq(struct dvb_frontend *fe,unsigned int freq, unsigned int if2)
440{
441 struct microtune_priv *priv = fe->tuner_priv;
442 unsigned int if1=1218*1000*1000;
443 unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
444 int ret;
445 unsigned char buf[6];
446
447 tuner_dbg("mt2050_set_if_freq freq=%d if1=%d if2=%d\n",
448 freq,if1,if2);
449
450 f_lo1=freq+if1;
451 f_lo1=(f_lo1/1000000)*1000000;
452
453 f_lo2=f_lo1-freq-if2;
454 f_lo2=(f_lo2/50000)*50000;
455
456 lo1=f_lo1/4000000;
457 lo2=f_lo2/4000000;
458
459 f_lo1_modulo= f_lo1-(lo1*4000000);
460 f_lo2_modulo= f_lo2-(lo2*4000000);
461
462 num1=4*f_lo1_modulo/4000000;
463 num2=4096*(f_lo2_modulo/1000)/4000;
464
465 // todo spurchecks
466
467 div1a=(lo1/12)-1;
468 div1b=lo1-(div1a+1)*12;
469
470 div2a=(lo2/8)-1;
471 div2b=lo2-(div2a+1)*8;
472
473 if (debug > 1) {
474 tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
475 tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
476 num1,num2,div1a,div1b,div2a,div2b);
477 }
478
479 buf[0]=1;
480 buf[1]= 4*div1b + num1;
481 if(freq<275*1000*1000) buf[1] = buf[1]|0x80;
482
483 buf[2]=div1a;
484 buf[3]=32*div2b + num2/256;
485 buf[4]=num2-(num2/256)*256;
486 buf[5]=div2a;
487 if(num2!=0) buf[5]=buf[5]|0x40;
488
489 if (debug > 1) {
490 int i;
491 tuner_dbg("bufs is: ");
492 for(i=0;i<6;i++)
493 printk("%x ",buf[i]);
494 printk("\n");
495 }
496
497 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,6);
498 if (ret!=6)
499 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
500}
501
502static int mt2050_set_tv_freq(struct dvb_frontend *fe,
503 struct analog_parameters *params)
504{
505 unsigned int if2;
506
507 if (params->std & V4L2_STD_525_60) {
508 // NTSC
509 if2 = 45750*1000;
510 } else {
511 // PAL
512 if2 = 38900*1000;
513 }
514 if (V4L2_TUNER_DIGITAL_TV == params->mode) {
515 // DVB (pinnacle 300i)
516 if2 = 36150*1000;
517 }
518 mt2050_set_if_freq(fe, params->frequency*62500, if2);
519 mt2050_set_antenna(fe, tv_antenna);
520
521 return 0;
522}
523
524static int mt2050_set_radio_freq(struct dvb_frontend *fe,
525 struct analog_parameters *params)
526{
527 struct microtune_priv *priv = fe->tuner_priv;
528 int if2;
529
530 if (params->std & V4L2_STD_525_60) {
531 tuner_dbg("pinnacle ntsc\n");
532 if2 = 41300 * 1000;
533 } else {
534 tuner_dbg("pinnacle pal\n");
535 if2 = 33300 * 1000;
536 }
537
538 mt2050_set_if_freq(fe, params->frequency * 125 / 2, if2);
539 mt2050_set_antenna(fe, radio_antenna);
540
541 return 0;
542}
543
544static int mt2050_set_params(struct dvb_frontend *fe,
545 struct analog_parameters *params)
546{
547 struct microtune_priv *priv = fe->tuner_priv;
548 int ret = -EINVAL;
549
550 switch (params->mode) {
551 case V4L2_TUNER_RADIO:
552 ret = mt2050_set_radio_freq(fe, params);
553 priv->frequency = params->frequency * 125 / 2;
554 break;
555 case V4L2_TUNER_ANALOG_TV:
556 case V4L2_TUNER_DIGITAL_TV:
557 ret = mt2050_set_tv_freq(fe, params);
558 priv->frequency = params->frequency * 62500;
559 break;
560 }
561
562 return ret;
563}
564
565static struct dvb_tuner_ops mt2050_tuner_ops = {
566 .set_analog_params = mt2050_set_params,
567 .release = microtune_release,
568 .get_frequency = microtune_get_frequency,
569};
570
571static int mt2050_init(struct dvb_frontend *fe)
572{
573 struct microtune_priv *priv = fe->tuner_priv;
574 unsigned char buf[2];
575 int ret;
576
577 buf[0]=6;
578 buf[1]=0x10;
579 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); // power
580
581 buf[0]=0x0f;
582 buf[1]=0x0f;
583 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); // m1lo
584
585 buf[0]=0x0d;
586 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
587 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
588
589 tuner_dbg("mt2050: sro is %x\n",buf[0]);
590
591 memcpy(&fe->ops.tuner_ops, &mt2050_tuner_ops, sizeof(struct dvb_tuner_ops));
592
593 return 0;
594}
595
596struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
597 struct i2c_adapter* i2c_adap,
598 u8 i2c_addr)
599{
600 struct microtune_priv *priv = NULL;
601 char *name;
602 unsigned char buf[21];
603 int company_code;
604
605 priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL);
606 if (priv == NULL)
607 return NULL;
608 fe->tuner_priv = priv;
609
610 priv->i2c_props.addr = i2c_addr;
611 priv->i2c_props.adap = i2c_adap;
612 priv->i2c_props.name = "mt20xx";
613
614 //priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
615
616 memset(buf,0,sizeof(buf));
617
618 name = "unknown";
619
620 tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
621 tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
622 if (debug) {
623 int i;
624 tuner_dbg("MT20xx hexdump:");
625 for(i=0;i<21;i++) {
626 printk(" %02x",buf[i]);
627 if(((i+1)%8)==0) printk(" ");
628 }
629 printk("\n");
630 }
631 company_code = buf[0x11] << 8 | buf[0x12];
632 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
633 company_code,buf[0x13],buf[0x14]);
634
635
636 if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
637 NULL != microtune_part[buf[0x13]])
638 name = microtune_part[buf[0x13]];
639 switch (buf[0x13]) {
640 case MT2032:
641 mt2032_init(fe);
642 break;
643 case MT2050:
644 mt2050_init(fe);
645 break;
646 default:
647 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
648 name);
649 return NULL;
650 }
651
652 strlcpy(fe->ops.tuner_ops.info.name, name,
653 sizeof(fe->ops.tuner_ops.info.name));
654 tuner_info("microtune %s found, OK\n",name);
655 return fe;
656}
657
658EXPORT_SYMBOL_GPL(microtune_attach);
659
660MODULE_DESCRIPTION("Microtune tuner driver");
661MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
662MODULE_LICENSE("GPL");
663
664/*
665 * Overrides for Emacs so that we follow Linus's tabbing style.
666 * ---------------------------------------------------------------------------
667 * Local variables:
668 * c-basic-offset: 8
669 * End:
670 */
diff --git a/drivers/media/video/mt20xx.h b/drivers/media/video/mt20xx.h
deleted file mode 100644
index aa848e14ce5e..000000000000
--- a/drivers/media/video/mt20xx.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __MT20XX_H__
18#define __MT20XX_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23#if defined(CONFIG_TUNER_MT20XX) || (defined(CONFIG_TUNER_MT20XX_MODULE) && defined(MODULE))
24extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
25 struct i2c_adapter* i2c_adap,
26 u8 i2c_addr);
27#else
28static inline struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
29 struct i2c_adapter* i2c_adap,
30 u8 i2c_addr)
31{
32 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
33 return NULL;
34}
35#endif
36
37#endif /* __MT20XX_H__ */
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index ba09826ddf48..179e47049a45 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -372,7 +372,7 @@ static int mt9m001_set_register(struct soc_camera_device *icd,
372} 372}
373#endif 373#endif
374 374
375const struct v4l2_queryctrl mt9m001_controls[] = { 375static const struct v4l2_queryctrl mt9m001_controls[] = {
376 { 376 {
377 .id = V4L2_CID_VFLIP, 377 .id = V4L2_CID_VFLIP,
378 .type = V4L2_CTRL_TYPE_BOOLEAN, 378 .type = V4L2_CTRL_TYPE_BOOLEAN,
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 7b223691ce96..d1391ac55096 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -452,7 +452,7 @@ static int mt9v022_set_register(struct soc_camera_device *icd,
452} 452}
453#endif 453#endif
454 454
455const struct v4l2_queryctrl mt9v022_controls[] = { 455static const struct v4l2_queryctrl mt9v022_controls[] = {
456 { 456 {
457 .id = V4L2_CID_VFLIP, 457 .id = V4L2_CID_VFLIP,
458 .type = V4L2_CTRL_TYPE_BOOLEAN, 458 .type = V4L2_CTRL_TYPE_BOOLEAN,
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 158b3d0c6532..9620c67fae77 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -1,14 +1,15 @@
1config VIDEO_PVRUSB2 1config VIDEO_PVRUSB2
2 tristate "Hauppauge WinTV-PVR USB2 support" 2 tristate "Hauppauge WinTV-PVR USB2 support"
3 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL 3 depends on VIDEO_V4L2 && I2C
4 select FW_LOADER 4 select FW_LOADER
5 select VIDEO_TUNER 5 select MEDIA_TUNER
6 select VIDEO_TVEEPROM 6 select VIDEO_TVEEPROM
7 select VIDEO_CX2341X 7 select VIDEO_CX2341X
8 select VIDEO_SAA711X 8 select VIDEO_SAA711X
9 select VIDEO_CX25840 9 select VIDEO_CX25840
10 select VIDEO_MSP3400 10 select VIDEO_MSP3400
11 select VIDEO_WM8775 11 select VIDEO_WM8775
12 select VIDEO_CS53L32A
12 ---help--- 13 ---help---
13 This is a video4linux driver for Conexant 23416 based 14 This is a video4linux driver for Conexant 23416 based
14 usb2 personal video recorder devices. 15 usb2 personal video recorder devices.
@@ -16,32 +17,6 @@ config VIDEO_PVRUSB2
16 To compile this driver as a module, choose M here: the 17 To compile this driver as a module, choose M here: the
17 module will be called pvrusb2 18 module will be called pvrusb2
18 19
19config VIDEO_PVRUSB2_ONAIR_CREATOR
20 bool "pvrusb2 driver support for OnAir Creator model"
21 depends on VIDEO_PVRUSB2 && EXPERIMENTAL
22 select VIDEO_SAA711X
23 select VIDEO_CS53L32A
24 ---help---
25
26 This option enables support for the OnAir Creator USB tuner
27 device. This is a hybrid device, however currently only
28 analog mode is supported.
29
30 If you are in doubt, say Y.
31
32config VIDEO_PVRUSB2_ONAIR_USB2
33 bool "pvrusb2 driver support for OnAir USB2 model"
34 depends on VIDEO_PVRUSB2 && EXPERIMENTAL
35 select VIDEO_SAA711X
36 select VIDEO_CS53L32A
37 ---help---
38
39 This option enables support for the OnAir USB2 tuner device
40 (also known as the Sasem tuner). This is a hybrid device,
41 however currently only analog mode is supported.
42
43 If you are in doubt, say Y.
44
45config VIDEO_PVRUSB2_SYSFS 20config VIDEO_PVRUSB2_SYSFS
46 bool "pvrusb2 sysfs support (EXPERIMENTAL)" 21 bool "pvrusb2 sysfs support (EXPERIMENTAL)"
47 default y 22 default y
@@ -59,29 +34,23 @@ config VIDEO_PVRUSB2_SYSFS
59 Note: This feature is experimental and subject to change. 34 Note: This feature is experimental and subject to change.
60 35
61config VIDEO_PVRUSB2_DVB 36config VIDEO_PVRUSB2_DVB
62 bool "pvrusb2 DVB support (EXPERIMENTAL)" 37 bool "pvrusb2 ATSC/DVB support (EXPERIMENTAL)"
63 default n 38 default y
64 depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL 39 depends on VIDEO_PVRUSB2 && DVB_CORE && EXPERIMENTAL
65 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 40 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
66 select DVB_S5H1409 if !DVB_FE_CUSTOMISE 41 select DVB_S5H1409 if !DVB_FE_CUSTOMISE
67 select DVB_S5H1411 if !DVB_FE_CUSTOMISE 42 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
68 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE 43 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
69 select DVB_TDA18271 if !DVB_FE_CUSTOMIZE 44 select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
70 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 45 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
71 select TUNER_TDA8290 if !DVB_FE_CUSTOMIZE 46 select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
72 ---help--- 47 ---help---
73 48
74 This option enables compilation of a DVB interface for the 49 This option enables a DVB interface for the pvrusb2 driver.
75 pvrusb2 driver. Currently this is very very experimental. 50 If your device does not support digital television, this
76 It is also limiting - the DVB interface can only access the 51 feature will have no affect on the driver's operation.
77 digital side of hybrid devices, and there are going to be
78 issues if you attempt to mess with the V4L side at the same
79 time. Don't turn this on unless you know what you are
80 doing.
81
82 If you are in doubt, say N.
83 52
84 Note: This feature is very experimental and might break 53 If you are in doubt, say Y.
85 54
86config VIDEO_PVRUSB2_DEBUGIFC 55config VIDEO_PVRUSB2_DEBUGIFC
87 bool "pvrusb2 debug interface" 56 bool "pvrusb2 debug interface"
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
index 5b3083c89aa9..4fda2de69ab7 100644
--- a/drivers/media/video/pvrusb2/Makefile
+++ b/drivers/media/video/pvrusb2/Makefile
@@ -16,5 +16,6 @@ pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
16obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o 16obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
17 17
18EXTRA_CFLAGS += -Idrivers/media/video 18EXTRA_CFLAGS += -Idrivers/media/video
19EXTRA_CFLAGS += -Idrivers/media/common/tuners
19EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 20EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
20EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 21EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h
index 11537ddf8aa3..707d2d9635d7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debug.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-debug.h
@@ -54,6 +54,7 @@ extern int pvrusb2_debug;
54#define PVR2_TRACE_DATA_FLOW (1 << 25) /* Track data flow */ 54#define PVR2_TRACE_DATA_FLOW (1 << 25) /* Track data flow */
55#define PVR2_TRACE_DEBUGIFC (1 << 26) /* Debug interface actions */ 55#define PVR2_TRACE_DEBUGIFC (1 << 26) /* Debug interface actions */
56#define PVR2_TRACE_GPIO (1 << 27) /* GPIO state bit changes */ 56#define PVR2_TRACE_GPIO (1 << 27) /* GPIO state bit changes */
57#define PVR2_TRACE_DVB_FEED (1 << 28) /* DVB transport feed debug */
57 58
58 59
59#endif /* __PVRUSB2_HDW_INTERNAL_H */ 60#endif /* __PVRUSB2_HDW_INTERNAL_H */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 3a141d93e1a9..5bf6d8fda1f9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -153,7 +153,6 @@ static const struct pvr2_device_desc pvr2_device_gotview_2d = {
153 153
154 154
155 155
156#ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_CREATOR
157/*------------------------------------------------------------------------*/ 156/*------------------------------------------------------------------------*/
158/* OnAir Creator */ 157/* OnAir Creator */
159 158
@@ -212,11 +211,9 @@ static const struct pvr2_device_desc pvr2_device_onair_creator = {
212 .dvb_props = &pvr2_onair_creator_fe_props, 211 .dvb_props = &pvr2_onair_creator_fe_props,
213#endif 212#endif
214}; 213};
215#endif
216 214
217 215
218 216
219#ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_USB2
220/*------------------------------------------------------------------------*/ 217/*------------------------------------------------------------------------*/
221/* OnAir USB 2.0 */ 218/* OnAir USB 2.0 */
222 219
@@ -274,7 +271,6 @@ static const struct pvr2_device_desc pvr2_device_onair_usb2 = {
274 .dvb_props = &pvr2_onair_usb2_fe_props, 271 .dvb_props = &pvr2_onair_usb2_fe_props,
275#endif 272#endif
276}; 273};
277#endif
278 274
279 275
280 276
@@ -497,14 +493,10 @@ struct usb_device_id pvr2_device_table[] = {
497 .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2}, 493 .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2},
498 { USB_DEVICE(0x1164, 0x0602), 494 { USB_DEVICE(0x1164, 0x0602),
499 .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2d}, 495 .driver_info = (kernel_ulong_t)&pvr2_device_gotview_2d},
500#ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_CREATOR
501 { USB_DEVICE(0x11ba, 0x1003), 496 { USB_DEVICE(0x11ba, 0x1003),
502 .driver_info = (kernel_ulong_t)&pvr2_device_onair_creator}, 497 .driver_info = (kernel_ulong_t)&pvr2_device_onair_creator},
503#endif
504#ifdef CONFIG_VIDEO_PVRUSB2_ONAIR_USB2
505 { USB_DEVICE(0x11ba, 0x1001), 498 { USB_DEVICE(0x11ba, 0x1001),
506 .driver_info = (kernel_ulong_t)&pvr2_device_onair_usb2}, 499 .driver_info = (kernel_ulong_t)&pvr2_device_onair_usb2},
507#endif
508 { USB_DEVICE(0x2040, 0x7300), 500 { USB_DEVICE(0x2040, 0x7300),
509 .driver_info = (kernel_ulong_t)&pvr2_device_73xxx}, 501 .driver_info = (kernel_ulong_t)&pvr2_device_73xxx},
510 { USB_DEVICE(0x2040, 0x7500), 502 { USB_DEVICE(0x2040, 0x7500),
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
index 6504c97e0bbc..6ec4bf81fc7f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
@@ -21,6 +21,7 @@
21#include <linux/kthread.h> 21#include <linux/kthread.h>
22#include <linux/freezer.h> 22#include <linux/freezer.h>
23#include "dvbdev.h" 23#include "dvbdev.h"
24#include "pvrusb2-debug.h"
24#include "pvrusb2-hdw-internal.h" 25#include "pvrusb2-hdw-internal.h"
25#include "pvrusb2-hdw.h" 26#include "pvrusb2-hdw.h"
26#include "pvrusb2-io.h" 27#include "pvrusb2-io.h"
@@ -35,7 +36,7 @@ static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
35 struct pvr2_buffer *bp; 36 struct pvr2_buffer *bp;
36 struct pvr2_stream *stream; 37 struct pvr2_stream *stream;
37 38
38 printk(KERN_DEBUG "dvb thread started\n"); 39 pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread started");
39 set_freezable(); 40 set_freezable();
40 41
41 stream = adap->channel.stream->stream; 42 stream = adap->channel.stream->stream;
@@ -82,7 +83,7 @@ static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap)
82 /* If we get here and ret is < 0, then an error has occurred. 83 /* If we get here and ret is < 0, then an error has occurred.
83 Probably would be a good idea to communicate that to DVB core... */ 84 Probably would be a good idea to communicate that to DVB core... */
84 85
85 printk(KERN_DEBUG "dvb thread stopped\n"); 86 pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread stopped");
86 87
87 return 0; 88 return 0;
88} 89}
@@ -210,7 +211,8 @@ static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
210 do { 211 do {
211 if (onoff) { 212 if (onoff) {
212 if (!adap->feedcount) { 213 if (!adap->feedcount) {
213 printk(KERN_DEBUG "start feeding\n"); 214 pvr2_trace(PVR2_TRACE_DVB_FEED,
215 "start feeding demux");
214 ret = pvr2_dvb_stream_start(adap); 216 ret = pvr2_dvb_stream_start(adap);
215 if (ret < 0) break; 217 if (ret < 0) break;
216 } 218 }
@@ -218,7 +220,8 @@ static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
218 } else if (adap->feedcount > 0) { 220 } else if (adap->feedcount > 0) {
219 (adap->feedcount)--; 221 (adap->feedcount)--;
220 if (!adap->feedcount) { 222 if (!adap->feedcount) {
221 printk(KERN_DEBUG "stop feeding\n"); 223 pvr2_trace(PVR2_TRACE_DVB_FEED,
224 "stop feeding demux");
222 pvr2_dvb_stream_end(adap); 225 pvr2_dvb_stream_end(adap);
223 } 226 }
224 } 227 }
@@ -230,15 +233,13 @@ static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
230 233
231static int pvr2_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) 234static int pvr2_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
232{ 235{
233 printk(KERN_DEBUG "start pid: 0x%04x, feedtype: %d\n", 236 pvr2_trace(PVR2_TRACE_DVB_FEED, "start pid: 0x%04x", dvbdmxfeed->pid);
234 dvbdmxfeed->pid, dvbdmxfeed->type);
235 return pvr2_dvb_ctrl_feed(dvbdmxfeed, 1); 237 return pvr2_dvb_ctrl_feed(dvbdmxfeed, 1);
236} 238}
237 239
238static int pvr2_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) 240static int pvr2_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
239{ 241{
240 printk(KERN_DEBUG "stop pid: 0x%04x, feedtype: %d\n", 242 pvr2_trace(PVR2_TRACE_DVB_FEED, "stop pid: 0x%04x", dvbdmxfeed->pid);
241 dvbdmxfeed->pid, dvbdmxfeed->type);
242 return pvr2_dvb_ctrl_feed(dvbdmxfeed, 0); 243 return pvr2_dvb_ctrl_feed(dvbdmxfeed, 0);
243} 244}
244 245
@@ -259,7 +260,8 @@ static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
259 &adap->channel.hdw->usb_dev->dev, 260 &adap->channel.hdw->usb_dev->dev,
260 adapter_nr); 261 adapter_nr);
261 if (ret < 0) { 262 if (ret < 0) {
262 err("dvb_register_adapter failed: error %d", ret); 263 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
264 "dvb_register_adapter failed: error %d", ret);
263 goto err; 265 goto err;
264 } 266 }
265 adap->dvb_adap.priv = adap; 267 adap->dvb_adap.priv = adap;
@@ -276,7 +278,8 @@ static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
276 278
277 ret = dvb_dmx_init(&adap->demux); 279 ret = dvb_dmx_init(&adap->demux);
278 if (ret < 0) { 280 if (ret < 0) {
279 err("dvb_dmx_init failed: error %d", ret); 281 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
282 "dvb_dmx_init failed: error %d", ret);
280 goto err_dmx; 283 goto err_dmx;
281 } 284 }
282 285
@@ -286,7 +289,8 @@ static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
286 289
287 ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap); 290 ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
288 if (ret < 0) { 291 if (ret < 0) {
289 err("dvb_dmxdev_init failed: error %d", ret); 292 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
293 "dvb_dmxdev_init failed: error %d", ret);
290 goto err_dmx_dev; 294 goto err_dmx_dev;
291 } 295 }
292 296
@@ -304,7 +308,7 @@ err:
304 308
305static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap) 309static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap)
306{ 310{
307 printk(KERN_DEBUG "unregistering DVB devices\n"); 311 pvr2_trace(PVR2_TRACE_INFO, "unregistering DVB devices");
308 dvb_net_release(&adap->dvb_net); 312 dvb_net_release(&adap->dvb_net);
309 adap->demux.dmx.close(&adap->demux.dmx); 313 adap->demux.dmx.close(&adap->demux.dmx);
310 dvb_dmxdev_release(&adap->dmxdev); 314 dvb_dmxdev_release(&adap->dmxdev);
@@ -320,7 +324,7 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
320 int ret = 0; 324 int ret = 0;
321 325
322 if (dvb_props == NULL) { 326 if (dvb_props == NULL) {
323 err("fe_props not defined!"); 327 pvr2_trace(PVR2_TRACE_ERROR_LEGS, "fe_props not defined!");
324 return -EINVAL; 328 return -EINVAL;
325 } 329 }
326 330
@@ -328,13 +332,15 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
328 &adap->channel, 332 &adap->channel,
329 (1 << PVR2_CVAL_INPUT_DTV)); 333 (1 << PVR2_CVAL_INPUT_DTV));
330 if (ret) { 334 if (ret) {
331 err("failed to grab control of dtv input (code=%d)", 335 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
336 "failed to grab control of dtv input (code=%d)",
332 ret); 337 ret);
333 return ret; 338 return ret;
334 } 339 }
335 340
336 if (dvb_props->frontend_attach == NULL) { 341 if (dvb_props->frontend_attach == NULL) {
337 err("frontend_attach not defined!"); 342 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
343 "frontend_attach not defined!");
338 ret = -EINVAL; 344 ret = -EINVAL;
339 goto done; 345 goto done;
340 } 346 }
@@ -342,7 +348,8 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
342 if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) { 348 if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
343 349
344 if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) { 350 if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
345 err("frontend registration failed!"); 351 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
352 "frontend registration failed!");
346 dvb_frontend_detach(adap->fe); 353 dvb_frontend_detach(adap->fe);
347 adap->fe = NULL; 354 adap->fe = NULL;
348 ret = -ENODEV; 355 ret = -ENODEV;
@@ -359,7 +366,8 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
359 adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl; 366 adap->fe->ops.ts_bus_ctrl = pvr2_dvb_bus_ctrl;
360 367
361 } else { 368 } else {
362 err("no frontend was attached!"); 369 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
370 "no frontend was attached!");
363 ret = -ENODEV; 371 ret = -ENODEV;
364 return ret; 372 return ret;
365 } 373 }
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index e086f14d5663..40e4c3bd2cb9 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -3,7 +3,7 @@ config VIDEO_SAA7134
3 depends on VIDEO_DEV && PCI && I2C && INPUT 3 depends on VIDEO_DEV && PCI && I2C && INPUT
4 select VIDEOBUF_DMA_SG 4 select VIDEOBUF_DMA_SG
5 select VIDEO_IR 5 select VIDEO_IR
6 select VIDEO_TUNER 6 select MEDIA_TUNER
7 select VIDEO_TVEEPROM 7 select VIDEO_TVEEPROM
8 select CRC32 8 select CRC32
9 ---help--- 9 ---help---
@@ -35,9 +35,9 @@ config VIDEO_SAA7134_DVB
35 select DVB_NXT200X if !DVB_FE_CUSTOMISE 35 select DVB_NXT200X if !DVB_FE_CUSTOMISE
36 select DVB_TDA10086 if !DVB_FE_CUSTOMISE 36 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
37 select DVB_TDA826X if !DVB_FE_CUSTOMISE 37 select DVB_TDA826X if !DVB_FE_CUSTOMISE
38 select DVB_TDA827X if !DVB_FE_CUSTOMISE 38 select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE
39 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 39 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
40 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 40 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
41 ---help--- 41 ---help---
42 This adds support for DVB cards based on the 42 This adds support for DVB cards based on the
43 Philips saa7134 chip. 43 Philips saa7134 chip.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index 9aff937ba7a5..3dbaa19a6d00 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -11,5 +11,6 @@ obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
11obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o 11obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
12 12
13EXTRA_CFLAGS += -Idrivers/media/video 13EXTRA_CFLAGS += -Idrivers/media/video
14EXTRA_CFLAGS += -Idrivers/media/common/tuners
14EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 15EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
15EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 16EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 98375955a84b..b111903aa322 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -47,6 +47,9 @@ static char name_svideo[] = "S-Video";
47/* ------------------------------------------------------------------ */ 47/* ------------------------------------------------------------------ */
48/* board config info */ 48/* board config info */
49 49
50/* If radio_type !=UNSET, radio_addr should be specified
51 */
52
50struct saa7134_board saa7134_boards[] = { 53struct saa7134_board saa7134_boards[] = {
51 [SAA7134_BOARD_UNKNOWN] = { 54 [SAA7134_BOARD_UNKNOWN] = {
52 .name = "UNKNOWN/GENERIC", 55 .name = "UNKNOWN/GENERIC",
@@ -3087,7 +3090,7 @@ struct saa7134_board saa7134_boards[] = {
3087 .tuner_type = TUNER_PHILIPS_TD1316, /* untested */ 3090 .tuner_type = TUNER_PHILIPS_TD1316, /* untested */
3088 .radio_type = TUNER_TEA5767, /* untested */ 3091 .radio_type = TUNER_TEA5767, /* untested */
3089 .tuner_addr = ADDR_UNSET, 3092 .tuner_addr = ADDR_UNSET,
3090 .radio_addr = ADDR_UNSET, 3093 .radio_addr = 0x60,
3091 .tda9887_conf = TDA9887_PRESENT, 3094 .tda9887_conf = TDA9887_PRESENT,
3092 .mpeg = SAA7134_MPEG_DVB, 3095 .mpeg = SAA7134_MPEG_DVB,
3093 .inputs = {{ 3096 .inputs = {{
@@ -4247,6 +4250,36 @@ struct saa7134_board saa7134_boards[] = {
4247 .amux = LINE1, 4250 .amux = LINE1,
4248 } }, 4251 } },
4249 }, 4252 },
4253 [SAA7134_BOARD_BEHOLD_H6] = {
4254 /* Igor Kuznetsov <igk@igk.ru> */
4255 .name = "Beholder BeholdTV H6",
4256 .audio_clock = 0x00187de7,
4257 .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
4258 .radio_type = UNSET,
4259 .tuner_addr = ADDR_UNSET,
4260 .radio_addr = ADDR_UNSET,
4261 .tda9887_conf = TDA9887_PRESENT,
4262 .inputs = {{
4263 .name = name_tv,
4264 .vmux = 3,
4265 .amux = TV,
4266 .tv = 1,
4267 }, {
4268 .name = name_comp1,
4269 .vmux = 1,
4270 .amux = LINE1,
4271 }, {
4272 .name = name_svideo,
4273 .vmux = 8,
4274 .amux = LINE1,
4275 } },
4276 .radio = {
4277 .name = name_radio,
4278 .amux = LINE2,
4279 },
4280 /* no DVB support for now */
4281 /* .mpeg = SAA7134_MPEG_DVB, */
4282 },
4250}; 4283};
4251 4284
4252const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 4285const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -5197,6 +5230,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
5197 .subvendor = 0x5ace, 5230 .subvendor = 0x5ace,
5198 .subdevice = 0x6193, 5231 .subdevice = 0x6193,
5199 .driver_data = SAA7134_BOARD_BEHOLD_M6, 5232 .driver_data = SAA7134_BOARD_BEHOLD_M6,
5233 }, {
5234 .vendor = PCI_VENDOR_ID_PHILIPS,
5235 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5236 .subvendor = 0x5ace,
5237 .subdevice = 0x6191,
5238 .driver_data = SAA7134_BOARD_BEHOLD_M6,
5200 },{ 5239 },{
5201 .vendor = PCI_VENDOR_ID_PHILIPS, 5240 .vendor = PCI_VENDOR_ID_PHILIPS,
5202 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 5241 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -5246,6 +5285,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
5246 .subdevice = 0xc900, 5285 .subdevice = 0xc900,
5247 .driver_data = SAA7134_BOARD_VIDEOMATE_T750, 5286 .driver_data = SAA7134_BOARD_VIDEOMATE_T750,
5248 }, { 5287 }, {
5288 .vendor = PCI_VENDOR_ID_PHILIPS,
5289 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
5290 .subvendor = 0x5ace,
5291 .subdevice = 0x6290,
5292 .driver_data = SAA7134_BOARD_BEHOLD_H6,
5293 }, {
5249 /* --- boards without eeprom + subsystem ID --- */ 5294 /* --- boards without eeprom + subsystem ID --- */
5250 .vendor = PCI_VENDOR_ID_PHILIPS, 5295 .vendor = PCI_VENDOR_ID_PHILIPS,
5251 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 5296 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -5577,20 +5622,87 @@ int saa7134_board_init1(struct saa7134_dev *dev)
5577 return 0; 5622 return 0;
5578} 5623}
5579 5624
5625static void saa7134_tuner_setup(struct saa7134_dev *dev)
5626{
5627 struct tuner_setup tun_setup;
5628 unsigned int mode_mask = T_RADIO |
5629 T_ANALOG_TV |
5630 T_DIGITAL_TV;
5631
5632 memset(&tun_setup, 0, sizeof(tun_setup));
5633 tun_setup.tuner_callback = saa7134_tuner_callback;
5634
5635 if (saa7134_boards[dev->board].radio_type != UNSET) {
5636 tun_setup.type = saa7134_boards[dev->board].radio_type;
5637 tun_setup.addr = saa7134_boards[dev->board].radio_addr;
5638
5639 tun_setup.mode_mask = T_RADIO;
5640
5641 saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
5642 mode_mask &= ~T_RADIO;
5643 }
5644
5645 if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type != UNSET)) {
5646 tun_setup.type = dev->tuner_type;
5647 tun_setup.addr = dev->tuner_addr;
5648 tun_setup.config = saa7134_boards[dev->board].tuner_config;
5649 tun_setup.tuner_callback = saa7134_tuner_callback;
5650
5651 tun_setup.mode_mask = mode_mask;
5652
5653 saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
5654 }
5655
5656 if (dev->tda9887_conf) {
5657 struct v4l2_priv_tun_config tda9887_cfg;
5658
5659 tda9887_cfg.tuner = TUNER_TDA9887;
5660 tda9887_cfg.priv = &dev->tda9887_conf;
5661
5662 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
5663 &tda9887_cfg);
5664 }
5665
5666 if (dev->tuner_type == TUNER_XC2028) {
5667 struct v4l2_priv_tun_config xc2028_cfg;
5668 struct xc2028_ctrl ctl;
5669
5670 memset(&xc2028_cfg, 0, sizeof(ctl));
5671 memset(&ctl, 0, sizeof(ctl));
5672
5673 ctl.fname = XC2028_DEFAULT_FIRMWARE;
5674 ctl.max_len = 64;
5675
5676 switch (dev->board) {
5677 case SAA7134_BOARD_AVERMEDIA_A16D:
5678 ctl.demod = XC3028_FE_ZARLINK456;
5679 break;
5680 default:
5681 ctl.demod = XC3028_FE_OREN538;
5682 ctl.mts = 1;
5683 }
5684
5685 xc2028_cfg.tuner = TUNER_XC2028;
5686 xc2028_cfg.priv = &ctl;
5687
5688 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
5689 }
5690}
5691
5580/* stuff which needs working i2c */ 5692/* stuff which needs working i2c */
5581int saa7134_board_init2(struct saa7134_dev *dev) 5693int saa7134_board_init2(struct saa7134_dev *dev)
5582{ 5694{
5583 unsigned char buf; 5695 unsigned char buf;
5584 int board; 5696 int board;
5585 struct tuner_setup tun_setup; 5697
5586 tun_setup.config = 0; 5698 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
5587 tun_setup.tuner_callback = saa7134_tuner_callback; 5699 dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
5588 5700
5589 switch (dev->board) { 5701 switch (dev->board) {
5590 case SAA7134_BOARD_BMK_MPEX_NOTUNER: 5702 case SAA7134_BOARD_BMK_MPEX_NOTUNER:
5591 case SAA7134_BOARD_BMK_MPEX_TUNER: 5703 case SAA7134_BOARD_BMK_MPEX_TUNER:
5592 dev->i2c_client.addr = 0x60; 5704 dev->i2c_client.addr = 0x60;
5593 board = (i2c_master_recv(&dev->i2c_client,&buf,0) < 0) 5705 board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
5594 ? SAA7134_BOARD_BMK_MPEX_NOTUNER 5706 ? SAA7134_BOARD_BMK_MPEX_NOTUNER
5595 : SAA7134_BOARD_BMK_MPEX_TUNER; 5707 : SAA7134_BOARD_BMK_MPEX_TUNER;
5596 if (board == dev->board) 5708 if (board == dev->board)
@@ -5600,21 +5712,9 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5600 saa7134_boards[dev->board].name); 5712 saa7134_boards[dev->board].name);
5601 dev->tuner_type = saa7134_boards[dev->board].tuner_type; 5713 dev->tuner_type = saa7134_boards[dev->board].tuner_type;
5602 5714
5603 if (TUNER_ABSENT != dev->tuner_type) {
5604 tun_setup.mode_mask = T_RADIO |
5605 T_ANALOG_TV |
5606 T_DIGITAL_TV;
5607 tun_setup.type = dev->tuner_type;
5608 tun_setup.addr = ADDR_UNSET;
5609 tun_setup.tuner_callback = saa7134_tuner_callback;
5610
5611 saa7134_i2c_call_clients(dev,
5612 TUNER_SET_TYPE_ADDR,
5613 &tun_setup);
5614 }
5615 break; 5715 break;
5616 case SAA7134_BOARD_MD7134: 5716 case SAA7134_BOARD_MD7134:
5617 { 5717 {
5618 u8 subaddr; 5718 u8 subaddr;
5619 u8 data[3]; 5719 u8 data[3];
5620 int ret, tuner_t; 5720 int ret, tuner_t;
@@ -5667,30 +5767,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5667 } 5767 }
5668 5768
5669 printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type); 5769 printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type);
5670 if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) {
5671 struct v4l2_priv_tun_config tda9887_cfg;
5672
5673 tda9887_cfg.tuner = TUNER_TDA9887;
5674 tda9887_cfg.priv = &dev->tda9887_conf;
5675
5676 dev->tda9887_conf = TDA9887_PRESENT |
5677 TDA9887_PORT1_ACTIVE |
5678 TDA9887_PORT2_ACTIVE;
5679
5680 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
5681 &tda9887_cfg);
5682 }
5683
5684 tun_setup.mode_mask = T_RADIO |
5685 T_ANALOG_TV |
5686 T_DIGITAL_TV;
5687 tun_setup.type = dev->tuner_type;
5688 tun_setup.addr = ADDR_UNSET;
5689
5690 saa7134_i2c_call_clients(dev,
5691 TUNER_SET_TYPE_ADDR, &tun_setup);
5692 }
5693 break; 5770 break;
5771 }
5694 case SAA7134_BOARD_PHILIPS_EUROPA: 5772 case SAA7134_BOARD_PHILIPS_EUROPA:
5695 if (dev->autodetected && (dev->eedata[0x41] == 0x1c)) { 5773 if (dev->autodetected && (dev->eedata[0x41] == 0x1c)) {
5696 /* Reconfigure board as Snake reference design */ 5774 /* Reconfigure board as Snake reference design */
@@ -5702,43 +5780,43 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5702 } 5780 }
5703 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 5781 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
5704 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: 5782 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
5783 {
5784
5705 /* The Philips EUROPA based hybrid boards have the tuner connected through 5785 /* The Philips EUROPA based hybrid boards have the tuner connected through
5706 * the channel decoder. We have to make it transparent to find it 5786 * the channel decoder. We have to make it transparent to find it
5707 */ 5787 */
5708 {
5709 u8 data[] = { 0x07, 0x02}; 5788 u8 data[] = { 0x07, 0x02};
5710 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5789 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5711 i2c_transfer(&dev->i2c_adap, &msg, 1); 5790 i2c_transfer(&dev->i2c_adap, &msg, 1);
5712 5791
5713 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
5714 tun_setup.type = dev->tuner_type;
5715 tun_setup.addr = dev->tuner_addr;
5716
5717 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
5718 }
5719 break; 5792 break;
5793 }
5720 case SAA7134_BOARD_PHILIPS_TIGER: 5794 case SAA7134_BOARD_PHILIPS_TIGER:
5721 case SAA7134_BOARD_PHILIPS_TIGER_S: 5795 case SAA7134_BOARD_PHILIPS_TIGER_S:
5722 { 5796 {
5723 u8 data[] = { 0x3c, 0x33, 0x60}; 5797 u8 data[] = { 0x3c, 0x33, 0x60};
5724 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5798 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5725 if(dev->autodetected && (dev->eedata[0x49] == 0x50)) { 5799 if (dev->autodetected && (dev->eedata[0x49] == 0x50)) {
5726 dev->board = SAA7134_BOARD_PHILIPS_TIGER_S; 5800 dev->board = SAA7134_BOARD_PHILIPS_TIGER_S;
5727 printk(KERN_INFO "%s: Reconfigured board as %s\n", 5801 printk(KERN_INFO "%s: Reconfigured board as %s\n",
5728 dev->name, saa7134_boards[dev->board].name); 5802 dev->name, saa7134_boards[dev->board].name);
5729 } 5803 }
5730 if(dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) { 5804 if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
5731 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; 5805 dev->tuner_type = TUNER_PHILIPS_TDA8290;
5732 tun_setup.type = TUNER_PHILIPS_TDA8290; 5806
5733 tun_setup.addr = 0x4b; 5807 saa7134_tuner_setup(dev);
5734 tun_setup.config = 2;
5735 5808
5736 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
5737 data[2] = 0x68; 5809 data[2] = 0x68;
5810 i2c_transfer(&dev->i2c_adap, &msg, 1);
5811
5812 /* Tuner setup is handled before I2C transfer.
5813 Due to that, there's no need to do it later
5814 */
5815 return 0;
5738 } 5816 }
5739 i2c_transfer(&dev->i2c_adap, &msg, 1); 5817 i2c_transfer(&dev->i2c_adap, &msg, 1);
5740 }
5741 break; 5818 break;
5819 }
5742 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 5820 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
5743 hauppauge_eeprom(dev, dev->eedata+0x80); 5821 hauppauge_eeprom(dev, dev->eedata+0x80);
5744 /* break intentionally omitted */ 5822 /* break intentionally omitted */
@@ -5751,52 +5829,55 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5751 case SAA7134_BOARD_AVERMEDIA_SUPER_007: 5829 case SAA7134_BOARD_AVERMEDIA_SUPER_007:
5752 case SAA7134_BOARD_TWINHAN_DTV_DVB_3056: 5830 case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
5753 case SAA7134_BOARD_CREATIX_CTX953: 5831 case SAA7134_BOARD_CREATIX_CTX953:
5832 {
5754 /* this is a hybrid board, initialize to analog mode 5833 /* this is a hybrid board, initialize to analog mode
5755 * and configure firmware eeprom address 5834 * and configure firmware eeprom address
5756 */ 5835 */
5757 {
5758 u8 data[] = { 0x3c, 0x33, 0x60}; 5836 u8 data[] = { 0x3c, 0x33, 0x60};
5759 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5837 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5760 i2c_transfer(&dev->i2c_adap, &msg, 1); 5838 i2c_transfer(&dev->i2c_adap, &msg, 1);
5761 }
5762 break; 5839 break;
5840 }
5763 case SAA7134_BOARD_FLYDVB_TRIO: 5841 case SAA7134_BOARD_FLYDVB_TRIO:
5764 { 5842 {
5765 u8 data[] = { 0x3c, 0x33, 0x62}; 5843 u8 data[] = { 0x3c, 0x33, 0x62};
5766 struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)}; 5844 struct i2c_msg msg = {.addr=0x09, .flags=0, .buf=data, .len = sizeof(data)};
5767 i2c_transfer(&dev->i2c_adap, &msg, 1); 5845 i2c_transfer(&dev->i2c_adap, &msg, 1);
5768 }
5769 break; 5846 break;
5847 }
5770 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: 5848 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
5771 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: 5849 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
5850 {
5772 /* initialize analog mode */ 5851 /* initialize analog mode */
5773 {
5774 u8 data[] = { 0x3c, 0x33, 0x6a}; 5852 u8 data[] = { 0x3c, 0x33, 0x6a};
5775 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5853 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5776 i2c_transfer(&dev->i2c_adap, &msg, 1); 5854 i2c_transfer(&dev->i2c_adap, &msg, 1);
5777 }
5778 break; 5855 break;
5856 }
5779 case SAA7134_BOARD_CINERGY_HT_PCMCIA: 5857 case SAA7134_BOARD_CINERGY_HT_PCMCIA:
5780 case SAA7134_BOARD_CINERGY_HT_PCI: 5858 case SAA7134_BOARD_CINERGY_HT_PCI:
5859 {
5781 /* initialize analog mode */ 5860 /* initialize analog mode */
5782 {
5783 u8 data[] = { 0x3c, 0x33, 0x68}; 5861 u8 data[] = { 0x3c, 0x33, 0x68};
5784 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; 5862 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
5785 i2c_transfer(&dev->i2c_adap, &msg, 1); 5863 i2c_transfer(&dev->i2c_adap, &msg, 1);
5786 }
5787 break; 5864 break;
5865 }
5788 case SAA7134_BOARD_KWORLD_ATSC110: 5866 case SAA7134_BOARD_KWORLD_ATSC110:
5789 { 5867 {
5790 /* enable tuner */ 5868 /* enable tuner */
5791 int i; 5869 int i;
5792 static const u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; 5870 static const u8 buffer [] = { 0x10, 0x12, 0x13, 0x04, 0x16,
5793 dev->i2c_client.addr = 0x0a; 5871 0x00, 0x14, 0x04, 0x17, 0x00 };
5794 for (i = 0; i < 5; i++) 5872 dev->i2c_client.addr = 0x0a;
5795 if (2 != i2c_master_send(&dev->i2c_client,&buffer[i*2],2)) 5873 for (i = 0; i < 5; i++)
5796 printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n", 5874 if (2 != i2c_master_send(&dev->i2c_client,
5797 dev->name, i); 5875 &buffer[i*2], 2))
5798 } 5876 printk(KERN_WARNING
5877 "%s: Unable to enable tuner(%i).\n",
5878 dev->name, i);
5799 break; 5879 break;
5880 }
5800 case SAA7134_BOARD_VIDEOMATE_DVBT_200: 5881 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
5801 case SAA7134_BOARD_VIDEOMATE_DVBT_200A: 5882 case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
5802 /* The T200 and the T200A share the same pci id. Consequently, 5883 /* The T200 and the T200A share the same pci id. Consequently,
@@ -5821,7 +5902,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5821 } 5902 }
5822 break; 5903 break;
5823 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: 5904 case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
5824 { 5905 {
5825 struct v4l2_priv_tun_config tea5767_cfg; 5906 struct v4l2_priv_tun_config tea5767_cfg;
5826 struct tea5767_ctrl ctl; 5907 struct tea5767_ctrl ctl;
5827 5908
@@ -5832,34 +5913,11 @@ int saa7134_board_init2(struct saa7134_dev *dev)
5832 tea5767_cfg.tuner = TUNER_TEA5767; 5913 tea5767_cfg.tuner = TUNER_TEA5767;
5833 tea5767_cfg.priv = &ctl; 5914 tea5767_cfg.priv = &ctl;
5834 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg); 5915 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg);
5835 }
5836 break; 5916 break;
5837 } 5917 }
5918 } /* switch() */
5838 5919
5839 if (dev->tuner_type == TUNER_XC2028) { 5920 saa7134_tuner_setup(dev);
5840 struct v4l2_priv_tun_config xc2028_cfg;
5841 struct xc2028_ctrl ctl;
5842
5843 memset(&xc2028_cfg, 0, sizeof(ctl));
5844 memset(&ctl, 0, sizeof(ctl));
5845
5846 ctl.fname = XC2028_DEFAULT_FIRMWARE;
5847 ctl.max_len = 64;
5848
5849 switch (dev->board) {
5850 case SAA7134_BOARD_AVERMEDIA_A16D:
5851 ctl.demod = XC3028_FE_ZARLINK456;
5852 break;
5853 default:
5854 ctl.demod = XC3028_FE_OREN538;
5855 ctl.mts = 1;
5856 }
5857
5858 xc2028_cfg.tuner = TUNER_XC2028;
5859 xc2028_cfg.priv = &ctl;
5860
5861 saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
5862 }
5863 5921
5864 return 0; 5922 return 0;
5865} 5923}
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 2ccfaba0c490..d8af3863f2d3 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -324,8 +324,6 @@ static u32 functionality(struct i2c_adapter *adap)
324static int attach_inform(struct i2c_client *client) 324static int attach_inform(struct i2c_client *client)
325{ 325{
326 struct saa7134_dev *dev = client->adapter->algo_data; 326 struct saa7134_dev *dev = client->adapter->algo_data;
327 int tuner = dev->tuner_type;
328 struct tuner_setup tun_setup;
329 327
330 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", 328 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
331 client->driver->driver.name, client->addr, client->name); 329 client->driver->driver.name, client->addr, client->name);
@@ -346,46 +344,6 @@ static int attach_inform(struct i2c_client *client)
346 } 344 }
347 } 345 }
348 346
349 if (!client->driver->command)
350 return 0;
351
352 if (saa7134_boards[dev->board].radio_type != UNSET) {
353
354 tun_setup.type = saa7134_boards[dev->board].radio_type;
355 tun_setup.addr = saa7134_boards[dev->board].radio_addr;
356
357 if ((tun_setup.addr == ADDR_UNSET) || (tun_setup.addr == client->addr)) {
358 tun_setup.mode_mask = T_RADIO;
359
360 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
361 }
362 }
363
364 if (tuner != UNSET) {
365 tun_setup.type = tuner;
366 tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
367 tun_setup.config = saa7134_boards[dev->board].tuner_config;
368 tun_setup.tuner_callback = saa7134_tuner_callback;
369
370 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
371
372 tun_setup.mode_mask = T_ANALOG_TV;
373
374 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
375 }
376
377 if (tuner == TUNER_TDA9887) {
378 struct v4l2_priv_tun_config tda9887_cfg;
379
380 tda9887_cfg.tuner = TUNER_TDA9887;
381 tda9887_cfg.priv = &dev->tda9887_conf;
382
383 client->driver->command(client, TUNER_SET_CONFIG,
384 &tda9887_cfg);
385 }
386 }
387
388
389 return 0; 347 return 0;
390} 348}
391 349
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 767ff30832f2..919632b10aae 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -531,6 +531,7 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
531 break; 531 break;
532 case SAA7134_BOARD_BEHOLD_607_9FM: 532 case SAA7134_BOARD_BEHOLD_607_9FM:
533 case SAA7134_BOARD_BEHOLD_M6: 533 case SAA7134_BOARD_BEHOLD_M6:
534 case SAA7134_BOARD_BEHOLD_H6:
534 snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); 535 snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV");
535 ir->get_key = get_key_beholdm6xx; 536 ir->get_key = get_key_beholdm6xx;
536 ir->ir_codes = ir_codes_behold; 537 ir->ir_codes = ir_codes_behold;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 924ffd13637e..34ff0d4998f3 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -263,6 +263,7 @@ struct saa7134_format {
263#define SAA7134_BOARD_VIDEOMATE_T750 139 263#define SAA7134_BOARD_VIDEOMATE_T750 139
264#define SAA7134_BOARD_AVERMEDIA_A700_PRO 140 264#define SAA7134_BOARD_AVERMEDIA_A700_PRO 140
265#define SAA7134_BOARD_AVERMEDIA_A700_HYBRID 141 265#define SAA7134_BOARD_AVERMEDIA_A700_HYBRID 141
266#define SAA7134_BOARD_BEHOLD_H6 142
266 267
267 268
268#define SAA7134_MAXBOARDS 8 269#define SAA7134_MAXBOARDS 8
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
deleted file mode 100644
index 0ebb5b525e57..000000000000
--- a/drivers/media/video/tda8290.c
+++ /dev/null
@@ -1,804 +0,0 @@
1/*
2
3 i2c tv tuner chip device driver
4 controls the philips tda8290+75 tuner chip combo.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 This "tda8290" module was split apart from the original "tuner" module.
21*/
22
23#include <linux/i2c.h>
24#include <linux/delay.h>
25#include <linux/videodev.h>
26#include "tuner-i2c.h"
27#include "tda8290.h"
28#include "tda827x.h"
29#include "tda18271.h"
30
31static int debug;
32module_param(debug, int, 0644);
33MODULE_PARM_DESC(debug, "enable verbose debug messages");
34
35/* ---------------------------------------------------------------------- */
36
37struct tda8290_priv {
38 struct tuner_i2c_props i2c_props;
39
40 unsigned char tda8290_easy_mode;
41
42 unsigned char tda827x_addr;
43
44 unsigned char ver;
45#define TDA8290 1
46#define TDA8295 2
47#define TDA8275 4
48#define TDA8275A 8
49#define TDA18271 16
50
51 struct tda827x_config cfg;
52};
53
54/*---------------------------------------------------------------------*/
55
56static int tda8290_i2c_bridge(struct dvb_frontend *fe, int close)
57{
58 struct tda8290_priv *priv = fe->analog_demod_priv;
59
60 unsigned char enable[2] = { 0x21, 0xC0 };
61 unsigned char disable[2] = { 0x21, 0x00 };
62 unsigned char *msg;
63
64 if (close) {
65 msg = enable;
66 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
67 /* let the bridge stabilize */
68 msleep(20);
69 } else {
70 msg = disable;
71 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
72 }
73
74 return 0;
75}
76
77static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close)
78{
79 struct tda8290_priv *priv = fe->analog_demod_priv;
80
81 unsigned char enable[2] = { 0x45, 0xc1 };
82 unsigned char disable[2] = { 0x46, 0x00 };
83 unsigned char buf[3] = { 0x45, 0x01, 0x00 };
84 unsigned char *msg;
85
86 if (close) {
87 msg = enable;
88 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
89 /* let the bridge stabilize */
90 msleep(20);
91 } else {
92 msg = disable;
93 tuner_i2c_xfer_send(&priv->i2c_props, msg, 1);
94 tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1);
95
96 buf[2] = msg[1];
97 buf[2] &= ~0x04;
98 tuner_i2c_xfer_send(&priv->i2c_props, buf, 3);
99 msleep(5);
100
101 msg[1] |= 0x04;
102 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
103 }
104
105 return 0;
106}
107
108/*---------------------------------------------------------------------*/
109
110static void set_audio(struct dvb_frontend *fe,
111 struct analog_parameters *params)
112{
113 struct tda8290_priv *priv = fe->analog_demod_priv;
114 char* mode;
115
116 if (params->std & V4L2_STD_MN) {
117 priv->tda8290_easy_mode = 0x01;
118 mode = "MN";
119 } else if (params->std & V4L2_STD_B) {
120 priv->tda8290_easy_mode = 0x02;
121 mode = "B";
122 } else if (params->std & V4L2_STD_GH) {
123 priv->tda8290_easy_mode = 0x04;
124 mode = "GH";
125 } else if (params->std & V4L2_STD_PAL_I) {
126 priv->tda8290_easy_mode = 0x08;
127 mode = "I";
128 } else if (params->std & V4L2_STD_DK) {
129 priv->tda8290_easy_mode = 0x10;
130 mode = "DK";
131 } else if (params->std & V4L2_STD_SECAM_L) {
132 priv->tda8290_easy_mode = 0x20;
133 mode = "L";
134 } else if (params->std & V4L2_STD_SECAM_LC) {
135 priv->tda8290_easy_mode = 0x40;
136 mode = "LC";
137 } else {
138 priv->tda8290_easy_mode = 0x10;
139 mode = "xx";
140 }
141
142 tuner_dbg("setting tda829x to system %s\n", mode);
143}
144
145static void tda8290_set_params(struct dvb_frontend *fe,
146 struct analog_parameters *params)
147{
148 struct tda8290_priv *priv = fe->analog_demod_priv;
149
150 unsigned char soft_reset[] = { 0x00, 0x00 };
151 unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode };
152 unsigned char expert_mode[] = { 0x01, 0x80 };
153 unsigned char agc_out_on[] = { 0x02, 0x00 };
154 unsigned char gainset_off[] = { 0x28, 0x14 };
155 unsigned char if_agc_spd[] = { 0x0f, 0x88 };
156 unsigned char adc_head_6[] = { 0x05, 0x04 };
157 unsigned char adc_head_9[] = { 0x05, 0x02 };
158 unsigned char adc_head_12[] = { 0x05, 0x01 };
159 unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
160 unsigned char pll_bw_low[] = { 0x0d, 0x27 };
161 unsigned char gainset_2[] = { 0x28, 0x64 };
162 unsigned char agc_rst_on[] = { 0x0e, 0x0b };
163 unsigned char agc_rst_off[] = { 0x0e, 0x09 };
164 unsigned char if_agc_set[] = { 0x0f, 0x81 };
165 unsigned char addr_adc_sat = 0x1a;
166 unsigned char addr_agc_stat = 0x1d;
167 unsigned char addr_pll_stat = 0x1b;
168 unsigned char adc_sat, agc_stat,
169 pll_stat;
170 int i;
171
172 set_audio(fe, params);
173
174 if (priv->cfg.config)
175 tuner_dbg("tda827xa config is 0x%02x\n", priv->cfg.config);
176 tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2);
177 tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2);
178 tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
179 msleep(1);
180
181 expert_mode[1] = priv->tda8290_easy_mode + 0x80;
182 tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
183 tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
184 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
185 if (priv->tda8290_easy_mode & 0x60)
186 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
187 else
188 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
189 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
190
191 tda8290_i2c_bridge(fe, 1);
192
193 if (fe->ops.tuner_ops.set_analog_params)
194 fe->ops.tuner_ops.set_analog_params(fe, params);
195
196 for (i = 0; i < 3; i++) {
197 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
198 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
199 if (pll_stat & 0x80) {
200 tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
201 tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
202 tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
203 tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
204 tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
205 break;
206 } else {
207 tuner_dbg("tda8290 not locked, no signal?\n");
208 msleep(100);
209 }
210 }
211 /* adjust headroom resp. gain */
212 if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
213 tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
214 agc_stat, adc_sat, pll_stat & 0x80);
215 tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
216 msleep(100);
217 tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
218 tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
219 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
220 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
221 if ((agc_stat > 115) || !(pll_stat & 0x80)) {
222 tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
223 agc_stat, pll_stat & 0x80);
224 if (priv->cfg.agcf)
225 priv->cfg.agcf(fe);
226 msleep(100);
227 tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
228 tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
229 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
230 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
231 if((agc_stat > 115) || !(pll_stat & 0x80)) {
232 tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
233 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
234 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2);
235 msleep(100);
236 }
237 }
238 }
239
240 /* l/ l' deadlock? */
241 if(priv->tda8290_easy_mode & 0x60) {
242 tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
243 tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
244 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
245 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
246 if ((adc_sat > 20) || !(pll_stat & 0x80)) {
247 tuner_dbg("trying to resolve SECAM L deadlock\n");
248 tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
249 msleep(40);
250 tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2);
251 }
252 }
253
254 tda8290_i2c_bridge(fe, 0);
255 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2);
256}
257
258/*---------------------------------------------------------------------*/
259
260static void tda8295_power(struct dvb_frontend *fe, int enable)
261{
262 struct tda8290_priv *priv = fe->analog_demod_priv;
263 unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */
264
265 tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
266 tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
267
268 if (enable)
269 buf[1] = 0x01;
270 else
271 buf[1] = 0x03;
272
273 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
274}
275
276static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable)
277{
278 struct tda8290_priv *priv = fe->analog_demod_priv;
279 unsigned char buf[] = { 0x01, 0x00 };
280
281 tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
282 tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
283
284 if (enable)
285 buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */
286 else
287 buf[1] = 0x00; /* reset active bit */
288
289 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
290}
291
292static void tda8295_set_video_std(struct dvb_frontend *fe)
293{
294 struct tda8290_priv *priv = fe->analog_demod_priv;
295 unsigned char buf[] = { 0x00, priv->tda8290_easy_mode };
296
297 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
298
299 tda8295_set_easy_mode(fe, 1);
300 msleep(20);
301 tda8295_set_easy_mode(fe, 0);
302}
303
304/*---------------------------------------------------------------------*/
305
306static void tda8295_agc1_out(struct dvb_frontend *fe, int enable)
307{
308 struct tda8290_priv *priv = fe->analog_demod_priv;
309 unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */
310
311 tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1);
312 tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1);
313
314 if (enable)
315 buf[1] &= ~0x40;
316 else
317 buf[1] |= 0x40;
318
319 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
320}
321
322static void tda8295_agc2_out(struct dvb_frontend *fe, int enable)
323{
324 struct tda8290_priv *priv = fe->analog_demod_priv;
325 unsigned char set_gpio_cf[] = { 0x44, 0x00 };
326 unsigned char set_gpio_val[] = { 0x46, 0x00 };
327
328 tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1);
329 tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1);
330 tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1);
331 tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1);
332
333 set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */
334
335 if (enable) {
336 set_gpio_cf[1] |= 0x01; /* config GPIO_0 as Open Drain Out */
337 set_gpio_val[1] &= 0xfe; /* set GPIO_0 pin low */
338 }
339 tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_cf, 2);
340 tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2);
341}
342
343static int tda8295_has_signal(struct dvb_frontend *fe)
344{
345 struct tda8290_priv *priv = fe->analog_demod_priv;
346
347 unsigned char hvpll_stat = 0x26;
348 unsigned char ret;
349
350 tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1);
351 tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1);
352 return (ret & 0x01) ? 65535 : 0;
353}
354
355/*---------------------------------------------------------------------*/
356
357static void tda8295_set_params(struct dvb_frontend *fe,
358 struct analog_parameters *params)
359{
360 struct tda8290_priv *priv = fe->analog_demod_priv;
361
362 unsigned char blanking_mode[] = { 0x1d, 0x00 };
363
364 set_audio(fe, params);
365
366 tuner_dbg("%s: freq = %d\n", __func__, params->frequency);
367
368 tda8295_power(fe, 1);
369 tda8295_agc1_out(fe, 1);
370
371 tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1);
372 tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1);
373
374 tda8295_set_video_std(fe);
375
376 blanking_mode[1] = 0x03;
377 tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2);
378 msleep(20);
379
380 tda8295_i2c_bridge(fe, 1);
381
382 if (fe->ops.tuner_ops.set_analog_params)
383 fe->ops.tuner_ops.set_analog_params(fe, params);
384
385 if (priv->cfg.agcf)
386 priv->cfg.agcf(fe);
387
388 if (tda8295_has_signal(fe))
389 tuner_dbg("tda8295 is locked\n");
390 else
391 tuner_dbg("tda8295 not locked, no signal?\n");
392
393 tda8295_i2c_bridge(fe, 0);
394}
395
396/*---------------------------------------------------------------------*/
397
398static int tda8290_has_signal(struct dvb_frontend *fe)
399{
400 struct tda8290_priv *priv = fe->analog_demod_priv;
401
402 unsigned char i2c_get_afc[1] = { 0x1B };
403 unsigned char afc = 0;
404
405 tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
406 tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1);
407 return (afc & 0x80)? 65535:0;
408}
409
410/*---------------------------------------------------------------------*/
411
412static void tda8290_standby(struct dvb_frontend *fe)
413{
414 struct tda8290_priv *priv = fe->analog_demod_priv;
415
416 unsigned char cb1[] = { 0x30, 0xD0 };
417 unsigned char tda8290_standby[] = { 0x00, 0x02 };
418 unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
419 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
420
421 tda8290_i2c_bridge(fe, 1);
422 if (priv->ver & TDA8275A)
423 cb1[1] = 0x90;
424 i2c_transfer(priv->i2c_props.adap, &msg, 1);
425 tda8290_i2c_bridge(fe, 0);
426 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2);
427 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2);
428}
429
430static void tda8295_standby(struct dvb_frontend *fe)
431{
432 tda8295_agc1_out(fe, 0); /* Put AGC in tri-state */
433
434 tda8295_power(fe, 0);
435}
436
437static void tda8290_init_if(struct dvb_frontend *fe)
438{
439 struct tda8290_priv *priv = fe->analog_demod_priv;
440
441 unsigned char set_VS[] = { 0x30, 0x6F };
442 unsigned char set_GP00_CF[] = { 0x20, 0x01 };
443 unsigned char set_GP01_CF[] = { 0x20, 0x0B };
444
445 if ((priv->cfg.config == 1) || (priv->cfg.config == 2))
446 tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2);
447 else
448 tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2);
449 tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2);
450}
451
452static void tda8295_init_if(struct dvb_frontend *fe)
453{
454 struct tda8290_priv *priv = fe->analog_demod_priv;
455
456 static unsigned char set_adc_ctl[] = { 0x33, 0x14 };
457 static unsigned char set_adc_ctl2[] = { 0x34, 0x00 };
458 static unsigned char set_pll_reg6[] = { 0x3e, 0x63 };
459 static unsigned char set_pll_reg0[] = { 0x38, 0x23 };
460 static unsigned char set_pll_reg7[] = { 0x3f, 0x01 };
461 static unsigned char set_pll_reg10[] = { 0x42, 0x61 };
462 static unsigned char set_gpio_reg0[] = { 0x44, 0x0b };
463
464 tda8295_power(fe, 1);
465
466 tda8295_set_easy_mode(fe, 0);
467 tda8295_set_video_std(fe);
468
469 tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl, 2);
470 tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl2, 2);
471 tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg6, 2);
472 tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg0, 2);
473 tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg7, 2);
474 tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg10, 2);
475 tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_reg0, 2);
476
477 tda8295_agc1_out(fe, 0);
478 tda8295_agc2_out(fe, 0);
479}
480
481static void tda8290_init_tuner(struct dvb_frontend *fe)
482{
483 struct tda8290_priv *priv = fe->analog_demod_priv;
484 unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
485 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
486 unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
487 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
488 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0,
489 .buf=tda8275_init, .len = 14};
490 if (priv->ver & TDA8275A)
491 msg.buf = tda8275a_init;
492
493 tda8290_i2c_bridge(fe, 1);
494 i2c_transfer(priv->i2c_props.adap, &msg, 1);
495 tda8290_i2c_bridge(fe, 0);
496}
497
498/*---------------------------------------------------------------------*/
499
500static void tda829x_release(struct dvb_frontend *fe)
501{
502 struct tda8290_priv *priv = fe->analog_demod_priv;
503
504 /* only try to release the tuner if we've
505 * attached it from within this module */
506 if (priv->ver & (TDA18271 | TDA8275 | TDA8275A))
507 if (fe->ops.tuner_ops.release)
508 fe->ops.tuner_ops.release(fe);
509
510 kfree(fe->analog_demod_priv);
511 fe->analog_demod_priv = NULL;
512}
513
514static struct tda18271_config tda829x_tda18271_config = {
515 .gate = TDA18271_GATE_ANALOG,
516};
517
518static int tda829x_find_tuner(struct dvb_frontend *fe)
519{
520 struct tda8290_priv *priv = fe->analog_demod_priv;
521 struct analog_demod_ops *analog_ops = &fe->ops.analog_ops;
522 int i, ret, tuners_found;
523 u32 tuner_addrs;
524 u8 data;
525 struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 };
526
527 if (NULL == analog_ops->i2c_gate_ctrl)
528 return -EINVAL;
529
530 analog_ops->i2c_gate_ctrl(fe, 1);
531
532 /* probe for tuner chip */
533 tuners_found = 0;
534 tuner_addrs = 0;
535 for (i = 0x60; i <= 0x63; i++) {
536 msg.addr = i;
537 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
538 if (ret == 1) {
539 tuners_found++;
540 tuner_addrs = (tuner_addrs << 8) + i;
541 }
542 }
543 /* if there is more than one tuner, we expect the right one is
544 behind the bridge and we choose the highest address that doesn't
545 give a response now
546 */
547
548 analog_ops->i2c_gate_ctrl(fe, 0);
549
550 if (tuners_found > 1)
551 for (i = 0; i < tuners_found; i++) {
552 msg.addr = tuner_addrs & 0xff;
553 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
554 if (ret == 1)
555 tuner_addrs = tuner_addrs >> 8;
556 else
557 break;
558 }
559
560 if (tuner_addrs == 0) {
561 tuner_addrs = 0x60;
562 tuner_info("could not clearly identify tuner address, "
563 "defaulting to %x\n", tuner_addrs);
564 } else {
565 tuner_addrs = tuner_addrs & 0xff;
566 tuner_info("setting tuner address to %x\n", tuner_addrs);
567 }
568 priv->tda827x_addr = tuner_addrs;
569 msg.addr = tuner_addrs;
570
571 analog_ops->i2c_gate_ctrl(fe, 1);
572 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
573
574 if (ret != 1) {
575 tuner_warn("tuner access failed!\n");
576 return -EREMOTEIO;
577 }
578
579 if ((data == 0x83) || (data == 0x84)) {
580 priv->ver |= TDA18271;
581 tda18271_attach(fe, priv->tda827x_addr,
582 priv->i2c_props.adap,
583 &tda829x_tda18271_config);
584 } else {
585 if ((data & 0x3c) == 0)
586 priv->ver |= TDA8275;
587 else
588 priv->ver |= TDA8275A;
589
590 tda827x_attach(fe, priv->tda827x_addr, priv->i2c_props.adap, &priv->cfg);
591 priv->cfg.switch_addr = priv->i2c_props.addr;
592 }
593 if (fe->ops.tuner_ops.init)
594 fe->ops.tuner_ops.init(fe);
595
596 if (fe->ops.tuner_ops.sleep)
597 fe->ops.tuner_ops.sleep(fe);
598
599 analog_ops->i2c_gate_ctrl(fe, 0);
600
601 return 0;
602}
603
604static int tda8290_probe(struct tuner_i2c_props *i2c_props)
605{
606#define TDA8290_ID 0x89
607 unsigned char tda8290_id[] = { 0x1f, 0x00 };
608
609 /* detect tda8290 */
610 tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1);
611 tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1);
612
613 if (tda8290_id[1] == TDA8290_ID) {
614 if (debug)
615 printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n",
616 __func__, i2c_adapter_id(i2c_props->adap),
617 i2c_props->addr);
618 return 0;
619 }
620
621 return -ENODEV;
622}
623
624static int tda8295_probe(struct tuner_i2c_props *i2c_props)
625{
626#define TDA8295_ID 0x8a
627 unsigned char tda8295_id[] = { 0x2f, 0x00 };
628
629 /* detect tda8295 */
630 tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1);
631 tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1);
632
633 if (tda8295_id[1] == TDA8295_ID) {
634 if (debug)
635 printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n",
636 __func__, i2c_adapter_id(i2c_props->adap),
637 i2c_props->addr);
638 return 0;
639 }
640
641 return -ENODEV;
642}
643
644static struct analog_demod_ops tda8290_ops = {
645 .set_params = tda8290_set_params,
646 .has_signal = tda8290_has_signal,
647 .standby = tda8290_standby,
648 .release = tda829x_release,
649 .i2c_gate_ctrl = tda8290_i2c_bridge,
650};
651
652static struct analog_demod_ops tda8295_ops = {
653 .set_params = tda8295_set_params,
654 .has_signal = tda8295_has_signal,
655 .standby = tda8295_standby,
656 .release = tda829x_release,
657 .i2c_gate_ctrl = tda8295_i2c_bridge,
658};
659
660struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
661 struct i2c_adapter *i2c_adap, u8 i2c_addr,
662 struct tda829x_config *cfg)
663{
664 struct tda8290_priv *priv = NULL;
665 char *name;
666
667 priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL);
668 if (priv == NULL)
669 return NULL;
670 fe->analog_demod_priv = priv;
671
672 priv->i2c_props.addr = i2c_addr;
673 priv->i2c_props.adap = i2c_adap;
674 priv->i2c_props.name = "tda829x";
675 if (cfg) {
676 priv->cfg.config = cfg->lna_cfg;
677 priv->cfg.tuner_callback = cfg->tuner_callback;
678 }
679
680 if (tda8290_probe(&priv->i2c_props) == 0) {
681 priv->ver = TDA8290;
682 memcpy(&fe->ops.analog_ops, &tda8290_ops,
683 sizeof(struct analog_demod_ops));
684 }
685
686 if (tda8295_probe(&priv->i2c_props) == 0) {
687 priv->ver = TDA8295;
688 memcpy(&fe->ops.analog_ops, &tda8295_ops,
689 sizeof(struct analog_demod_ops));
690 }
691
692 if ((!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) &&
693 (tda829x_find_tuner(fe) < 0))
694 goto fail;
695
696 switch (priv->ver) {
697 case TDA8290:
698 name = "tda8290";
699 break;
700 case TDA8295:
701 name = "tda8295";
702 break;
703 case TDA8290 | TDA8275:
704 name = "tda8290+75";
705 break;
706 case TDA8295 | TDA8275:
707 name = "tda8295+75";
708 break;
709 case TDA8290 | TDA8275A:
710 name = "tda8290+75a";
711 break;
712 case TDA8295 | TDA8275A:
713 name = "tda8295+75a";
714 break;
715 case TDA8290 | TDA18271:
716 name = "tda8290+18271";
717 break;
718 case TDA8295 | TDA18271:
719 name = "tda8295+18271";
720 break;
721 default:
722 goto fail;
723 }
724 tuner_info("type set to %s\n", name);
725
726 fe->ops.analog_ops.info.name = name;
727
728 if (priv->ver & TDA8290) {
729 tda8290_init_tuner(fe);
730 tda8290_init_if(fe);
731 } else if (priv->ver & TDA8295)
732 tda8295_init_if(fe);
733
734 return fe;
735
736fail:
737 tda829x_release(fe);
738 return NULL;
739}
740EXPORT_SYMBOL_GPL(tda829x_attach);
741
742int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
743{
744 struct tuner_i2c_props i2c_props = {
745 .adap = i2c_adap,
746 .addr = i2c_addr,
747 };
748
749 unsigned char soft_reset[] = { 0x00, 0x00 };
750 unsigned char easy_mode_b[] = { 0x01, 0x02 };
751 unsigned char easy_mode_g[] = { 0x01, 0x04 };
752 unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
753 unsigned char addr_dto_lsb = 0x07;
754 unsigned char data;
755#define PROBE_BUFFER_SIZE 8
756 unsigned char buf[PROBE_BUFFER_SIZE];
757 int i;
758
759 /* rule out tda9887, which would return the same byte repeatedly */
760 tuner_i2c_xfer_send(&i2c_props, soft_reset, 1);
761 tuner_i2c_xfer_recv(&i2c_props, buf, PROBE_BUFFER_SIZE);
762 for (i = 1; i < PROBE_BUFFER_SIZE; i++) {
763 if (buf[i] != buf[0])
764 break;
765 }
766
767 /* all bytes are equal, not a tda829x - probably a tda9887 */
768 if (i == PROBE_BUFFER_SIZE)
769 return -ENODEV;
770
771 if ((tda8290_probe(&i2c_props) == 0) ||
772 (tda8295_probe(&i2c_props) == 0))
773 return 0;
774
775 /* fall back to old probing method */
776 tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
777 tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
778 tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
779 tuner_i2c_xfer_recv(&i2c_props, &data, 1);
780 if (data == 0) {
781 tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
782 tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
783 tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
784 tuner_i2c_xfer_recv(&i2c_props, &data, 1);
785 if (data == 0x7b) {
786 return 0;
787 }
788 }
789 tuner_i2c_xfer_send(&i2c_props, restore_9886, 3);
790 return -ENODEV;
791}
792EXPORT_SYMBOL_GPL(tda829x_probe);
793
794MODULE_DESCRIPTION("Philips/NXP TDA8290/TDA8295 analog IF demodulator driver");
795MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann, Michael Krufky");
796MODULE_LICENSE("GPL");
797
798/*
799 * Overrides for Emacs so that we follow Linus's tabbing style.
800 * ---------------------------------------------------------------------------
801 * Local variables:
802 * c-basic-offset: 8
803 * End:
804 */
diff --git a/drivers/media/video/tda8290.h b/drivers/media/video/tda8290.h
deleted file mode 100644
index d3bbf276a469..000000000000
--- a/drivers/media/video/tda8290.h
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TDA8290_H__
18#define __TDA8290_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23struct tda829x_config {
24 unsigned int lna_cfg;
25 int (*tuner_callback) (void *dev, int command, int arg);
26
27 unsigned int probe_tuner:1;
28#define TDA829X_PROBE_TUNER 0
29#define TDA829X_DONT_PROBE 1
30};
31
32#if defined(CONFIG_TUNER_TDA8290) || (defined(CONFIG_TUNER_TDA8290_MODULE) && defined(MODULE))
33extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr);
34
35extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
36 struct i2c_adapter *i2c_adap,
37 u8 i2c_addr,
38 struct tda829x_config *cfg);
39#else
40static inline int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
43 return -EINVAL;
44}
45
46static inline struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
47 struct i2c_adapter *i2c_adap,
48 u8 i2c_addr,
49 struct tda829x_config *cfg)
50{
51 printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
52 __func__);
53 return NULL;
54}
55#endif
56
57#endif /* __TDA8290_H__ */
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
deleted file mode 100644
index a0545ba957b0..000000000000
--- a/drivers/media/video/tda9887.c
+++ /dev/null
@@ -1,717 +0,0 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/i2c.h>
4#include <linux/types.h>
5#include <linux/init.h>
6#include <linux/errno.h>
7#include <linux/slab.h>
8#include <linux/delay.h>
9#include <linux/videodev.h>
10#include <media/v4l2-common.h>
11#include <media/tuner.h>
12#include "tuner-i2c.h"
13#include "tda9887.h"
14
15
16/* Chips:
17 TDA9885 (PAL, NTSC)
18 TDA9886 (PAL, SECAM, NTSC)
19 TDA9887 (PAL, SECAM, NTSC, FM Radio)
20
21 Used as part of several tuners
22*/
23
24static int debug;
25module_param(debug, int, 0644);
26MODULE_PARM_DESC(debug, "enable verbose debug messages");
27
28static DEFINE_MUTEX(tda9887_list_mutex);
29static LIST_HEAD(hybrid_tuner_instance_list);
30
31struct tda9887_priv {
32 struct tuner_i2c_props i2c_props;
33 struct list_head hybrid_tuner_instance_list;
34
35 unsigned char data[4];
36 unsigned int config;
37 unsigned int mode;
38 unsigned int audmode;
39 v4l2_std_id std;
40};
41
42/* ---------------------------------------------------------------------- */
43
44#define UNSET (-1U)
45
46struct tvnorm {
47 v4l2_std_id std;
48 char *name;
49 unsigned char b;
50 unsigned char c;
51 unsigned char e;
52};
53
54/* ---------------------------------------------------------------------- */
55
56//
57// TDA defines
58//
59
60//// first reg (b)
61#define cVideoTrapBypassOFF 0x00 // bit b0
62#define cVideoTrapBypassON 0x01 // bit b0
63
64#define cAutoMuteFmInactive 0x00 // bit b1
65#define cAutoMuteFmActive 0x02 // bit b1
66
67#define cIntercarrier 0x00 // bit b2
68#define cQSS 0x04 // bit b2
69
70#define cPositiveAmTV 0x00 // bit b3:4
71#define cFmRadio 0x08 // bit b3:4
72#define cNegativeFmTV 0x10 // bit b3:4
73
74
75#define cForcedMuteAudioON 0x20 // bit b5
76#define cForcedMuteAudioOFF 0x00 // bit b5
77
78#define cOutputPort1Active 0x00 // bit b6
79#define cOutputPort1Inactive 0x40 // bit b6
80
81#define cOutputPort2Active 0x00 // bit b7
82#define cOutputPort2Inactive 0x80 // bit b7
83
84
85//// second reg (c)
86#define cDeemphasisOFF 0x00 // bit c5
87#define cDeemphasisON 0x20 // bit c5
88
89#define cDeemphasis75 0x00 // bit c6
90#define cDeemphasis50 0x40 // bit c6
91
92#define cAudioGain0 0x00 // bit c7
93#define cAudioGain6 0x80 // bit c7
94
95#define cTopMask 0x1f // bit c0:4
96#define cTopDefault 0x10 // bit c0:4
97
98//// third reg (e)
99#define cAudioIF_4_5 0x00 // bit e0:1
100#define cAudioIF_5_5 0x01 // bit e0:1
101#define cAudioIF_6_0 0x02 // bit e0:1
102#define cAudioIF_6_5 0x03 // bit e0:1
103
104
105#define cVideoIFMask 0x1c // bit e2:4
106/* Video IF selection in TV Mode (bit B3=0) */
107#define cVideoIF_58_75 0x00 // bit e2:4
108#define cVideoIF_45_75 0x04 // bit e2:4
109#define cVideoIF_38_90 0x08 // bit e2:4
110#define cVideoIF_38_00 0x0C // bit e2:4
111#define cVideoIF_33_90 0x10 // bit e2:4
112#define cVideoIF_33_40 0x14 // bit e2:4
113#define cRadioIF_45_75 0x18 // bit e2:4
114#define cRadioIF_38_90 0x1C // bit e2:4
115
116/* IF1 selection in Radio Mode (bit B3=1) */
117#define cRadioIF_33_30 0x00 // bit e2,4 (also 0x10,0x14)
118#define cRadioIF_41_30 0x04 // bit e2,4
119
120/* Output of AFC pin in radio mode when bit E7=1 */
121#define cRadioAGC_SIF 0x00 // bit e3
122#define cRadioAGC_FM 0x08 // bit e3
123
124#define cTunerGainNormal 0x00 // bit e5
125#define cTunerGainLow 0x20 // bit e5
126
127#define cGating_18 0x00 // bit e6
128#define cGating_36 0x40 // bit e6
129
130#define cAgcOutON 0x80 // bit e7
131#define cAgcOutOFF 0x00 // bit e7
132
133/* ---------------------------------------------------------------------- */
134
135static struct tvnorm tvnorms[] = {
136 {
137 .std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
138 .name = "PAL-BGHN",
139 .b = ( cNegativeFmTV |
140 cQSS ),
141 .c = ( cDeemphasisON |
142 cDeemphasis50 |
143 cTopDefault),
144 .e = ( cGating_36 |
145 cAudioIF_5_5 |
146 cVideoIF_38_90 ),
147 },{
148 .std = V4L2_STD_PAL_I,
149 .name = "PAL-I",
150 .b = ( cNegativeFmTV |
151 cQSS ),
152 .c = ( cDeemphasisON |
153 cDeemphasis50 |
154 cTopDefault),
155 .e = ( cGating_36 |
156 cAudioIF_6_0 |
157 cVideoIF_38_90 ),
158 },{
159 .std = V4L2_STD_PAL_DK,
160 .name = "PAL-DK",
161 .b = ( cNegativeFmTV |
162 cQSS ),
163 .c = ( cDeemphasisON |
164 cDeemphasis50 |
165 cTopDefault),
166 .e = ( cGating_36 |
167 cAudioIF_6_5 |
168 cVideoIF_38_90 ),
169 },{
170 .std = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
171 .name = "PAL-M/Nc",
172 .b = ( cNegativeFmTV |
173 cQSS ),
174 .c = ( cDeemphasisON |
175 cDeemphasis75 |
176 cTopDefault),
177 .e = ( cGating_36 |
178 cAudioIF_4_5 |
179 cVideoIF_45_75 ),
180 },{
181 .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
182 .name = "SECAM-BGH",
183 .b = ( cPositiveAmTV |
184 cQSS ),
185 .c = ( cTopDefault),
186 .e = ( cGating_36 |
187 cAudioIF_5_5 |
188 cVideoIF_38_90 ),
189 },{
190 .std = V4L2_STD_SECAM_L,
191 .name = "SECAM-L",
192 .b = ( cPositiveAmTV |
193 cQSS ),
194 .c = ( cTopDefault),
195 .e = ( cGating_36 |
196 cAudioIF_6_5 |
197 cVideoIF_38_90 ),
198 },{
199 .std = V4L2_STD_SECAM_LC,
200 .name = "SECAM-L'",
201 .b = ( cOutputPort2Inactive |
202 cPositiveAmTV |
203 cQSS ),
204 .c = ( cTopDefault),
205 .e = ( cGating_36 |
206 cAudioIF_6_5 |
207 cVideoIF_33_90 ),
208 },{
209 .std = V4L2_STD_SECAM_DK,
210 .name = "SECAM-DK",
211 .b = ( cNegativeFmTV |
212 cQSS ),
213 .c = ( cDeemphasisON |
214 cDeemphasis50 |
215 cTopDefault),
216 .e = ( cGating_36 |
217 cAudioIF_6_5 |
218 cVideoIF_38_90 ),
219 },{
220 .std = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
221 .name = "NTSC-M",
222 .b = ( cNegativeFmTV |
223 cQSS ),
224 .c = ( cDeemphasisON |
225 cDeemphasis75 |
226 cTopDefault),
227 .e = ( cGating_36 |
228 cAudioIF_4_5 |
229 cVideoIF_45_75 ),
230 },{
231 .std = V4L2_STD_NTSC_M_JP,
232 .name = "NTSC-M-JP",
233 .b = ( cNegativeFmTV |
234 cQSS ),
235 .c = ( cDeemphasisON |
236 cDeemphasis50 |
237 cTopDefault),
238 .e = ( cGating_36 |
239 cAudioIF_4_5 |
240 cVideoIF_58_75 ),
241 }
242};
243
244static struct tvnorm radio_stereo = {
245 .name = "Radio Stereo",
246 .b = ( cFmRadio |
247 cQSS ),
248 .c = ( cDeemphasisOFF |
249 cAudioGain6 |
250 cTopDefault),
251 .e = ( cTunerGainLow |
252 cAudioIF_5_5 |
253 cRadioIF_38_90 ),
254};
255
256static struct tvnorm radio_mono = {
257 .name = "Radio Mono",
258 .b = ( cFmRadio |
259 cQSS ),
260 .c = ( cDeemphasisON |
261 cDeemphasis75 |
262 cTopDefault),
263 .e = ( cTunerGainLow |
264 cAudioIF_5_5 |
265 cRadioIF_38_90 ),
266};
267
268/* ---------------------------------------------------------------------- */
269
270static void dump_read_message(struct dvb_frontend *fe, unsigned char *buf)
271{
272 struct tda9887_priv *priv = fe->analog_demod_priv;
273
274 static char *afc[16] = {
275 "- 12.5 kHz",
276 "- 37.5 kHz",
277 "- 62.5 kHz",
278 "- 87.5 kHz",
279 "-112.5 kHz",
280 "-137.5 kHz",
281 "-162.5 kHz",
282 "-187.5 kHz [min]",
283 "+187.5 kHz [max]",
284 "+162.5 kHz",
285 "+137.5 kHz",
286 "+112.5 kHz",
287 "+ 87.5 kHz",
288 "+ 62.5 kHz",
289 "+ 37.5 kHz",
290 "+ 12.5 kHz",
291 };
292 tuner_info("read: 0x%2x\n", buf[0]);
293 tuner_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
294 tuner_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
295 tuner_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
296 tuner_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
297 tuner_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
298}
299
300static void dump_write_message(struct dvb_frontend *fe, unsigned char *buf)
301{
302 struct tda9887_priv *priv = fe->analog_demod_priv;
303
304 static char *sound[4] = {
305 "AM/TV",
306 "FM/radio",
307 "FM/TV",
308 "FM/radio"
309 };
310 static char *adjust[32] = {
311 "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
312 "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1",
313 "0", "+1", "+2", "+3", "+4", "+5", "+6", "+7",
314 "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15"
315 };
316 static char *deemph[4] = {
317 "no", "no", "75", "50"
318 };
319 static char *carrier[4] = {
320 "4.5 MHz",
321 "5.5 MHz",
322 "6.0 MHz",
323 "6.5 MHz / AM"
324 };
325 static char *vif[8] = {
326 "58.75 MHz",
327 "45.75 MHz",
328 "38.9 MHz",
329 "38.0 MHz",
330 "33.9 MHz",
331 "33.4 MHz",
332 "45.75 MHz + pin13",
333 "38.9 MHz + pin13",
334 };
335 static char *rif[4] = {
336 "44 MHz",
337 "52 MHz",
338 "52 MHz",
339 "44 MHz",
340 };
341
342 tuner_info("write: byte B 0x%02x\n", buf[1]);
343 tuner_info(" B0 video mode : %s\n",
344 (buf[1] & 0x01) ? "video trap" : "sound trap");
345 tuner_info(" B1 auto mute fm : %s\n",
346 (buf[1] & 0x02) ? "yes" : "no");
347 tuner_info(" B2 carrier mode : %s\n",
348 (buf[1] & 0x04) ? "QSS" : "Intercarrier");
349 tuner_info(" B3-4 tv sound/radio : %s\n",
350 sound[(buf[1] & 0x18) >> 3]);
351 tuner_info(" B5 force mute audio: %s\n",
352 (buf[1] & 0x20) ? "yes" : "no");
353 tuner_info(" B6 output port 1 : %s\n",
354 (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
355 tuner_info(" B7 output port 2 : %s\n",
356 (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
357
358 tuner_info("write: byte C 0x%02x\n", buf[2]);
359 tuner_info(" C0-4 top adjustment : %s dB\n",
360 adjust[buf[2] & 0x1f]);
361 tuner_info(" C5-6 de-emphasis : %s\n",
362 deemph[(buf[2] & 0x60) >> 5]);
363 tuner_info(" C7 audio gain : %s\n",
364 (buf[2] & 0x80) ? "-6" : "0");
365
366 tuner_info("write: byte E 0x%02x\n", buf[3]);
367 tuner_info(" E0-1 sound carrier : %s\n",
368 carrier[(buf[3] & 0x03)]);
369 tuner_info(" E6 l pll gating : %s\n",
370 (buf[3] & 0x40) ? "36" : "13");
371
372 if (buf[1] & 0x08) {
373 /* radio */
374 tuner_info(" E2-4 video if : %s\n",
375 rif[(buf[3] & 0x0c) >> 2]);
376 tuner_info(" E7 vif agc output : %s\n",
377 (buf[3] & 0x80)
378 ? ((buf[3] & 0x10) ? "fm-agc radio" :
379 "sif-agc radio")
380 : "fm radio carrier afc");
381 } else {
382 /* video */
383 tuner_info(" E2-4 video if : %s\n",
384 vif[(buf[3] & 0x1c) >> 2]);
385 tuner_info(" E5 tuner gain : %s\n",
386 (buf[3] & 0x80)
387 ? ((buf[3] & 0x20) ? "external" : "normal")
388 : ((buf[3] & 0x20) ? "minimum" : "normal"));
389 tuner_info(" E7 vif agc output : %s\n",
390 (buf[3] & 0x80) ? ((buf[3] & 0x20)
391 ? "pin3 port, pin22 vif agc out"
392 : "pin22 port, pin3 vif acg ext in")
393 : "pin3+pin22 port");
394 }
395 tuner_info("--\n");
396}
397
398/* ---------------------------------------------------------------------- */
399
400static int tda9887_set_tvnorm(struct dvb_frontend *fe)
401{
402 struct tda9887_priv *priv = fe->analog_demod_priv;
403 struct tvnorm *norm = NULL;
404 char *buf = priv->data;
405 int i;
406
407 if (priv->mode == V4L2_TUNER_RADIO) {
408 if (priv->audmode == V4L2_TUNER_MODE_MONO)
409 norm = &radio_mono;
410 else
411 norm = &radio_stereo;
412 } else {
413 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
414 if (tvnorms[i].std & priv->std) {
415 norm = tvnorms+i;
416 break;
417 }
418 }
419 }
420 if (NULL == norm) {
421 tuner_dbg("Unsupported tvnorm entry - audio muted\n");
422 return -1;
423 }
424
425 tuner_dbg("configure for: %s\n", norm->name);
426 buf[1] = norm->b;
427 buf[2] = norm->c;
428 buf[3] = norm->e;
429 return 0;
430}
431
432static unsigned int port1 = UNSET;
433static unsigned int port2 = UNSET;
434static unsigned int qss = UNSET;
435static unsigned int adjust = UNSET;
436
437module_param(port1, int, 0644);
438module_param(port2, int, 0644);
439module_param(qss, int, 0644);
440module_param(adjust, int, 0644);
441
442static int tda9887_set_insmod(struct dvb_frontend *fe)
443{
444 struct tda9887_priv *priv = fe->analog_demod_priv;
445 char *buf = priv->data;
446
447 if (UNSET != port1) {
448 if (port1)
449 buf[1] |= cOutputPort1Inactive;
450 else
451 buf[1] &= ~cOutputPort1Inactive;
452 }
453 if (UNSET != port2) {
454 if (port2)
455 buf[1] |= cOutputPort2Inactive;
456 else
457 buf[1] &= ~cOutputPort2Inactive;
458 }
459
460 if (UNSET != qss) {
461 if (qss)
462 buf[1] |= cQSS;
463 else
464 buf[1] &= ~cQSS;
465 }
466
467 if (adjust >= 0x00 && adjust < 0x20) {
468 buf[2] &= ~cTopMask;
469 buf[2] |= adjust;
470 }
471 return 0;
472}
473
474static int tda9887_do_config(struct dvb_frontend *fe)
475{
476 struct tda9887_priv *priv = fe->analog_demod_priv;
477 char *buf = priv->data;
478
479 if (priv->config & TDA9887_PORT1_ACTIVE)
480 buf[1] &= ~cOutputPort1Inactive;
481 if (priv->config & TDA9887_PORT1_INACTIVE)
482 buf[1] |= cOutputPort1Inactive;
483 if (priv->config & TDA9887_PORT2_ACTIVE)
484 buf[1] &= ~cOutputPort2Inactive;
485 if (priv->config & TDA9887_PORT2_INACTIVE)
486 buf[1] |= cOutputPort2Inactive;
487
488 if (priv->config & TDA9887_QSS)
489 buf[1] |= cQSS;
490 if (priv->config & TDA9887_INTERCARRIER)
491 buf[1] &= ~cQSS;
492
493 if (priv->config & TDA9887_AUTOMUTE)
494 buf[1] |= cAutoMuteFmActive;
495 if (priv->config & TDA9887_DEEMPHASIS_MASK) {
496 buf[2] &= ~0x60;
497 switch (priv->config & TDA9887_DEEMPHASIS_MASK) {
498 case TDA9887_DEEMPHASIS_NONE:
499 buf[2] |= cDeemphasisOFF;
500 break;
501 case TDA9887_DEEMPHASIS_50:
502 buf[2] |= cDeemphasisON | cDeemphasis50;
503 break;
504 case TDA9887_DEEMPHASIS_75:
505 buf[2] |= cDeemphasisON | cDeemphasis75;
506 break;
507 }
508 }
509 if (priv->config & TDA9887_TOP_SET) {
510 buf[2] &= ~cTopMask;
511 buf[2] |= (priv->config >> 8) & cTopMask;
512 }
513 if ((priv->config & TDA9887_INTERCARRIER_NTSC) &&
514 (priv->std & V4L2_STD_NTSC))
515 buf[1] &= ~cQSS;
516 if (priv->config & TDA9887_GATING_18)
517 buf[3] &= ~cGating_36;
518
519 if (priv->mode == V4L2_TUNER_RADIO) {
520 if (priv->config & TDA9887_RIF_41_3) {
521 buf[3] &= ~cVideoIFMask;
522 buf[3] |= cRadioIF_41_30;
523 }
524 if (priv->config & TDA9887_GAIN_NORMAL)
525 buf[3] &= ~cTunerGainLow;
526 }
527
528 return 0;
529}
530
531/* ---------------------------------------------------------------------- */
532
533static int tda9887_status(struct dvb_frontend *fe)
534{
535 struct tda9887_priv *priv = fe->analog_demod_priv;
536 unsigned char buf[1];
537 int rc;
538
539 memset(buf,0,sizeof(buf));
540 if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,1)))
541 tuner_info("i2c i/o error: rc == %d (should be 1)\n", rc);
542 dump_read_message(fe, buf);
543 return 0;
544}
545
546static void tda9887_configure(struct dvb_frontend *fe)
547{
548 struct tda9887_priv *priv = fe->analog_demod_priv;
549 int rc;
550
551 memset(priv->data,0,sizeof(priv->data));
552 tda9887_set_tvnorm(fe);
553
554 /* A note on the port settings:
555 These settings tend to depend on the specifics of the board.
556 By default they are set to inactive (bit value 1) by this driver,
557 overwriting any changes made by the tvnorm. This means that it
558 is the responsibility of the module using the tda9887 to set
559 these values in case of changes in the tvnorm.
560 In many cases port 2 should be made active (0) when selecting
561 SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
562
563 For the other standards the tda9887 application note says that
564 the ports should be set to active (0), but, again, that may
565 differ depending on the precise hardware configuration.
566 */
567 priv->data[1] |= cOutputPort1Inactive;
568 priv->data[1] |= cOutputPort2Inactive;
569
570 tda9887_do_config(fe);
571 tda9887_set_insmod(fe);
572
573 if (priv->mode == T_STANDBY)
574 priv->data[1] |= cForcedMuteAudioON;
575
576 tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
577 priv->data[1], priv->data[2], priv->data[3]);
578 if (debug > 1)
579 dump_write_message(fe, priv->data);
580
581 if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,priv->data,4)))
582 tuner_info("i2c i/o error: rc == %d (should be 4)\n", rc);
583
584 if (debug > 2) {
585 msleep_interruptible(1000);
586 tda9887_status(fe);
587 }
588}
589
590/* ---------------------------------------------------------------------- */
591
592static void tda9887_tuner_status(struct dvb_frontend *fe)
593{
594 struct tda9887_priv *priv = fe->analog_demod_priv;
595 tuner_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n",
596 priv->data[1], priv->data[2], priv->data[3]);
597}
598
599static int tda9887_get_afc(struct dvb_frontend *fe)
600{
601 struct tda9887_priv *priv = fe->analog_demod_priv;
602 static int AFC_BITS_2_kHz[] = {
603 -12500, -37500, -62500, -97500,
604 -112500, -137500, -162500, -187500,
605 187500, 162500, 137500, 112500,
606 97500 , 62500, 37500 , 12500
607 };
608 int afc=0;
609 __u8 reg = 0;
610
611 if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,&reg,1))
612 afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
613
614 return afc;
615}
616
617static void tda9887_standby(struct dvb_frontend *fe)
618{
619 struct tda9887_priv *priv = fe->analog_demod_priv;
620
621 priv->mode = T_STANDBY;
622
623 tda9887_configure(fe);
624}
625
626static void tda9887_set_params(struct dvb_frontend *fe,
627 struct analog_parameters *params)
628{
629 struct tda9887_priv *priv = fe->analog_demod_priv;
630
631 priv->mode = params->mode;
632 priv->audmode = params->audmode;
633 priv->std = params->std;
634 tda9887_configure(fe);
635}
636
637static int tda9887_set_config(struct dvb_frontend *fe, void *priv_cfg)
638{
639 struct tda9887_priv *priv = fe->analog_demod_priv;
640
641 priv->config = *(unsigned int *)priv_cfg;
642 tda9887_configure(fe);
643
644 return 0;
645}
646
647static void tda9887_release(struct dvb_frontend *fe)
648{
649 struct tda9887_priv *priv = fe->analog_demod_priv;
650
651 mutex_lock(&tda9887_list_mutex);
652
653 if (priv)
654 hybrid_tuner_release_state(priv);
655
656 mutex_unlock(&tda9887_list_mutex);
657
658 fe->analog_demod_priv = NULL;
659}
660
661static struct analog_demod_ops tda9887_ops = {
662 .info = {
663 .name = "tda9887",
664 },
665 .set_params = tda9887_set_params,
666 .standby = tda9887_standby,
667 .tuner_status = tda9887_tuner_status,
668 .get_afc = tda9887_get_afc,
669 .release = tda9887_release,
670 .set_config = tda9887_set_config,
671};
672
673struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
674 struct i2c_adapter *i2c_adap,
675 u8 i2c_addr)
676{
677 struct tda9887_priv *priv = NULL;
678 int instance;
679
680 mutex_lock(&tda9887_list_mutex);
681
682 instance = hybrid_tuner_request_state(struct tda9887_priv, priv,
683 hybrid_tuner_instance_list,
684 i2c_adap, i2c_addr, "tda9887");
685 switch (instance) {
686 case 0:
687 mutex_unlock(&tda9887_list_mutex);
688 return NULL;
689 break;
690 case 1:
691 fe->analog_demod_priv = priv;
692 priv->mode = T_STANDBY;
693 tuner_info("tda988[5/6/7] found\n");
694 break;
695 default:
696 fe->analog_demod_priv = priv;
697 break;
698 }
699
700 mutex_unlock(&tda9887_list_mutex);
701
702 memcpy(&fe->ops.analog_ops, &tda9887_ops,
703 sizeof(struct analog_demod_ops));
704
705 return fe;
706}
707EXPORT_SYMBOL_GPL(tda9887_attach);
708
709MODULE_LICENSE("GPL");
710
711/*
712 * Overrides for Emacs so that we follow Linus's tabbing style.
713 * ---------------------------------------------------------------------------
714 * Local variables:
715 * c-basic-offset: 8
716 * End:
717 */
diff --git a/drivers/media/video/tda9887.h b/drivers/media/video/tda9887.h
deleted file mode 100644
index be49dcbfc70e..000000000000
--- a/drivers/media/video/tda9887.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TDA9887_H__
18#define __TDA9887_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23/* ------------------------------------------------------------------------ */
24#if defined(CONFIG_TUNER_TDA9887) || (defined(CONFIG_TUNER_TDA9887_MODULE) && defined(MODULE))
25extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
26 struct i2c_adapter *i2c_adap,
27 u8 i2c_addr);
28#else
29static inline struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
30 struct i2c_adapter *i2c_adap,
31 u8 i2c_addr)
32{
33 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
34 return NULL;
35}
36#endif
37
38#endif /* __TDA9887_H__ */
diff --git a/drivers/media/video/tea5761.c b/drivers/media/video/tea5761.c
deleted file mode 100644
index b93cdef9ac73..000000000000
--- a/drivers/media/video/tea5761.c
+++ /dev/null
@@ -1,324 +0,0 @@
1/*
2 * For Philips TEA5761 FM Chip
3 * I2C address is allways 0x20 (0x10 at 7-bit mode).
4 *
5 * Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org)
6 * This code is placed under the terms of the GNUv2 General Public License
7 *
8 */
9
10#include <linux/i2c.h>
11#include <linux/delay.h>
12#include <linux/videodev.h>
13#include <media/tuner.h>
14#include "tuner-i2c.h"
15#include "tea5761.h"
16
17static int debug;
18module_param(debug, int, 0644);
19MODULE_PARM_DESC(debug, "enable verbose debug messages");
20
21struct tea5761_priv {
22 struct tuner_i2c_props i2c_props;
23
24 u32 frequency;
25};
26
27/*****************************************************************************/
28
29/***************************
30 * TEA5761HN I2C registers *
31 ***************************/
32
33/* INTREG - Read: bytes 0 and 1 / Write: byte 0 */
34
35 /* first byte for reading */
36#define TEA5761_INTREG_IFFLAG 0x10
37#define TEA5761_INTREG_LEVFLAG 0x8
38#define TEA5761_INTREG_FRRFLAG 0x2
39#define TEA5761_INTREG_BLFLAG 0x1
40
41 /* second byte for reading / byte for writing */
42#define TEA5761_INTREG_IFMSK 0x10
43#define TEA5761_INTREG_LEVMSK 0x8
44#define TEA5761_INTREG_FRMSK 0x2
45#define TEA5761_INTREG_BLMSK 0x1
46
47/* FRQSET - Read: bytes 2 and 3 / Write: byte 1 and 2 */
48
49 /* First byte */
50#define TEA5761_FRQSET_SEARCH_UP 0x80 /* 1=Station search from botton to up */
51#define TEA5761_FRQSET_SEARCH_MODE 0x40 /* 1=Search mode */
52
53 /* Bits 0-5 for divider MSB */
54
55 /* Second byte */
56 /* Bits 0-7 for divider LSB */
57
58/* TNCTRL - Read: bytes 4 and 5 / Write: Bytes 3 and 4 */
59
60 /* first byte */
61
62#define TEA5761_TNCTRL_PUPD_0 0x40 /* Power UP/Power Down MSB */
63#define TEA5761_TNCTRL_BLIM 0X20 /* 1= Japan Frequencies, 0= European frequencies */
64#define TEA5761_TNCTRL_SWPM 0x10 /* 1= software port is FRRFLAG */
65#define TEA5761_TNCTRL_IFCTC 0x08 /* 1= IF count time 15.02 ms, 0= IF count time 2.02 ms */
66#define TEA5761_TNCTRL_AFM 0x04
67#define TEA5761_TNCTRL_SMUTE 0x02 /* 1= Soft mute */
68#define TEA5761_TNCTRL_SNC 0x01
69
70 /* second byte */
71
72#define TEA5761_TNCTRL_MU 0x80 /* 1=Hard mute */
73#define TEA5761_TNCTRL_SSL_1 0x40
74#define TEA5761_TNCTRL_SSL_0 0x20
75#define TEA5761_TNCTRL_HLSI 0x10
76#define TEA5761_TNCTRL_MST 0x08 /* 1 = mono */
77#define TEA5761_TNCTRL_SWP 0x04
78#define TEA5761_TNCTRL_DTC 0x02 /* 1 = deemphasis 50 us, 0 = deemphasis 75 us */
79#define TEA5761_TNCTRL_AHLSI 0x01
80
81/* FRQCHECK - Read: bytes 6 and 7 */
82 /* First byte */
83
84 /* Bits 0-5 for divider MSB */
85
86 /* Second byte */
87 /* Bits 0-7 for divider LSB */
88
89/* TUNCHECK - Read: bytes 8 and 9 */
90
91 /* First byte */
92#define TEA5761_TUNCHECK_IF_MASK 0x7e /* IF count */
93#define TEA5761_TUNCHECK_TUNTO 0x01
94
95 /* Second byte */
96#define TEA5761_TUNCHECK_LEV_MASK 0xf0 /* Level Count */
97#define TEA5761_TUNCHECK_LD 0x08
98#define TEA5761_TUNCHECK_STEREO 0x04
99
100/* TESTREG - Read: bytes 10 and 11 / Write: bytes 5 and 6 */
101
102 /* All zero = no test mode */
103
104/* MANID - Read: bytes 12 and 13 */
105
106 /* First byte - should be 0x10 */
107#define TEA5767_MANID_VERSION_MASK 0xf0 /* Version = 1 */
108#define TEA5767_MANID_ID_MSB_MASK 0x0f /* Manufacurer ID - should be 0 */
109
110 /* Second byte - Should be 0x2b */
111
112#define TEA5767_MANID_ID_LSB_MASK 0xfe /* Manufacturer ID - should be 0x15 */
113#define TEA5767_MANID_IDAV 0x01 /* 1 = Chip has ID, 0 = Chip has no ID */
114
115/* Chip ID - Read: bytes 14 and 15 */
116
117 /* First byte - should be 0x57 */
118
119 /* Second byte - should be 0x61 */
120
121/*****************************************************************************/
122
123#define FREQ_OFFSET 0 /* for TEA5767, it is 700 to give the right freq */
124static void tea5761_status_dump(unsigned char *buffer)
125{
126 unsigned int div, frq;
127
128 div = ((buffer[2] & 0x3f) << 8) | buffer[3];
129
130 frq = 1000 * (div * 32768 / 1000 + FREQ_OFFSET + 225) / 4; /* Freq in KHz */
131
132 printk(KERN_INFO "tea5761: Frequency %d.%03d KHz (divider = 0x%04x)\n",
133 frq / 1000, frq % 1000, div);
134}
135
136/* Freq should be specifyed at 62.5 Hz */
137static int set_radio_freq(struct dvb_frontend *fe,
138 struct analog_parameters *params)
139{
140 struct tea5761_priv *priv = fe->tuner_priv;
141 unsigned int frq = params->frequency;
142 unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
143 unsigned div;
144 int rc;
145
146 tuner_dbg("radio freq counter %d\n", frq);
147
148 if (params->mode == T_STANDBY) {
149 tuner_dbg("TEA5761 set to standby mode\n");
150 buffer[5] |= TEA5761_TNCTRL_MU;
151 } else {
152 buffer[4] |= TEA5761_TNCTRL_PUPD_0;
153 }
154
155
156 if (params->audmode == V4L2_TUNER_MODE_MONO) {
157 tuner_dbg("TEA5761 set to mono\n");
158 buffer[5] |= TEA5761_TNCTRL_MST;
159 } else {
160 tuner_dbg("TEA5761 set to stereo\n");
161 }
162
163 div = (1000 * (frq * 4 / 16 + 700 + 225) ) >> 15;
164 buffer[1] = (div >> 8) & 0x3f;
165 buffer[2] = div & 0xff;
166
167 if (debug)
168 tea5761_status_dump(buffer);
169
170 if (7 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 7)))
171 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
172
173 priv->frequency = frq * 125 / 2;
174
175 return 0;
176}
177
178static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
179{
180 struct tea5761_priv *priv = fe->tuner_priv;
181 int rc;
182
183 memset(buffer, 0, 16);
184 if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16))) {
185 tuner_warn("i2c i/o error: rc == %d (should be 16)\n", rc);
186 return -EREMOTEIO;
187 }
188
189 return 0;
190}
191
192static inline int tea5761_signal(struct dvb_frontend *fe, const char *buffer)
193{
194 struct tea5761_priv *priv = fe->tuner_priv;
195
196 int signal = ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4));
197
198 tuner_dbg("Signal strength: %d\n", signal);
199
200 return signal;
201}
202
203static inline int tea5761_stereo(struct dvb_frontend *fe, const char *buffer)
204{
205 struct tea5761_priv *priv = fe->tuner_priv;
206
207 int stereo = buffer[9] & TEA5761_TUNCHECK_STEREO;
208
209 tuner_dbg("Radio ST GET = %02x\n", stereo);
210
211 return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
212}
213
214static int tea5761_get_status(struct dvb_frontend *fe, u32 *status)
215{
216 unsigned char buffer[16];
217
218 *status = 0;
219
220 if (0 == tea5761_read_status(fe, buffer)) {
221 if (tea5761_signal(fe, buffer))
222 *status = TUNER_STATUS_LOCKED;
223 if (tea5761_stereo(fe, buffer))
224 *status |= TUNER_STATUS_STEREO;
225 }
226
227 return 0;
228}
229
230static int tea5761_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
231{
232 unsigned char buffer[16];
233
234 *strength = 0;
235
236 if (0 == tea5761_read_status(fe, buffer))
237 *strength = tea5761_signal(fe, buffer);
238
239 return 0;
240}
241
242int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
243{
244 unsigned char buffer[16];
245 int rc;
246 struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
247
248 if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) {
249 printk(KERN_WARNING "it is not a TEA5761. Received %i chars.\n", rc);
250 return -EINVAL;
251 }
252
253 if ((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061)) {
254 printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x."
255 " It is not a TEA5761\n",
256 buffer[13], buffer[14], buffer[15]);
257 return -EINVAL;
258 }
259 printk(KERN_WARNING "tea5761: TEA%02x%02x detected. "
260 "Manufacturer ID= 0x%02x\n",
261 buffer[14], buffer[15], buffer[13]);
262
263 return 0;
264}
265
266static int tea5761_release(struct dvb_frontend *fe)
267{
268 kfree(fe->tuner_priv);
269 fe->tuner_priv = NULL;
270
271 return 0;
272}
273
274static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency)
275{
276 struct tea5761_priv *priv = fe->tuner_priv;
277 *frequency = priv->frequency;
278 return 0;
279}
280
281static struct dvb_tuner_ops tea5761_tuner_ops = {
282 .info = {
283 .name = "tea5761", // Philips TEA5761HN FM Radio
284 },
285 .set_analog_params = set_radio_freq,
286 .release = tea5761_release,
287 .get_frequency = tea5761_get_frequency,
288 .get_status = tea5761_get_status,
289 .get_rf_strength = tea5761_get_rf_strength,
290};
291
292struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
293 struct i2c_adapter* i2c_adap,
294 u8 i2c_addr)
295{
296 struct tea5761_priv *priv = NULL;
297
298 if (tea5761_autodetection(i2c_adap, i2c_addr) == EINVAL)
299 return NULL;
300
301 priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL);
302 if (priv == NULL)
303 return NULL;
304 fe->tuner_priv = priv;
305
306 priv->i2c_props.addr = i2c_addr;
307 priv->i2c_props.adap = i2c_adap;
308 priv->i2c_props.name = "tea5761";
309
310 memcpy(&fe->ops.tuner_ops, &tea5761_tuner_ops,
311 sizeof(struct dvb_tuner_ops));
312
313 tuner_info("type set to %s\n", "Philips TEA5761HN FM Radio");
314
315 return fe;
316}
317
318
319EXPORT_SYMBOL_GPL(tea5761_attach);
320EXPORT_SYMBOL_GPL(tea5761_autodetection);
321
322MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver");
323MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
324MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tea5761.h b/drivers/media/video/tea5761.h
deleted file mode 100644
index 8eb62722b988..000000000000
--- a/drivers/media/video/tea5761.h
+++ /dev/null
@@ -1,47 +0,0 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TEA5761_H__
18#define __TEA5761_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23#if defined(CONFIG_TUNER_TEA5761) || (defined(CONFIG_TUNER_TEA5761_MODULE) && defined(MODULE))
24extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
25
26extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
27 struct i2c_adapter* i2c_adap,
28 u8 i2c_addr);
29#else
30static inline int tea5761_autodetection(struct i2c_adapter* i2c_adap,
31 u8 i2c_addr)
32{
33 printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
34 __func__);
35 return -EINVAL;
36}
37
38static inline struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
39 struct i2c_adapter* i2c_adap,
40 u8 i2c_addr)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
43 return NULL;
44}
45#endif
46
47#endif /* __TEA5761_H__ */
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
deleted file mode 100644
index f6e7d7ad8424..000000000000
--- a/drivers/media/video/tea5767.c
+++ /dev/null
@@ -1,474 +0,0 @@
1/*
2 * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
3 * I2C address is allways 0xC0.
4 *
5 *
6 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
7 * This code is placed under the terms of the GNU General Public License
8 *
9 * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
10 * from their contributions on DScaler.
11 */
12
13#include <linux/i2c.h>
14#include <linux/delay.h>
15#include <linux/videodev.h>
16#include "tuner-i2c.h"
17#include "tea5767.h"
18
19static int debug;
20module_param(debug, int, 0644);
21MODULE_PARM_DESC(debug, "enable verbose debug messages");
22
23/*****************************************************************************/
24
25struct tea5767_priv {
26 struct tuner_i2c_props i2c_props;
27 u32 frequency;
28 struct tea5767_ctrl ctrl;
29};
30
31/*****************************************************************************/
32
33/******************************
34 * Write mode register values *
35 ******************************/
36
37/* First register */
38#define TEA5767_MUTE 0x80 /* Mutes output */
39#define TEA5767_SEARCH 0x40 /* Activates station search */
40/* Bits 0-5 for divider MSB */
41
42/* Second register */
43/* Bits 0-7 for divider LSB */
44
45/* Third register */
46
47/* Station search from botton to up */
48#define TEA5767_SEARCH_UP 0x80
49
50/* Searches with ADC output = 10 */
51#define TEA5767_SRCH_HIGH_LVL 0x60
52
53/* Searches with ADC output = 10 */
54#define TEA5767_SRCH_MID_LVL 0x40
55
56/* Searches with ADC output = 5 */
57#define TEA5767_SRCH_LOW_LVL 0x20
58
59/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
60#define TEA5767_HIGH_LO_INJECT 0x10
61
62/* Disable stereo */
63#define TEA5767_MONO 0x08
64
65/* Disable right channel and turns to mono */
66#define TEA5767_MUTE_RIGHT 0x04
67
68/* Disable left channel and turns to mono */
69#define TEA5767_MUTE_LEFT 0x02
70
71#define TEA5767_PORT1_HIGH 0x01
72
73/* Fourth register */
74#define TEA5767_PORT2_HIGH 0x80
75/* Chips stops working. Only I2C bus remains on */
76#define TEA5767_STDBY 0x40
77
78/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
79#define TEA5767_JAPAN_BAND 0x20
80
81/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
82#define TEA5767_XTAL_32768 0x10
83
84/* Cuts weak signals */
85#define TEA5767_SOFT_MUTE 0x08
86
87/* Activates high cut control */
88#define TEA5767_HIGH_CUT_CTRL 0x04
89
90/* Activates stereo noise control */
91#define TEA5767_ST_NOISE_CTL 0x02
92
93/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
94#define TEA5767_SRCH_IND 0x01
95
96/* Fifth register */
97
98/* By activating, it will use Xtal at 13 MHz as reference for divider */
99#define TEA5767_PLLREF_ENABLE 0x80
100
101/* By activating, deemphasis=50, or else, deemphasis of 50us */
102#define TEA5767_DEEMPH_75 0X40
103
104/*****************************
105 * Read mode register values *
106 *****************************/
107
108/* First register */
109#define TEA5767_READY_FLAG_MASK 0x80
110#define TEA5767_BAND_LIMIT_MASK 0X40
111/* Bits 0-5 for divider MSB after search or preset */
112
113/* Second register */
114/* Bits 0-7 for divider LSB after search or preset */
115
116/* Third register */
117#define TEA5767_STEREO_MASK 0x80
118#define TEA5767_IF_CNTR_MASK 0x7f
119
120/* Fourth register */
121#define TEA5767_ADC_LEVEL_MASK 0xf0
122
123/* should be 0 */
124#define TEA5767_CHIP_ID_MASK 0x0f
125
126/* Fifth register */
127/* Reserved for future extensions */
128#define TEA5767_RESERVED_MASK 0xff
129
130/*****************************************************************************/
131
132static void tea5767_status_dump(struct tea5767_priv *priv,
133 unsigned char *buffer)
134{
135 unsigned int div, frq;
136
137 if (TEA5767_READY_FLAG_MASK & buffer[0])
138 tuner_info("Ready Flag ON\n");
139 else
140 tuner_info("Ready Flag OFF\n");
141
142 if (TEA5767_BAND_LIMIT_MASK & buffer[0])
143 tuner_info("Tuner at band limit\n");
144 else
145 tuner_info("Tuner not at band limit\n");
146
147 div = ((buffer[0] & 0x3f) << 8) | buffer[1];
148
149 switch (priv->ctrl.xtal_freq) {
150 case TEA5767_HIGH_LO_13MHz:
151 frq = (div * 50000 - 700000 - 225000) / 4; /* Freq in KHz */
152 break;
153 case TEA5767_LOW_LO_13MHz:
154 frq = (div * 50000 + 700000 + 225000) / 4; /* Freq in KHz */
155 break;
156 case TEA5767_LOW_LO_32768:
157 frq = (div * 32768 + 700000 + 225000) / 4; /* Freq in KHz */
158 break;
159 case TEA5767_HIGH_LO_32768:
160 default:
161 frq = (div * 32768 - 700000 - 225000) / 4; /* Freq in KHz */
162 break;
163 }
164 buffer[0] = (div >> 8) & 0x3f;
165 buffer[1] = div & 0xff;
166
167 tuner_info("Frequency %d.%03d KHz (divider = 0x%04x)\n",
168 frq / 1000, frq % 1000, div);
169
170 if (TEA5767_STEREO_MASK & buffer[2])
171 tuner_info("Stereo\n");
172 else
173 tuner_info("Mono\n");
174
175 tuner_info("IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK);
176
177 tuner_info("ADC Level = %d\n",
178 (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4);
179
180 tuner_info("Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK));
181
182 tuner_info("Reserved = 0x%02x\n",
183 (buffer[4] & TEA5767_RESERVED_MASK));
184}
185
186/* Freq should be specifyed at 62.5 Hz */
187static int set_radio_freq(struct dvb_frontend *fe,
188 struct analog_parameters *params)
189{
190 struct tea5767_priv *priv = fe->tuner_priv;
191 unsigned int frq = params->frequency;
192 unsigned char buffer[5];
193 unsigned div;
194 int rc;
195
196 tuner_dbg("radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
197
198 buffer[2] = 0;
199
200 if (priv->ctrl.port1)
201 buffer[2] |= TEA5767_PORT1_HIGH;
202
203 if (params->audmode == V4L2_TUNER_MODE_MONO) {
204 tuner_dbg("TEA5767 set to mono\n");
205 buffer[2] |= TEA5767_MONO;
206 } else {
207 tuner_dbg("TEA5767 set to stereo\n");
208 }
209
210
211 buffer[3] = 0;
212
213 if (priv->ctrl.port2)
214 buffer[3] |= TEA5767_PORT2_HIGH;
215
216 if (priv->ctrl.high_cut)
217 buffer[3] |= TEA5767_HIGH_CUT_CTRL;
218
219 if (priv->ctrl.st_noise)
220 buffer[3] |= TEA5767_ST_NOISE_CTL;
221
222 if (priv->ctrl.soft_mute)
223 buffer[3] |= TEA5767_SOFT_MUTE;
224
225 if (priv->ctrl.japan_band)
226 buffer[3] |= TEA5767_JAPAN_BAND;
227
228 buffer[4] = 0;
229
230 if (priv->ctrl.deemph_75)
231 buffer[4] |= TEA5767_DEEMPH_75;
232
233 if (priv->ctrl.pllref)
234 buffer[4] |= TEA5767_PLLREF_ENABLE;
235
236
237 /* Rounds freq to next decimal value - for 62.5 KHz step */
238 /* frq = 20*(frq/16)+radio_frq[frq%16]; */
239
240 switch (priv->ctrl.xtal_freq) {
241 case TEA5767_HIGH_LO_13MHz:
242 tuner_dbg("radio HIGH LO inject xtal @ 13 MHz\n");
243 buffer[2] |= TEA5767_HIGH_LO_INJECT;
244 div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000;
245 break;
246 case TEA5767_LOW_LO_13MHz:
247 tuner_dbg("radio LOW LO inject xtal @ 13 MHz\n");
248
249 div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000;
250 break;
251 case TEA5767_LOW_LO_32768:
252 tuner_dbg("radio LOW LO inject xtal @ 32,768 MHz\n");
253 buffer[3] |= TEA5767_XTAL_32768;
254 /* const 700=4000*175 Khz - to adjust freq to right value */
255 div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15;
256 break;
257 case TEA5767_HIGH_LO_32768:
258 default:
259 tuner_dbg("radio HIGH LO inject xtal @ 32,768 MHz\n");
260
261 buffer[2] |= TEA5767_HIGH_LO_INJECT;
262 buffer[3] |= TEA5767_XTAL_32768;
263 div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
264 break;
265 }
266 buffer[0] = (div >> 8) & 0x3f;
267 buffer[1] = div & 0xff;
268
269 if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
270 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
271
272 if (debug) {
273 if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
274 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
275 else
276 tea5767_status_dump(priv, buffer);
277 }
278
279 priv->frequency = frq * 125 / 2;
280
281 return 0;
282}
283
284static int tea5767_read_status(struct dvb_frontend *fe, char *buffer)
285{
286 struct tea5767_priv *priv = fe->tuner_priv;
287 int rc;
288
289 memset(buffer, 0, 5);
290 if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) {
291 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
292 return -EREMOTEIO;
293 }
294
295 return 0;
296}
297
298static inline int tea5767_signal(struct dvb_frontend *fe, const char *buffer)
299{
300 struct tea5767_priv *priv = fe->tuner_priv;
301
302 int signal = ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
303
304 tuner_dbg("Signal strength: %d\n", signal);
305
306 return signal;
307}
308
309static inline int tea5767_stereo(struct dvb_frontend *fe, const char *buffer)
310{
311 struct tea5767_priv *priv = fe->tuner_priv;
312
313 int stereo = buffer[2] & TEA5767_STEREO_MASK;
314
315 tuner_dbg("Radio ST GET = %02x\n", stereo);
316
317 return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
318}
319
320static int tea5767_get_status(struct dvb_frontend *fe, u32 *status)
321{
322 unsigned char buffer[5];
323
324 *status = 0;
325
326 if (0 == tea5767_read_status(fe, buffer)) {
327 if (tea5767_signal(fe, buffer))
328 *status = TUNER_STATUS_LOCKED;
329 if (tea5767_stereo(fe, buffer))
330 *status |= TUNER_STATUS_STEREO;
331 }
332
333 return 0;
334}
335
336static int tea5767_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
337{
338 unsigned char buffer[5];
339
340 *strength = 0;
341
342 if (0 == tea5767_read_status(fe, buffer))
343 *strength = tea5767_signal(fe, buffer);
344
345 return 0;
346}
347
348static int tea5767_standby(struct dvb_frontend *fe)
349{
350 unsigned char buffer[5];
351 struct tea5767_priv *priv = fe->tuner_priv;
352 unsigned div, rc;
353
354 div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */
355 buffer[0] = (div >> 8) & 0x3f;
356 buffer[1] = div & 0xff;
357 buffer[2] = TEA5767_PORT1_HIGH;
358 buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
359 TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY;
360 buffer[4] = 0;
361
362 if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
363 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
364
365 return 0;
366}
367
368int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
369{
370 struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
371 unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
372 int rc;
373
374 if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
375 printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc);
376 return EINVAL;
377 }
378
379 /* If all bytes are the same then it's a TV tuner and not a tea5767 */
380 if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
381 buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
382 printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n");
383 return EINVAL;
384 }
385
386 /* Status bytes:
387 * Byte 4: bit 3:1 : CI (Chip Identification) == 0
388 * bit 0 : internally set to 0
389 * Byte 5: bit 7:0 : == 0
390 */
391 if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
392 printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n");
393 return EINVAL;
394 }
395
396
397 return 0;
398}
399
400static int tea5767_release(struct dvb_frontend *fe)
401{
402 kfree(fe->tuner_priv);
403 fe->tuner_priv = NULL;
404
405 return 0;
406}
407
408static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency)
409{
410 struct tea5767_priv *priv = fe->tuner_priv;
411 *frequency = priv->frequency;
412
413 return 0;
414}
415
416static int tea5767_set_config (struct dvb_frontend *fe, void *priv_cfg)
417{
418 struct tea5767_priv *priv = fe->tuner_priv;
419
420 memcpy(&priv->ctrl, priv_cfg, sizeof(priv->ctrl));
421
422 return 0;
423}
424
425static struct dvb_tuner_ops tea5767_tuner_ops = {
426 .info = {
427 .name = "tea5767", // Philips TEA5767HN FM Radio
428 },
429
430 .set_analog_params = set_radio_freq,
431 .set_config = tea5767_set_config,
432 .sleep = tea5767_standby,
433 .release = tea5767_release,
434 .get_frequency = tea5767_get_frequency,
435 .get_status = tea5767_get_status,
436 .get_rf_strength = tea5767_get_rf_strength,
437};
438
439struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
440 struct i2c_adapter* i2c_adap,
441 u8 i2c_addr)
442{
443 struct tea5767_priv *priv = NULL;
444
445 priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL);
446 if (priv == NULL)
447 return NULL;
448 fe->tuner_priv = priv;
449
450 priv->i2c_props.addr = i2c_addr;
451 priv->i2c_props.adap = i2c_adap;
452 priv->i2c_props.name = "tea5767";
453
454 priv->ctrl.xtal_freq = TEA5767_HIGH_LO_32768;
455 priv->ctrl.port1 = 1;
456 priv->ctrl.port2 = 1;
457 priv->ctrl.high_cut = 1;
458 priv->ctrl.st_noise = 1;
459 priv->ctrl.japan_band = 1;
460
461 memcpy(&fe->ops.tuner_ops, &tea5767_tuner_ops,
462 sizeof(struct dvb_tuner_ops));
463
464 tuner_info("type set to %s\n", "Philips TEA5767HN FM Radio");
465
466 return fe;
467}
468
469EXPORT_SYMBOL_GPL(tea5767_attach);
470EXPORT_SYMBOL_GPL(tea5767_autodetection);
471
472MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver");
473MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
474MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tea5767.h b/drivers/media/video/tea5767.h
deleted file mode 100644
index 7b547c092e25..000000000000
--- a/drivers/media/video/tea5767.h
+++ /dev/null
@@ -1,66 +0,0 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TEA5767_H__
18#define __TEA5767_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23enum tea5767_xtal {
24 TEA5767_LOW_LO_32768 = 0,
25 TEA5767_HIGH_LO_32768 = 1,
26 TEA5767_LOW_LO_13MHz = 2,
27 TEA5767_HIGH_LO_13MHz = 3,
28};
29
30struct tea5767_ctrl {
31 unsigned int port1:1;
32 unsigned int port2:1;
33 unsigned int high_cut:1;
34 unsigned int st_noise:1;
35 unsigned int soft_mute:1;
36 unsigned int japan_band:1;
37 unsigned int deemph_75:1;
38 unsigned int pllref:1;
39 enum tea5767_xtal xtal_freq;
40};
41
42#if defined(CONFIG_TUNER_TEA5767) || (defined(CONFIG_TUNER_TEA5767_MODULE) && defined(MODULE))
43extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
44
45extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
46 struct i2c_adapter* i2c_adap,
47 u8 i2c_addr);
48#else
49static inline int tea5767_autodetection(struct i2c_adapter* i2c_adap,
50 u8 i2c_addr)
51{
52 printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
53 __func__);
54 return -EINVAL;
55}
56
57static inline struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
58 struct i2c_adapter* i2c_adap,
59 u8 i2c_addr)
60{
61 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
62 return NULL;
63}
64#endif
65
66#endif /* __TEA5767_H__ */
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 2a2748238c78..cc19c4abb467 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -33,6 +33,46 @@
33 33
34#define PREFIX t->i2c->driver->driver.name 34#define PREFIX t->i2c->driver->driver.name
35 35
36/** This macro allows us to probe dynamically, avoiding static links */
37#ifdef CONFIG_DVB_CORE_ATTACH
38#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
39 int __r = -EINVAL; \
40 typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
41 if (__a) { \
42 __r = (int) __a(ARGS); \
43 } else { \
44 printk(KERN_ERR "TUNER: Unable to find " \
45 "symbol "#FUNCTION"()\n"); \
46 } \
47 symbol_put(FUNCTION); \
48 __r; \
49})
50
51static void tuner_detach(struct dvb_frontend *fe)
52{
53 if (fe->ops.tuner_ops.release) {
54 fe->ops.tuner_ops.release(fe);
55 symbol_put_addr(fe->ops.tuner_ops.release);
56 }
57 if (fe->ops.analog_ops.release) {
58 fe->ops.analog_ops.release(fe);
59 symbol_put_addr(fe->ops.analog_ops.release);
60 }
61}
62#else
63#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
64 FUNCTION(ARGS); \
65})
66
67static void tuner_detach(struct dvb_frontend *fe)
68{
69 if (fe->ops.tuner_ops.release)
70 fe->ops.tuner_ops.release(fe);
71 if (fe->ops.analog_ops.release)
72 fe->ops.analog_ops.release(fe);
73}
74#endif
75
36struct tuner { 76struct tuner {
37 /* device */ 77 /* device */
38 struct dvb_frontend fe; 78 struct dvb_frontend fe;
@@ -56,7 +96,7 @@ struct tuner {
56 96
57/* standard i2c insmod options */ 97/* standard i2c insmod options */
58static unsigned short normal_i2c[] = { 98static unsigned short normal_i2c[] = {
59#if defined(CONFIG_TUNER_TEA5761) || (defined(CONFIG_TUNER_TEA5761_MODULE) && defined(MODULE)) 99#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
60 0x10, 100 0x10,
61#endif 101#endif
62 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ 102 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
@@ -139,22 +179,6 @@ static void fe_set_params(struct dvb_frontend *fe,
139 fe_tuner_ops->set_analog_params(fe, params); 179 fe_tuner_ops->set_analog_params(fe, params);
140} 180}
141 181
142static void fe_release(struct dvb_frontend *fe)
143{
144 if (fe->ops.tuner_ops.release)
145 fe->ops.tuner_ops.release(fe);
146
147 /* DO NOT kfree(fe->analog_demod_priv)
148 *
149 * If we are in this function, analog_demod_priv contains a pointer
150 * to struct tuner *t. This will be kfree'd in tuner_detach().
151 *
152 * Otherwise, fe->ops.analog_demod_ops->release will
153 * handle the cleanup for analog demodulator modules.
154 */
155 fe->analog_demod_priv = NULL;
156}
157
158static void fe_standby(struct dvb_frontend *fe) 182static void fe_standby(struct dvb_frontend *fe)
159{ 183{
160 struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops; 184 struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
@@ -191,7 +215,6 @@ static void tuner_status(struct dvb_frontend *fe);
191static struct analog_demod_ops tuner_core_ops = { 215static struct analog_demod_ops tuner_core_ops = {
192 .set_params = fe_set_params, 216 .set_params = fe_set_params,
193 .standby = fe_standby, 217 .standby = fe_standby,
194 .release = fe_release,
195 .has_signal = fe_has_signal, 218 .has_signal = fe_has_signal,
196 .set_config = fe_set_config, 219 .set_config = fe_set_config,
197 .tuner_status = tuner_status 220 .tuner_status = tuner_status
@@ -323,7 +346,8 @@ static void attach_tda829x(struct tuner *t)
323 .lna_cfg = t->config, 346 .lna_cfg = t->config,
324 .tuner_callback = t->tuner_callback, 347 .tuner_callback = t->tuner_callback,
325 }; 348 };
326 tda829x_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); 349 dvb_attach(tda829x_attach,
350 &t->fe, t->i2c->adapter, t->i2c->addr, &cfg);
327} 351}
328 352
329static struct xc5000_config xc5000_cfg; 353static struct xc5000_config xc5000_cfg;
@@ -356,12 +380,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
356 } 380 }
357 381
358 /* discard private data, in case set_type() was previously called */ 382 /* discard private data, in case set_type() was previously called */
359 if (analog_ops->release) 383 tuner_detach(&t->fe);
360 analog_ops->release(&t->fe); 384 t->fe.analog_demod_priv = NULL;
361 385
362 switch (t->type) { 386 switch (t->type) {
363 case TUNER_MT2032: 387 case TUNER_MT2032:
364 microtune_attach(&t->fe, t->i2c->adapter, t->i2c->addr); 388 dvb_attach(microtune_attach,
389 &t->fe, t->i2c->adapter, t->i2c->addr);
365 break; 390 break;
366 case TUNER_PHILIPS_TDA8290: 391 case TUNER_PHILIPS_TDA8290:
367 { 392 {
@@ -369,12 +394,14 @@ static void set_type(struct i2c_client *c, unsigned int type,
369 break; 394 break;
370 } 395 }
371 case TUNER_TEA5767: 396 case TUNER_TEA5767:
372 if (!tea5767_attach(&t->fe, t->i2c->adapter, t->i2c->addr)) 397 if (!dvb_attach(tea5767_attach, &t->fe,
398 t->i2c->adapter, t->i2c->addr))
373 goto attach_failed; 399 goto attach_failed;
374 t->mode_mask = T_RADIO; 400 t->mode_mask = T_RADIO;
375 break; 401 break;
376 case TUNER_TEA5761: 402 case TUNER_TEA5761:
377 if (!tea5761_attach(&t->fe, t->i2c->adapter, t->i2c->addr)) 403 if (!dvb_attach(tea5761_attach, &t->fe,
404 t->i2c->adapter, t->i2c->addr))
378 goto attach_failed; 405 goto attach_failed;
379 t->mode_mask = T_RADIO; 406 t->mode_mask = T_RADIO;
380 break; 407 break;
@@ -388,8 +415,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
388 buffer[2] = 0x86; 415 buffer[2] = 0x86;
389 buffer[3] = 0x54; 416 buffer[3] = 0x54;
390 i2c_master_send(c, buffer, 4); 417 i2c_master_send(c, buffer, 4);
391 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, 418 if (!dvb_attach(simple_tuner_attach, &t->fe,
392 t->type)) 419 t->i2c->adapter, t->i2c->addr, t->type))
393 goto attach_failed; 420 goto attach_failed;
394 break; 421 break;
395 case TUNER_PHILIPS_TD1316: 422 case TUNER_PHILIPS_TD1316:
@@ -397,9 +424,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
397 buffer[1] = 0xdc; 424 buffer[1] = 0xdc;
398 buffer[2] = 0x86; 425 buffer[2] = 0x86;
399 buffer[3] = 0xa4; 426 buffer[3] = 0xa4;
400 i2c_master_send(c,buffer,4); 427 i2c_master_send(c, buffer, 4);
401 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, 428 if (!dvb_attach(simple_tuner_attach, &t->fe,
402 t->i2c->addr, t->type)) 429 t->i2c->adapter, t->i2c->addr, t->type))
403 goto attach_failed; 430 goto attach_failed;
404 break; 431 break;
405 case TUNER_XC2028: 432 case TUNER_XC2028:
@@ -409,12 +436,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
409 .i2c_addr = t->i2c->addr, 436 .i2c_addr = t->i2c->addr,
410 .callback = t->tuner_callback, 437 .callback = t->tuner_callback,
411 }; 438 };
412 if (!xc2028_attach(&t->fe, &cfg)) 439 if (!dvb_attach(xc2028_attach, &t->fe, &cfg))
413 goto attach_failed; 440 goto attach_failed;
414 break; 441 break;
415 } 442 }
416 case TUNER_TDA9887: 443 case TUNER_TDA9887:
417 tda9887_attach(&t->fe, t->i2c->adapter, t->i2c->addr); 444 dvb_attach(tda9887_attach,
445 &t->fe, t->i2c->adapter, t->i2c->addr);
418 break; 446 break;
419 case TUNER_XC5000: 447 case TUNER_XC5000:
420 { 448 {
@@ -424,7 +452,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
424 xc5000_cfg.if_khz = 5380; 452 xc5000_cfg.if_khz = 5380;
425 xc5000_cfg.priv = c->adapter->algo_data; 453 xc5000_cfg.priv = c->adapter->algo_data;
426 xc5000_cfg.tuner_callback = t->tuner_callback; 454 xc5000_cfg.tuner_callback = t->tuner_callback;
427 if (!xc5000_attach(&t->fe, t->i2c->adapter, &xc5000_cfg)) 455 if (!dvb_attach(xc5000_attach,
456 &t->fe, t->i2c->adapter, &xc5000_cfg))
428 goto attach_failed; 457 goto attach_failed;
429 458
430 xc_tuner_ops = &t->fe.ops.tuner_ops; 459 xc_tuner_ops = &t->fe.ops.tuner_ops;
@@ -433,8 +462,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
433 break; 462 break;
434 } 463 }
435 default: 464 default:
436 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, 465 if (!dvb_attach(simple_tuner_attach, &t->fe,
437 t->i2c->addr, t->type)) 466 t->i2c->adapter, t->i2c->addr, t->type))
438 goto attach_failed; 467 goto attach_failed;
439 468
440 break; 469 break;
@@ -442,12 +471,14 @@ static void set_type(struct i2c_client *c, unsigned int type,
442 471
443 if ((NULL == analog_ops->set_params) && 472 if ((NULL == analog_ops->set_params) &&
444 (fe_tuner_ops->set_analog_params)) { 473 (fe_tuner_ops->set_analog_params)) {
474
445 strlcpy(t->i2c->name, fe_tuner_ops->info.name, 475 strlcpy(t->i2c->name, fe_tuner_ops->info.name,
446 sizeof(t->i2c->name)); 476 sizeof(t->i2c->name));
447 477
448 t->fe.analog_demod_priv = t; 478 t->fe.analog_demod_priv = t;
449 memcpy(analog_ops, &tuner_core_ops, 479 memcpy(analog_ops, &tuner_core_ops,
450 sizeof(struct analog_demod_ops)); 480 sizeof(struct analog_demod_ops));
481
451 } else { 482 } else {
452 strlcpy(t->i2c->name, analog_ops->info.name, 483 strlcpy(t->i2c->name, analog_ops->info.name,
453 sizeof(t->i2c->name)); 484 sizeof(t->i2c->name));
@@ -645,8 +676,8 @@ static void tuner_status(struct dvb_frontend *fe)
645{ 676{
646 struct tuner *t = fe->analog_demod_priv; 677 struct tuner *t = fe->analog_demod_priv;
647 unsigned long freq, freq_fraction; 678 unsigned long freq, freq_fraction;
648 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 679 struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
649 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 680 struct analog_demod_ops *analog_ops = &fe->ops.analog_ops;
650 const char *p; 681 const char *p;
651 682
652 switch (t->mode) { 683 switch (t->mode) {
@@ -730,8 +761,10 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
730 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 761 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
731 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 762 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
732 763
733 if (tuner_debug>1) 764 if (tuner_debug > 1) {
734 v4l_i2c_print_ioctl(client,cmd); 765 v4l_i2c_print_ioctl(client,cmd);
766 printk("\n");
767 }
735 768
736 switch (cmd) { 769 switch (cmd) {
737 /* --- configuration --- */ 770 /* --- configuration --- */
@@ -1112,8 +1145,9 @@ static int tuner_probe(struct i2c_client *client,
1112 if (!no_autodetect) { 1145 if (!no_autodetect) {
1113 switch (client->addr) { 1146 switch (client->addr) {
1114 case 0x10: 1147 case 0x10:
1115 if (tea5761_autodetection(t->i2c->adapter, 1148 if (tuner_symbol_probe(tea5761_autodetection,
1116 t->i2c->addr) >= 0) { 1149 t->i2c->adapter,
1150 t->i2c->addr) >= 0) {
1117 t->type = TUNER_TEA5761; 1151 t->type = TUNER_TEA5761;
1118 t->mode_mask = T_RADIO; 1152 t->mode_mask = T_RADIO;
1119 t->mode = T_STANDBY; 1153 t->mode = T_STANDBY;
@@ -1132,8 +1166,8 @@ static int tuner_probe(struct i2c_client *client,
1132 case 0x4b: 1166 case 0x4b:
1133 /* If chip is not tda8290, don't register. 1167 /* If chip is not tda8290, don't register.
1134 since it can be tda9887*/ 1168 since it can be tda9887*/
1135 if (tda829x_probe(t->i2c->adapter, 1169 if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
1136 t->i2c->addr) == 0) { 1170 t->i2c->addr) == 0) {
1137 tuner_dbg("tda829x detected\n"); 1171 tuner_dbg("tda829x detected\n");
1138 } else { 1172 } else {
1139 /* Default is being tda9887 */ 1173 /* Default is being tda9887 */
@@ -1145,7 +1179,8 @@ static int tuner_probe(struct i2c_client *client,
1145 } 1179 }
1146 break; 1180 break;
1147 case 0x60: 1181 case 0x60:
1148 if (tea5767_autodetection(t->i2c->adapter, t->i2c->addr) 1182 if (tuner_symbol_probe(tea5767_autodetection,
1183 t->i2c->adapter, t->i2c->addr)
1149 != EINVAL) { 1184 != EINVAL) {
1150 t->type = TUNER_TEA5767; 1185 t->type = TUNER_TEA5767;
1151 t->mode_mask = T_RADIO; 1186 t->mode_mask = T_RADIO;
@@ -1234,10 +1269,9 @@ static int tuner_legacy_probe(struct i2c_adapter *adap)
1234static int tuner_remove(struct i2c_client *client) 1269static int tuner_remove(struct i2c_client *client)
1235{ 1270{
1236 struct tuner *t = i2c_get_clientdata(client); 1271 struct tuner *t = i2c_get_clientdata(client);
1237 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
1238 1272
1239 if (analog_ops->release) 1273 tuner_detach(&t->fe);
1240 analog_ops->release(&t->fe); 1274 t->fe.analog_demod_priv = NULL;
1241 1275
1242 list_del(&t->list); 1276 list_del(&t->list);
1243 kfree(t); 1277 kfree(t);
diff --git a/drivers/media/video/tuner-i2c.h b/drivers/media/video/tuner-i2c.h
deleted file mode 100644
index 3ad6c8e0b04c..000000000000
--- a/drivers/media/video/tuner-i2c.h
+++ /dev/null
@@ -1,173 +0,0 @@
1/*
2 tuner-i2c.h - i2c interface for different tuners
3
4 Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef __TUNER_I2C_H__
22#define __TUNER_I2C_H__
23
24#include <linux/i2c.h>
25
26struct tuner_i2c_props {
27 u8 addr;
28 struct i2c_adapter *adap;
29
30 /* used for tuner instance management */
31 int count;
32 char *name;
33};
34
35static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len)
36{
37 struct i2c_msg msg = { .addr = props->addr, .flags = 0,
38 .buf = buf, .len = len };
39 int ret = i2c_transfer(props->adap, &msg, 1);
40
41 return (ret == 1) ? len : ret;
42}
43
44static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, char *buf, int len)
45{
46 struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD,
47 .buf = buf, .len = len };
48 int ret = i2c_transfer(props->adap, &msg, 1);
49
50 return (ret == 1) ? len : ret;
51}
52
53static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
54 char *obuf, int olen,
55 char *ibuf, int ilen)
56{
57 struct i2c_msg msg[2] = { { .addr = props->addr, .flags = 0,
58 .buf = obuf, .len = olen },
59 { .addr = props->addr, .flags = I2C_M_RD,
60 .buf = ibuf, .len = ilen } };
61 int ret = i2c_transfer(props->adap, msg, 2);
62
63 return (ret == 2) ? ilen : ret;
64}
65
66/* Callers must declare as a global for the module:
67 *
68 * static LIST_HEAD(hybrid_tuner_instance_list);
69 *
70 * hybrid_tuner_instance_list should be the third argument
71 * passed into hybrid_tuner_request_state().
72 *
73 * state structure must contain the following:
74 *
75 * struct list_head hybrid_tuner_instance_list;
76 * struct tuner_i2c_props i2c_props;
77 *
78 * hybrid_tuner_instance_list (both within state structure and globally)
79 * is only required if the driver is using hybrid_tuner_request_state
80 * and hybrid_tuner_release_state to manage state sharing between
81 * multiple instances of hybrid tuners.
82 */
83
84#define tuner_printk(kernlvl, i2cprops, fmt, arg...) do { \
85 printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name, \
86 i2cprops.adap ? \
87 i2c_adapter_id(i2cprops.adap) : -1, \
88 i2cprops.addr, ##arg); \
89 } while (0)
90
91/* TO DO: convert all callers of these macros to pass in
92 * struct tuner_i2c_props, then remove the macro wrappers */
93
94#define __tuner_warn(i2cprops, fmt, arg...) do { \
95 tuner_printk(KERN_WARNING, i2cprops, fmt, ##arg); \
96 } while (0)
97
98#define __tuner_info(i2cprops, fmt, arg...) do { \
99 tuner_printk(KERN_INFO, i2cprops, fmt, ##arg); \
100 } while (0)
101
102#define __tuner_err(i2cprops, fmt, arg...) do { \
103 tuner_printk(KERN_ERR, i2cprops, fmt, ##arg); \
104 } while (0)
105
106#define __tuner_dbg(i2cprops, fmt, arg...) do { \
107 if ((debug)) \
108 tuner_printk(KERN_DEBUG, i2cprops, fmt, ##arg); \
109 } while (0)
110
111#define tuner_warn(fmt, arg...) __tuner_warn(priv->i2c_props, fmt, ##arg)
112#define tuner_info(fmt, arg...) __tuner_info(priv->i2c_props, fmt, ##arg)
113#define tuner_err(fmt, arg...) __tuner_err(priv->i2c_props, fmt, ##arg)
114#define tuner_dbg(fmt, arg...) __tuner_dbg(priv->i2c_props, fmt, ##arg)
115
116/****************************************************************************/
117
118/* The return value of hybrid_tuner_request_state indicates the number of
119 * instances using this tuner object.
120 *
121 * 0 - no instances, indicates an error - kzalloc must have failed
122 *
123 * 1 - one instance, indicates that the tuner object was created successfully
124 *
125 * 2 (or more) instances, indicates that an existing tuner object was found
126 */
127
128#define hybrid_tuner_request_state(type, state, list, i2cadap, i2caddr, devname)\
129({ \
130 int __ret = 0; \
131 list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \
132 if (((i2cadap) && (state->i2c_props.adap)) && \
133 ((i2c_adapter_id(state->i2c_props.adap) == \
134 i2c_adapter_id(i2cadap)) && \
135 (i2caddr == state->i2c_props.addr))) { \
136 __tuner_info(state->i2c_props, \
137 "attaching existing instance\n"); \
138 state->i2c_props.count++; \
139 __ret = state->i2c_props.count; \
140 break; \
141 } \
142 } \
143 if (0 == __ret) { \
144 state = kzalloc(sizeof(type), GFP_KERNEL); \
145 if (NULL == state) \
146 goto __fail; \
147 state->i2c_props.addr = i2caddr; \
148 state->i2c_props.adap = i2cadap; \
149 state->i2c_props.name = devname; \
150 __tuner_info(state->i2c_props, \
151 "creating new instance\n"); \
152 list_add_tail(&state->hybrid_tuner_instance_list, &list);\
153 state->i2c_props.count++; \
154 __ret = state->i2c_props.count; \
155 } \
156__fail: \
157 __ret; \
158})
159
160#define hybrid_tuner_release_state(state) \
161({ \
162 int __ret; \
163 state->i2c_props.count--; \
164 __ret = state->i2c_props.count; \
165 if (!state->i2c_props.count) { \
166 __tuner_info(state->i2c_props, "destroying instance\n");\
167 list_del(&state->hybrid_tuner_instance_list); \
168 kfree(state); \
169 } \
170 __ret; \
171})
172
173#endif /* __TUNER_I2C_H__ */
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
deleted file mode 100644
index be8d903171b7..000000000000
--- a/drivers/media/video/tuner-simple.c
+++ /dev/null
@@ -1,1093 +0,0 @@
1/*
2 * i2c tv tuner chip device driver
3 * controls all those simple 4-control-bytes style tuners.
4 *
5 * This "tuner-simple" module was split apart from the original "tuner" module.
6 */
7#include <linux/delay.h>
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include <media/tuner.h>
11#include <media/v4l2-common.h>
12#include <media/tuner-types.h>
13#include "tuner-i2c.h"
14#include "tuner-simple.h"
15
16static int debug;
17module_param(debug, int, 0644);
18MODULE_PARM_DESC(debug, "enable verbose debug messages");
19
20#define TUNER_SIMPLE_MAX 64
21static unsigned int simple_devcount;
22
23static int offset;
24module_param(offset, int, 0664);
25MODULE_PARM_DESC(offset, "Allows to specify an offset for tuner");
26
27static unsigned int atv_input[TUNER_SIMPLE_MAX] = \
28 { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 };
29static unsigned int dtv_input[TUNER_SIMPLE_MAX] = \
30 { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 };
31module_param_array(atv_input, int, NULL, 0644);
32module_param_array(dtv_input, int, NULL, 0644);
33MODULE_PARM_DESC(atv_input, "specify atv rf input, 0 for autoselect");
34MODULE_PARM_DESC(dtv_input, "specify dtv rf input, 0 for autoselect");
35
36/* ---------------------------------------------------------------------- */
37
38/* tv standard selection for Temic 4046 FM5
39 this value takes the low bits of control byte 2
40 from datasheet Rev.01, Feb.00
41 standard BG I L L2 D
42 picture IF 38.9 38.9 38.9 33.95 38.9
43 sound 1 33.4 32.9 32.4 40.45 32.4
44 sound 2 33.16
45 NICAM 33.05 32.348 33.05 33.05
46 */
47#define TEMIC_SET_PAL_I 0x05
48#define TEMIC_SET_PAL_DK 0x09
49#define TEMIC_SET_PAL_L 0x0a /* SECAM ? */
50#define TEMIC_SET_PAL_L2 0x0b /* change IF ! */
51#define TEMIC_SET_PAL_BG 0x0c
52
53/* tv tuner system standard selection for Philips FQ1216ME
54 this value takes the low bits of control byte 2
55 from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
56 standard BG DK I L L`
57 picture carrier 38.90 38.90 38.90 38.90 33.95
58 colour 34.47 34.47 34.47 34.47 38.38
59 sound 1 33.40 32.40 32.90 32.40 40.45
60 sound 2 33.16 - - - -
61 NICAM 33.05 33.05 32.35 33.05 39.80
62 */
63#define PHILIPS_SET_PAL_I 0x01 /* Bit 2 always zero !*/
64#define PHILIPS_SET_PAL_BGDK 0x09
65#define PHILIPS_SET_PAL_L2 0x0a
66#define PHILIPS_SET_PAL_L 0x0b
67
68/* system switching for Philips FI1216MF MK2
69 from datasheet "1996 Jul 09",
70 standard BG L L'
71 picture carrier 38.90 38.90 33.95
72 colour 34.47 34.37 38.38
73 sound 1 33.40 32.40 40.45
74 sound 2 33.16 - -
75 NICAM 33.05 33.05 39.80
76 */
77#define PHILIPS_MF_SET_STD_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */
78#define PHILIPS_MF_SET_STD_L 0x03 /* Used on Secam France */
79#define PHILIPS_MF_SET_STD_LC 0x02 /* Used on SECAM L' */
80
81/* Control byte */
82
83#define TUNER_RATIO_MASK 0x06 /* Bit cb1:cb2 */
84#define TUNER_RATIO_SELECT_50 0x00
85#define TUNER_RATIO_SELECT_32 0x02
86#define TUNER_RATIO_SELECT_166 0x04
87#define TUNER_RATIO_SELECT_62 0x06
88
89#define TUNER_CHARGE_PUMP 0x40 /* Bit cb6 */
90
91/* Status byte */
92
93#define TUNER_POR 0x80
94#define TUNER_FL 0x40
95#define TUNER_MODE 0x38
96#define TUNER_AFC 0x07
97#define TUNER_SIGNAL 0x07
98#define TUNER_STEREO 0x10
99
100#define TUNER_PLL_LOCKED 0x40
101#define TUNER_STEREO_MK3 0x04
102
103static DEFINE_MUTEX(tuner_simple_list_mutex);
104static LIST_HEAD(hybrid_tuner_instance_list);
105
106struct tuner_simple_priv {
107 unsigned int nr;
108 u16 last_div;
109
110 struct tuner_i2c_props i2c_props;
111 struct list_head hybrid_tuner_instance_list;
112
113 unsigned int type;
114 struct tunertype *tun;
115
116 u32 frequency;
117 u32 bandwidth;
118};
119
120/* ---------------------------------------------------------------------- */
121
122static int tuner_read_status(struct dvb_frontend *fe)
123{
124 struct tuner_simple_priv *priv = fe->tuner_priv;
125 unsigned char byte;
126
127 if (1 != tuner_i2c_xfer_recv(&priv->i2c_props, &byte, 1))
128 return 0;
129
130 return byte;
131}
132
133static inline int tuner_signal(const int status)
134{
135 return (status & TUNER_SIGNAL) << 13;
136}
137
138static inline int tuner_stereo(const int type, const int status)
139{
140 switch (type) {
141 case TUNER_PHILIPS_FM1216ME_MK3:
142 case TUNER_PHILIPS_FM1236_MK3:
143 case TUNER_PHILIPS_FM1256_IH3:
144 case TUNER_LG_NTSC_TAPE:
145 return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
146 default:
147 return status & TUNER_STEREO;
148 }
149}
150
151static inline int tuner_islocked(const int status)
152{
153 return (status & TUNER_FL);
154}
155
156static inline int tuner_afcstatus(const int status)
157{
158 return (status & TUNER_AFC) - 2;
159}
160
161
162static int simple_get_status(struct dvb_frontend *fe, u32 *status)
163{
164 struct tuner_simple_priv *priv = fe->tuner_priv;
165 int tuner_status;
166
167 if (priv->i2c_props.adap == NULL)
168 return -EINVAL;
169
170 tuner_status = tuner_read_status(fe);
171
172 *status = 0;
173
174 if (tuner_islocked(tuner_status))
175 *status = TUNER_STATUS_LOCKED;
176 if (tuner_stereo(priv->type, tuner_status))
177 *status |= TUNER_STATUS_STEREO;
178
179 tuner_dbg("AFC Status: %d\n", tuner_afcstatus(tuner_status));
180
181 return 0;
182}
183
184static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
185{
186 struct tuner_simple_priv *priv = fe->tuner_priv;
187 int signal;
188
189 if (priv->i2c_props.adap == NULL)
190 return -EINVAL;
191
192 signal = tuner_signal(tuner_read_status(fe));
193
194 *strength = signal;
195
196 tuner_dbg("Signal strength: %d\n", signal);
197
198 return 0;
199}
200
201/* ---------------------------------------------------------------------- */
202
203static inline char *tuner_param_name(enum param_type type)
204{
205 char *name;
206
207 switch (type) {
208 case TUNER_PARAM_TYPE_RADIO:
209 name = "radio";
210 break;
211 case TUNER_PARAM_TYPE_PAL:
212 name = "pal";
213 break;
214 case TUNER_PARAM_TYPE_SECAM:
215 name = "secam";
216 break;
217 case TUNER_PARAM_TYPE_NTSC:
218 name = "ntsc";
219 break;
220 case TUNER_PARAM_TYPE_DIGITAL:
221 name = "digital";
222 break;
223 default:
224 name = "unknown";
225 break;
226 }
227 return name;
228}
229
230static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe,
231 enum param_type desired_type)
232{
233 struct tuner_simple_priv *priv = fe->tuner_priv;
234 struct tunertype *tun = priv->tun;
235 int i;
236
237 for (i = 0; i < tun->count; i++)
238 if (desired_type == tun->params[i].type)
239 break;
240
241 /* use default tuner params if desired_type not available */
242 if (i == tun->count) {
243 tuner_dbg("desired params (%s) undefined for tuner %d\n",
244 tuner_param_name(desired_type), priv->type);
245 i = 0;
246 }
247
248 tuner_dbg("using tuner params #%d (%s)\n", i,
249 tuner_param_name(tun->params[i].type));
250
251 return &tun->params[i];
252}
253
254static int simple_config_lookup(struct dvb_frontend *fe,
255 struct tuner_params *t_params,
256 int *frequency, u8 *config, u8 *cb)
257{
258 struct tuner_simple_priv *priv = fe->tuner_priv;
259 int i;
260
261 for (i = 0; i < t_params->count; i++) {
262 if (*frequency > t_params->ranges[i].limit)
263 continue;
264 break;
265 }
266 if (i == t_params->count) {
267 tuner_dbg("frequency out of range (%d > %d)\n",
268 *frequency, t_params->ranges[i - 1].limit);
269 *frequency = t_params->ranges[--i].limit;
270 }
271 *config = t_params->ranges[i].config;
272 *cb = t_params->ranges[i].cb;
273
274 tuner_dbg("freq = %d.%02d (%d), range = %d, "
275 "config = 0x%02x, cb = 0x%02x\n",
276 *frequency / 16, *frequency % 16 * 100 / 16, *frequency,
277 i, *config, *cb);
278
279 return i;
280}
281
282/* ---------------------------------------------------------------------- */
283
284static void simple_set_rf_input(struct dvb_frontend *fe,
285 u8 *config, u8 *cb, unsigned int rf)
286{
287 struct tuner_simple_priv *priv = fe->tuner_priv;
288
289 switch (priv->type) {
290 case TUNER_PHILIPS_TUV1236D:
291 switch (rf) {
292 case 1:
293 *cb |= 0x08;
294 break;
295 default:
296 *cb &= ~0x08;
297 break;
298 }
299 break;
300 case TUNER_PHILIPS_FCV1236D:
301 switch (rf) {
302 case 1:
303 *cb |= 0x01;
304 break;
305 default:
306 *cb &= ~0x01;
307 break;
308 }
309 break;
310 default:
311 break;
312 }
313}
314
315static int simple_std_setup(struct dvb_frontend *fe,
316 struct analog_parameters *params,
317 u8 *config, u8 *cb)
318{
319 struct tuner_simple_priv *priv = fe->tuner_priv;
320 u8 tuneraddr;
321 int rc;
322
323 /* tv norm specific stuff for multi-norm tuners */
324 switch (priv->type) {
325 case TUNER_PHILIPS_SECAM: /* FI1216MF */
326 /* 0x01 -> ??? no change ??? */
327 /* 0x02 -> PAL BDGHI / SECAM L */
328 /* 0x04 -> ??? PAL others / SECAM others ??? */
329 *cb &= ~0x03;
330 if (params->std & V4L2_STD_SECAM_L)
331 /* also valid for V4L2_STD_SECAM */
332 *cb |= PHILIPS_MF_SET_STD_L;
333 else if (params->std & V4L2_STD_SECAM_LC)
334 *cb |= PHILIPS_MF_SET_STD_LC;
335 else /* V4L2_STD_B|V4L2_STD_GH */
336 *cb |= PHILIPS_MF_SET_STD_BG;
337 break;
338
339 case TUNER_TEMIC_4046FM5:
340 *cb &= ~0x0f;
341
342 if (params->std & V4L2_STD_PAL_BG) {
343 *cb |= TEMIC_SET_PAL_BG;
344
345 } else if (params->std & V4L2_STD_PAL_I) {
346 *cb |= TEMIC_SET_PAL_I;
347
348 } else if (params->std & V4L2_STD_PAL_DK) {
349 *cb |= TEMIC_SET_PAL_DK;
350
351 } else if (params->std & V4L2_STD_SECAM_L) {
352 *cb |= TEMIC_SET_PAL_L;
353
354 }
355 break;
356
357 case TUNER_PHILIPS_FQ1216ME:
358 *cb &= ~0x0f;
359
360 if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
361 *cb |= PHILIPS_SET_PAL_BGDK;
362
363 } else if (params->std & V4L2_STD_PAL_I) {
364 *cb |= PHILIPS_SET_PAL_I;
365
366 } else if (params->std & V4L2_STD_SECAM_L) {
367 *cb |= PHILIPS_SET_PAL_L;
368
369 }
370 break;
371
372 case TUNER_PHILIPS_FCV1236D:
373 /* 0x00 -> ATSC antenna input 1 */
374 /* 0x01 -> ATSC antenna input 2 */
375 /* 0x02 -> NTSC antenna input 1 */
376 /* 0x03 -> NTSC antenna input 2 */
377 *cb &= ~0x03;
378 if (!(params->std & V4L2_STD_ATSC))
379 *cb |= 2;
380 break;
381
382 case TUNER_MICROTUNE_4042FI5:
383 /* Set the charge pump for fast tuning */
384 *config |= TUNER_CHARGE_PUMP;
385 break;
386
387 case TUNER_PHILIPS_TUV1236D:
388 {
389 /* 0x40 -> ATSC antenna input 1 */
390 /* 0x48 -> ATSC antenna input 2 */
391 /* 0x00 -> NTSC antenna input 1 */
392 /* 0x08 -> NTSC antenna input 2 */
393 u8 buffer[4] = { 0x14, 0x00, 0x17, 0x00};
394 *cb &= ~0x40;
395 if (params->std & V4L2_STD_ATSC) {
396 *cb |= 0x40;
397 buffer[1] = 0x04;
398 }
399 /* set to the correct mode (analog or digital) */
400 tuneraddr = priv->i2c_props.addr;
401 priv->i2c_props.addr = 0x0a;
402 rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[0], 2);
403 if (2 != rc)
404 tuner_warn("i2c i/o error: rc == %d "
405 "(should be 2)\n", rc);
406 rc = tuner_i2c_xfer_send(&priv->i2c_props, &buffer[2], 2);
407 if (2 != rc)
408 tuner_warn("i2c i/o error: rc == %d "
409 "(should be 2)\n", rc);
410 priv->i2c_props.addr = tuneraddr;
411 break;
412 }
413 }
414 if (atv_input[priv->nr])
415 simple_set_rf_input(fe, config, cb, atv_input[priv->nr]);
416
417 return 0;
418}
419
420static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
421 u16 div, u8 config, u8 cb)
422{
423 struct tuner_simple_priv *priv = fe->tuner_priv;
424 int rc;
425
426 switch (priv->type) {
427 case TUNER_LG_TDVS_H06XF:
428 /* Set the Auxiliary Byte. */
429 buffer[0] = buffer[2];
430 buffer[0] &= ~0x20;
431 buffer[0] |= 0x18;
432 buffer[1] = 0x20;
433 tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]);
434
435 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
436 if (2 != rc)
437 tuner_warn("i2c i/o error: rc == %d "
438 "(should be 2)\n", rc);
439 break;
440 case TUNER_MICROTUNE_4042FI5:
441 {
442 /* FIXME - this may also work for other tuners */
443 unsigned long timeout = jiffies + msecs_to_jiffies(1);
444 u8 status_byte = 0;
445
446 /* Wait until the PLL locks */
447 for (;;) {
448 if (time_after(jiffies, timeout))
449 return 0;
450 rc = tuner_i2c_xfer_recv(&priv->i2c_props,
451 &status_byte, 1);
452 if (1 != rc) {
453 tuner_warn("i2c i/o read error: rc == %d "
454 "(should be 1)\n", rc);
455 break;
456 }
457 if (status_byte & TUNER_PLL_LOCKED)
458 break;
459 udelay(10);
460 }
461
462 /* Set the charge pump for optimized phase noise figure */
463 config &= ~TUNER_CHARGE_PUMP;
464 buffer[0] = (div>>8) & 0x7f;
465 buffer[1] = div & 0xff;
466 buffer[2] = config;
467 buffer[3] = cb;
468 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
469 buffer[0], buffer[1], buffer[2], buffer[3]);
470
471 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
472 if (4 != rc)
473 tuner_warn("i2c i/o error: rc == %d "
474 "(should be 4)\n", rc);
475 break;
476 }
477 }
478
479 return 0;
480}
481
482static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
483{
484 struct tuner_simple_priv *priv = fe->tuner_priv;
485
486 switch (priv->type) {
487 case TUNER_TENA_9533_DI:
488 case TUNER_YMEC_TVF_5533MF:
489 tuner_dbg("This tuner doesn't have FM. "
490 "Most cards have a TEA5767 for FM\n");
491 return 0;
492 case TUNER_PHILIPS_FM1216ME_MK3:
493 case TUNER_PHILIPS_FM1236_MK3:
494 case TUNER_PHILIPS_FMD1216ME_MK3:
495 case TUNER_LG_NTSC_TAPE:
496 case TUNER_PHILIPS_FM1256_IH3:
497 buffer[3] = 0x19;
498 break;
499 case TUNER_TNF_5335MF:
500 buffer[3] = 0x11;
501 break;
502 case TUNER_LG_PAL_FM:
503 buffer[3] = 0xa5;
504 break;
505 case TUNER_THOMSON_DTT761X:
506 buffer[3] = 0x39;
507 break;
508 case TUNER_MICROTUNE_4049FM5:
509 default:
510 buffer[3] = 0xa4;
511 break;
512 }
513
514 return 0;
515}
516
517/* ---------------------------------------------------------------------- */
518
519static int simple_set_tv_freq(struct dvb_frontend *fe,
520 struct analog_parameters *params)
521{
522 struct tuner_simple_priv *priv = fe->tuner_priv;
523 u8 config, cb;
524 u16 div;
525 struct tunertype *tun;
526 u8 buffer[4];
527 int rc, IFPCoff, i;
528 enum param_type desired_type;
529 struct tuner_params *t_params;
530
531 tun = priv->tun;
532
533 /* IFPCoff = Video Intermediate Frequency - Vif:
534 940 =16*58.75 NTSC/J (Japan)
535 732 =16*45.75 M/N STD
536 704 =16*44 ATSC (at DVB code)
537 632 =16*39.50 I U.K.
538 622.4=16*38.90 B/G D/K I, L STD
539 592 =16*37.00 D China
540 590 =16.36.875 B Australia
541 543.2=16*33.95 L' STD
542 171.2=16*10.70 FM Radio (at set_radio_freq)
543 */
544
545 if (params->std == V4L2_STD_NTSC_M_JP) {
546 IFPCoff = 940;
547 desired_type = TUNER_PARAM_TYPE_NTSC;
548 } else if ((params->std & V4L2_STD_MN) &&
549 !(params->std & ~V4L2_STD_MN)) {
550 IFPCoff = 732;
551 desired_type = TUNER_PARAM_TYPE_NTSC;
552 } else if (params->std == V4L2_STD_SECAM_LC) {
553 IFPCoff = 543;
554 desired_type = TUNER_PARAM_TYPE_SECAM;
555 } else {
556 IFPCoff = 623;
557 desired_type = TUNER_PARAM_TYPE_PAL;
558 }
559
560 t_params = simple_tuner_params(fe, desired_type);
561
562 i = simple_config_lookup(fe, t_params, &params->frequency,
563 &config, &cb);
564
565 div = params->frequency + IFPCoff + offset;
566
567 tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, "
568 "Offset=%d.%02d MHz, div=%0d\n",
569 params->frequency / 16, params->frequency % 16 * 100 / 16,
570 IFPCoff / 16, IFPCoff % 16 * 100 / 16,
571 offset / 16, offset % 16 * 100 / 16, div);
572
573 /* tv norm specific stuff for multi-norm tuners */
574 simple_std_setup(fe, params, &config, &cb);
575
576 if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
577 buffer[0] = config;
578 buffer[1] = cb;
579 buffer[2] = (div>>8) & 0x7f;
580 buffer[3] = div & 0xff;
581 } else {
582 buffer[0] = (div>>8) & 0x7f;
583 buffer[1] = div & 0xff;
584 buffer[2] = config;
585 buffer[3] = cb;
586 }
587 priv->last_div = div;
588 if (t_params->has_tda9887) {
589 struct v4l2_priv_tun_config tda9887_cfg;
590 int config = 0;
591 int is_secam_l = (params->std & (V4L2_STD_SECAM_L |
592 V4L2_STD_SECAM_LC)) &&
593 !(params->std & ~(V4L2_STD_SECAM_L |
594 V4L2_STD_SECAM_LC));
595
596 tda9887_cfg.tuner = TUNER_TDA9887;
597 tda9887_cfg.priv = &config;
598
599 if (params->std == V4L2_STD_SECAM_LC) {
600 if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
601 config |= TDA9887_PORT1_ACTIVE;
602 if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc)
603 config |= TDA9887_PORT2_ACTIVE;
604 } else {
605 if (t_params->port1_active)
606 config |= TDA9887_PORT1_ACTIVE;
607 if (t_params->port2_active)
608 config |= TDA9887_PORT2_ACTIVE;
609 }
610 if (t_params->intercarrier_mode)
611 config |= TDA9887_INTERCARRIER;
612 if (is_secam_l) {
613 if (i == 0 && t_params->default_top_secam_low)
614 config |= TDA9887_TOP(t_params->default_top_secam_low);
615 else if (i == 1 && t_params->default_top_secam_mid)
616 config |= TDA9887_TOP(t_params->default_top_secam_mid);
617 else if (t_params->default_top_secam_high)
618 config |= TDA9887_TOP(t_params->default_top_secam_high);
619 } else {
620 if (i == 0 && t_params->default_top_low)
621 config |= TDA9887_TOP(t_params->default_top_low);
622 else if (i == 1 && t_params->default_top_mid)
623 config |= TDA9887_TOP(t_params->default_top_mid);
624 else if (t_params->default_top_high)
625 config |= TDA9887_TOP(t_params->default_top_high);
626 }
627 if (t_params->default_pll_gating_18)
628 config |= TDA9887_GATING_18;
629 i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
630 &tda9887_cfg);
631 }
632 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
633 buffer[0], buffer[1], buffer[2], buffer[3]);
634
635 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
636 if (4 != rc)
637 tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
638
639 simple_post_tune(fe, &buffer[0], div, config, cb);
640
641 return 0;
642}
643
644static int simple_set_radio_freq(struct dvb_frontend *fe,
645 struct analog_parameters *params)
646{
647 struct tunertype *tun;
648 struct tuner_simple_priv *priv = fe->tuner_priv;
649 u8 buffer[4];
650 u16 div;
651 int rc, j;
652 struct tuner_params *t_params;
653 unsigned int freq = params->frequency;
654
655 tun = priv->tun;
656
657 for (j = tun->count-1; j > 0; j--)
658 if (tun->params[j].type == TUNER_PARAM_TYPE_RADIO)
659 break;
660 /* default t_params (j=0) will be used if desired type wasn't found */
661 t_params = &tun->params[j];
662
663 /* Select Radio 1st IF used */
664 switch (t_params->radio_if) {
665 case 0: /* 10.7 MHz */
666 freq += (unsigned int)(10.7*16000);
667 break;
668 case 1: /* 33.3 MHz */
669 freq += (unsigned int)(33.3*16000);
670 break;
671 case 2: /* 41.3 MHz */
672 freq += (unsigned int)(41.3*16000);
673 break;
674 default:
675 tuner_warn("Unsupported radio_if value %d\n",
676 t_params->radio_if);
677 return 0;
678 }
679
680 /* Bandswitch byte */
681 simple_radio_bandswitch(fe, &buffer[0]);
682
683 buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) |
684 TUNER_RATIO_SELECT_50; /* 50 kHz step */
685
686 /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
687 freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
688 freq * (1/800) */
689 div = (freq + 400) / 800;
690
691 if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
692 buffer[0] = buffer[2];
693 buffer[1] = buffer[3];
694 buffer[2] = (div>>8) & 0x7f;
695 buffer[3] = div & 0xff;
696 } else {
697 buffer[0] = (div>>8) & 0x7f;
698 buffer[1] = div & 0xff;
699 }
700
701 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
702 buffer[0], buffer[1], buffer[2], buffer[3]);
703 priv->last_div = div;
704
705 if (t_params->has_tda9887) {
706 int config = 0;
707 struct v4l2_priv_tun_config tda9887_cfg;
708
709 tda9887_cfg.tuner = TUNER_TDA9887;
710 tda9887_cfg.priv = &config;
711
712 if (t_params->port1_active &&
713 !t_params->port1_fm_high_sensitivity)
714 config |= TDA9887_PORT1_ACTIVE;
715 if (t_params->port2_active &&
716 !t_params->port2_fm_high_sensitivity)
717 config |= TDA9887_PORT2_ACTIVE;
718 if (t_params->intercarrier_mode)
719 config |= TDA9887_INTERCARRIER;
720/* if (t_params->port1_set_for_fm_mono)
721 config &= ~TDA9887_PORT1_ACTIVE;*/
722 if (t_params->fm_gain_normal)
723 config |= TDA9887_GAIN_NORMAL;
724 if (t_params->radio_if == 2)
725 config |= TDA9887_RIF_41_3;
726 i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
727 &tda9887_cfg);
728 }
729 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
730 if (4 != rc)
731 tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
732
733 return 0;
734}
735
736static int simple_set_params(struct dvb_frontend *fe,
737 struct analog_parameters *params)
738{
739 struct tuner_simple_priv *priv = fe->tuner_priv;
740 int ret = -EINVAL;
741
742 if (priv->i2c_props.adap == NULL)
743 return -EINVAL;
744
745 switch (params->mode) {
746 case V4L2_TUNER_RADIO:
747 ret = simple_set_radio_freq(fe, params);
748 priv->frequency = params->frequency * 125 / 2;
749 break;
750 case V4L2_TUNER_ANALOG_TV:
751 case V4L2_TUNER_DIGITAL_TV:
752 ret = simple_set_tv_freq(fe, params);
753 priv->frequency = params->frequency * 62500;
754 break;
755 }
756 priv->bandwidth = 0;
757
758 return ret;
759}
760
761static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf,
762 const struct dvb_frontend_parameters *params)
763{
764 struct tuner_simple_priv *priv = fe->tuner_priv;
765
766 switch (priv->type) {
767 case TUNER_PHILIPS_FMD1216ME_MK3:
768 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ &&
769 params->frequency >= 158870000)
770 buf[3] |= 0x08;
771 break;
772 case TUNER_PHILIPS_TD1316:
773 /* determine band */
774 buf[3] |= (params->frequency < 161000000) ? 1 :
775 (params->frequency < 444000000) ? 2 : 4;
776
777 /* setup PLL filter */
778 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
779 buf[3] |= 1 << 3;
780 break;
781 case TUNER_PHILIPS_TUV1236D:
782 case TUNER_PHILIPS_FCV1236D:
783 {
784 unsigned int new_rf;
785
786 if (dtv_input[priv->nr])
787 new_rf = dtv_input[priv->nr];
788 else
789 switch (params->u.vsb.modulation) {
790 case QAM_64:
791 case QAM_256:
792 new_rf = 1;
793 break;
794 case VSB_8:
795 default:
796 new_rf = 0;
797 break;
798 }
799 simple_set_rf_input(fe, &buf[2], &buf[3], new_rf);
800 break;
801 }
802 default:
803 break;
804 }
805}
806
807static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf,
808 const struct dvb_frontend_parameters *params)
809{
810 /* This function returns the tuned frequency on success, 0 on error */
811 struct tuner_simple_priv *priv = fe->tuner_priv;
812 struct tunertype *tun = priv->tun;
813 static struct tuner_params *t_params;
814 u8 config, cb;
815 u32 div;
816 int ret, frequency = params->frequency / 62500;
817
818 t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL);
819 ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb);
820 if (ret < 0)
821 return 0; /* failure */
822
823 div = ((frequency + t_params->iffreq) * 62500 + offset +
824 tun->stepsize/2) / tun->stepsize;
825
826 buf[0] = div >> 8;
827 buf[1] = div & 0xff;
828 buf[2] = config;
829 buf[3] = cb;
830
831 simple_set_dvb(fe, buf, params);
832
833 tuner_dbg("%s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
834 tun->name, div, buf[0], buf[1], buf[2], buf[3]);
835
836 /* calculate the frequency we set it to */
837 return (div * tun->stepsize) - t_params->iffreq;
838}
839
840static int simple_dvb_calc_regs(struct dvb_frontend *fe,
841 struct dvb_frontend_parameters *params,
842 u8 *buf, int buf_len)
843{
844 struct tuner_simple_priv *priv = fe->tuner_priv;
845 u32 frequency;
846
847 if (buf_len < 5)
848 return -EINVAL;
849
850 frequency = simple_dvb_configure(fe, buf+1, params);
851 if (frequency == 0)
852 return -EINVAL;
853
854 buf[0] = priv->i2c_props.addr;
855
856 priv->frequency = frequency;
857 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ?
858 params->u.ofdm.bandwidth : 0;
859
860 return 5;
861}
862
863static int simple_dvb_set_params(struct dvb_frontend *fe,
864 struct dvb_frontend_parameters *params)
865{
866 struct tuner_simple_priv *priv = fe->tuner_priv;
867 u32 prev_freq, prev_bw;
868 int ret;
869 u8 buf[5];
870
871 if (priv->i2c_props.adap == NULL)
872 return -EINVAL;
873
874 prev_freq = priv->frequency;
875 prev_bw = priv->bandwidth;
876
877 ret = simple_dvb_calc_regs(fe, params, buf, 5);
878 if (ret != 5)
879 goto fail;
880
881 /* put analog demod in standby when tuning digital */
882 if (fe->ops.analog_ops.standby)
883 fe->ops.analog_ops.standby(fe);
884
885 if (fe->ops.i2c_gate_ctrl)
886 fe->ops.i2c_gate_ctrl(fe, 1);
887
888 /* buf[0] contains the i2c address, but *
889 * we already have it in i2c_props.addr */
890 ret = tuner_i2c_xfer_send(&priv->i2c_props, buf+1, 4);
891 if (ret != 4)
892 goto fail;
893
894 return 0;
895fail:
896 /* calc_regs sets frequency and bandwidth. if we failed, unset them */
897 priv->frequency = prev_freq;
898 priv->bandwidth = prev_bw;
899
900 return ret;
901}
902
903static int simple_init(struct dvb_frontend *fe)
904{
905 struct tuner_simple_priv *priv = fe->tuner_priv;
906
907 if (priv->i2c_props.adap == NULL)
908 return -EINVAL;
909
910 if (priv->tun->initdata) {
911 int ret;
912
913 if (fe->ops.i2c_gate_ctrl)
914 fe->ops.i2c_gate_ctrl(fe, 1);
915
916 ret = tuner_i2c_xfer_send(&priv->i2c_props,
917 priv->tun->initdata + 1,
918 priv->tun->initdata[0]);
919 if (ret != priv->tun->initdata[0])
920 return ret;
921 }
922
923 return 0;
924}
925
926static int simple_sleep(struct dvb_frontend *fe)
927{
928 struct tuner_simple_priv *priv = fe->tuner_priv;
929
930 if (priv->i2c_props.adap == NULL)
931 return -EINVAL;
932
933 if (priv->tun->sleepdata) {
934 int ret;
935
936 if (fe->ops.i2c_gate_ctrl)
937 fe->ops.i2c_gate_ctrl(fe, 1);
938
939 ret = tuner_i2c_xfer_send(&priv->i2c_props,
940 priv->tun->sleepdata + 1,
941 priv->tun->sleepdata[0]);
942 if (ret != priv->tun->sleepdata[0])
943 return ret;
944 }
945
946 return 0;
947}
948
949static int simple_release(struct dvb_frontend *fe)
950{
951 struct tuner_simple_priv *priv = fe->tuner_priv;
952
953 mutex_lock(&tuner_simple_list_mutex);
954
955 if (priv)
956 hybrid_tuner_release_state(priv);
957
958 mutex_unlock(&tuner_simple_list_mutex);
959
960 fe->tuner_priv = NULL;
961
962 return 0;
963}
964
965static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency)
966{
967 struct tuner_simple_priv *priv = fe->tuner_priv;
968 *frequency = priv->frequency;
969 return 0;
970}
971
972static int simple_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
973{
974 struct tuner_simple_priv *priv = fe->tuner_priv;
975 *bandwidth = priv->bandwidth;
976 return 0;
977}
978
979static struct dvb_tuner_ops simple_tuner_ops = {
980 .init = simple_init,
981 .sleep = simple_sleep,
982 .set_analog_params = simple_set_params,
983 .set_params = simple_dvb_set_params,
984 .calc_regs = simple_dvb_calc_regs,
985 .release = simple_release,
986 .get_frequency = simple_get_frequency,
987 .get_bandwidth = simple_get_bandwidth,
988 .get_status = simple_get_status,
989 .get_rf_strength = simple_get_rf_strength,
990};
991
992struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
993 struct i2c_adapter *i2c_adap,
994 u8 i2c_addr,
995 unsigned int type)
996{
997 struct tuner_simple_priv *priv = NULL;
998 int instance;
999
1000 if (type >= tuner_count) {
1001 printk(KERN_WARNING "%s: invalid tuner type: %d (max: %d)\n",
1002 __func__, type, tuner_count-1);
1003 return NULL;
1004 }
1005
1006 /* If i2c_adap is set, check that the tuner is at the correct address.
1007 * Otherwise, if i2c_adap is NULL, the tuner will be programmed directly
1008 * by the digital demod via calc_regs.
1009 */
1010 if (i2c_adap != NULL) {
1011 u8 b[1];
1012 struct i2c_msg msg = {
1013 .addr = i2c_addr, .flags = I2C_M_RD,
1014 .buf = b, .len = 1,
1015 };
1016
1017 if (fe->ops.i2c_gate_ctrl)
1018 fe->ops.i2c_gate_ctrl(fe, 1);
1019
1020 if (1 != i2c_transfer(i2c_adap, &msg, 1))
1021 tuner_warn("unable to probe %s, proceeding anyway.",
1022 tuners[type].name);
1023
1024 if (fe->ops.i2c_gate_ctrl)
1025 fe->ops.i2c_gate_ctrl(fe, 0);
1026 }
1027
1028 mutex_lock(&tuner_simple_list_mutex);
1029
1030 instance = hybrid_tuner_request_state(struct tuner_simple_priv, priv,
1031 hybrid_tuner_instance_list,
1032 i2c_adap, i2c_addr,
1033 "tuner-simple");
1034 switch (instance) {
1035 case 0:
1036 mutex_unlock(&tuner_simple_list_mutex);
1037 return NULL;
1038 break;
1039 case 1:
1040 fe->tuner_priv = priv;
1041
1042 priv->type = type;
1043 priv->tun = &tuners[type];
1044 priv->nr = simple_devcount++;
1045 break;
1046 default:
1047 fe->tuner_priv = priv;
1048 break;
1049 }
1050
1051 mutex_unlock(&tuner_simple_list_mutex);
1052
1053 memcpy(&fe->ops.tuner_ops, &simple_tuner_ops,
1054 sizeof(struct dvb_tuner_ops));
1055
1056 tuner_info("type set to %d (%s)\n", type, priv->tun->name);
1057
1058 if ((debug) || ((atv_input[priv->nr] > 0) ||
1059 (dtv_input[priv->nr] > 0))) {
1060 if (0 == atv_input[priv->nr])
1061 tuner_info("tuner %d atv rf input will be "
1062 "autoselected\n", priv->nr);
1063 else
1064 tuner_info("tuner %d atv rf input will be "
1065 "set to input %d (insmod option)\n",
1066 priv->nr, atv_input[priv->nr]);
1067 if (0 == dtv_input[priv->nr])
1068 tuner_info("tuner %d dtv rf input will be "
1069 "autoselected\n", priv->nr);
1070 else
1071 tuner_info("tuner %d dtv rf input will be "
1072 "set to input %d (insmod option)\n",
1073 priv->nr, dtv_input[priv->nr]);
1074 }
1075
1076 strlcpy(fe->ops.tuner_ops.info.name, priv->tun->name,
1077 sizeof(fe->ops.tuner_ops.info.name));
1078
1079 return fe;
1080}
1081EXPORT_SYMBOL_GPL(simple_tuner_attach);
1082
1083MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver");
1084MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
1085MODULE_LICENSE("GPL");
1086
1087/*
1088 * Overrides for Emacs so that we follow Linus's tabbing style.
1089 * ---------------------------------------------------------------------------
1090 * Local variables:
1091 * c-basic-offset: 8
1092 * End:
1093 */
diff --git a/drivers/media/video/tuner-simple.h b/drivers/media/video/tuner-simple.h
deleted file mode 100644
index e46cf0121e03..000000000000
--- a/drivers/media/video/tuner-simple.h
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TUNER_SIMPLE_H__
18#define __TUNER_SIMPLE_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23#if defined(CONFIG_TUNER_SIMPLE) || (defined(CONFIG_TUNER_SIMPLE_MODULE) && defined(MODULE))
24extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
25 struct i2c_adapter *i2c_adap,
26 u8 i2c_addr,
27 unsigned int type);
28#else
29static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
30 struct i2c_adapter *i2c_adap,
31 u8 i2c_addr,
32 unsigned int type)
33{
34 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
35 return NULL;
36}
37#endif
38
39#endif /* __TUNER_SIMPLE_H__ */
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c
deleted file mode 100644
index 10dddca8b5d1..000000000000
--- a/drivers/media/video/tuner-types.c
+++ /dev/null
@@ -1,1652 +0,0 @@
1/*
2 *
3 * i2c tv tuner chip device type database.
4 *
5 */
6
7#include <linux/i2c.h>
8#include <media/tuner.h>
9#include <media/tuner-types.h>
10
11/* ---------------------------------------------------------------------- */
12
13/*
14 * The floats in the tuner struct are computed at compile time
15 * by gcc and cast back to integers. Thus we don't violate the
16 * "no float in kernel" rule.
17 *
18 * A tuner_range may be referenced by multiple tuner_params structs.
19 * There are many duplicates in here. Reusing tuner_range structs,
20 * rather than defining new ones for each tuner, will cut down on
21 * memory usage, and is preferred when possible.
22 *
23 * Each tuner_params array may contain one or more elements, one
24 * for each video standard.
25 *
26 * FIXME: tuner_params struct contains an element, tda988x. We must
27 * set this for all tuners that contain a tda988x chip, and then we
28 * can remove this setting from the various card structs.
29 *
30 * FIXME: Right now, all tuners are using the first tuner_params[]
31 * array element for analog mode. In the future, we will be merging
32 * similar tuner definitions together, such that each tuner definition
33 * will have a tuner_params struct for each available video standard.
34 * At that point, the tuner_params[] array element will be chosen
35 * based on the video standard in use.
36 */
37
38/* The following was taken from dvb-pll.c: */
39
40/* Set AGC TOP value to 103 dBuV:
41 * 0x80 = Control Byte
42 * 0x40 = 250 uA charge pump (irrelevant)
43 * 0x18 = Aux Byte to follow
44 * 0x06 = 64.5 kHz divider (irrelevant)
45 * 0x01 = Disable Vt (aka sleep)
46 *
47 * 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA)
48 * 0x50 = AGC Take over point = 103 dBuV
49 */
50static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 };
51
52/* 0x04 = 166.67 kHz divider
53 *
54 * 0x80 = AGC Time constant 50ms Iagc = 9 uA
55 * 0x20 = AGC Take over point = 112 dBuV
56 */
57static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 };
58
59/* 0-9 */
60/* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */
61
62static struct tuner_range tuner_temic_pal_ranges[] = {
63 { 16 * 140.25 /*MHz*/, 0x8e, 0x02, },
64 { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
65 { 16 * 999.99 , 0x8e, 0x01, },
66};
67
68static struct tuner_params tuner_temic_pal_params[] = {
69 {
70 .type = TUNER_PARAM_TYPE_PAL,
71 .ranges = tuner_temic_pal_ranges,
72 .count = ARRAY_SIZE(tuner_temic_pal_ranges),
73 },
74};
75
76/* ------------ TUNER_PHILIPS_PAL_I - Philips PAL_I ------------ */
77
78static struct tuner_range tuner_philips_pal_i_ranges[] = {
79 { 16 * 140.25 /*MHz*/, 0x8e, 0xa0, },
80 { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
81 { 16 * 999.99 , 0x8e, 0x30, },
82};
83
84static struct tuner_params tuner_philips_pal_i_params[] = {
85 {
86 .type = TUNER_PARAM_TYPE_PAL,
87 .ranges = tuner_philips_pal_i_ranges,
88 .count = ARRAY_SIZE(tuner_philips_pal_i_ranges),
89 },
90};
91
92/* ------------ TUNER_PHILIPS_NTSC - Philips NTSC ------------ */
93
94static struct tuner_range tuner_philips_ntsc_ranges[] = {
95 { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
96 { 16 * 451.25 /*MHz*/, 0x8e, 0x90, },
97 { 16 * 999.99 , 0x8e, 0x30, },
98};
99
100static struct tuner_params tuner_philips_ntsc_params[] = {
101 {
102 .type = TUNER_PARAM_TYPE_NTSC,
103 .ranges = tuner_philips_ntsc_ranges,
104 .count = ARRAY_SIZE(tuner_philips_ntsc_ranges),
105 .cb_first_if_lower_freq = 1,
106 },
107};
108
109/* ------------ TUNER_PHILIPS_SECAM - Philips SECAM ------------ */
110
111static struct tuner_range tuner_philips_secam_ranges[] = {
112 { 16 * 168.25 /*MHz*/, 0x8e, 0xa7, },
113 { 16 * 447.25 /*MHz*/, 0x8e, 0x97, },
114 { 16 * 999.99 , 0x8e, 0x37, },
115};
116
117static struct tuner_params tuner_philips_secam_params[] = {
118 {
119 .type = TUNER_PARAM_TYPE_SECAM,
120 .ranges = tuner_philips_secam_ranges,
121 .count = ARRAY_SIZE(tuner_philips_secam_ranges),
122 .cb_first_if_lower_freq = 1,
123 },
124};
125
126/* ------------ TUNER_PHILIPS_PAL - Philips PAL ------------ */
127
128static struct tuner_range tuner_philips_pal_ranges[] = {
129 { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
130 { 16 * 447.25 /*MHz*/, 0x8e, 0x90, },
131 { 16 * 999.99 , 0x8e, 0x30, },
132};
133
134static struct tuner_params tuner_philips_pal_params[] = {
135 {
136 .type = TUNER_PARAM_TYPE_PAL,
137 .ranges = tuner_philips_pal_ranges,
138 .count = ARRAY_SIZE(tuner_philips_pal_ranges),
139 .cb_first_if_lower_freq = 1,
140 },
141};
142
143/* ------------ TUNER_TEMIC_NTSC - TEMIC NTSC ------------ */
144
145static struct tuner_range tuner_temic_ntsc_ranges[] = {
146 { 16 * 157.25 /*MHz*/, 0x8e, 0x02, },
147 { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
148 { 16 * 999.99 , 0x8e, 0x01, },
149};
150
151static struct tuner_params tuner_temic_ntsc_params[] = {
152 {
153 .type = TUNER_PARAM_TYPE_NTSC,
154 .ranges = tuner_temic_ntsc_ranges,
155 .count = ARRAY_SIZE(tuner_temic_ntsc_ranges),
156 },
157};
158
159/* ------------ TUNER_TEMIC_PAL_I - TEMIC PAL_I ------------ */
160
161static struct tuner_range tuner_temic_pal_i_ranges[] = {
162 { 16 * 170.00 /*MHz*/, 0x8e, 0x02, },
163 { 16 * 450.00 /*MHz*/, 0x8e, 0x04, },
164 { 16 * 999.99 , 0x8e, 0x01, },
165};
166
167static struct tuner_params tuner_temic_pal_i_params[] = {
168 {
169 .type = TUNER_PARAM_TYPE_PAL,
170 .ranges = tuner_temic_pal_i_ranges,
171 .count = ARRAY_SIZE(tuner_temic_pal_i_ranges),
172 },
173};
174
175/* ------------ TUNER_TEMIC_4036FY5_NTSC - TEMIC NTSC ------------ */
176
177static struct tuner_range tuner_temic_4036fy5_ntsc_ranges[] = {
178 { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
179 { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
180 { 16 * 999.99 , 0x8e, 0x30, },
181};
182
183static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = {
184 {
185 .type = TUNER_PARAM_TYPE_NTSC,
186 .ranges = tuner_temic_4036fy5_ntsc_ranges,
187 .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_ranges),
188 },
189};
190
191/* ------------ TUNER_ALPS_TSBH1_NTSC - TEMIC NTSC ------------ */
192
193static struct tuner_range tuner_alps_tsb_1_ranges[] = {
194 { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
195 { 16 * 385.25 /*MHz*/, 0x8e, 0x02, },
196 { 16 * 999.99 , 0x8e, 0x08, },
197};
198
199static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = {
200 {
201 .type = TUNER_PARAM_TYPE_NTSC,
202 .ranges = tuner_alps_tsb_1_ranges,
203 .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
204 },
205};
206
207/* 10-19 */
208/* ------------ TUNER_ALPS_TSBE1_PAL - TEMIC PAL ------------ */
209
210static struct tuner_params tuner_alps_tsb_1_params[] = {
211 {
212 .type = TUNER_PARAM_TYPE_PAL,
213 .ranges = tuner_alps_tsb_1_ranges,
214 .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
215 },
216};
217
218/* ------------ TUNER_ALPS_TSBB5_PAL_I - Alps PAL_I ------------ */
219
220static struct tuner_range tuner_alps_tsb_5_pal_ranges[] = {
221 { 16 * 133.25 /*MHz*/, 0x8e, 0x01, },
222 { 16 * 351.25 /*MHz*/, 0x8e, 0x02, },
223 { 16 * 999.99 , 0x8e, 0x08, },
224};
225
226static struct tuner_params tuner_alps_tsbb5_params[] = {
227 {
228 .type = TUNER_PARAM_TYPE_PAL,
229 .ranges = tuner_alps_tsb_5_pal_ranges,
230 .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
231 },
232};
233
234/* ------------ TUNER_ALPS_TSBE5_PAL - Alps PAL ------------ */
235
236static struct tuner_params tuner_alps_tsbe5_params[] = {
237 {
238 .type = TUNER_PARAM_TYPE_PAL,
239 .ranges = tuner_alps_tsb_5_pal_ranges,
240 .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
241 },
242};
243
244/* ------------ TUNER_ALPS_TSBC5_PAL - Alps PAL ------------ */
245
246static struct tuner_params tuner_alps_tsbc5_params[] = {
247 {
248 .type = TUNER_PARAM_TYPE_PAL,
249 .ranges = tuner_alps_tsb_5_pal_ranges,
250 .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
251 },
252};
253
254/* ------------ TUNER_TEMIC_4006FH5_PAL - TEMIC PAL ------------ */
255
256static struct tuner_range tuner_lg_pal_ranges[] = {
257 { 16 * 170.00 /*MHz*/, 0x8e, 0xa0, },
258 { 16 * 450.00 /*MHz*/, 0x8e, 0x90, },
259 { 16 * 999.99 , 0x8e, 0x30, },
260};
261
262static struct tuner_params tuner_temic_4006fh5_params[] = {
263 {
264 .type = TUNER_PARAM_TYPE_PAL,
265 .ranges = tuner_lg_pal_ranges,
266 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
267 },
268};
269
270/* ------------ TUNER_ALPS_TSHC6_NTSC - Alps NTSC ------------ */
271
272static struct tuner_range tuner_alps_tshc6_ntsc_ranges[] = {
273 { 16 * 137.25 /*MHz*/, 0x8e, 0x14, },
274 { 16 * 385.25 /*MHz*/, 0x8e, 0x12, },
275 { 16 * 999.99 , 0x8e, 0x11, },
276};
277
278static struct tuner_params tuner_alps_tshc6_params[] = {
279 {
280 .type = TUNER_PARAM_TYPE_NTSC,
281 .ranges = tuner_alps_tshc6_ntsc_ranges,
282 .count = ARRAY_SIZE(tuner_alps_tshc6_ntsc_ranges),
283 },
284};
285
286/* ------------ TUNER_TEMIC_PAL_DK - TEMIC PAL ------------ */
287
288static struct tuner_range tuner_temic_pal_dk_ranges[] = {
289 { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
290 { 16 * 456.25 /*MHz*/, 0x8e, 0x90, },
291 { 16 * 999.99 , 0x8e, 0x30, },
292};
293
294static struct tuner_params tuner_temic_pal_dk_params[] = {
295 {
296 .type = TUNER_PARAM_TYPE_PAL,
297 .ranges = tuner_temic_pal_dk_ranges,
298 .count = ARRAY_SIZE(tuner_temic_pal_dk_ranges),
299 },
300};
301
302/* ------------ TUNER_PHILIPS_NTSC_M - Philips NTSC ------------ */
303
304static struct tuner_range tuner_philips_ntsc_m_ranges[] = {
305 { 16 * 160.00 /*MHz*/, 0x8e, 0xa0, },
306 { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
307 { 16 * 999.99 , 0x8e, 0x30, },
308};
309
310static struct tuner_params tuner_philips_ntsc_m_params[] = {
311 {
312 .type = TUNER_PARAM_TYPE_NTSC,
313 .ranges = tuner_philips_ntsc_m_ranges,
314 .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
315 },
316};
317
318/* ------------ TUNER_TEMIC_4066FY5_PAL_I - TEMIC PAL_I ------------ */
319
320static struct tuner_range tuner_temic_40x6f_5_pal_ranges[] = {
321 { 16 * 169.00 /*MHz*/, 0x8e, 0xa0, },
322 { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
323 { 16 * 999.99 , 0x8e, 0x30, },
324};
325
326static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = {
327 {
328 .type = TUNER_PARAM_TYPE_PAL,
329 .ranges = tuner_temic_40x6f_5_pal_ranges,
330 .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
331 },
332};
333
334/* ------------ TUNER_TEMIC_4006FN5_MULTI_PAL - TEMIC PAL ------------ */
335
336static struct tuner_params tuner_temic_4006fn5_multi_params[] = {
337 {
338 .type = TUNER_PARAM_TYPE_PAL,
339 .ranges = tuner_temic_40x6f_5_pal_ranges,
340 .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
341 },
342};
343
344/* 20-29 */
345/* ------------ TUNER_TEMIC_4009FR5_PAL - TEMIC PAL ------------ */
346
347static struct tuner_range tuner_temic_4009f_5_pal_ranges[] = {
348 { 16 * 141.00 /*MHz*/, 0x8e, 0xa0, },
349 { 16 * 464.00 /*MHz*/, 0x8e, 0x90, },
350 { 16 * 999.99 , 0x8e, 0x30, },
351};
352
353static struct tuner_params tuner_temic_4009f_5_params[] = {
354 {
355 .type = TUNER_PARAM_TYPE_PAL,
356 .ranges = tuner_temic_4009f_5_pal_ranges,
357 .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
358 },
359};
360
361/* ------------ TUNER_TEMIC_4039FR5_NTSC - TEMIC NTSC ------------ */
362
363static struct tuner_range tuner_temic_4x3x_f_5_ntsc_ranges[] = {
364 { 16 * 158.00 /*MHz*/, 0x8e, 0xa0, },
365 { 16 * 453.00 /*MHz*/, 0x8e, 0x90, },
366 { 16 * 999.99 , 0x8e, 0x30, },
367};
368
369static struct tuner_params tuner_temic_4039fr5_params[] = {
370 {
371 .type = TUNER_PARAM_TYPE_NTSC,
372 .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
373 .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
374 },
375};
376
377/* ------------ TUNER_TEMIC_4046FM5 - TEMIC PAL ------------ */
378
379static struct tuner_params tuner_temic_4046fm5_params[] = {
380 {
381 .type = TUNER_PARAM_TYPE_PAL,
382 .ranges = tuner_temic_40x6f_5_pal_ranges,
383 .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
384 },
385};
386
387/* ------------ TUNER_PHILIPS_PAL_DK - Philips PAL ------------ */
388
389static struct tuner_params tuner_philips_pal_dk_params[] = {
390 {
391 .type = TUNER_PARAM_TYPE_PAL,
392 .ranges = tuner_lg_pal_ranges,
393 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
394 },
395};
396
397/* ------------ TUNER_PHILIPS_FQ1216ME - Philips PAL ------------ */
398
399static struct tuner_params tuner_philips_fq1216me_params[] = {
400 {
401 .type = TUNER_PARAM_TYPE_PAL,
402 .ranges = tuner_lg_pal_ranges,
403 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
404 .has_tda9887 = 1,
405 .port1_active = 1,
406 .port2_active = 1,
407 .port2_invert_for_secam_lc = 1,
408 },
409};
410
411/* ------------ TUNER_LG_PAL_I_FM - LGINNOTEK PAL_I ------------ */
412
413static struct tuner_params tuner_lg_pal_i_fm_params[] = {
414 {
415 .type = TUNER_PARAM_TYPE_PAL,
416 .ranges = tuner_lg_pal_ranges,
417 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
418 },
419};
420
421/* ------------ TUNER_LG_PAL_I - LGINNOTEK PAL_I ------------ */
422
423static struct tuner_params tuner_lg_pal_i_params[] = {
424 {
425 .type = TUNER_PARAM_TYPE_PAL,
426 .ranges = tuner_lg_pal_ranges,
427 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
428 },
429};
430
431/* ------------ TUNER_LG_NTSC_FM - LGINNOTEK NTSC ------------ */
432
433static struct tuner_range tuner_lg_ntsc_fm_ranges[] = {
434 { 16 * 210.00 /*MHz*/, 0x8e, 0xa0, },
435 { 16 * 497.00 /*MHz*/, 0x8e, 0x90, },
436 { 16 * 999.99 , 0x8e, 0x30, },
437};
438
439static struct tuner_params tuner_lg_ntsc_fm_params[] = {
440 {
441 .type = TUNER_PARAM_TYPE_NTSC,
442 .ranges = tuner_lg_ntsc_fm_ranges,
443 .count = ARRAY_SIZE(tuner_lg_ntsc_fm_ranges),
444 },
445};
446
447/* ------------ TUNER_LG_PAL_FM - LGINNOTEK PAL ------------ */
448
449static struct tuner_params tuner_lg_pal_fm_params[] = {
450 {
451 .type = TUNER_PARAM_TYPE_PAL,
452 .ranges = tuner_lg_pal_ranges,
453 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
454 },
455};
456
457/* ------------ TUNER_LG_PAL - LGINNOTEK PAL ------------ */
458
459static struct tuner_params tuner_lg_pal_params[] = {
460 {
461 .type = TUNER_PARAM_TYPE_PAL,
462 .ranges = tuner_lg_pal_ranges,
463 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
464 },
465};
466
467/* 30-39 */
468/* ------------ TUNER_TEMIC_4009FN5_MULTI_PAL_FM - TEMIC PAL ------------ */
469
470static struct tuner_params tuner_temic_4009_fn5_multi_pal_fm_params[] = {
471 {
472 .type = TUNER_PARAM_TYPE_PAL,
473 .ranges = tuner_temic_4009f_5_pal_ranges,
474 .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
475 },
476};
477
478/* ------------ TUNER_SHARP_2U5JF5540_NTSC - SHARP NTSC ------------ */
479
480static struct tuner_range tuner_sharp_2u5jf5540_ntsc_ranges[] = {
481 { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
482 { 16 * 317.25 /*MHz*/, 0x8e, 0x02, },
483 { 16 * 999.99 , 0x8e, 0x08, },
484};
485
486static struct tuner_params tuner_sharp_2u5jf5540_params[] = {
487 {
488 .type = TUNER_PARAM_TYPE_NTSC,
489 .ranges = tuner_sharp_2u5jf5540_ntsc_ranges,
490 .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_ntsc_ranges),
491 },
492};
493
494/* ------------ TUNER_Samsung_PAL_TCPM9091PD27 - Samsung PAL ------------ */
495
496static struct tuner_range tuner_samsung_pal_tcpm9091pd27_ranges[] = {
497 { 16 * 169 /*MHz*/, 0x8e, 0xa0, },
498 { 16 * 464 /*MHz*/, 0x8e, 0x90, },
499 { 16 * 999.99 , 0x8e, 0x30, },
500};
501
502static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = {
503 {
504 .type = TUNER_PARAM_TYPE_PAL,
505 .ranges = tuner_samsung_pal_tcpm9091pd27_ranges,
506 .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_ranges),
507 },
508};
509
510/* ------------ TUNER_TEMIC_4106FH5 - TEMIC PAL ------------ */
511
512static struct tuner_params tuner_temic_4106fh5_params[] = {
513 {
514 .type = TUNER_PARAM_TYPE_PAL,
515 .ranges = tuner_temic_4009f_5_pal_ranges,
516 .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
517 },
518};
519
520/* ------------ TUNER_TEMIC_4012FY5 - TEMIC PAL ------------ */
521
522static struct tuner_params tuner_temic_4012fy5_params[] = {
523 {
524 .type = TUNER_PARAM_TYPE_PAL,
525 .ranges = tuner_temic_pal_ranges,
526 .count = ARRAY_SIZE(tuner_temic_pal_ranges),
527 },
528};
529
530/* ------------ TUNER_TEMIC_4136FY5 - TEMIC NTSC ------------ */
531
532static struct tuner_params tuner_temic_4136_fy5_params[] = {
533 {
534 .type = TUNER_PARAM_TYPE_NTSC,
535 .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
536 .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
537 },
538};
539
540/* ------------ TUNER_LG_PAL_NEW_TAPC - LGINNOTEK PAL ------------ */
541
542static struct tuner_range tuner_lg_new_tapc_ranges[] = {
543 { 16 * 170.00 /*MHz*/, 0x8e, 0x01, },
544 { 16 * 450.00 /*MHz*/, 0x8e, 0x02, },
545 { 16 * 999.99 , 0x8e, 0x08, },
546};
547
548static struct tuner_params tuner_lg_pal_new_tapc_params[] = {
549 {
550 .type = TUNER_PARAM_TYPE_PAL,
551 .ranges = tuner_lg_new_tapc_ranges,
552 .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
553 },
554};
555
556/* ------------ TUNER_PHILIPS_FM1216ME_MK3 - Philips PAL ------------ */
557
558static struct tuner_range tuner_fm1216me_mk3_pal_ranges[] = {
559 { 16 * 158.00 /*MHz*/, 0x8e, 0x01, },
560 { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
561 { 16 * 999.99 , 0x8e, 0x04, },
562};
563
564static struct tuner_params tuner_fm1216me_mk3_params[] = {
565 {
566 .type = TUNER_PARAM_TYPE_PAL,
567 .ranges = tuner_fm1216me_mk3_pal_ranges,
568 .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
569 .cb_first_if_lower_freq = 1,
570 .has_tda9887 = 1,
571 .port1_active = 1,
572 .port2_active = 1,
573 .port2_invert_for_secam_lc = 1,
574 .port1_fm_high_sensitivity = 1,
575 .default_top_mid = -2,
576 .default_top_secam_mid = -2,
577 .default_top_secam_high = -2,
578 },
579};
580
581/* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */
582
583static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = {
584 {
585 .type = TUNER_PARAM_TYPE_NTSC,
586 .ranges = tuner_lg_new_tapc_ranges,
587 .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
588 },
589};
590
591/* 40-49 */
592/* ------------ TUNER_HITACHI_NTSC - HITACHI NTSC ------------ */
593
594static struct tuner_params tuner_hitachi_ntsc_params[] = {
595 {
596 .type = TUNER_PARAM_TYPE_NTSC,
597 .ranges = tuner_lg_new_tapc_ranges,
598 .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
599 },
600};
601
602/* ------------ TUNER_PHILIPS_PAL_MK - Philips PAL ------------ */
603
604static struct tuner_range tuner_philips_pal_mk_pal_ranges[] = {
605 { 16 * 140.25 /*MHz*/, 0x8e, 0x01, },
606 { 16 * 463.25 /*MHz*/, 0x8e, 0xc2, },
607 { 16 * 999.99 , 0x8e, 0xcf, },
608};
609
610static struct tuner_params tuner_philips_pal_mk_params[] = {
611 {
612 .type = TUNER_PARAM_TYPE_PAL,
613 .ranges = tuner_philips_pal_mk_pal_ranges,
614 .count = ARRAY_SIZE(tuner_philips_pal_mk_pal_ranges),
615 },
616};
617
618/* ---- TUNER_PHILIPS_FCV1236D - Philips FCV1236D (ATSC/NTSC) ---- */
619
620static struct tuner_range tuner_philips_fcv1236d_ntsc_ranges[] = {
621 { 16 * 157.25 /*MHz*/, 0x8e, 0xa2, },
622 { 16 * 451.25 /*MHz*/, 0x8e, 0x92, },
623 { 16 * 999.99 , 0x8e, 0x32, },
624};
625
626static struct tuner_range tuner_philips_fcv1236d_atsc_ranges[] = {
627 { 16 * 159.00 /*MHz*/, 0x8e, 0xa0, },
628 { 16 * 453.00 /*MHz*/, 0x8e, 0x90, },
629 { 16 * 999.99 , 0x8e, 0x30, },
630};
631
632static struct tuner_params tuner_philips_fcv1236d_params[] = {
633 {
634 .type = TUNER_PARAM_TYPE_NTSC,
635 .ranges = tuner_philips_fcv1236d_ntsc_ranges,
636 .count = ARRAY_SIZE(tuner_philips_fcv1236d_ntsc_ranges),
637 },
638 {
639 .type = TUNER_PARAM_TYPE_DIGITAL,
640 .ranges = tuner_philips_fcv1236d_atsc_ranges,
641 .count = ARRAY_SIZE(tuner_philips_fcv1236d_atsc_ranges),
642 .iffreq = 16 * 44.00,
643 },
644};
645
646/* ------------ TUNER_PHILIPS_FM1236_MK3 - Philips NTSC ------------ */
647
648static struct tuner_range tuner_fm1236_mk3_ntsc_ranges[] = {
649 { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
650 { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
651 { 16 * 999.99 , 0x8e, 0x04, },
652};
653
654static struct tuner_params tuner_fm1236_mk3_params[] = {
655 {
656 .type = TUNER_PARAM_TYPE_NTSC,
657 .ranges = tuner_fm1236_mk3_ntsc_ranges,
658 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
659 .cb_first_if_lower_freq = 1,
660 .has_tda9887 = 1,
661 .port1_active = 1,
662 .port2_active = 1,
663 .port1_fm_high_sensitivity = 1,
664 },
665};
666
667/* ------------ TUNER_PHILIPS_4IN1 - Philips NTSC ------------ */
668
669static struct tuner_params tuner_philips_4in1_params[] = {
670 {
671 .type = TUNER_PARAM_TYPE_NTSC,
672 .ranges = tuner_fm1236_mk3_ntsc_ranges,
673 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
674 },
675};
676
677/* ------------ TUNER_MICROTUNE_4049FM5 - Microtune PAL ------------ */
678
679static struct tuner_params tuner_microtune_4049_fm5_params[] = {
680 {
681 .type = TUNER_PARAM_TYPE_PAL,
682 .ranges = tuner_temic_4009f_5_pal_ranges,
683 .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
684 .has_tda9887 = 1,
685 .port1_invert_for_secam_lc = 1,
686 .default_pll_gating_18 = 1,
687 .fm_gain_normal=1,
688 .radio_if = 1, /* 33.3 MHz */
689 },
690};
691
692/* ------------ TUNER_PANASONIC_VP27 - Panasonic NTSC ------------ */
693
694static struct tuner_range tuner_panasonic_vp27_ntsc_ranges[] = {
695 { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
696 { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
697 { 16 * 999.99 , 0xce, 0x08, },
698};
699
700static struct tuner_params tuner_panasonic_vp27_params[] = {
701 {
702 .type = TUNER_PARAM_TYPE_NTSC,
703 .ranges = tuner_panasonic_vp27_ntsc_ranges,
704 .count = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges),
705 .has_tda9887 = 1,
706 .intercarrier_mode = 1,
707 .default_top_low = -3,
708 .default_top_mid = -3,
709 .default_top_high = -3,
710 },
711};
712
713/* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */
714
715static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = {
716 { 16 * 161.25 /*MHz*/, 0x8e, 0xa0, },
717 { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
718 { 16 * 999.99 , 0x8e, 0x30, },
719};
720
721static struct tuner_params tuner_tnf_8831bgff_params[] = {
722 {
723 .type = TUNER_PARAM_TYPE_PAL,
724 .ranges = tuner_tnf_8831bgff_pal_ranges,
725 .count = ARRAY_SIZE(tuner_tnf_8831bgff_pal_ranges),
726 },
727};
728
729/* ------------ TUNER_MICROTUNE_4042FI5 - Microtune NTSC ------------ */
730
731static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = {
732 { 16 * 162.00 /*MHz*/, 0x8e, 0xa2, },
733 { 16 * 457.00 /*MHz*/, 0x8e, 0x94, },
734 { 16 * 999.99 , 0x8e, 0x31, },
735};
736
737static struct tuner_range tuner_microtune_4042fi5_atsc_ranges[] = {
738 { 16 * 162.00 /*MHz*/, 0x8e, 0xa1, },
739 { 16 * 457.00 /*MHz*/, 0x8e, 0x91, },
740 { 16 * 999.99 , 0x8e, 0x31, },
741};
742
743static struct tuner_params tuner_microtune_4042fi5_params[] = {
744 {
745 .type = TUNER_PARAM_TYPE_NTSC,
746 .ranges = tuner_microtune_4042fi5_ntsc_ranges,
747 .count = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges),
748 },
749 {
750 .type = TUNER_PARAM_TYPE_DIGITAL,
751 .ranges = tuner_microtune_4042fi5_atsc_ranges,
752 .count = ARRAY_SIZE(tuner_microtune_4042fi5_atsc_ranges),
753 .iffreq = 16 * 44.00 /*MHz*/,
754 },
755};
756
757/* 50-59 */
758/* ------------ TUNER_TCL_2002N - TCL NTSC ------------ */
759
760static struct tuner_range tuner_tcl_2002n_ntsc_ranges[] = {
761 { 16 * 172.00 /*MHz*/, 0x8e, 0x01, },
762 { 16 * 448.00 /*MHz*/, 0x8e, 0x02, },
763 { 16 * 999.99 , 0x8e, 0x08, },
764};
765
766static struct tuner_params tuner_tcl_2002n_params[] = {
767 {
768 .type = TUNER_PARAM_TYPE_NTSC,
769 .ranges = tuner_tcl_2002n_ntsc_ranges,
770 .count = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges),
771 .cb_first_if_lower_freq = 1,
772 },
773};
774
775/* ------------ TUNER_PHILIPS_FM1256_IH3 - Philips PAL ------------ */
776
777static struct tuner_params tuner_philips_fm1256_ih3_params[] = {
778 {
779 .type = TUNER_PARAM_TYPE_PAL,
780 .ranges = tuner_fm1236_mk3_ntsc_ranges,
781 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
782 .radio_if = 1, /* 33.3 MHz */
783 },
784};
785
786/* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */
787
788/* single range used for both ntsc and atsc */
789static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = {
790 { 16 * 157.25 /*MHz*/, 0x8e, 0x39, },
791 { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, },
792 { 16 * 999.99 , 0x8e, 0x3c, },
793};
794
795static struct tuner_params tuner_thomson_dtt7610_params[] = {
796 {
797 .type = TUNER_PARAM_TYPE_NTSC,
798 .ranges = tuner_thomson_dtt7610_ntsc_ranges,
799 .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges),
800 },
801 {
802 .type = TUNER_PARAM_TYPE_DIGITAL,
803 .ranges = tuner_thomson_dtt7610_ntsc_ranges,
804 .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges),
805 .iffreq = 16 * 44.00 /*MHz*/,
806 },
807};
808
809/* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */
810
811static struct tuner_range tuner_philips_fq1286_ntsc_ranges[] = {
812 { 16 * 160.00 /*MHz*/, 0x8e, 0x41, },
813 { 16 * 454.00 /*MHz*/, 0x8e, 0x42, },
814 { 16 * 999.99 , 0x8e, 0x04, },
815};
816
817static struct tuner_params tuner_philips_fq1286_params[] = {
818 {
819 .type = TUNER_PARAM_TYPE_NTSC,
820 .ranges = tuner_philips_fq1286_ntsc_ranges,
821 .count = ARRAY_SIZE(tuner_philips_fq1286_ntsc_ranges),
822 },
823};
824
825/* ------------ TUNER_TCL_2002MB - TCL PAL ------------ */
826
827static struct tuner_range tuner_tcl_2002mb_pal_ranges[] = {
828 { 16 * 170.00 /*MHz*/, 0xce, 0x01, },
829 { 16 * 450.00 /*MHz*/, 0xce, 0x02, },
830 { 16 * 999.99 , 0xce, 0x08, },
831};
832
833static struct tuner_params tuner_tcl_2002mb_params[] = {
834 {
835 .type = TUNER_PARAM_TYPE_PAL,
836 .ranges = tuner_tcl_2002mb_pal_ranges,
837 .count = ARRAY_SIZE(tuner_tcl_2002mb_pal_ranges),
838 },
839};
840
841/* ------------ TUNER_PHILIPS_FQ1216AME_MK4 - Philips PAL ------------ */
842
843static struct tuner_range tuner_philips_fq12_6a___mk4_pal_ranges[] = {
844 { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
845 { 16 * 442.00 /*MHz*/, 0xce, 0x02, },
846 { 16 * 999.99 , 0xce, 0x04, },
847};
848
849static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = {
850 {
851 .type = TUNER_PARAM_TYPE_PAL,
852 .ranges = tuner_philips_fq12_6a___mk4_pal_ranges,
853 .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges),
854 .has_tda9887 = 1,
855 .port1_active = 1,
856 .port2_invert_for_secam_lc = 1,
857 .default_top_mid = -2,
858 .default_top_secam_low = -2,
859 .default_top_secam_mid = -2,
860 .default_top_secam_high = -2,
861 },
862};
863
864/* ------------ TUNER_PHILIPS_FQ1236A_MK4 - Philips NTSC ------------ */
865
866static struct tuner_params tuner_philips_fq1236a_mk4_params[] = {
867 {
868 .type = TUNER_PARAM_TYPE_NTSC,
869 .ranges = tuner_fm1236_mk3_ntsc_ranges,
870 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
871 },
872};
873
874/* ------------ TUNER_YMEC_TVF_8531MF - Philips NTSC ------------ */
875
876static struct tuner_params tuner_ymec_tvf_8531mf_params[] = {
877 {
878 .type = TUNER_PARAM_TYPE_NTSC,
879 .ranges = tuner_philips_ntsc_m_ranges,
880 .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
881 },
882};
883
884/* ------------ TUNER_YMEC_TVF_5533MF - Philips NTSC ------------ */
885
886static struct tuner_range tuner_ymec_tvf_5533mf_ntsc_ranges[] = {
887 { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
888 { 16 * 454.00 /*MHz*/, 0x8e, 0x02, },
889 { 16 * 999.99 , 0x8e, 0x04, },
890};
891
892static struct tuner_params tuner_ymec_tvf_5533mf_params[] = {
893 {
894 .type = TUNER_PARAM_TYPE_NTSC,
895 .ranges = tuner_ymec_tvf_5533mf_ntsc_ranges,
896 .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_ntsc_ranges),
897 },
898};
899
900/* 60-69 */
901/* ------------ TUNER_THOMSON_DTT761X - THOMSON ATSC ------------ */
902/* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
903
904static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = {
905 { 16 * 145.25 /*MHz*/, 0x8e, 0x39, },
906 { 16 * 415.25 /*MHz*/, 0x8e, 0x3a, },
907 { 16 * 999.99 , 0x8e, 0x3c, },
908};
909
910static struct tuner_range tuner_thomson_dtt761x_atsc_ranges[] = {
911 { 16 * 147.00 /*MHz*/, 0x8e, 0x39, },
912 { 16 * 417.00 /*MHz*/, 0x8e, 0x3a, },
913 { 16 * 999.99 , 0x8e, 0x3c, },
914};
915
916static struct tuner_params tuner_thomson_dtt761x_params[] = {
917 {
918 .type = TUNER_PARAM_TYPE_NTSC,
919 .ranges = tuner_thomson_dtt761x_ntsc_ranges,
920 .count = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges),
921 .has_tda9887 = 1,
922 .fm_gain_normal = 1,
923 .radio_if = 2, /* 41.3 MHz */
924 },
925 {
926 .type = TUNER_PARAM_TYPE_DIGITAL,
927 .ranges = tuner_thomson_dtt761x_atsc_ranges,
928 .count = ARRAY_SIZE(tuner_thomson_dtt761x_atsc_ranges),
929 .iffreq = 16 * 44.00, /*MHz*/
930 },
931};
932
933/* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */
934
935static struct tuner_range tuner_tena_9533_di_pal_ranges[] = {
936 { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
937 { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
938 { 16 * 999.99 , 0x8e, 0x04, },
939};
940
941static struct tuner_params tuner_tena_9533_di_params[] = {
942 {
943 .type = TUNER_PARAM_TYPE_PAL,
944 .ranges = tuner_tena_9533_di_pal_ranges,
945 .count = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges),
946 },
947};
948
949/* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */
950
951static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
952 { 16 * 160.00 /*MHz*/, 0x86, 0x51, },
953 { 16 * 442.00 /*MHz*/, 0x86, 0x52, },
954 { 16 * 999.99 , 0x86, 0x54, },
955};
956
957static struct tuner_range tuner_philips_fmd1216me_mk3_dvb_ranges[] = {
958 { 16 * 143.87 /*MHz*/, 0xbc, 0x41 },
959 { 16 * 158.87 /*MHz*/, 0xf4, 0x41 },
960 { 16 * 329.87 /*MHz*/, 0xbc, 0x42 },
961 { 16 * 441.87 /*MHz*/, 0xf4, 0x42 },
962 { 16 * 625.87 /*MHz*/, 0xbc, 0x44 },
963 { 16 * 803.87 /*MHz*/, 0xf4, 0x44 },
964 { 16 * 999.99 , 0xfc, 0x44 },
965};
966
967static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
968 {
969 .type = TUNER_PARAM_TYPE_PAL,
970 .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
971 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
972 .has_tda9887 = 1,
973 .port1_active = 1,
974 .port2_active = 1,
975 .port2_fm_high_sensitivity = 1,
976 .port2_invert_for_secam_lc = 1,
977 .port1_set_for_fm_mono = 1,
978 },
979 {
980 .type = TUNER_PARAM_TYPE_DIGITAL,
981 .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges,
982 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges),
983 .iffreq = 16 * 36.125, /*MHz*/
984 },
985};
986
987
988/* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */
989
990static struct tuner_range tuner_tua6034_ntsc_ranges[] = {
991 { 16 * 165.00 /*MHz*/, 0x8e, 0x01 },
992 { 16 * 450.00 /*MHz*/, 0x8e, 0x02 },
993 { 16 * 999.99 , 0x8e, 0x04 },
994};
995
996static struct tuner_range tuner_tua6034_atsc_ranges[] = {
997 { 16 * 165.00 /*MHz*/, 0xce, 0x01 },
998 { 16 * 450.00 /*MHz*/, 0xce, 0x02 },
999 { 16 * 999.99 , 0xce, 0x04 },
1000};
1001
1002static struct tuner_params tuner_lg_tdvs_h06xf_params[] = {
1003 {
1004 .type = TUNER_PARAM_TYPE_NTSC,
1005 .ranges = tuner_tua6034_ntsc_ranges,
1006 .count = ARRAY_SIZE(tuner_tua6034_ntsc_ranges),
1007 },
1008 {
1009 .type = TUNER_PARAM_TYPE_DIGITAL,
1010 .ranges = tuner_tua6034_atsc_ranges,
1011 .count = ARRAY_SIZE(tuner_tua6034_atsc_ranges),
1012 .iffreq = 16 * 44.00,
1013 },
1014};
1015
1016/* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */
1017
1018static struct tuner_range tuner_ymec_tvf66t5_b_dff_pal_ranges[] = {
1019 { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
1020 { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
1021 { 16 * 999.99 , 0x8e, 0x08, },
1022};
1023
1024static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = {
1025 {
1026 .type = TUNER_PARAM_TYPE_PAL,
1027 .ranges = tuner_ymec_tvf66t5_b_dff_pal_ranges,
1028 .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_pal_ranges),
1029 },
1030};
1031
1032/* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */
1033
1034static struct tuner_range tuner_lg_taln_ntsc_ranges[] = {
1035 { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
1036 { 16 * 373.25 /*MHz*/, 0x8e, 0x02, },
1037 { 16 * 999.99 , 0x8e, 0x08, },
1038};
1039
1040static struct tuner_range tuner_lg_taln_pal_secam_ranges[] = {
1041 { 16 * 150.00 /*MHz*/, 0x8e, 0x01, },
1042 { 16 * 425.00 /*MHz*/, 0x8e, 0x02, },
1043 { 16 * 999.99 , 0x8e, 0x08, },
1044};
1045
1046static struct tuner_params tuner_lg_taln_params[] = {
1047 {
1048 .type = TUNER_PARAM_TYPE_NTSC,
1049 .ranges = tuner_lg_taln_ntsc_ranges,
1050 .count = ARRAY_SIZE(tuner_lg_taln_ntsc_ranges),
1051 },{
1052 .type = TUNER_PARAM_TYPE_PAL,
1053 .ranges = tuner_lg_taln_pal_secam_ranges,
1054 .count = ARRAY_SIZE(tuner_lg_taln_pal_secam_ranges),
1055 },
1056};
1057
1058/* ------------ TUNER_PHILIPS_TD1316 - Philips PAL ------------ */
1059
1060static struct tuner_range tuner_philips_td1316_pal_ranges[] = {
1061 { 16 * 160.00 /*MHz*/, 0xc8, 0xa1, },
1062 { 16 * 442.00 /*MHz*/, 0xc8, 0xa2, },
1063 { 16 * 999.99 , 0xc8, 0xa4, },
1064};
1065
1066static struct tuner_range tuner_philips_td1316_dvb_ranges[] = {
1067 { 16 * 93.834 /*MHz*/, 0xca, 0x60, },
1068 { 16 * 123.834 /*MHz*/, 0xca, 0xa0, },
1069 { 16 * 163.834 /*MHz*/, 0xca, 0xc0, },
1070 { 16 * 253.834 /*MHz*/, 0xca, 0x60, },
1071 { 16 * 383.834 /*MHz*/, 0xca, 0xa0, },
1072 { 16 * 443.834 /*MHz*/, 0xca, 0xc0, },
1073 { 16 * 583.834 /*MHz*/, 0xca, 0x60, },
1074 { 16 * 793.834 /*MHz*/, 0xca, 0xa0, },
1075 { 16 * 999.999 , 0xca, 0xe0, },
1076};
1077
1078static struct tuner_params tuner_philips_td1316_params[] = {
1079 {
1080 .type = TUNER_PARAM_TYPE_PAL,
1081 .ranges = tuner_philips_td1316_pal_ranges,
1082 .count = ARRAY_SIZE(tuner_philips_td1316_pal_ranges),
1083 },
1084 {
1085 .type = TUNER_PARAM_TYPE_DIGITAL,
1086 .ranges = tuner_philips_td1316_dvb_ranges,
1087 .count = ARRAY_SIZE(tuner_philips_td1316_dvb_ranges),
1088 .iffreq = 16 * 36.166667 /*MHz*/,
1089 },
1090};
1091
1092/* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */
1093
1094static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = {
1095 { 16 * 157.25 /*MHz*/, 0xce, 0x01, },
1096 { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
1097 { 16 * 999.99 , 0xce, 0x04, },
1098};
1099
1100static struct tuner_range tuner_tuv1236d_atsc_ranges[] = {
1101 { 16 * 157.25 /*MHz*/, 0xc6, 0x41, },
1102 { 16 * 454.00 /*MHz*/, 0xc6, 0x42, },
1103 { 16 * 999.99 , 0xc6, 0x44, },
1104};
1105
1106static struct tuner_params tuner_tuv1236d_params[] = {
1107 {
1108 .type = TUNER_PARAM_TYPE_NTSC,
1109 .ranges = tuner_tuv1236d_ntsc_ranges,
1110 .count = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges),
1111 },
1112 {
1113 .type = TUNER_PARAM_TYPE_DIGITAL,
1114 .ranges = tuner_tuv1236d_atsc_ranges,
1115 .count = ARRAY_SIZE(tuner_tuv1236d_atsc_ranges),
1116 .iffreq = 16 * 44.00,
1117 },
1118};
1119
1120/* ------------ TUNER_TNF_xxx5 - Texas Instruments--------- */
1121/* This is known to work with Tenna TVF58t5-MFF and TVF5835 MFF
1122 * but it is expected to work also with other Tenna/Ymec
1123 * models based on TI SN 761677 chip on both PAL and NTSC
1124 */
1125
1126static struct tuner_range tuner_tnf_5335_d_if_pal_ranges[] = {
1127 { 16 * 168.25 /*MHz*/, 0x8e, 0x01, },
1128 { 16 * 471.25 /*MHz*/, 0x8e, 0x02, },
1129 { 16 * 999.99 , 0x8e, 0x08, },
1130};
1131
1132static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = {
1133 { 16 * 169.25 /*MHz*/, 0x8e, 0x01, },
1134 { 16 * 469.25 /*MHz*/, 0x8e, 0x02, },
1135 { 16 * 999.99 , 0x8e, 0x08, },
1136};
1137
1138static struct tuner_params tuner_tnf_5335mf_params[] = {
1139 {
1140 .type = TUNER_PARAM_TYPE_NTSC,
1141 .ranges = tuner_tnf_5335mf_ntsc_ranges,
1142 .count = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges),
1143 },
1144 {
1145 .type = TUNER_PARAM_TYPE_PAL,
1146 .ranges = tuner_tnf_5335_d_if_pal_ranges,
1147 .count = ARRAY_SIZE(tuner_tnf_5335_d_if_pal_ranges),
1148 },
1149};
1150
1151/* 70-79 */
1152/* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */
1153
1154/* '+ 4' turns on the Low Noise Amplifier */
1155static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = {
1156 { 16 * 130.00 /*MHz*/, 0xce, 0x01 + 4, },
1157 { 16 * 364.50 /*MHz*/, 0xce, 0x02 + 4, },
1158 { 16 * 999.99 , 0xce, 0x08 + 4, },
1159};
1160
1161static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
1162 {
1163 .type = TUNER_PARAM_TYPE_NTSC,
1164 .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges,
1165 .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges),
1166 },
1167};
1168
1169/* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */
1170
1171static struct tuner_range tuner_thomson_fe6600_pal_ranges[] = {
1172 { 16 * 160.00 /*MHz*/, 0xfe, 0x11, },
1173 { 16 * 442.00 /*MHz*/, 0xf6, 0x12, },
1174 { 16 * 999.99 , 0xf6, 0x18, },
1175};
1176
1177static struct tuner_range tuner_thomson_fe6600_dvb_ranges[] = {
1178 { 16 * 250.00 /*MHz*/, 0xb4, 0x12, },
1179 { 16 * 455.00 /*MHz*/, 0xfe, 0x11, },
1180 { 16 * 775.50 /*MHz*/, 0xbc, 0x18, },
1181 { 16 * 999.99 , 0xf4, 0x18, },
1182};
1183
1184static struct tuner_params tuner_thomson_fe6600_params[] = {
1185 {
1186 .type = TUNER_PARAM_TYPE_PAL,
1187 .ranges = tuner_thomson_fe6600_pal_ranges,
1188 .count = ARRAY_SIZE(tuner_thomson_fe6600_pal_ranges),
1189 },
1190 {
1191 .type = TUNER_PARAM_TYPE_DIGITAL,
1192 .ranges = tuner_thomson_fe6600_dvb_ranges,
1193 .count = ARRAY_SIZE(tuner_thomson_fe6600_dvb_ranges),
1194 .iffreq = 16 * 36.125 /*MHz*/,
1195 },
1196};
1197
1198/* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */
1199
1200/* '+ 4' turns on the Low Noise Amplifier */
1201static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = {
1202 { 16 * 146.25 /*MHz*/, 0xce, 0x01 + 4, },
1203 { 16 * 428.50 /*MHz*/, 0xce, 0x02 + 4, },
1204 { 16 * 999.99 , 0xce, 0x08 + 4, },
1205};
1206
1207static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = {
1208 {
1209 .type = TUNER_PARAM_TYPE_PAL,
1210 .ranges = tuner_samsung_tcpg_6121p30a_pal_ranges,
1211 .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges),
1212 .has_tda9887 = 1,
1213 .port1_active = 1,
1214 .port2_active = 1,
1215 .port2_invert_for_secam_lc = 1,
1216 },
1217};
1218
1219/* --------------------------------------------------------------------- */
1220
1221struct tunertype tuners[] = {
1222 /* 0-9 */
1223 [TUNER_TEMIC_PAL] = { /* TEMIC PAL */
1224 .name = "Temic PAL (4002 FH5)",
1225 .params = tuner_temic_pal_params,
1226 .count = ARRAY_SIZE(tuner_temic_pal_params),
1227 },
1228 [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */
1229 .name = "Philips PAL_I (FI1246 and compatibles)",
1230 .params = tuner_philips_pal_i_params,
1231 .count = ARRAY_SIZE(tuner_philips_pal_i_params),
1232 },
1233 [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */
1234 .name = "Philips NTSC (FI1236,FM1236 and compatibles)",
1235 .params = tuner_philips_ntsc_params,
1236 .count = ARRAY_SIZE(tuner_philips_ntsc_params),
1237 },
1238 [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */
1239 .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
1240 .params = tuner_philips_secam_params,
1241 .count = ARRAY_SIZE(tuner_philips_secam_params),
1242 },
1243 [TUNER_ABSENT] = { /* Tuner Absent */
1244 .name = "NoTuner",
1245 },
1246 [TUNER_PHILIPS_PAL] = { /* Philips PAL */
1247 .name = "Philips PAL_BG (FI1216 and compatibles)",
1248 .params = tuner_philips_pal_params,
1249 .count = ARRAY_SIZE(tuner_philips_pal_params),
1250 },
1251 [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */
1252 .name = "Temic NTSC (4032 FY5)",
1253 .params = tuner_temic_ntsc_params,
1254 .count = ARRAY_SIZE(tuner_temic_ntsc_params),
1255 },
1256 [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */
1257 .name = "Temic PAL_I (4062 FY5)",
1258 .params = tuner_temic_pal_i_params,
1259 .count = ARRAY_SIZE(tuner_temic_pal_i_params),
1260 },
1261 [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */
1262 .name = "Temic NTSC (4036 FY5)",
1263 .params = tuner_temic_4036fy5_ntsc_params,
1264 .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_params),
1265 },
1266 [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */
1267 .name = "Alps HSBH1",
1268 .params = tuner_alps_tsbh1_ntsc_params,
1269 .count = ARRAY_SIZE(tuner_alps_tsbh1_ntsc_params),
1270 },
1271
1272 /* 10-19 */
1273 [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */
1274 .name = "Alps TSBE1",
1275 .params = tuner_alps_tsb_1_params,
1276 .count = ARRAY_SIZE(tuner_alps_tsb_1_params),
1277 },
1278 [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */
1279 .name = "Alps TSBB5",
1280 .params = tuner_alps_tsbb5_params,
1281 .count = ARRAY_SIZE(tuner_alps_tsbb5_params),
1282 },
1283 [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */
1284 .name = "Alps TSBE5",
1285 .params = tuner_alps_tsbe5_params,
1286 .count = ARRAY_SIZE(tuner_alps_tsbe5_params),
1287 },
1288 [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */
1289 .name = "Alps TSBC5",
1290 .params = tuner_alps_tsbc5_params,
1291 .count = ARRAY_SIZE(tuner_alps_tsbc5_params),
1292 },
1293 [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */
1294 .name = "Temic PAL_BG (4006FH5)",
1295 .params = tuner_temic_4006fh5_params,
1296 .count = ARRAY_SIZE(tuner_temic_4006fh5_params),
1297 },
1298 [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */
1299 .name = "Alps TSCH6",
1300 .params = tuner_alps_tshc6_params,
1301 .count = ARRAY_SIZE(tuner_alps_tshc6_params),
1302 },
1303 [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */
1304 .name = "Temic PAL_DK (4016 FY5)",
1305 .params = tuner_temic_pal_dk_params,
1306 .count = ARRAY_SIZE(tuner_temic_pal_dk_params),
1307 },
1308 [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */
1309 .name = "Philips NTSC_M (MK2)",
1310 .params = tuner_philips_ntsc_m_params,
1311 .count = ARRAY_SIZE(tuner_philips_ntsc_m_params),
1312 },
1313 [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */
1314 .name = "Temic PAL_I (4066 FY5)",
1315 .params = tuner_temic_4066fy5_pal_i_params,
1316 .count = ARRAY_SIZE(tuner_temic_4066fy5_pal_i_params),
1317 },
1318 [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */
1319 .name = "Temic PAL* auto (4006 FN5)",
1320 .params = tuner_temic_4006fn5_multi_params,
1321 .count = ARRAY_SIZE(tuner_temic_4006fn5_multi_params),
1322 },
1323
1324 /* 20-29 */
1325 [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */
1326 .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
1327 .params = tuner_temic_4009f_5_params,
1328 .count = ARRAY_SIZE(tuner_temic_4009f_5_params),
1329 },
1330 [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */
1331 .name = "Temic NTSC (4039 FR5)",
1332 .params = tuner_temic_4039fr5_params,
1333 .count = ARRAY_SIZE(tuner_temic_4039fr5_params),
1334 },
1335 [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */
1336 .name = "Temic PAL/SECAM multi (4046 FM5)",
1337 .params = tuner_temic_4046fm5_params,
1338 .count = ARRAY_SIZE(tuner_temic_4046fm5_params),
1339 },
1340 [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */
1341 .name = "Philips PAL_DK (FI1256 and compatibles)",
1342 .params = tuner_philips_pal_dk_params,
1343 .count = ARRAY_SIZE(tuner_philips_pal_dk_params),
1344 },
1345 [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */
1346 .name = "Philips PAL/SECAM multi (FQ1216ME)",
1347 .params = tuner_philips_fq1216me_params,
1348 .count = ARRAY_SIZE(tuner_philips_fq1216me_params),
1349 },
1350 [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */
1351 .name = "LG PAL_I+FM (TAPC-I001D)",
1352 .params = tuner_lg_pal_i_fm_params,
1353 .count = ARRAY_SIZE(tuner_lg_pal_i_fm_params),
1354 },
1355 [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */
1356 .name = "LG PAL_I (TAPC-I701D)",
1357 .params = tuner_lg_pal_i_params,
1358 .count = ARRAY_SIZE(tuner_lg_pal_i_params),
1359 },
1360 [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */
1361 .name = "LG NTSC+FM (TPI8NSR01F)",
1362 .params = tuner_lg_ntsc_fm_params,
1363 .count = ARRAY_SIZE(tuner_lg_ntsc_fm_params),
1364 },
1365 [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */
1366 .name = "LG PAL_BG+FM (TPI8PSB01D)",
1367 .params = tuner_lg_pal_fm_params,
1368 .count = ARRAY_SIZE(tuner_lg_pal_fm_params),
1369 },
1370 [TUNER_LG_PAL] = { /* LGINNOTEK PAL */
1371 .name = "LG PAL_BG (TPI8PSB11D)",
1372 .params = tuner_lg_pal_params,
1373 .count = ARRAY_SIZE(tuner_lg_pal_params),
1374 },
1375
1376 /* 30-39 */
1377 [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */
1378 .name = "Temic PAL* auto + FM (4009 FN5)",
1379 .params = tuner_temic_4009_fn5_multi_pal_fm_params,
1380 .count = ARRAY_SIZE(tuner_temic_4009_fn5_multi_pal_fm_params),
1381 },
1382 [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */
1383 .name = "SHARP NTSC_JP (2U5JF5540)",
1384 .params = tuner_sharp_2u5jf5540_params,
1385 .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_params),
1386 },
1387 [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */
1388 .name = "Samsung PAL TCPM9091PD27",
1389 .params = tuner_samsung_pal_tcpm9091pd27_params,
1390 .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_params),
1391 },
1392 [TUNER_MT2032] = { /* Microtune PAL|NTSC */
1393 .name = "MT20xx universal",
1394 /* see mt20xx.c for details */ },
1395 [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */
1396 .name = "Temic PAL_BG (4106 FH5)",
1397 .params = tuner_temic_4106fh5_params,
1398 .count = ARRAY_SIZE(tuner_temic_4106fh5_params),
1399 },
1400 [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */
1401 .name = "Temic PAL_DK/SECAM_L (4012 FY5)",
1402 .params = tuner_temic_4012fy5_params,
1403 .count = ARRAY_SIZE(tuner_temic_4012fy5_params),
1404 },
1405 [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */
1406 .name = "Temic NTSC (4136 FY5)",
1407 .params = tuner_temic_4136_fy5_params,
1408 .count = ARRAY_SIZE(tuner_temic_4136_fy5_params),
1409 },
1410 [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */
1411 .name = "LG PAL (newer TAPC series)",
1412 .params = tuner_lg_pal_new_tapc_params,
1413 .count = ARRAY_SIZE(tuner_lg_pal_new_tapc_params),
1414 },
1415 [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */
1416 .name = "Philips PAL/SECAM multi (FM1216ME MK3)",
1417 .params = tuner_fm1216me_mk3_params,
1418 .count = ARRAY_SIZE(tuner_fm1216me_mk3_params),
1419 },
1420 [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */
1421 .name = "LG NTSC (newer TAPC series)",
1422 .params = tuner_lg_ntsc_new_tapc_params,
1423 .count = ARRAY_SIZE(tuner_lg_ntsc_new_tapc_params),
1424 },
1425
1426 /* 40-49 */
1427 [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */
1428 .name = "HITACHI V7-J180AT",
1429 .params = tuner_hitachi_ntsc_params,
1430 .count = ARRAY_SIZE(tuner_hitachi_ntsc_params),
1431 },
1432 [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */
1433 .name = "Philips PAL_MK (FI1216 MK)",
1434 .params = tuner_philips_pal_mk_params,
1435 .count = ARRAY_SIZE(tuner_philips_pal_mk_params),
1436 },
1437 [TUNER_PHILIPS_FCV1236D] = { /* Philips ATSC */
1438 .name = "Philips FCV1236D ATSC/NTSC dual in",
1439 .params = tuner_philips_fcv1236d_params,
1440 .count = ARRAY_SIZE(tuner_philips_fcv1236d_params),
1441 .min = 16 * 53.00,
1442 .max = 16 * 803.00,
1443 .stepsize = 62500,
1444 },
1445 [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */
1446 .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)",
1447 .params = tuner_fm1236_mk3_params,
1448 .count = ARRAY_SIZE(tuner_fm1236_mk3_params),
1449 },
1450 [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */
1451 .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)",
1452 .params = tuner_philips_4in1_params,
1453 .count = ARRAY_SIZE(tuner_philips_4in1_params),
1454 },
1455 [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */
1456 .name = "Microtune 4049 FM5",
1457 .params = tuner_microtune_4049_fm5_params,
1458 .count = ARRAY_SIZE(tuner_microtune_4049_fm5_params),
1459 },
1460 [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */
1461 .name = "Panasonic VP27s/ENGE4324D",
1462 .params = tuner_panasonic_vp27_params,
1463 .count = ARRAY_SIZE(tuner_panasonic_vp27_params),
1464 },
1465 [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
1466 .name = "LG NTSC (TAPE series)",
1467 .params = tuner_fm1236_mk3_params,
1468 .count = ARRAY_SIZE(tuner_fm1236_mk3_params),
1469 },
1470 [TUNER_TNF_8831BGFF] = { /* Philips PAL */
1471 .name = "Tenna TNF 8831 BGFF)",
1472 .params = tuner_tnf_8831bgff_params,
1473 .count = ARRAY_SIZE(tuner_tnf_8831bgff_params),
1474 },
1475 [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */
1476 .name = "Microtune 4042 FI5 ATSC/NTSC dual in",
1477 .params = tuner_microtune_4042fi5_params,
1478 .count = ARRAY_SIZE(tuner_microtune_4042fi5_params),
1479 .min = 16 * 57.00,
1480 .max = 16 * 858.00,
1481 .stepsize = 62500,
1482 },
1483
1484 /* 50-59 */
1485 [TUNER_TCL_2002N] = { /* TCL NTSC */
1486 .name = "TCL 2002N",
1487 .params = tuner_tcl_2002n_params,
1488 .count = ARRAY_SIZE(tuner_tcl_2002n_params),
1489 },
1490 [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */
1491 .name = "Philips PAL/SECAM_D (FM 1256 I-H3)",
1492 .params = tuner_philips_fm1256_ih3_params,
1493 .count = ARRAY_SIZE(tuner_philips_fm1256_ih3_params),
1494 },
1495 [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */
1496 .name = "Thomson DTT 7610 (ATSC/NTSC)",
1497 .params = tuner_thomson_dtt7610_params,
1498 .count = ARRAY_SIZE(tuner_thomson_dtt7610_params),
1499 .min = 16 * 44.00,
1500 .max = 16 * 958.00,
1501 .stepsize = 62500,
1502 },
1503 [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */
1504 .name = "Philips FQ1286",
1505 .params = tuner_philips_fq1286_params,
1506 .count = ARRAY_SIZE(tuner_philips_fq1286_params),
1507 },
1508 [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */
1509 .name = "Philips/NXP TDA 8290/8295 + 8275/8275A/18271",
1510 /* see tda8290.c for details */ },
1511 [TUNER_TCL_2002MB] = { /* TCL PAL */
1512 .name = "TCL 2002MB",
1513 .params = tuner_tcl_2002mb_params,
1514 .count = ARRAY_SIZE(tuner_tcl_2002mb_params),
1515 },
1516 [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */
1517 .name = "Philips PAL/SECAM multi (FQ1216AME MK4)",
1518 .params = tuner_philips_fq1216ame_mk4_params,
1519 .count = ARRAY_SIZE(tuner_philips_fq1216ame_mk4_params),
1520 },
1521 [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */
1522 .name = "Philips FQ1236A MK4",
1523 .params = tuner_philips_fq1236a_mk4_params,
1524 .count = ARRAY_SIZE(tuner_philips_fq1236a_mk4_params),
1525 },
1526 [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */
1527 .name = "Ymec TVision TVF-8531MF/8831MF/8731MF",
1528 .params = tuner_ymec_tvf_8531mf_params,
1529 .count = ARRAY_SIZE(tuner_ymec_tvf_8531mf_params),
1530 },
1531 [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */
1532 .name = "Ymec TVision TVF-5533MF",
1533 .params = tuner_ymec_tvf_5533mf_params,
1534 .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_params),
1535 },
1536
1537 /* 60-69 */
1538 [TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */
1539 /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
1540 .name = "Thomson DTT 761X (ATSC/NTSC)",
1541 .params = tuner_thomson_dtt761x_params,
1542 .count = ARRAY_SIZE(tuner_thomson_dtt761x_params),
1543 .min = 16 * 57.00,
1544 .max = 16 * 863.00,
1545 .stepsize = 62500,
1546 .initdata = tua603x_agc103,
1547 },
1548 [TUNER_TENA_9533_DI] = { /* Philips PAL */
1549 .name = "Tena TNF9533-D/IF/TNF9533-B/DF",
1550 .params = tuner_tena_9533_di_params,
1551 .count = ARRAY_SIZE(tuner_tena_9533_di_params),
1552 },
1553 [TUNER_TEA5767] = { /* Philips RADIO */
1554 .name = "Philips TEA5767HN FM Radio",
1555 /* see tea5767.c for details */
1556 },
1557 [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */
1558 .name = "Philips FMD1216ME MK3 Hybrid Tuner",
1559 .params = tuner_philips_fmd1216me_mk3_params,
1560 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params),
1561 .min = 16 * 50.87,
1562 .max = 16 * 858.00,
1563 .stepsize = 166667,
1564 .initdata = tua603x_agc112,
1565 .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
1566 },
1567 [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */
1568 .name = "LG TDVS-H06xF", /* H061F, H062F & H064F */
1569 .params = tuner_lg_tdvs_h06xf_params,
1570 .count = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params),
1571 .min = 16 * 54.00,
1572 .max = 16 * 863.00,
1573 .stepsize = 62500,
1574 .initdata = tua603x_agc103,
1575 },
1576 [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
1577 .name = "Ymec TVF66T5-B/DFF",
1578 .params = tuner_ymec_tvf66t5_b_dff_params,
1579 .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_params),
1580 },
1581 [TUNER_LG_TALN] = { /* LGINNOTEK NTSC / PAL / SECAM */
1582 .name = "LG TALN series",
1583 .params = tuner_lg_taln_params,
1584 .count = ARRAY_SIZE(tuner_lg_taln_params),
1585 },
1586 [TUNER_PHILIPS_TD1316] = { /* Philips PAL */
1587 .name = "Philips TD1316 Hybrid Tuner",
1588 .params = tuner_philips_td1316_params,
1589 .count = ARRAY_SIZE(tuner_philips_td1316_params),
1590 .min = 16 * 87.00,
1591 .max = 16 * 895.00,
1592 .stepsize = 166667,
1593 },
1594 [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */
1595 .name = "Philips TUV1236D ATSC/NTSC dual in",
1596 .params = tuner_tuv1236d_params,
1597 .count = ARRAY_SIZE(tuner_tuv1236d_params),
1598 .min = 16 * 54.00,
1599 .max = 16 * 864.00,
1600 .stepsize = 62500,
1601 },
1602 [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */
1603 .name = "Tena TNF 5335 and similar models",
1604 .params = tuner_tnf_5335mf_params,
1605 .count = ARRAY_SIZE(tuner_tnf_5335mf_params),
1606 },
1607
1608 /* 70-79 */
1609 [TUNER_SAMSUNG_TCPN_2121P30A] = { /* Samsung NTSC */
1610 .name = "Samsung TCPN 2121P30A",
1611 .params = tuner_samsung_tcpn_2121p30a_params,
1612 .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params),
1613 },
1614 [TUNER_XC2028] = { /* Xceive 2028 */
1615 .name = "Xceive xc2028/xc3028 tuner",
1616 /* see tuner-xc2028.c for details */
1617 },
1618 [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */
1619 .name = "Thomson FE6600",
1620 .params = tuner_thomson_fe6600_params,
1621 .count = ARRAY_SIZE(tuner_thomson_fe6600_params),
1622 .min = 16 * 44.25,
1623 .max = 16 * 858.00,
1624 .stepsize = 166667,
1625 },
1626 [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */
1627 .name = "Samsung TCPG 6121P30A",
1628 .params = tuner_samsung_tcpg_6121p30a_params,
1629 .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params),
1630 },
1631 [TUNER_TDA9887] = { /* Philips TDA 9887 IF PLL Demodulator.
1632 This chip is part of some modern tuners */
1633 .name = "Philips TDA988[5,6,7] IF PLL Demodulator",
1634 /* see tda9887.c for details */
1635 },
1636 [TUNER_TEA5761] = { /* Philips RADIO */
1637 .name = "Philips TEA5761 FM Radio",
1638 /* see tea5767.c for details */
1639 },
1640 [TUNER_XC5000] = { /* Xceive 5000 */
1641 .name = "Xceive 5000 tuner",
1642 /* see xc5000.c for details */
1643 },
1644};
1645EXPORT_SYMBOL(tuners);
1646
1647unsigned const int tuner_count = ARRAY_SIZE(tuners);
1648EXPORT_SYMBOL(tuner_count);
1649
1650MODULE_DESCRIPTION("Simple tuner device type database");
1651MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
1652MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tuner-xc2028-types.h b/drivers/media/video/tuner-xc2028-types.h
deleted file mode 100644
index 74dc46a71f64..000000000000
--- a/drivers/media/video/tuner-xc2028-types.h
+++ /dev/null
@@ -1,141 +0,0 @@
1/* tuner-xc2028_types
2 *
3 * This file includes internal tipes to be used inside tuner-xc2028.
4 * Shouldn't be included outside tuner-xc2028
5 *
6 * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
7 * This code is placed under the terms of the GNU General Public License v2
8 */
9
10/* xc3028 firmware types */
11
12/* BASE firmware should be loaded before any other firmware */
13#define BASE (1<<0)
14#define BASE_TYPES (BASE|F8MHZ|MTS|FM|INPUT1|INPUT2|INIT1)
15
16/* F8MHZ marks BASE firmwares for 8 MHz Bandwidth */
17#define F8MHZ (1<<1)
18
19/* Multichannel Television Sound (MTS)
20 Those firmwares are capable of using xc2038 DSP to decode audio and
21 produce a baseband audio output on some pins of the chip.
22 There are MTS firmwares for the most used video standards. It should be
23 required to use MTS firmwares, depending on the way audio is routed into
24 the bridge chip
25 */
26#define MTS (1<<2)
27
28/* FIXME: I have no idea what's the difference between
29 D2620 and D2633 firmwares
30 */
31#define D2620 (1<<3)
32#define D2633 (1<<4)
33
34/* DTV firmwares for 6, 7 and 8 MHz
35 DTV6 - 6MHz - ATSC/DVB-C/DVB-T/ISDB-T/DOCSIS
36 DTV8 - 8MHz - DVB-C/DVB-T
37 */
38#define DTV6 (1 << 5)
39#define QAM (1 << 6)
40#define DTV7 (1<<7)
41#define DTV78 (1<<8)
42#define DTV8 (1<<9)
43
44#define DTV_TYPES (D2620|D2633|DTV6|QAM|DTV7|DTV78|DTV8|ATSC)
45
46/* There's a FM | BASE firmware + FM specific firmware (std=0) */
47#define FM (1<<10)
48
49#define STD_SPECIFIC_TYPES (MTS|FM|LCD|NOGD)
50
51/* Applies only for FM firmware
52 Makes it use RF input 1 (pin #2) instead of input 2 (pin #4)
53 */
54#define INPUT1 (1<<11)
55
56
57/* LCD firmwares exist only for MTS STD/MN (PAL or NTSC/M)
58 and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr)
59 There are variants both with and without NOGD
60 Those firmwares produce better result with LCD displays
61 */
62#define LCD (1<<12)
63
64/* NOGD firmwares exist only for MTS STD/MN (PAL or NTSC/M)
65 and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr)
66 The NOGD firmwares don't have group delay compensation filter
67 */
68#define NOGD (1<<13)
69
70/* Old firmwares were broken into init0 and init1 */
71#define INIT1 (1<<14)
72
73/* SCODE firmware selects particular behaviours */
74#define MONO (1 << 15)
75#define ATSC (1 << 16)
76#define IF (1 << 17)
77#define LG60 (1 << 18)
78#define ATI638 (1 << 19)
79#define OREN538 (1 << 20)
80#define OREN36 (1 << 21)
81#define TOYOTA388 (1 << 22)
82#define TOYOTA794 (1 << 23)
83#define DIBCOM52 (1 << 24)
84#define ZARLINK456 (1 << 25)
85#define CHINA (1 << 26)
86#define F6MHZ (1 << 27)
87#define INPUT2 (1 << 28)
88#define SCODE (1 << 29)
89
90/* This flag identifies that the scode table has a new format */
91#define HAS_IF (1 << 30)
92
93/* There are different scode tables for MTS and non-MTS.
94 The MTS firmwares support mono only
95 */
96#define SCODE_TYPES (SCODE | MTS)
97
98
99/* Newer types not defined on videodev2.h.
100 The original idea were to move all those types to videodev2.h, but
101 it seemed overkill, since, with the exception of SECAM/K3, the other
102 types seem to be autodetected.
103 It is not clear where secam/k3 is used, nor we have a feedback of this
104 working or being autodetected by the standard secam firmware.
105 */
106
107#define V4L2_STD_SECAM_K3 (0x04000000)
108
109/* Audio types */
110
111#define V4L2_STD_A2_A (1LL<<32)
112#define V4L2_STD_A2_B (1LL<<33)
113#define V4L2_STD_NICAM_A (1LL<<34)
114#define V4L2_STD_NICAM_B (1LL<<35)
115#define V4L2_STD_AM (1LL<<36)
116#define V4L2_STD_BTSC (1LL<<37)
117#define V4L2_STD_EIAJ (1LL<<38)
118
119#define V4L2_STD_A2 (V4L2_STD_A2_A | V4L2_STD_A2_B)
120#define V4L2_STD_NICAM (V4L2_STD_NICAM_A | V4L2_STD_NICAM_B)
121
122/* To preserve backward compatibilty,
123 (std & V4L2_STD_AUDIO) = 0 means that ALL audio stds are supported
124 */
125
126#define V4L2_STD_AUDIO (V4L2_STD_A2 | \
127 V4L2_STD_NICAM | \
128 V4L2_STD_AM | \
129 V4L2_STD_BTSC | \
130 V4L2_STD_EIAJ)
131
132/* Used standards with audio restrictions */
133
134#define V4L2_STD_PAL_BG_A2_A (V4L2_STD_PAL_BG | V4L2_STD_A2_A)
135#define V4L2_STD_PAL_BG_A2_B (V4L2_STD_PAL_BG | V4L2_STD_A2_B)
136#define V4L2_STD_PAL_BG_NICAM_A (V4L2_STD_PAL_BG | V4L2_STD_NICAM_A)
137#define V4L2_STD_PAL_BG_NICAM_B (V4L2_STD_PAL_BG | V4L2_STD_NICAM_B)
138#define V4L2_STD_PAL_DK_A2 (V4L2_STD_PAL_DK | V4L2_STD_A2)
139#define V4L2_STD_PAL_DK_NICAM (V4L2_STD_PAL_DK | V4L2_STD_NICAM)
140#define V4L2_STD_SECAM_L_NICAM (V4L2_STD_SECAM_L | V4L2_STD_NICAM)
141#define V4L2_STD_SECAM_L_AM (V4L2_STD_SECAM_L | V4L2_STD_AM)
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c
deleted file mode 100644
index 9e9003cffc7f..000000000000
--- a/drivers/media/video/tuner-xc2028.c
+++ /dev/null
@@ -1,1227 +0,0 @@
1/* tuner-xc2028
2 *
3 * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
4 *
5 * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
6 * - frontend interface
7 *
8 * This code is placed under the terms of the GNU General Public License v2
9 */
10
11#include <linux/i2c.h>
12#include <asm/div64.h>
13#include <linux/firmware.h>
14#include <linux/videodev2.h>
15#include <linux/delay.h>
16#include <media/tuner.h>
17#include <linux/mutex.h>
18#include "tuner-i2c.h"
19#include "tuner-xc2028.h"
20#include "tuner-xc2028-types.h"
21
22#include <linux/dvb/frontend.h>
23#include "dvb_frontend.h"
24
25
26static int debug;
27module_param(debug, int, 0644);
28MODULE_PARM_DESC(debug, "enable verbose debug messages");
29
30static char audio_std[8];
31module_param_string(audio_std, audio_std, sizeof(audio_std), 0);
32MODULE_PARM_DESC(audio_std,
33 "Audio standard. XC3028 audio decoder explicitly "
34 "needs to know what audio\n"
35 "standard is needed for some video standards with audio A2 or NICAM.\n"
36 "The valid values are:\n"
37 "A2\n"
38 "A2/A\n"
39 "A2/B\n"
40 "NICAM\n"
41 "NICAM/A\n"
42 "NICAM/B\n");
43
44static char firmware_name[FIRMWARE_NAME_MAX];
45module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
46MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the "
47 "default firmware name\n");
48
49static LIST_HEAD(xc2028_list);
50static DEFINE_MUTEX(xc2028_list_mutex);
51
52/* struct for storing firmware table */
53struct firmware_description {
54 unsigned int type;
55 v4l2_std_id id;
56 __u16 int_freq;
57 unsigned char *ptr;
58 unsigned int size;
59};
60
61struct firmware_properties {
62 unsigned int type;
63 v4l2_std_id id;
64 v4l2_std_id std_req;
65 __u16 int_freq;
66 unsigned int scode_table;
67 int scode_nr;
68};
69
70struct xc2028_data {
71 struct list_head xc2028_list;
72 struct tuner_i2c_props i2c_props;
73 int (*tuner_callback) (void *dev,
74 int command, int arg);
75 void *video_dev;
76 int count;
77 __u32 frequency;
78
79 struct firmware_description *firm;
80 int firm_size;
81 __u16 firm_version;
82
83 __u16 hwmodel;
84 __u16 hwvers;
85
86 struct xc2028_ctrl ctrl;
87
88 struct firmware_properties cur_fw;
89
90 struct mutex lock;
91};
92
93#define i2c_send(priv, buf, size) ({ \
94 int _rc; \
95 _rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size); \
96 if (size != _rc) \
97 tuner_info("i2c output error: rc = %d (should be %d)\n",\
98 _rc, (int)size); \
99 _rc; \
100})
101
102#define i2c_rcv(priv, buf, size) ({ \
103 int _rc; \
104 _rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size); \
105 if (size != _rc) \
106 tuner_err("i2c input error: rc = %d (should be %d)\n", \
107 _rc, (int)size); \
108 _rc; \
109})
110
111#define i2c_send_recv(priv, obuf, osize, ibuf, isize) ({ \
112 int _rc; \
113 _rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, obuf, osize, \
114 ibuf, isize); \
115 if (isize != _rc) \
116 tuner_err("i2c input error: rc = %d (should be %d)\n", \
117 _rc, (int)isize); \
118 _rc; \
119})
120
121#define send_seq(priv, data...) ({ \
122 static u8 _val[] = data; \
123 int _rc; \
124 if (sizeof(_val) != \
125 (_rc = tuner_i2c_xfer_send(&priv->i2c_props, \
126 _val, sizeof(_val)))) { \
127 tuner_err("Error on line %d: %d\n", __LINE__, _rc); \
128 } else \
129 msleep(10); \
130 _rc; \
131})
132
133static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val)
134{
135 unsigned char buf[2];
136 unsigned char ibuf[2];
137
138 tuner_dbg("%s %04x called\n", __func__, reg);
139
140 buf[0] = reg >> 8;
141 buf[1] = (unsigned char) reg;
142
143 if (i2c_send_recv(priv, buf, 2, ibuf, 2) != 2)
144 return -EIO;
145
146 *val = (ibuf[1]) | (ibuf[0] << 8);
147 return 0;
148}
149
150#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
151static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
152{
153 if (type & BASE)
154 printk("BASE ");
155 if (type & INIT1)
156 printk("INIT1 ");
157 if (type & F8MHZ)
158 printk("F8MHZ ");
159 if (type & MTS)
160 printk("MTS ");
161 if (type & D2620)
162 printk("D2620 ");
163 if (type & D2633)
164 printk("D2633 ");
165 if (type & DTV6)
166 printk("DTV6 ");
167 if (type & QAM)
168 printk("QAM ");
169 if (type & DTV7)
170 printk("DTV7 ");
171 if (type & DTV78)
172 printk("DTV78 ");
173 if (type & DTV8)
174 printk("DTV8 ");
175 if (type & FM)
176 printk("FM ");
177 if (type & INPUT1)
178 printk("INPUT1 ");
179 if (type & LCD)
180 printk("LCD ");
181 if (type & NOGD)
182 printk("NOGD ");
183 if (type & MONO)
184 printk("MONO ");
185 if (type & ATSC)
186 printk("ATSC ");
187 if (type & IF)
188 printk("IF ");
189 if (type & LG60)
190 printk("LG60 ");
191 if (type & ATI638)
192 printk("ATI638 ");
193 if (type & OREN538)
194 printk("OREN538 ");
195 if (type & OREN36)
196 printk("OREN36 ");
197 if (type & TOYOTA388)
198 printk("TOYOTA388 ");
199 if (type & TOYOTA794)
200 printk("TOYOTA794 ");
201 if (type & DIBCOM52)
202 printk("DIBCOM52 ");
203 if (type & ZARLINK456)
204 printk("ZARLINK456 ");
205 if (type & CHINA)
206 printk("CHINA ");
207 if (type & F6MHZ)
208 printk("F6MHZ ");
209 if (type & INPUT2)
210 printk("INPUT2 ");
211 if (type & SCODE)
212 printk("SCODE ");
213 if (type & HAS_IF)
214 printk("HAS_IF_%d ", int_freq);
215}
216
217static v4l2_std_id parse_audio_std_option(void)
218{
219 if (strcasecmp(audio_std, "A2") == 0)
220 return V4L2_STD_A2;
221 if (strcasecmp(audio_std, "A2/A") == 0)
222 return V4L2_STD_A2_A;
223 if (strcasecmp(audio_std, "A2/B") == 0)
224 return V4L2_STD_A2_B;
225 if (strcasecmp(audio_std, "NICAM") == 0)
226 return V4L2_STD_NICAM;
227 if (strcasecmp(audio_std, "NICAM/A") == 0)
228 return V4L2_STD_NICAM_A;
229 if (strcasecmp(audio_std, "NICAM/B") == 0)
230 return V4L2_STD_NICAM_B;
231
232 return 0;
233}
234
235static void free_firmware(struct xc2028_data *priv)
236{
237 int i;
238 tuner_dbg("%s called\n", __func__);
239
240 if (!priv->firm)
241 return;
242
243 for (i = 0; i < priv->firm_size; i++)
244 kfree(priv->firm[i].ptr);
245
246 kfree(priv->firm);
247
248 priv->firm = NULL;
249 priv->firm_size = 0;
250
251 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
252}
253
254static int load_all_firmwares(struct dvb_frontend *fe)
255{
256 struct xc2028_data *priv = fe->tuner_priv;
257 const struct firmware *fw = NULL;
258 unsigned char *p, *endp;
259 int rc = 0;
260 int n, n_array;
261 char name[33];
262 char *fname;
263
264 tuner_dbg("%s called\n", __func__);
265
266 if (!firmware_name[0])
267 fname = priv->ctrl.fname;
268 else
269 fname = firmware_name;
270
271 tuner_dbg("Reading firmware %s\n", fname);
272 rc = request_firmware(&fw, fname, &priv->i2c_props.adap->dev);
273 if (rc < 0) {
274 if (rc == -ENOENT)
275 tuner_err("Error: firmware %s not found.\n",
276 fname);
277 else
278 tuner_err("Error %d while requesting firmware %s \n",
279 rc, fname);
280
281 return rc;
282 }
283 p = fw->data;
284 endp = p + fw->size;
285
286 if (fw->size < sizeof(name) - 1 + 2 + 2) {
287 tuner_err("Error: firmware file %s has invalid size!\n",
288 fname);
289 goto corrupt;
290 }
291
292 memcpy(name, p, sizeof(name) - 1);
293 name[sizeof(name) - 1] = 0;
294 p += sizeof(name) - 1;
295
296 priv->firm_version = le16_to_cpu(*(__u16 *) p);
297 p += 2;
298
299 n_array = le16_to_cpu(*(__u16 *) p);
300 p += 2;
301
302 tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
303 n_array, fname, name,
304 priv->firm_version >> 8, priv->firm_version & 0xff);
305
306 priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
307 if (priv->firm == NULL) {
308 tuner_err("Not enough memory to load firmware file.\n");
309 rc = -ENOMEM;
310 goto err;
311 }
312 priv->firm_size = n_array;
313
314 n = -1;
315 while (p < endp) {
316 __u32 type, size;
317 v4l2_std_id id;
318 __u16 int_freq = 0;
319
320 n++;
321 if (n >= n_array) {
322 tuner_err("More firmware images in file than "
323 "were expected!\n");
324 goto corrupt;
325 }
326
327 /* Checks if there's enough bytes to read */
328 if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) {
329 tuner_err("Firmware header is incomplete!\n");
330 goto corrupt;
331 }
332
333 type = le32_to_cpu(*(__u32 *) p);
334 p += sizeof(type);
335
336 id = le64_to_cpu(*(v4l2_std_id *) p);
337 p += sizeof(id);
338
339 if (type & HAS_IF) {
340 int_freq = le16_to_cpu(*(__u16 *) p);
341 p += sizeof(int_freq);
342 }
343
344 size = le32_to_cpu(*(__u32 *) p);
345 p += sizeof(size);
346
347 if ((!size) || (size + p > endp)) {
348 tuner_err("Firmware type ");
349 dump_firm_type(type);
350 printk("(%x), id %llx is corrupted "
351 "(size=%d, expected %d)\n",
352 type, (unsigned long long)id,
353 (unsigned)(endp - p), size);
354 goto corrupt;
355 }
356
357 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
358 if (priv->firm[n].ptr == NULL) {
359 tuner_err("Not enough memory to load firmware file.\n");
360 rc = -ENOMEM;
361 goto err;
362 }
363 tuner_dbg("Reading firmware type ");
364 if (debug) {
365 dump_firm_type_and_int_freq(type, int_freq);
366 printk("(%x), id %llx, size=%d.\n",
367 type, (unsigned long long)id, size);
368 }
369
370 memcpy(priv->firm[n].ptr, p, size);
371 priv->firm[n].type = type;
372 priv->firm[n].id = id;
373 priv->firm[n].size = size;
374 priv->firm[n].int_freq = int_freq;
375
376 p += size;
377 }
378
379 if (n + 1 != priv->firm_size) {
380 tuner_err("Firmware file is incomplete!\n");
381 goto corrupt;
382 }
383
384 goto done;
385
386corrupt:
387 rc = -EINVAL;
388 tuner_err("Error: firmware file is corrupted!\n");
389
390err:
391 tuner_info("Releasing partially loaded firmware file.\n");
392 free_firmware(priv);
393
394done:
395 release_firmware(fw);
396 if (rc == 0)
397 tuner_dbg("Firmware files loaded.\n");
398
399 return rc;
400}
401
402static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
403 v4l2_std_id *id)
404{
405 struct xc2028_data *priv = fe->tuner_priv;
406 int i, best_i = -1, best_nr_matches = 0;
407 unsigned int type_mask = 0;
408
409 tuner_dbg("%s called, want type=", __func__);
410 if (debug) {
411 dump_firm_type(type);
412 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
413 }
414
415 if (!priv->firm) {
416 tuner_err("Error! firmware not loaded\n");
417 return -EINVAL;
418 }
419
420 if (((type & ~SCODE) == 0) && (*id == 0))
421 *id = V4L2_STD_PAL;
422
423 if (type & BASE)
424 type_mask = BASE_TYPES;
425 else if (type & SCODE) {
426 type &= SCODE_TYPES;
427 type_mask = SCODE_TYPES & ~HAS_IF;
428 } else if (type & DTV_TYPES)
429 type_mask = DTV_TYPES;
430 else if (type & STD_SPECIFIC_TYPES)
431 type_mask = STD_SPECIFIC_TYPES;
432
433 type &= type_mask;
434
435 if (!(type & SCODE))
436 type_mask = ~0;
437
438 /* Seek for exact match */
439 for (i = 0; i < priv->firm_size; i++) {
440 if ((type == (priv->firm[i].type & type_mask)) &&
441 (*id == priv->firm[i].id))
442 goto found;
443 }
444
445 /* Seek for generic video standard match */
446 for (i = 0; i < priv->firm_size; i++) {
447 v4l2_std_id match_mask;
448 int nr_matches;
449
450 if (type != (priv->firm[i].type & type_mask))
451 continue;
452
453 match_mask = *id & priv->firm[i].id;
454 if (!match_mask)
455 continue;
456
457 if ((*id & match_mask) == *id)
458 goto found; /* Supports all the requested standards */
459
460 nr_matches = hweight64(match_mask);
461 if (nr_matches > best_nr_matches) {
462 best_nr_matches = nr_matches;
463 best_i = i;
464 }
465 }
466
467 if (best_nr_matches > 0) {
468 tuner_dbg("Selecting best matching firmware (%d bits) for "
469 "type=", best_nr_matches);
470 dump_firm_type(type);
471 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
472 i = best_i;
473 goto found;
474 }
475
476 /*FIXME: Would make sense to seek for type "hint" match ? */
477
478 i = -ENOENT;
479 goto ret;
480
481found:
482 *id = priv->firm[i].id;
483
484ret:
485 tuner_dbg("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
486 if (debug) {
487 dump_firm_type(type);
488 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
489 }
490 return i;
491}
492
493static int load_firmware(struct dvb_frontend *fe, unsigned int type,
494 v4l2_std_id *id)
495{
496 struct xc2028_data *priv = fe->tuner_priv;
497 int pos, rc;
498 unsigned char *p, *endp, buf[priv->ctrl.max_len];
499
500 tuner_dbg("%s called\n", __func__);
501
502 pos = seek_firmware(fe, type, id);
503 if (pos < 0)
504 return pos;
505
506 tuner_info("Loading firmware for type=");
507 dump_firm_type(priv->firm[pos].type);
508 printk("(%x), id %016llx.\n", priv->firm[pos].type,
509 (unsigned long long)*id);
510
511 p = priv->firm[pos].ptr;
512 endp = p + priv->firm[pos].size;
513
514 while (p < endp) {
515 __u16 size;
516
517 /* Checks if there's enough bytes to read */
518 if (p + sizeof(size) > endp) {
519 tuner_err("Firmware chunk size is wrong\n");
520 return -EINVAL;
521 }
522
523 size = le16_to_cpu(*(__u16 *) p);
524 p += sizeof(size);
525
526 if (size == 0xffff)
527 return 0;
528
529 if (!size) {
530 /* Special callback command received */
531 rc = priv->tuner_callback(priv->video_dev,
532 XC2028_TUNER_RESET, 0);
533 if (rc < 0) {
534 tuner_err("Error at RESET code %d\n",
535 (*p) & 0x7f);
536 return -EINVAL;
537 }
538 continue;
539 }
540 if (size >= 0xff00) {
541 switch (size) {
542 case 0xff00:
543 rc = priv->tuner_callback(priv->video_dev,
544 XC2028_RESET_CLK, 0);
545 if (rc < 0) {
546 tuner_err("Error at RESET code %d\n",
547 (*p) & 0x7f);
548 return -EINVAL;
549 }
550 break;
551 default:
552 tuner_info("Invalid RESET code %d\n",
553 size & 0x7f);
554 return -EINVAL;
555
556 }
557 continue;
558 }
559
560 /* Checks for a sleep command */
561 if (size & 0x8000) {
562 msleep(size & 0x7fff);
563 continue;
564 }
565
566 if ((size + p > endp)) {
567 tuner_err("missing bytes: need %d, have %d\n",
568 size, (int)(endp - p));
569 return -EINVAL;
570 }
571
572 buf[0] = *p;
573 p++;
574 size--;
575
576 /* Sends message chunks */
577 while (size > 0) {
578 int len = (size < priv->ctrl.max_len - 1) ?
579 size : priv->ctrl.max_len - 1;
580
581 memcpy(buf + 1, p, len);
582
583 rc = i2c_send(priv, buf, len + 1);
584 if (rc < 0) {
585 tuner_err("%d returned from send\n", rc);
586 return -EINVAL;
587 }
588
589 p += len;
590 size -= len;
591 }
592 }
593 return 0;
594}
595
596static int load_scode(struct dvb_frontend *fe, unsigned int type,
597 v4l2_std_id *id, __u16 int_freq, int scode)
598{
599 struct xc2028_data *priv = fe->tuner_priv;
600 int pos, rc;
601 unsigned char *p;
602
603 tuner_dbg("%s called\n", __func__);
604
605 if (!int_freq) {
606 pos = seek_firmware(fe, type, id);
607 if (pos < 0)
608 return pos;
609 } else {
610 for (pos = 0; pos < priv->firm_size; pos++) {
611 if ((priv->firm[pos].int_freq == int_freq) &&
612 (priv->firm[pos].type & HAS_IF))
613 break;
614 }
615 if (pos == priv->firm_size)
616 return -ENOENT;
617 }
618
619 p = priv->firm[pos].ptr;
620
621 if (priv->firm[pos].type & HAS_IF) {
622 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
623 return -EINVAL;
624 p += 12 * scode;
625 } else {
626 /* 16 SCODE entries per file; each SCODE entry is 12 bytes and
627 * has a 2-byte size header in the firmware format. */
628 if (priv->firm[pos].size != 14 * 16 || scode >= 16 ||
629 le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12)
630 return -EINVAL;
631 p += 14 * scode + 2;
632 }
633
634 tuner_info("Loading SCODE for type=");
635 dump_firm_type_and_int_freq(priv->firm[pos].type,
636 priv->firm[pos].int_freq);
637 printk("(%x), id %016llx.\n", priv->firm[pos].type,
638 (unsigned long long)*id);
639
640 if (priv->firm_version < 0x0202)
641 rc = send_seq(priv, {0x20, 0x00, 0x00, 0x00});
642 else
643 rc = send_seq(priv, {0xa0, 0x00, 0x00, 0x00});
644 if (rc < 0)
645 return -EIO;
646
647 rc = i2c_send(priv, p, 12);
648 if (rc < 0)
649 return -EIO;
650
651 rc = send_seq(priv, {0x00, 0x8c});
652 if (rc < 0)
653 return -EIO;
654
655 return 0;
656}
657
658static int check_firmware(struct dvb_frontend *fe, unsigned int type,
659 v4l2_std_id std, __u16 int_freq)
660{
661 struct xc2028_data *priv = fe->tuner_priv;
662 struct firmware_properties new_fw;
663 int rc = 0, is_retry = 0;
664 u16 version, hwmodel;
665 v4l2_std_id std0;
666
667 tuner_dbg("%s called\n", __func__);
668
669 if (!priv->firm) {
670 if (!priv->ctrl.fname) {
671 tuner_info("xc2028/3028 firmware name not set!\n");
672 return -EINVAL;
673 }
674
675 rc = load_all_firmwares(fe);
676 if (rc < 0)
677 return rc;
678 }
679
680 if (priv->ctrl.mts && !(type & FM))
681 type |= MTS;
682
683retry:
684 new_fw.type = type;
685 new_fw.id = std;
686 new_fw.std_req = std;
687 new_fw.scode_table = SCODE | priv->ctrl.scode_table;
688 new_fw.scode_nr = 0;
689 new_fw.int_freq = int_freq;
690
691 tuner_dbg("checking firmware, user requested type=");
692 if (debug) {
693 dump_firm_type(new_fw.type);
694 printk("(%x), id %016llx, ", new_fw.type,
695 (unsigned long long)new_fw.std_req);
696 if (!int_freq) {
697 printk("scode_tbl ");
698 dump_firm_type(priv->ctrl.scode_table);
699 printk("(%x), ", priv->ctrl.scode_table);
700 } else
701 printk("int_freq %d, ", new_fw.int_freq);
702 printk("scode_nr %d\n", new_fw.scode_nr);
703 }
704
705 /* No need to reload base firmware if it matches */
706 if (((BASE | new_fw.type) & BASE_TYPES) ==
707 (priv->cur_fw.type & BASE_TYPES)) {
708 tuner_dbg("BASE firmware not changed.\n");
709 goto skip_base;
710 }
711
712 /* Updating BASE - forget about all currently loaded firmware */
713 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
714
715 /* Reset is needed before loading firmware */
716 rc = priv->tuner_callback(priv->video_dev,
717 XC2028_TUNER_RESET, 0);
718 if (rc < 0)
719 goto fail;
720
721 /* BASE firmwares are all std0 */
722 std0 = 0;
723 rc = load_firmware(fe, BASE | new_fw.type, &std0);
724 if (rc < 0) {
725 tuner_err("Error %d while loading base firmware\n",
726 rc);
727 goto fail;
728 }
729
730 /* Load INIT1, if needed */
731 tuner_dbg("Load init1 firmware, if exists\n");
732
733 rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0);
734 if (rc == -ENOENT)
735 rc = load_firmware(fe, (BASE | INIT1 | new_fw.type) & ~F8MHZ,
736 &std0);
737 if (rc < 0 && rc != -ENOENT) {
738 tuner_err("Error %d while loading init1 firmware\n",
739 rc);
740 goto fail;
741 }
742
743skip_base:
744 /*
745 * No need to reload standard specific firmware if base firmware
746 * was not reloaded and requested video standards have not changed.
747 */
748 if (priv->cur_fw.type == (BASE | new_fw.type) &&
749 priv->cur_fw.std_req == std) {
750 tuner_dbg("Std-specific firmware already loaded.\n");
751 goto skip_std_specific;
752 }
753
754 /* Reloading std-specific firmware forces a SCODE update */
755 priv->cur_fw.scode_table = 0;
756
757 rc = load_firmware(fe, new_fw.type, &new_fw.id);
758 if (rc == -ENOENT)
759 rc = load_firmware(fe, new_fw.type & ~F8MHZ, &new_fw.id);
760
761 if (rc < 0)
762 goto fail;
763
764skip_std_specific:
765 if (priv->cur_fw.scode_table == new_fw.scode_table &&
766 priv->cur_fw.scode_nr == new_fw.scode_nr) {
767 tuner_dbg("SCODE firmware already loaded.\n");
768 goto check_device;
769 }
770
771 if (new_fw.type & FM)
772 goto check_device;
773
774 /* Load SCODE firmware, if exists */
775 tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
776
777 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
778 new_fw.int_freq, new_fw.scode_nr);
779
780check_device:
781 if (xc2028_get_reg(priv, 0x0004, &version) < 0 ||
782 xc2028_get_reg(priv, 0x0008, &hwmodel) < 0) {
783 tuner_err("Unable to read tuner registers.\n");
784 goto fail;
785 }
786
787 tuner_dbg("Device is Xceive %d version %d.%d, "
788 "firmware version %d.%d\n",
789 hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
790 (version & 0xf0) >> 4, version & 0xf);
791
792 /* Check firmware version against what we downloaded. */
793 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
794 tuner_err("Incorrect readback of firmware version.\n");
795 goto fail;
796 }
797
798 /* Check that the tuner hardware model remains consistent over time. */
799 if (priv->hwmodel == 0 && (hwmodel == 2028 || hwmodel == 3028)) {
800 priv->hwmodel = hwmodel;
801 priv->hwvers = version & 0xff00;
802 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
803 priv->hwvers != (version & 0xff00)) {
804 tuner_err("Read invalid device hardware information - tuner "
805 "hung?\n");
806 goto fail;
807 }
808
809 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
810
811 /*
812 * By setting BASE in cur_fw.type only after successfully loading all
813 * firmwares, we can:
814 * 1. Identify that BASE firmware with type=0 has been loaded;
815 * 2. Tell whether BASE firmware was just changed the next time through.
816 */
817 priv->cur_fw.type |= BASE;
818
819 return 0;
820
821fail:
822 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
823 if (!is_retry) {
824 msleep(50);
825 is_retry = 1;
826 tuner_dbg("Retrying firmware load\n");
827 goto retry;
828 }
829
830 if (rc == -ENOENT)
831 rc = -EINVAL;
832 return rc;
833}
834
835static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
836{
837 struct xc2028_data *priv = fe->tuner_priv;
838 u16 frq_lock, signal = 0;
839 int rc;
840
841 tuner_dbg("%s called\n", __func__);
842
843 mutex_lock(&priv->lock);
844
845 /* Sync Lock Indicator */
846 rc = xc2028_get_reg(priv, 0x0002, &frq_lock);
847 if (rc < 0)
848 goto ret;
849
850 /* Frequency is locked */
851 if (frq_lock == 1)
852 signal = 32768;
853
854 /* Get SNR of the video signal */
855 rc = xc2028_get_reg(priv, 0x0040, &signal);
856 if (rc < 0)
857 goto ret;
858
859 /* Use both frq_lock and signal to generate the result */
860 signal = signal || ((signal & 0x07) << 12);
861
862ret:
863 mutex_unlock(&priv->lock);
864
865 *strength = signal;
866
867 tuner_dbg("signal strength is %d\n", signal);
868
869 return rc;
870}
871
872#define DIV 15625
873
874static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
875 enum tuner_mode new_mode,
876 unsigned int type,
877 v4l2_std_id std,
878 u16 int_freq)
879{
880 struct xc2028_data *priv = fe->tuner_priv;
881 int rc = -EINVAL;
882 unsigned char buf[4];
883 u32 div, offset = 0;
884
885 tuner_dbg("%s called\n", __func__);
886
887 mutex_lock(&priv->lock);
888
889 tuner_dbg("should set frequency %d kHz\n", freq / 1000);
890
891 if (check_firmware(fe, type, std, int_freq) < 0)
892 goto ret;
893
894 /* On some cases xc2028 can disable video output, if
895 * very weak signals are received. By sending a soft
896 * reset, this is re-enabled. So, it is better to always
897 * send a soft reset before changing channels, to be sure
898 * that xc2028 will be in a safe state.
899 * Maybe this might also be needed for DTV.
900 */
901 if (new_mode == T_ANALOG_TV) {
902 rc = send_seq(priv, {0x00, 0x00});
903 } else if (priv->cur_fw.type & ATSC) {
904 offset = 1750000;
905 } else {
906 offset = 2750000;
907 /*
908 * We must adjust the offset by 500kHz in two cases in order
909 * to correctly center the IF output:
910 * 1) When the ZARLINK456 or DIBCOM52 tables were explicitly
911 * selected and a 7MHz channel is tuned;
912 * 2) When tuning a VHF channel with DTV78 firmware.
913 */
914 if (((priv->cur_fw.type & DTV7) &&
915 (priv->cur_fw.scode_table & (ZARLINK456 | DIBCOM52))) ||
916 ((priv->cur_fw.type & DTV78) && freq < 470000000))
917 offset -= 500000;
918 }
919
920 div = (freq - offset + DIV / 2) / DIV;
921
922 /* CMD= Set frequency */
923 if (priv->firm_version < 0x0202)
924 rc = send_seq(priv, {0x00, 0x02, 0x00, 0x00});
925 else
926 rc = send_seq(priv, {0x80, 0x02, 0x00, 0x00});
927 if (rc < 0)
928 goto ret;
929
930 /* Return code shouldn't be checked.
931 The reset CLK is needed only with tm6000.
932 Driver should work fine even if this fails.
933 */
934 priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1);
935
936 msleep(10);
937
938 buf[0] = 0xff & (div >> 24);
939 buf[1] = 0xff & (div >> 16);
940 buf[2] = 0xff & (div >> 8);
941 buf[3] = 0xff & (div);
942
943 rc = i2c_send(priv, buf, sizeof(buf));
944 if (rc < 0)
945 goto ret;
946 msleep(100);
947
948 priv->frequency = freq;
949
950 tuner_dbg("divisor= %02x %02x %02x %02x (freq=%d.%03d)\n",
951 buf[0], buf[1], buf[2], buf[3],
952 freq / 1000000, (freq % 1000000) / 1000);
953
954 rc = 0;
955
956ret:
957 mutex_unlock(&priv->lock);
958
959 return rc;
960}
961
962static int xc2028_set_analog_freq(struct dvb_frontend *fe,
963 struct analog_parameters *p)
964{
965 struct xc2028_data *priv = fe->tuner_priv;
966 unsigned int type=0;
967
968 tuner_dbg("%s called\n", __func__);
969
970 if (p->mode == V4L2_TUNER_RADIO) {
971 type |= FM;
972 if (priv->ctrl.input1)
973 type |= INPUT1;
974 return generic_set_freq(fe, (625l * p->frequency) / 10,
975 T_ANALOG_TV, type, 0, 0);
976 }
977
978 /* if std is not defined, choose one */
979 if (!p->std)
980 p->std = V4L2_STD_MN;
981
982 /* PAL/M, PAL/N, PAL/Nc and NTSC variants should use 6MHz firmware */
983 if (!(p->std & V4L2_STD_MN))
984 type |= F8MHZ;
985
986 /* Add audio hack to std mask */
987 p->std |= parse_audio_std_option();
988
989 return generic_set_freq(fe, 62500l * p->frequency,
990 T_ANALOG_TV, type, p->std, 0);
991}
992
993static int xc2028_set_params(struct dvb_frontend *fe,
994 struct dvb_frontend_parameters *p)
995{
996 struct xc2028_data *priv = fe->tuner_priv;
997 unsigned int type=0;
998 fe_bandwidth_t bw = BANDWIDTH_8_MHZ;
999 u16 demod = 0;
1000
1001 tuner_dbg("%s called\n", __func__);
1002
1003 if (priv->ctrl.d2633)
1004 type |= D2633;
1005 else
1006 type |= D2620;
1007
1008 switch(fe->ops.info.type) {
1009 case FE_OFDM:
1010 bw = p->u.ofdm.bandwidth;
1011 break;
1012 case FE_QAM:
1013 tuner_info("WARN: There are some reports that "
1014 "QAM 6 MHz doesn't work.\n"
1015 "If this works for you, please report by "
1016 "e-mail to: v4l-dvb-maintainer@linuxtv.org\n");
1017 bw = BANDWIDTH_6_MHZ;
1018 type |= QAM;
1019 break;
1020 case FE_ATSC:
1021 bw = BANDWIDTH_6_MHZ;
1022 /* The only ATSC firmware (at least on v2.7) is D2633,
1023 so overrides ctrl->d2633 */
1024 type |= ATSC| D2633;
1025 type &= ~D2620;
1026 break;
1027 /* DVB-S is not supported */
1028 default:
1029 return -EINVAL;
1030 }
1031
1032 switch (bw) {
1033 case BANDWIDTH_8_MHZ:
1034 if (p->frequency < 470000000)
1035 priv->ctrl.vhfbw7 = 0;
1036 else
1037 priv->ctrl.uhfbw8 = 1;
1038 type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8;
1039 type |= F8MHZ;
1040 break;
1041 case BANDWIDTH_7_MHZ:
1042 if (p->frequency < 470000000)
1043 priv->ctrl.vhfbw7 = 1;
1044 else
1045 priv->ctrl.uhfbw8 = 0;
1046 type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7;
1047 type |= F8MHZ;
1048 break;
1049 case BANDWIDTH_6_MHZ:
1050 type |= DTV6;
1051 priv->ctrl.vhfbw7 = 0;
1052 priv->ctrl.uhfbw8 = 0;
1053 break;
1054 default:
1055 tuner_err("error: bandwidth not supported.\n");
1056 };
1057
1058 /* All S-code tables need a 200kHz shift */
1059 if (priv->ctrl.demod)
1060 demod = priv->ctrl.demod + 200;
1061
1062 return generic_set_freq(fe, p->frequency,
1063 T_DIGITAL_TV, type, 0, demod);
1064}
1065
1066
1067static int xc2028_dvb_release(struct dvb_frontend *fe)
1068{
1069 struct xc2028_data *priv = fe->tuner_priv;
1070
1071 tuner_dbg("%s called\n", __func__);
1072
1073 mutex_lock(&xc2028_list_mutex);
1074
1075 priv->count--;
1076
1077 if (!priv->count) {
1078 list_del(&priv->xc2028_list);
1079
1080 kfree(priv->ctrl.fname);
1081
1082 free_firmware(priv);
1083 kfree(priv);
1084 fe->tuner_priv = NULL;
1085 }
1086
1087 mutex_unlock(&xc2028_list_mutex);
1088
1089 return 0;
1090}
1091
1092static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1093{
1094 struct xc2028_data *priv = fe->tuner_priv;
1095
1096 tuner_dbg("%s called\n", __func__);
1097
1098 *frequency = priv->frequency;
1099
1100 return 0;
1101}
1102
1103static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
1104{
1105 struct xc2028_data *priv = fe->tuner_priv;
1106 struct xc2028_ctrl *p = priv_cfg;
1107 int rc = 0;
1108
1109 tuner_dbg("%s called\n", __func__);
1110
1111 mutex_lock(&priv->lock);
1112
1113 memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
1114 if (priv->ctrl.max_len < 9)
1115 priv->ctrl.max_len = 13;
1116
1117 if (p->fname) {
1118 if (priv->ctrl.fname && strcmp(p->fname, priv->ctrl.fname)) {
1119 kfree(priv->ctrl.fname);
1120 free_firmware(priv);
1121 }
1122
1123 priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
1124 if (priv->ctrl.fname == NULL)
1125 rc = -ENOMEM;
1126 }
1127
1128 mutex_unlock(&priv->lock);
1129
1130 return rc;
1131}
1132
1133static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
1134 .info = {
1135 .name = "Xceive XC3028",
1136 .frequency_min = 42000000,
1137 .frequency_max = 864000000,
1138 .frequency_step = 50000,
1139 },
1140
1141 .set_config = xc2028_set_config,
1142 .set_analog_params = xc2028_set_analog_freq,
1143 .release = xc2028_dvb_release,
1144 .get_frequency = xc2028_get_frequency,
1145 .get_rf_strength = xc2028_signal,
1146 .set_params = xc2028_set_params,
1147};
1148
1149struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
1150 struct xc2028_config *cfg)
1151{
1152 struct xc2028_data *priv;
1153 void *video_dev;
1154
1155 if (debug)
1156 printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n");
1157
1158 if (NULL == cfg)
1159 return NULL;
1160
1161 if (!fe) {
1162 printk(KERN_ERR "xc2028: No frontend!\n");
1163 return NULL;
1164 }
1165
1166 video_dev = cfg->i2c_adap->algo_data;
1167
1168 if (debug)
1169 printk(KERN_DEBUG "xc2028: video_dev =%p\n", video_dev);
1170
1171 mutex_lock(&xc2028_list_mutex);
1172
1173 list_for_each_entry(priv, &xc2028_list, xc2028_list) {
1174 if (&priv->i2c_props.adap->dev == &cfg->i2c_adap->dev) {
1175 video_dev = NULL;
1176 if (debug)
1177 printk(KERN_DEBUG "xc2028: reusing device\n");
1178
1179 break;
1180 }
1181 }
1182
1183 if (video_dev) {
1184 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1185 if (priv == NULL) {
1186 mutex_unlock(&xc2028_list_mutex);
1187 return NULL;
1188 }
1189
1190 priv->i2c_props.addr = cfg->i2c_addr;
1191 priv->i2c_props.adap = cfg->i2c_adap;
1192 priv->i2c_props.name = "xc2028";
1193
1194 priv->video_dev = video_dev;
1195 priv->tuner_callback = cfg->callback;
1196 priv->ctrl.max_len = 13;
1197
1198 mutex_init(&priv->lock);
1199
1200 list_add_tail(&priv->xc2028_list, &xc2028_list);
1201 }
1202
1203 fe->tuner_priv = priv;
1204 priv->count++;
1205
1206 if (debug)
1207 printk(KERN_DEBUG "xc2028: usage count is %i\n", priv->count);
1208
1209 memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
1210 sizeof(xc2028_dvb_tuner_ops));
1211
1212 tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner");
1213
1214 if (cfg->ctrl)
1215 xc2028_set_config(fe, cfg->ctrl);
1216
1217 mutex_unlock(&xc2028_list_mutex);
1218
1219 return fe;
1220}
1221
1222EXPORT_SYMBOL(xc2028_attach);
1223
1224MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
1225MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
1226MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
1227MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tuner-xc2028.h b/drivers/media/video/tuner-xc2028.h
deleted file mode 100644
index fc2f132a5541..000000000000
--- a/drivers/media/video/tuner-xc2028.h
+++ /dev/null
@@ -1,63 +0,0 @@
1/* tuner-xc2028
2 *
3 * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
4 * This code is placed under the terms of the GNU General Public License v2
5 */
6
7#ifndef __TUNER_XC2028_H__
8#define __TUNER_XC2028_H__
9
10#include "dvb_frontend.h"
11
12#define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw"
13
14/* Dmoduler IF (kHz) */
15#define XC3028_FE_DEFAULT 0 /* Don't load SCODE */
16#define XC3028_FE_LG60 6000
17#define XC3028_FE_ATI638 6380
18#define XC3028_FE_OREN538 5380
19#define XC3028_FE_OREN36 3600
20#define XC3028_FE_TOYOTA388 3880
21#define XC3028_FE_TOYOTA794 7940
22#define XC3028_FE_DIBCOM52 5200
23#define XC3028_FE_ZARLINK456 4560
24#define XC3028_FE_CHINA 5200
25
26struct xc2028_ctrl {
27 char *fname;
28 int max_len;
29 unsigned int scode_table;
30 unsigned int mts :1;
31 unsigned int d2633 :1;
32 unsigned int input1:1;
33 unsigned int vhfbw7:1;
34 unsigned int uhfbw8:1;
35 unsigned int demod;
36};
37
38struct xc2028_config {
39 struct i2c_adapter *i2c_adap;
40 u8 i2c_addr;
41 void *video_dev;
42 struct xc2028_ctrl *ctrl;
43 int (*callback) (void *dev, int command, int arg);
44};
45
46/* xc2028 commands for callback */
47#define XC2028_TUNER_RESET 0
48#define XC2028_RESET_CLK 1
49
50#if defined(CONFIG_TUNER_XC2028) || (defined(CONFIG_TUNER_XC2028_MODULE) && defined(MODULE))
51extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
52 struct xc2028_config *cfg);
53#else
54static inline struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
55 struct xc2028_config *cfg)
56{
57 printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
58 __func__);
59 return NULL;
60}
61#endif
62
63#endif /* __TUNER_XC2028_H__ */
diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/video/usbvision/Kconfig
index fc24ef05b3f3..74e1d3075a20 100644
--- a/drivers/media/video/usbvision/Kconfig
+++ b/drivers/media/video/usbvision/Kconfig
@@ -1,7 +1,7 @@
1config VIDEO_USBVISION 1config VIDEO_USBVISION
2 tristate "USB video devices based on Nogatech NT1003/1004/1005" 2 tristate "USB video devices based on Nogatech NT1003/1004/1005"
3 depends on I2C && VIDEO_V4L2 3 depends on I2C && VIDEO_V4L2
4 select VIDEO_TUNER 4 select MEDIA_TUNER
5 select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO 5 select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
6 ---help--- 6 ---help---
7 There are more than 50 different USB video devices based on 7 There are more than 50 different USB video devices based on
diff --git a/drivers/media/video/usbvision/Makefile b/drivers/media/video/usbvision/Makefile
index 9ac92a80c645..338718750945 100644
--- a/drivers/media/video/usbvision/Makefile
+++ b/drivers/media/video/usbvision/Makefile
@@ -3,3 +3,4 @@ usbvision-objs := usbvision-core.o usbvision-video.o usbvision-i2c.o usbvision-
3obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o 3obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o
4 4
5EXTRA_CFLAGS += -Idrivers/media/video 5EXTRA_CFLAGS += -Idrivers/media/video
6EXTRA_CFLAGS += -Idrivers/media/common/tuners