aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/Kconfig172
-rw-r--r--drivers/media/Makefile10
-rw-r--r--drivers/media/common/tuners/Kconfig146
-rw-r--r--drivers/media/common/tuners/Makefile25
-rw-r--r--drivers/media/common/tuners/mt2060.c (renamed from drivers/media/dvb/frontends/mt2060.c)0
-rw-r--r--drivers/media/common/tuners/mt2060.h (renamed from drivers/media/dvb/frontends/mt2060.h)4
-rw-r--r--drivers/media/common/tuners/mt2060_priv.h (renamed from drivers/media/dvb/frontends/mt2060_priv.h)0
-rw-r--r--drivers/media/common/tuners/mt20xx.c (renamed from drivers/media/video/mt20xx.c)0
-rw-r--r--drivers/media/common/tuners/mt20xx.h (renamed from drivers/media/video/mt20xx.h)2
-rw-r--r--drivers/media/common/tuners/mt2131.c (renamed from drivers/media/dvb/frontends/mt2131.c)0
-rw-r--r--drivers/media/common/tuners/mt2131.h (renamed from drivers/media/dvb/frontends/mt2131.h)4
-rw-r--r--drivers/media/common/tuners/mt2131_priv.h (renamed from drivers/media/dvb/frontends/mt2131_priv.h)0
-rw-r--r--drivers/media/common/tuners/mt2266.c (renamed from drivers/media/dvb/frontends/mt2266.c)0
-rw-r--r--drivers/media/common/tuners/mt2266.h (renamed from drivers/media/dvb/frontends/mt2266.h)4
-rw-r--r--drivers/media/common/tuners/qt1010.c (renamed from drivers/media/dvb/frontends/qt1010.c)0
-rw-r--r--drivers/media/common/tuners/qt1010.h (renamed from drivers/media/dvb/frontends/qt1010.h)4
-rw-r--r--drivers/media/common/tuners/qt1010_priv.h (renamed from drivers/media/dvb/frontends/qt1010_priv.h)0
-rw-r--r--drivers/media/common/tuners/tda18271-common.c (renamed from drivers/media/dvb/frontends/tda18271-common.c)0
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c (renamed from drivers/media/dvb/frontends/tda18271-fe.c)0
-rw-r--r--drivers/media/common/tuners/tda18271-maps.c (renamed from drivers/media/dvb/frontends/tda18271-tables.c)0
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h (renamed from drivers/media/dvb/frontends/tda18271-priv.h)0
-rw-r--r--drivers/media/common/tuners/tda18271.h (renamed from drivers/media/dvb/frontends/tda18271.h)2
-rw-r--r--drivers/media/common/tuners/tda827x.c (renamed from drivers/media/dvb/frontends/tda827x.c)0
-rw-r--r--drivers/media/common/tuners/tda827x.h (renamed from drivers/media/dvb/frontends/tda827x.h)4
-rw-r--r--drivers/media/common/tuners/tda8290.c (renamed from drivers/media/video/tda8290.c)8
-rw-r--r--drivers/media/common/tuners/tda8290.h (renamed from drivers/media/video/tda8290.h)2
-rw-r--r--drivers/media/common/tuners/tda9887.c (renamed from drivers/media/video/tda9887.c)0
-rw-r--r--drivers/media/common/tuners/tda9887.h (renamed from drivers/media/video/tda9887.h)2
-rw-r--r--drivers/media/common/tuners/tea5761.c (renamed from drivers/media/video/tea5761.c)0
-rw-r--r--drivers/media/common/tuners/tea5761.h (renamed from drivers/media/video/tea5761.h)2
-rw-r--r--drivers/media/common/tuners/tea5767.c (renamed from drivers/media/video/tea5767.c)0
-rw-r--r--drivers/media/common/tuners/tea5767.h (renamed from drivers/media/video/tea5767.h)2
-rw-r--r--drivers/media/common/tuners/tuner-i2c.h (renamed from drivers/media/video/tuner-i2c.h)0
-rw-r--r--drivers/media/common/tuners/tuner-simple.c (renamed from drivers/media/video/tuner-simple.c)0
-rw-r--r--drivers/media/common/tuners/tuner-simple.h (renamed from drivers/media/video/tuner-simple.h)2
-rw-r--r--drivers/media/common/tuners/tuner-types.c (renamed from drivers/media/video/tuner-types.c)0
-rw-r--r--drivers/media/common/tuners/tuner-xc2028-types.h (renamed from drivers/media/video/tuner-xc2028-types.h)0
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c (renamed from drivers/media/video/tuner-xc2028.c)0
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.h (renamed from drivers/media/video/tuner-xc2028.h)2
-rw-r--r--drivers/media/common/tuners/xc5000.c (renamed from drivers/media/dvb/frontends/xc5000.c)0
-rw-r--r--drivers/media/common/tuners/xc5000.h (renamed from drivers/media/dvb/frontends/xc5000.h)6
-rw-r--r--drivers/media/common/tuners/xc5000_priv.h (renamed from drivers/media/dvb/frontends/xc5000_priv.h)0
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/b2c2/Kconfig2
-rw-r--r--drivers/media/dvb/b2c2/Makefile2
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig2
-rw-r--r--drivers/media/dvb/bt8xx/Makefile2
-rw-r--r--drivers/media/dvb/bt8xx/dst.c2
-rw-r--r--drivers/media/dvb/dvb-core/Kconfig34
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig26
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile2
-rw-r--r--drivers/media/dvb/frontends/Kconfig121
-rw-r--r--drivers/media/dvb/frontends/Makefile11
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c2
-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/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/tuner-core.c124
-rw-r--r--drivers/media/video/usbvision/Kconfig2
-rw-r--r--drivers/media/video/usbvision/Makefile1
140 files changed, 11030 insertions, 700 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 128bb9cd5755..ddf57e135c6c 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -5,16 +5,20 @@
5menu "Multimedia devices" 5menu "Multimedia devices"
6 depends on HAS_IOMEM 6 depends on HAS_IOMEM
7 7
8comment "Multimedia core support"
9
10#
11# V4L core and enabled API's
12#
13
8config VIDEO_DEV 14config VIDEO_DEV
9 tristate "Video For Linux" 15 tristate "Video For Linux"
10 ---help--- 16 ---help---
11 Support for audio/video capture and overlay devices and FM radio 17 V4L core support for video capture and overlay devices, webcams and
12 cards. The exact capabilities of each device vary. 18 AM/FM radio cards.
13 19
14 This kernel includes support for the new Video for Linux Two API, 20 This kernel includes support for the new Video for Linux Two API,
15 (V4L2) as well as the original system. Drivers and applications 21 (V4L2).
16 need to be rewritten to use V4L2, but drivers for popular cards
17 and applications for most video capture functions already exist.
18 22
19 Additional info and docs are available on the web at 23 Additional info and docs are available on the web at
20 <http://linuxtv.org> 24 <http://linuxtv.org>
@@ -36,8 +40,11 @@ config VIDEO_ALLOW_V4L1
36 default VIDEO_DEV && VIDEO_V4L2_COMMON 40 default VIDEO_DEV && VIDEO_V4L2_COMMON
37 select VIDEO_V4L1_COMPAT 41 select VIDEO_V4L1_COMPAT
38 ---help--- 42 ---help---
39 Enables a compatibility API used by most V4L2 devices to allow 43 Enables drivers based on the legacy V4L1 API.
40 its usage with legacy applications that supports only V4L1 api. 44
45 This api were developed to be used at Kernel 2.2 and 2.4, but
46 lacks support for several video standards. There are several
47 drivers at kernel that still depends on it.
41 48
42 If you are unsure as to whether this is required, answer Y. 49 If you are unsure as to whether this is required, answer Y.
43 50
@@ -46,9 +53,8 @@ config VIDEO_V4L1_COMPAT
46 depends on VIDEO_DEV 53 depends on VIDEO_DEV
47 default VIDEO_DEV 54 default VIDEO_DEV
48 ---help--- 55 ---help---
49 This api were developed to be used at Kernel 2.2 and 2.4, but 56 Enables a compatibility API used by most V4L2 devices to allow
50 lacks support for several video standards. There are several 57 its usage with legacy applications that supports only V4L1 api.
51 drivers at kernel that still depends on it.
52 58
53 Documentation for the original API is included in the file 59 Documentation for the original API is included in the file
54 <Documentation/video4linux/API.html>. 60 <Documentation/video4linux/API.html>.
@@ -58,135 +64,57 @@ config VIDEO_V4L1_COMPAT
58 64
59 If you are unsure as to whether this is required, answer Y. 65 If you are unsure as to whether this is required, answer Y.
60 66
61config VIDEO_V4L2 67#
62 tristate 68# DVB Core
63 depends on VIDEO_DEV && VIDEO_V4L2_COMMON 69#
64 default VIDEO_DEV && VIDEO_V4L2_COMMON
65
66config VIDEO_V4L1
67 tristate
68 depends on VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
69 default VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1
70
71source "drivers/media/video/Kconfig"
72
73source "drivers/media/radio/Kconfig"
74
75source "drivers/media/dvb/Kconfig"
76
77source "drivers/media/common/Kconfig"
78 70
79config VIDEO_TUNER 71config DVB_CORE
80 tristate 72 tristate "DVB for Linux"
81 depends on I2C 73 depends on NET && INET
82 select TUNER_XC2028 if !VIDEO_TUNER_CUSTOMIZE 74 select CRC32
83 select TUNER_MT20XX if !VIDEO_TUNER_CUSTOMIZE
84 select TUNER_TDA8290 if !VIDEO_TUNER_CUSTOMIZE
85 select TUNER_TEA5761 if !VIDEO_TUNER_CUSTOMIZE
86 select TUNER_TEA5767 if !VIDEO_TUNER_CUSTOMIZE
87 select TUNER_SIMPLE if !VIDEO_TUNER_CUSTOMIZE
88 select TUNER_TDA9887 if !VIDEO_TUNER_CUSTOMIZE
89
90menuconfig VIDEO_TUNER_CUSTOMIZE
91 bool "Customize analog tuner modules to build"
92 depends on VIDEO_TUNER
93 help 75 help
94 This allows the user to deselect tuner drivers unnecessary 76 DVB core utility functions for device handling, software fallbacks etc.
95 for their hardware from the build. Use this option with care
96 as deselecting tuner drivers which are in fact necessary will
97 result in V4L devices which cannot be tuned due to lack of
98 driver support
99 77
100 If unsure say N. 78 Enable this if you own a DVB/ATSC adapter and want to use it or if
101 79 you compile Linux for a digital SetTopBox.
102if VIDEO_TUNER_CUSTOMIZE
103
104config TUNER_XC2028
105 tristate "XCeive xc2028/xc3028 tuners"
106 depends on I2C && FW_LOADER
107 default m if VIDEO_TUNER_CUSTOMIZE
108 help
109 Say Y here to include support for the xc2028/xc3028 tuners.
110 80
111config TUNER_MT20XX 81 Say Y when you have a DVB or an ATSC card and want to use it.
112 tristate "Microtune 2032 / 2050 tuners"
113 depends on I2C
114 default m if VIDEO_TUNER_CUSTOMIZE
115 help
116 Say Y here to include support for the MT2032 / MT2050 tuner.
117
118config TUNER_TDA8290
119 tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
120 depends on I2C
121 select DVB_TDA827X
122 select DVB_TDA18271
123 default m if VIDEO_TUNER_CUSTOMIZE
124 help
125 Say Y here to include support for Philips TDA8290+8275(a) tuner.
126 82
127config TUNER_TEA5761 83 API specs and user tools are available from <http://www.linuxtv.org/>.
128 tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
129 depends on I2C && EXPERIMENTAL
130 default m if VIDEO_TUNER_CUSTOMIZE
131 help
132 Say Y here to include support for the Philips TEA5761 radio tuner.
133 84
134config TUNER_TEA5767 85 Please report problems regarding this support to the LinuxDVB
135 tristate "TEA 5767 radio tuner" 86 mailing list.
136 depends on I2C
137 default m if VIDEO_TUNER_CUSTOMIZE
138 help
139 Say Y here to include support for the Philips TEA5767 radio tuner.
140 87
141config TUNER_SIMPLE 88 If unsure say N.
142 tristate "Simple tuner support"
143 depends on I2C
144 select TUNER_TDA9887
145 default m if VIDEO_TUNER_CUSTOMIZE
146 help
147 Say Y here to include support for various simple tuners.
148 89
149config TUNER_TDA9887 90config VIDEO_MEDIA
150 tristate "TDA 9885/6/7 analog IF demodulator" 91 tristate
151 depends on I2C 92 default DVB_CORE || VIDEO_DEV
152 default m if VIDEO_TUNER_CUSTOMIZE 93 depends on DVB_CORE || VIDEO_DEV
153 help
154 Say Y here to include support for Philips TDA9885/6/7
155 analog IF demodulator.
156 94
157endif # VIDEO_TUNER_CUSTOMIZE 95comment "Multimedia drivers"
158 96
159config VIDEOBUF_GEN 97source "drivers/media/common/Kconfig"
160 tristate
161 98
162config VIDEOBUF_DMA_SG 99#
163 depends on HAS_DMA 100# Tuner drivers for DVB and V4L
164 select VIDEOBUF_GEN 101#
165 tristate
166 102
167config VIDEOBUF_VMALLOC 103source "drivers/media/common/tuners/Kconfig"
168 select VIDEOBUF_GEN
169 tristate
170 104
171config VIDEOBUF_DVB 105#
172 tristate 106# Video/Radio/Hybrid adapters
173 select VIDEOBUF_GEN 107#
174 select VIDEOBUF_DMA_SG
175 108
176config VIDEO_BTCX 109source "drivers/media/video/Kconfig"
177 tristate
178 110
179config VIDEO_IR_I2C 111source "drivers/media/radio/Kconfig"
180 tristate
181 112
182config VIDEO_IR 113#
183 tristate 114# DVB adapters
184 depends on INPUT 115#
185 select VIDEO_IR_I2C if I2C
186 116
187config VIDEO_TVEEPROM 117source "drivers/media/dvb/Kconfig"
188 tristate
189 depends on I2C
190 118
191config DAB 119config DAB
192 boolean "DAB adapters" 120 boolean "DAB adapters"
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 7b8bb6949f5e..73f742c7e818 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,10 +2,10 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5obj-y := common/ 5obj-$(CONFIG_VIDEO_MEDIA) += common/
6obj-y += video/ 6
7# Since hybrid devices are here, should be compiled if DVB and/or V4L
8obj-$(CONFIG_VIDEO_MEDIA) += video/
9
7obj-$(CONFIG_VIDEO_DEV) += radio/ 10obj-$(CONFIG_VIDEO_DEV) += radio/
8obj-$(CONFIG_DVB_CORE) += dvb/ 11obj-$(CONFIG_DVB_CORE) += dvb/
9ifeq ($(CONFIG_DVB_CORE),)
10 obj-$(CONFIG_VIDEO_TUNER) += dvb/frontends/
11endif
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
new file mode 100644
index 000000000000..7b379e1ce01b
--- /dev/null
+++ b/drivers/media/common/tuners/Kconfig
@@ -0,0 +1,146 @@
1config MEDIA_ATTACH
2 bool "Load and attach frontend driver modules as needed"
3 depends on DVB_CORE
4 depends on MODULES
5 help
6 Remove the static dependency of DVB card drivers on all
7 frontend modules for all possible card variants. Instead,
8 allow the card drivers to only load the frontend modules
9 they require. This saves several KBytes of memory.
10
11 Note: You will need module-init-tools v3.2 or later for this feature.
12
13 If unsure say Y.
14
15config MEDIA_TUNER
16 tristate
17 default DVB_CORE || VIDEO_DEV
18 depends on DVB_CORE || VIDEO_DEV
19 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
20 select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
21 select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
22 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
23 select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
24 select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE
25 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
26 select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE
27
28menuconfig MEDIA_TUNER_CUSTOMIZE
29 bool "Customize analog and hybrid tuner modules to build"
30 depends on MEDIA_TUNER
31 help
32 This allows the user to deselect tuner drivers unnecessary
33 for their hardware from the build. Use this option with care
34 as deselecting tuner drivers which are in fact necessary will
35 result in V4L/DVB devices which cannot be tuned due to lack of
36 driver support
37
38 If unsure say N.
39
40if MEDIA_TUNER_CUSTOMIZE
41
42config MEDIA_TUNER_SIMPLE
43 tristate "Simple tuner support"
44 depends on I2C
45 select MEDIA_TUNER_TDA9887
46 default m if MEDIA_TUNER_CUSTOMIZE
47 help
48 Say Y here to include support for various simple tuners.
49
50config MEDIA_TUNER_TDA8290
51 tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
52 depends on I2C
53 select MEDIA_TUNER_TDA827X
54 select MEDIA_TUNER_TDA18271
55 default m if MEDIA_TUNER_CUSTOMIZE
56 help
57 Say Y here to include support for Philips TDA8290+8275(a) tuner.
58
59config MEDIA_TUNER_TDA827X
60 tristate "Philips TDA827X silicon tuner"
61 depends on DVB_CORE && I2C
62 default m if DVB_FE_CUSTOMISE
63 help
64 A DVB-T silicon tuner module. Say Y when you want to support this tuner.
65
66config MEDIA_TUNER_TDA18271
67 tristate "NXP TDA18271 silicon tuner"
68 depends on I2C
69 default m if DVB_FE_CUSTOMISE
70 help
71 A silicon tuner module. Say Y when you want to support this tuner.
72
73config MEDIA_TUNER_TDA9887
74 tristate "TDA 9885/6/7 analog IF demodulator"
75 depends on I2C
76 default m if MEDIA_TUNER_CUSTOMIZE
77 help
78 Say Y here to include support for Philips TDA9885/6/7
79 analog IF demodulator.
80
81config MEDIA_TUNER_TEA5761
82 tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
83 depends on I2C && EXPERIMENTAL
84 default m if MEDIA_TUNER_CUSTOMIZE
85 help
86 Say Y here to include support for the Philips TEA5761 radio tuner.
87
88config MEDIA_TUNER_TEA5767
89 tristate "TEA 5767 radio tuner"
90 depends on I2C
91 default m if MEDIA_TUNER_CUSTOMIZE
92 help
93 Say Y here to include support for the Philips TEA5767 radio tuner.
94
95config MEDIA_TUNER_MT20XX
96 tristate "Microtune 2032 / 2050 tuners"
97 depends on I2C
98 default m if MEDIA_TUNER_CUSTOMIZE
99 help
100 Say Y here to include support for the MT2032 / MT2050 tuner.
101
102config MEDIA_TUNER_MT2060
103 tristate "Microtune MT2060 silicon IF tuner"
104 depends on I2C
105 default m if DVB_FE_CUSTOMISE
106 help
107 A driver for the silicon IF tuner MT2060 from Microtune.
108
109config MEDIA_TUNER_MT2266
110 tristate "Microtune MT2266 silicon tuner"
111 depends on I2C
112 default m if DVB_FE_CUSTOMISE
113 help
114 A driver for the silicon baseband tuner MT2266 from Microtune.
115
116config MEDIA_TUNER_MT2131
117 tristate "Microtune MT2131 silicon tuner"
118 depends on I2C
119 default m if DVB_FE_CUSTOMISE
120 help
121 A driver for the silicon baseband tuner MT2131 from Microtune.
122
123config MEDIA_TUNER_QT1010
124 tristate "Quantek QT1010 silicon tuner"
125 depends on DVB_CORE && I2C
126 default m if DVB_FE_CUSTOMISE
127 help
128 A driver for the silicon tuner QT1010 from Quantek.
129
130config MEDIA_TUNER_XC2028
131 tristate "XCeive xc2028/xc3028 tuners"
132 depends on I2C && FW_LOADER
133 default m if MEDIA_TUNER_CUSTOMIZE
134 help
135 Say Y here to include support for the xc2028/xc3028 tuners.
136
137config MEDIA_TUNER_XC5000
138 tristate "Xceive XC5000 silicon tuner"
139 depends on I2C
140 default m if DVB_FE_CUSTOMISE
141 help
142 A driver for the silicon tuner XC5000 from Xceive.
143 This device is only used inside a SiP called togther with a
144 demodulator for now.
145
146endif # MEDIA_TUNER_CUSTOMIZE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
new file mode 100644
index 000000000000..236d9932fd92
--- /dev/null
+++ b/drivers/media/common/tuners/Makefile
@@ -0,0 +1,25 @@
1#
2# Makefile for common V4L/DVB tuners
3#
4
5tda18271-objs := tda18271-maps.o tda18271-common.o tda18271-fe.o
6
7obj-$(CONFIG_MEDIA_TUNER_XC2028) += tuner-xc2028.o
8obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-simple.o
9# tuner-types will be merged into tuner-simple, in the future
10obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-types.o
11obj-$(CONFIG_MEDIA_TUNER_MT20XX) += mt20xx.o
12obj-$(CONFIG_MEDIA_TUNER_TDA8290) += tda8290.o
13obj-$(CONFIG_MEDIA_TUNER_TEA5767) += tea5767.o
14obj-$(CONFIG_MEDIA_TUNER_TEA5761) += tea5761.o
15obj-$(CONFIG_MEDIA_TUNER_TDA9887) += tda9887.o
16obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
17obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
18obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
19obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
20obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
21obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
22obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
23
24EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
25EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/frontends/mt2060.c b/drivers/media/common/tuners/mt2060.c
index 1305b0e63ce5..1305b0e63ce5 100644
--- a/drivers/media/dvb/frontends/mt2060.c
+++ b/drivers/media/common/tuners/mt2060.c
diff --git a/drivers/media/dvb/frontends/mt2060.h b/drivers/media/common/tuners/mt2060.h
index acba0058f519..cb60caffb6b6 100644
--- a/drivers/media/dvb/frontends/mt2060.h
+++ b/drivers/media/common/tuners/mt2060.h
@@ -30,7 +30,7 @@ struct mt2060_config {
30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ 30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
31}; 31};
32 32
33#if defined(CONFIG_DVB_TUNER_MT2060) || (defined(CONFIG_DVB_TUNER_MT2060_MODULE) && defined(MODULE)) 33#if defined(CONFIG_MEDIA_TUNER_MT2060) || (defined(CONFIG_MEDIA_TUNER_MT2060_MODULE) && defined(MODULE))
34extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1); 34extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
35#else 35#else
36static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1) 36static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
@@ -38,6 +38,6 @@ static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struc
38 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 38 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
39 return NULL; 39 return NULL;
40} 40}
41#endif // CONFIG_DVB_TUNER_MT2060 41#endif // CONFIG_MEDIA_TUNER_MT2060
42 42
43#endif 43#endif
diff --git a/drivers/media/dvb/frontends/mt2060_priv.h b/drivers/media/common/tuners/mt2060_priv.h
index 5eaccdefd0b0..5eaccdefd0b0 100644
--- a/drivers/media/dvb/frontends/mt2060_priv.h
+++ b/drivers/media/common/tuners/mt2060_priv.h
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/common/tuners/mt20xx.c
index fbcb28233737..fbcb28233737 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/common/tuners/mt20xx.c
diff --git a/drivers/media/video/mt20xx.h b/drivers/media/common/tuners/mt20xx.h
index aa848e14ce5e..259553a24903 100644
--- a/drivers/media/video/mt20xx.h
+++ b/drivers/media/common/tuners/mt20xx.h
@@ -20,7 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include "dvb_frontend.h" 21#include "dvb_frontend.h"
22 22
23#if defined(CONFIG_TUNER_MT20XX) || (defined(CONFIG_TUNER_MT20XX_MODULE) && defined(MODULE)) 23#if defined(CONFIG_MEDIA_TUNER_MT20XX) || (defined(CONFIG_MEDIA_TUNER_MT20XX_MODULE) && defined(MODULE))
24extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, 24extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
25 struct i2c_adapter* i2c_adap, 25 struct i2c_adapter* i2c_adap,
26 u8 i2c_addr); 26 u8 i2c_addr);
diff --git a/drivers/media/dvb/frontends/mt2131.c b/drivers/media/common/tuners/mt2131.c
index e254bcfc2efb..e254bcfc2efb 100644
--- a/drivers/media/dvb/frontends/mt2131.c
+++ b/drivers/media/common/tuners/mt2131.c
diff --git a/drivers/media/dvb/frontends/mt2131.h b/drivers/media/common/tuners/mt2131.h
index 606d8576bc98..cd8376f6f7b4 100644
--- a/drivers/media/dvb/frontends/mt2131.h
+++ b/drivers/media/common/tuners/mt2131.h
@@ -30,7 +30,7 @@ struct mt2131_config {
30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */ 30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
31}; 31};
32 32
33#if defined(CONFIG_DVB_TUNER_MT2131) || (defined(CONFIG_DVB_TUNER_MT2131_MODULE) && defined(MODULE)) 33#if defined(CONFIG_MEDIA_TUNER_MT2131) || (defined(CONFIG_MEDIA_TUNER_MT2131_MODULE) && defined(MODULE))
34extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe, 34extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
35 struct i2c_adapter *i2c, 35 struct i2c_adapter *i2c,
36 struct mt2131_config *cfg, 36 struct mt2131_config *cfg,
@@ -44,7 +44,7 @@ static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL; 45 return NULL;
46} 46}
47#endif /* CONFIG_DVB_TUNER_MT2131 */ 47#endif /* CONFIG_MEDIA_TUNER_MT2131 */
48 48
49#endif /* __MT2131_H__ */ 49#endif /* __MT2131_H__ */
50 50
diff --git a/drivers/media/dvb/frontends/mt2131_priv.h b/drivers/media/common/tuners/mt2131_priv.h
index e930759c2c00..e930759c2c00 100644
--- a/drivers/media/dvb/frontends/mt2131_priv.h
+++ b/drivers/media/common/tuners/mt2131_priv.h
diff --git a/drivers/media/dvb/frontends/mt2266.c b/drivers/media/common/tuners/mt2266.c
index 54b18f94b14b..54b18f94b14b 100644
--- a/drivers/media/dvb/frontends/mt2266.c
+++ b/drivers/media/common/tuners/mt2266.c
diff --git a/drivers/media/dvb/frontends/mt2266.h b/drivers/media/common/tuners/mt2266.h
index c5113efe333c..4d083882d044 100644
--- a/drivers/media/dvb/frontends/mt2266.h
+++ b/drivers/media/common/tuners/mt2266.h
@@ -24,7 +24,7 @@ struct mt2266_config {
24 u8 i2c_address; 24 u8 i2c_address;
25}; 25};
26 26
27#if defined(CONFIG_DVB_TUNER_MT2266) || (defined(CONFIG_DVB_TUNER_MT2266_MODULE) && defined(MODULE)) 27#if defined(CONFIG_MEDIA_TUNER_MT2266) || (defined(CONFIG_MEDIA_TUNER_MT2266_MODULE) && defined(MODULE))
28extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg); 28extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
29#else 29#else
30static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg) 30static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
@@ -32,6 +32,6 @@ static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struc
32 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 32 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
33 return NULL; 33 return NULL;
34} 34}
35#endif // CONFIG_DVB_TUNER_MT2266 35#endif // CONFIG_MEDIA_TUNER_MT2266
36 36
37#endif 37#endif
diff --git a/drivers/media/dvb/frontends/qt1010.c b/drivers/media/common/tuners/qt1010.c
index 825aa1412e6f..825aa1412e6f 100644
--- a/drivers/media/dvb/frontends/qt1010.c
+++ b/drivers/media/common/tuners/qt1010.c
diff --git a/drivers/media/dvb/frontends/qt1010.h b/drivers/media/common/tuners/qt1010.h
index cff6a7ca5380..807fb7b6146b 100644
--- a/drivers/media/dvb/frontends/qt1010.h
+++ b/drivers/media/common/tuners/qt1010.h
@@ -36,7 +36,7 @@ struct qt1010_config {
36 * @param cfg tuner hw based configuration 36 * @param cfg tuner hw based configuration
37 * @return fe pointer on success, NULL on failure 37 * @return fe pointer on success, NULL on failure
38 */ 38 */
39#if defined(CONFIG_DVB_TUNER_QT1010) || (defined(CONFIG_DVB_TUNER_QT1010_MODULE) && defined(MODULE)) 39#if defined(CONFIG_MEDIA_TUNER_QT1010) || (defined(CONFIG_MEDIA_TUNER_QT1010_MODULE) && defined(MODULE))
40extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe, 40extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
41 struct i2c_adapter *i2c, 41 struct i2c_adapter *i2c,
42 struct qt1010_config *cfg); 42 struct qt1010_config *cfg);
@@ -48,6 +48,6 @@ static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
49 return NULL; 49 return NULL;
50} 50}
51#endif // CONFIG_DVB_TUNER_QT1010 51#endif // CONFIG_MEDIA_TUNER_QT1010
52 52
53#endif 53#endif
diff --git a/drivers/media/dvb/frontends/qt1010_priv.h b/drivers/media/common/tuners/qt1010_priv.h
index 090cf475f099..090cf475f099 100644
--- a/drivers/media/dvb/frontends/qt1010_priv.h
+++ b/drivers/media/common/tuners/qt1010_priv.h
diff --git a/drivers/media/dvb/frontends/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index e27a7620a32f..e27a7620a32f 100644
--- a/drivers/media/dvb/frontends/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
diff --git a/drivers/media/dvb/frontends/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index b262100ae897..b262100ae897 100644
--- a/drivers/media/dvb/frontends/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
diff --git a/drivers/media/dvb/frontends/tda18271-tables.c b/drivers/media/common/tuners/tda18271-maps.c
index 83e7561960c1..83e7561960c1 100644
--- a/drivers/media/dvb/frontends/tda18271-tables.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
diff --git a/drivers/media/dvb/frontends/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 2bc5eb368ea2..2bc5eb368ea2 100644
--- a/drivers/media/dvb/frontends/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
diff --git a/drivers/media/dvb/frontends/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 0e7af8d05a38..7db9831c0cb0 100644
--- a/drivers/media/dvb/frontends/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -81,7 +81,7 @@ struct tda18271_config {
81 unsigned int small_i2c:1; 81 unsigned int small_i2c:1;
82}; 82};
83 83
84#if defined(CONFIG_DVB_TDA18271) || (defined(CONFIG_DVB_TDA18271_MODULE) && defined(MODULE)) 84#if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE))
85extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, 85extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
86 struct i2c_adapter *i2c, 86 struct i2c_adapter *i2c,
87 struct tda18271_config *cfg); 87 struct tda18271_config *cfg);
diff --git a/drivers/media/dvb/frontends/tda827x.c b/drivers/media/common/tuners/tda827x.c
index d30d2c9094d9..d30d2c9094d9 100644
--- a/drivers/media/dvb/frontends/tda827x.c
+++ b/drivers/media/common/tuners/tda827x.c
diff --git a/drivers/media/dvb/frontends/tda827x.h b/drivers/media/common/tuners/tda827x.h
index b73c23570dab..7850a9a1dc8f 100644
--- a/drivers/media/dvb/frontends/tda827x.h
+++ b/drivers/media/common/tuners/tda827x.h
@@ -51,7 +51,7 @@ struct tda827x_config
51 * @param cfg optional callback function pointers. 51 * @param cfg optional callback function pointers.
52 * @return FE pointer on success, NULL on failure. 52 * @return FE pointer on success, NULL on failure.
53 */ 53 */
54#if defined(CONFIG_DVB_TDA827X) || (defined(CONFIG_DVB_TDA827X_MODULE) && defined(MODULE)) 54#if defined(CONFIG_MEDIA_TUNER_TDA827X) || (defined(CONFIG_MEDIA_TUNER_TDA827X_MODULE) && defined(MODULE))
55extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr, 55extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr,
56 struct i2c_adapter *i2c, 56 struct i2c_adapter *i2c,
57 struct tda827x_config *cfg); 57 struct tda827x_config *cfg);
@@ -64,6 +64,6 @@ static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe,
64 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 64 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
65 return NULL; 65 return NULL;
66} 66}
67#endif // CONFIG_DVB_TDA827X 67#endif // CONFIG_MEDIA_TUNER_TDA827X
68 68
69#endif // __DVB_TDA827X_H__ 69#endif // __DVB_TDA827X_H__
diff --git a/drivers/media/video/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 0ebb5b525e57..91204d3f282d 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -578,16 +578,16 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
578 578
579 if ((data == 0x83) || (data == 0x84)) { 579 if ((data == 0x83) || (data == 0x84)) {
580 priv->ver |= TDA18271; 580 priv->ver |= TDA18271;
581 tda18271_attach(fe, priv->tda827x_addr, 581 dvb_attach(tda18271_attach, fe, priv->tda827x_addr,
582 priv->i2c_props.adap, 582 priv->i2c_props.adap, &tda829x_tda18271_config);
583 &tda829x_tda18271_config);
584 } else { 583 } else {
585 if ((data & 0x3c) == 0) 584 if ((data & 0x3c) == 0)
586 priv->ver |= TDA8275; 585 priv->ver |= TDA8275;
587 else 586 else
588 priv->ver |= TDA8275A; 587 priv->ver |= TDA8275A;
589 588
590 tda827x_attach(fe, priv->tda827x_addr, priv->i2c_props.adap, &priv->cfg); 589 dvb_attach(tda827x_attach, fe, priv->tda827x_addr,
590 priv->i2c_props.adap, &priv->cfg);
591 priv->cfg.switch_addr = priv->i2c_props.addr; 591 priv->cfg.switch_addr = priv->i2c_props.addr;
592 } 592 }
593 if (fe->ops.tuner_ops.init) 593 if (fe->ops.tuner_ops.init)
diff --git a/drivers/media/video/tda8290.h b/drivers/media/common/tuners/tda8290.h
index d3bbf276a469..aa074f3f0c07 100644
--- a/drivers/media/video/tda8290.h
+++ b/drivers/media/common/tuners/tda8290.h
@@ -29,7 +29,7 @@ struct tda829x_config {
29#define TDA829X_DONT_PROBE 1 29#define TDA829X_DONT_PROBE 1
30}; 30};
31 31
32#if defined(CONFIG_TUNER_TDA8290) || (defined(CONFIG_TUNER_TDA8290_MODULE) && defined(MODULE)) 32#if defined(CONFIG_MEDIA_TUNER_TDA8290) || (defined(CONFIG_MEDIA_TUNER_TDA8290_MODULE) && defined(MODULE))
33extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr); 33extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr);
34 34
35extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, 35extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/video/tda9887.c b/drivers/media/common/tuners/tda9887.c
index a0545ba957b0..a0545ba957b0 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
diff --git a/drivers/media/video/tda9887.h b/drivers/media/common/tuners/tda9887.h
index be49dcbfc70e..acc419e8c4fc 100644
--- a/drivers/media/video/tda9887.h
+++ b/drivers/media/common/tuners/tda9887.h
@@ -21,7 +21,7 @@
21#include "dvb_frontend.h" 21#include "dvb_frontend.h"
22 22
23/* ------------------------------------------------------------------------ */ 23/* ------------------------------------------------------------------------ */
24#if defined(CONFIG_TUNER_TDA9887) || (defined(CONFIG_TUNER_TDA9887_MODULE) && defined(MODULE)) 24#if defined(CONFIG_MEDIA_TUNER_TDA9887) || (defined(CONFIG_MEDIA_TUNER_TDA9887_MODULE) && defined(MODULE))
25extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, 25extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
26 struct i2c_adapter *i2c_adap, 26 struct i2c_adapter *i2c_adap,
27 u8 i2c_addr); 27 u8 i2c_addr);
diff --git a/drivers/media/video/tea5761.c b/drivers/media/common/tuners/tea5761.c
index b93cdef9ac73..b93cdef9ac73 100644
--- a/drivers/media/video/tea5761.c
+++ b/drivers/media/common/tuners/tea5761.c
diff --git a/drivers/media/video/tea5761.h b/drivers/media/common/tuners/tea5761.h
index 8eb62722b988..2e2ff82c95a4 100644
--- a/drivers/media/video/tea5761.h
+++ b/drivers/media/common/tuners/tea5761.h
@@ -20,7 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include "dvb_frontend.h" 21#include "dvb_frontend.h"
22 22
23#if defined(CONFIG_TUNER_TEA5761) || (defined(CONFIG_TUNER_TEA5761_MODULE) && defined(MODULE)) 23#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
24extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); 24extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
25 25
26extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, 26extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/video/tea5767.c b/drivers/media/common/tuners/tea5767.c
index f6e7d7ad8424..f6e7d7ad8424 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/common/tuners/tea5767.c
diff --git a/drivers/media/video/tea5767.h b/drivers/media/common/tuners/tea5767.h
index 7b547c092e25..d30ab1b483de 100644
--- a/drivers/media/video/tea5767.h
+++ b/drivers/media/common/tuners/tea5767.h
@@ -39,7 +39,7 @@ struct tea5767_ctrl {
39 enum tea5767_xtal xtal_freq; 39 enum tea5767_xtal xtal_freq;
40}; 40};
41 41
42#if defined(CONFIG_TUNER_TEA5767) || (defined(CONFIG_TUNER_TEA5767_MODULE) && defined(MODULE)) 42#if defined(CONFIG_MEDIA_TUNER_TEA5767) || (defined(CONFIG_MEDIA_TUNER_TEA5767_MODULE) && defined(MODULE))
43extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr); 43extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
44 44
45extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, 45extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/video/tuner-i2c.h b/drivers/media/common/tuners/tuner-i2c.h
index 3ad6c8e0b04c..3ad6c8e0b04c 100644
--- a/drivers/media/video/tuner-i2c.h
+++ b/drivers/media/common/tuners/tuner-i2c.h
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index be8d903171b7..be8d903171b7 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
diff --git a/drivers/media/video/tuner-simple.h b/drivers/media/common/tuners/tuner-simple.h
index e46cf0121e03..381fa5d35a9b 100644
--- a/drivers/media/video/tuner-simple.h
+++ b/drivers/media/common/tuners/tuner-simple.h
@@ -20,7 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include "dvb_frontend.h" 21#include "dvb_frontend.h"
22 22
23#if defined(CONFIG_TUNER_SIMPLE) || (defined(CONFIG_TUNER_SIMPLE_MODULE) && defined(MODULE)) 23#if defined(CONFIG_MEDIA_TUNER_SIMPLE) || (defined(CONFIG_MEDIA_TUNER_SIMPLE_MODULE) && defined(MODULE))
24extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, 24extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
25 struct i2c_adapter *i2c_adap, 25 struct i2c_adapter *i2c_adap,
26 u8 i2c_addr, 26 u8 i2c_addr,
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 10dddca8b5d1..10dddca8b5d1 100644
--- a/drivers/media/video/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
diff --git a/drivers/media/video/tuner-xc2028-types.h b/drivers/media/common/tuners/tuner-xc2028-types.h
index 74dc46a71f64..74dc46a71f64 100644
--- a/drivers/media/video/tuner-xc2028-types.h
+++ b/drivers/media/common/tuners/tuner-xc2028-types.h
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index 9e9003cffc7f..9e9003cffc7f 100644
--- a/drivers/media/video/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
diff --git a/drivers/media/video/tuner-xc2028.h b/drivers/media/common/tuners/tuner-xc2028.h
index fc2f132a5541..216025cf5d4b 100644
--- a/drivers/media/video/tuner-xc2028.h
+++ b/drivers/media/common/tuners/tuner-xc2028.h
@@ -47,7 +47,7 @@ struct xc2028_config {
47#define XC2028_TUNER_RESET 0 47#define XC2028_TUNER_RESET 0
48#define XC2028_RESET_CLK 1 48#define XC2028_RESET_CLK 1
49 49
50#if defined(CONFIG_TUNER_XC2028) || (defined(CONFIG_TUNER_XC2028_MODULE) && defined(MODULE)) 50#if defined(CONFIG_MEDIA_TUNER_XC2028) || (defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
51extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, 51extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
52 struct xc2028_config *cfg); 52 struct xc2028_config *cfg);
53#else 53#else
diff --git a/drivers/media/dvb/frontends/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 43d35bdb221f..43d35bdb221f 100644
--- a/drivers/media/dvb/frontends/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
diff --git a/drivers/media/dvb/frontends/xc5000.h b/drivers/media/common/tuners/xc5000.h
index b890883a0cdc..0ee80f9d19b8 100644
--- a/drivers/media/dvb/frontends/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -45,8 +45,8 @@ struct xc5000_config {
45/* xc5000 callback command */ 45/* xc5000 callback command */
46#define XC5000_TUNER_RESET 0 46#define XC5000_TUNER_RESET 0
47 47
48#if defined(CONFIG_DVB_TUNER_XC5000) || \ 48#if defined(CONFIG_MEDIA_TUNER_XC5000) || \
49 (defined(CONFIG_DVB_TUNER_XC5000_MODULE) && defined(MODULE)) 49 (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
50extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, 50extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
51 struct i2c_adapter *i2c, 51 struct i2c_adapter *i2c,
52 struct xc5000_config *cfg); 52 struct xc5000_config *cfg);
@@ -58,6 +58,6 @@ static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
58 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 58 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
59 return NULL; 59 return NULL;
60} 60}
61#endif // CONFIG_DVB_TUNER_XC5000 61#endif // CONFIG_MEDIA_TUNER_XC5000
62 62
63#endif // __XC5000_H__ 63#endif // __XC5000_H__
diff --git a/drivers/media/dvb/frontends/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h
index 13b2d19341da..13b2d19341da 100644
--- a/drivers/media/dvb/frontends/xc5000_priv.h
+++ b/drivers/media/common/tuners/xc5000_priv.h
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 03ef88acd9b8..7b21b49f1945 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -1,9 +1,7 @@
1# 1#
2# Multimedia device configuration 2# DVB device configuration
3# 3#
4 4
5source "drivers/media/dvb/dvb-core/Kconfig"
6
7menuconfig DVB_CAPTURE_DRIVERS 5menuconfig DVB_CAPTURE_DRIVERS
8 bool "DVB/ATSC adapters" 6 bool "DVB/ATSC adapters"
9 depends on DVB_CORE 7 depends on DVB_CORE
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 6ec5afba1ca7..73dc2ee9b014 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -9,7 +9,7 @@ config DVB_B2C2_FLEXCOP
9 select DVB_STV0297 if !DVB_FE_CUSTOMISE 9 select DVB_STV0297 if !DVB_FE_CUSTOMISE
10 select DVB_BCM3510 if !DVB_FE_CUSTOMISE 10 select DVB_BCM3510 if !DVB_FE_CUSTOMISE
11 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 11 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
12 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 12 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
13 select DVB_S5H1420 if !DVB_FE_CUSTOMISE 13 select DVB_S5H1420 if !DVB_FE_CUSTOMISE
14 select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE 14 select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
15 select DVB_ISL6421 if !DVB_FE_CUSTOMISE 15 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index 870e2848c296..d9db066f9854 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -14,4 +14,4 @@ b2c2-flexcop-usb-objs = flexcop-usb.o
14obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o 14obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
15 15
16EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 16EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
17EXTRA_CFLAGS += -Idrivers/media/video/ 17EXTRA_CFLAGS += -Idrivers/media/common/tuners/
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 902c762e0b7f..d1239b8342f8 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -8,7 +8,7 @@ config DVB_BT8XX
8 select DVB_OR51211 if !DVB_FE_CUSTOMISE 8 select DVB_OR51211 if !DVB_FE_CUSTOMISE
9 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 9 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
10 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 10 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
11 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 11 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
12 select FW_LOADER 12 select FW_LOADER
13 help 13 help
14 Support for PCI cards based on the Bt8xx PCI bridge. Examples are 14 Support for PCI cards based on the Bt8xx PCI bridge. Examples are
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile
index 9d3e68b5d6eb..d98f1d49ffa8 100644
--- a/drivers/media/dvb/bt8xx/Makefile
+++ b/drivers/media/dvb/bt8xx/Makefile
@@ -3,4 +3,4 @@ obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
3EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 3EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
4EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 4EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
5EXTRA_CFLAGS += -Idrivers/media/video/bt8xx 5EXTRA_CFLAGS += -Idrivers/media/video/bt8xx
6EXTRA_CFLAGS += -Idrivers/media/video 6EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 75711bde23ad..a7637562e742 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1714,7 +1714,7 @@ static void dst_release(struct dvb_frontend *fe)
1714 struct dst_state *state = fe->demodulator_priv; 1714 struct dst_state *state = fe->demodulator_priv;
1715 if (state->dst_ca) { 1715 if (state->dst_ca) {
1716 dvb_unregister_device(state->dst_ca); 1716 dvb_unregister_device(state->dst_ca);
1717#ifdef CONFIG_DVB_CORE_ATTACH 1717#ifdef CONFIG_MEDIA_ATTACH
1718 symbol_put(dst_ca_attach); 1718 symbol_put(dst_ca_attach);
1719#endif 1719#endif
1720 } 1720 }
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig
deleted file mode 100644
index e3e6839f8073..000000000000
--- a/drivers/media/dvb/dvb-core/Kconfig
+++ /dev/null
@@ -1,34 +0,0 @@
1config DVB_CORE
2 tristate "DVB for Linux"
3 depends on NET && INET
4 select CRC32
5 help
6 Support Digital Video Broadcasting hardware. Enable this if you
7 own a DVB adapter and want to use it or if you compile Linux for
8 a digital SetTopBox.
9
10 DVB core utility functions for device handling, software fallbacks etc.
11 Say Y when you have a DVB card and want to use it. Say Y if your want
12 to build your drivers outside the kernel, but need the DVB core. All
13 in-kernel drivers will select this automatically if needed.
14
15 API specs and user tools are available from <http://www.linuxtv.org/>.
16
17 Please report problems regarding this driver to the LinuxDVB
18 mailing list.
19
20 If unsure say N.
21
22config DVB_CORE_ATTACH
23 bool "Load and attach frontend modules as needed"
24 depends on DVB_CORE
25 depends on MODULES
26 help
27 Remove the static dependency of DVB card drivers on all
28 frontend modules for all possible card variants. Instead,
29 allow the card drivers to only load the frontend modules
30 they require. This saves several KBytes of memory.
31
32 Note: You will need module-init-tools v3.2 or later for this feature.
33
34 If unsure say Y.
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 2dddd08c5445..8cbdb218952f 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1189,7 +1189,7 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
1189} 1189}
1190EXPORT_SYMBOL(dvb_unregister_frontend); 1190EXPORT_SYMBOL(dvb_unregister_frontend);
1191 1191
1192#ifdef CONFIG_DVB_CORE_ATTACH 1192#ifdef CONFIG_MEDIA_ATTACH
1193void dvb_frontend_detach(struct dvb_frontend* fe) 1193void dvb_frontend_detach(struct dvb_frontend* fe)
1194{ 1194{
1195 void *ptr; 1195 void *ptr;
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 5f9a737c6de1..89d12dc477a7 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -115,7 +115,7 @@ extern int dvb_usercopy(struct inode *inode, struct file *file,
115 unsigned int cmd, void *arg)); 115 unsigned int cmd, void *arg));
116 116
117/** generic DVB attach function. */ 117/** generic DVB attach function. */
118#ifdef CONFIG_DVB_CORE_ATTACH 118#ifdef CONFIG_MEDIA_ATTACH
119#define dvb_attach(FUNCTION, ARGS...) ({ \ 119#define dvb_attach(FUNCTION, ARGS...) ({ \
120 void *__r = NULL; \ 120 void *__r = NULL; \
121 typeof(&FUNCTION) __a = symbol_request(FUNCTION); \ 121 typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 3c8493d2026d..4c1cff9feb2e 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -25,7 +25,7 @@ config DVB_USB_A800
25 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" 25 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
26 depends on DVB_USB 26 depends on DVB_USB
27 select DVB_DIB3000MC 27 select DVB_DIB3000MC
28 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 28 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
29 select DVB_PLL if !DVB_FE_CUSTOMISE 29 select DVB_PLL if !DVB_FE_CUSTOMISE
30 help 30 help
31 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. 31 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
@@ -35,7 +35,7 @@ config DVB_USB_DIBUSB_MB
35 depends on DVB_USB 35 depends on DVB_USB
36 select DVB_PLL if !DVB_FE_CUSTOMISE 36 select DVB_PLL if !DVB_FE_CUSTOMISE
37 select DVB_DIB3000MB 37 select DVB_DIB3000MB
38 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 38 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
39 help 39 help
40 Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by 40 Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
41 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. 41 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
@@ -56,7 +56,7 @@ config DVB_USB_DIBUSB_MC
56 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" 56 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
57 depends on DVB_USB 57 depends on DVB_USB
58 select DVB_DIB3000MC 58 select DVB_DIB3000MC
59 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 59 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
60 help 60 help
61 Support for USB2.0 DVB-T receivers based on reference designs made by 61 Support for USB2.0 DVB-T receivers based on reference designs made by
62 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. 62 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
@@ -73,8 +73,8 @@ config DVB_USB_DIB0700
73 select DVB_DIB7000P 73 select DVB_DIB7000P
74 select DVB_DIB7000M 74 select DVB_DIB7000M
75 select DVB_DIB3000MC 75 select DVB_DIB3000MC
76 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 76 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
77 select DVB_TUNER_MT2266 if !DVB_FE_CUSTOMISE 77 select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE
78 select DVB_TUNER_DIB0070 78 select DVB_TUNER_DIB0070
79 help 79 help
80 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The 80 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
@@ -93,7 +93,7 @@ config DVB_USB_UMT_010
93 depends on DVB_USB 93 depends on DVB_USB
94 select DVB_PLL if !DVB_FE_CUSTOMISE 94 select DVB_PLL if !DVB_FE_CUSTOMISE
95 select DVB_DIB3000MC 95 select DVB_DIB3000MC
96 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 96 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
97 help 97 help
98 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. 98 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
99 99
@@ -105,7 +105,7 @@ config DVB_USB_CXUSB
105 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 105 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
106 select DVB_MT352 if !DVB_FE_CUSTOMISE 106 select DVB_MT352 if !DVB_FE_CUSTOMISE
107 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 107 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
108 select TUNER_SIMPLE if !DVB_FE_CUSTOMISE 108 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
109 help 109 help
110 Say Y here to support the Conexant USB2.0 hybrid reference design. 110 Say Y here to support the Conexant USB2.0 hybrid reference design.
111 Currently, only DVB and ATSC modes are supported, analog mode 111 Currently, only DVB and ATSC modes are supported, analog mode
@@ -118,7 +118,7 @@ config DVB_USB_M920X
118 tristate "Uli m920x DVB-T USB2.0 support" 118 tristate "Uli m920x DVB-T USB2.0 support"
119 depends on DVB_USB 119 depends on DVB_USB
120 select DVB_MT352 if !DVB_FE_CUSTOMISE 120 select DVB_MT352 if !DVB_FE_CUSTOMISE
121 select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE 121 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
122 help 122 help
123 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. 123 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
124 Currently, only devices with a product id of 124 Currently, only devices with a product id of
@@ -129,7 +129,7 @@ config DVB_USB_GL861
129 tristate "Genesys Logic GL861 USB2.0 support" 129 tristate "Genesys Logic GL861 USB2.0 support"
130 depends on DVB_USB 130 depends on DVB_USB
131 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 131 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
132 select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE 132 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
133 help 133 help
134 Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0 134 Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
135 receiver with USB ID 0db0:5581. 135 receiver with USB ID 0db0:5581.
@@ -138,7 +138,7 @@ config DVB_USB_AU6610
138 tristate "Alcor Micro AU6610 USB2.0 support" 138 tristate "Alcor Micro AU6610 USB2.0 support"
139 depends on DVB_USB 139 depends on DVB_USB
140 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 140 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
141 select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE 141 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
142 help 142 help
143 Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver. 143 Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
144 144
@@ -190,7 +190,7 @@ config DVB_USB_NOVA_T_USB2
190 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" 190 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
191 depends on DVB_USB 191 depends on DVB_USB
192 select DVB_DIB3000MC 192 select DVB_DIB3000MC
193 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 193 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
194 select DVB_PLL if !DVB_FE_CUSTOMISE 194 select DVB_PLL if !DVB_FE_CUSTOMISE
195 help 195 help
196 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. 196 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
@@ -227,8 +227,8 @@ config DVB_USB_OPERA1
227config DVB_USB_AF9005 227config DVB_USB_AF9005
228 tristate "Afatech AF9005 DVB-T USB1.1 support" 228 tristate "Afatech AF9005 DVB-T USB1.1 support"
229 depends on DVB_USB && EXPERIMENTAL 229 depends on DVB_USB && EXPERIMENTAL
230 select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE 230 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
231 select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE 231 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
232 help 232 help
233 Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver 233 Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
234 and the TerraTec Cinergy T USB XE (Rev.1) 234 and the TerraTec Cinergy T USB XE (Rev.1)
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 60a910052c16..c6511a6c0ab8 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -63,5 +63,5 @@ obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
63 63
64EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 64EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
65# due to tuner-xc3028 65# due to tuner-xc3028
66EXTRA_CFLAGS += -Idrivers/media/video 66EXTRA_CFLAGS += -Idrivers/media/common/tuners
67 67
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index f5fceb3cdb3c..6d2384605927 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -15,22 +15,36 @@ config DVB_FE_CUSTOMISE
15comment "DVB-S (satellite) frontends" 15comment "DVB-S (satellite) frontends"
16 depends on DVB_CORE 16 depends on DVB_CORE
17 17
18config DVB_STV0299 18config DVB_CX24110
19 tristate "ST STV0299 based" 19 tristate "Conexant CX24110 based"
20 depends on DVB_CORE && I2C 20 depends on DVB_CORE && I2C
21 default m if DVB_FE_CUSTOMISE 21 default m if DVB_FE_CUSTOMISE
22 help 22 help
23 A DVB-S tuner module. Say Y when you want to support this frontend. 23 A DVB-S tuner module. Say Y when you want to support this frontend.
24 24
25config DVB_CX24110 25config DVB_CX24123
26 tristate "Conexant CX24110 based" 26 tristate "Conexant CX24123 based"
27 depends on DVB_CORE && I2C 27 depends on DVB_CORE && I2C
28 default m if DVB_FE_CUSTOMISE 28 default m if DVB_FE_CUSTOMISE
29 help 29 help
30 A DVB-S tuner module. Say Y when you want to support this frontend. 30 A DVB-S tuner module. Say Y when you want to support this frontend.
31 31
32config DVB_CX24123 32config DVB_MT312
33 tristate "Conexant CX24123 based" 33 tristate "Zarlink VP310/MT312 based"
34 depends on DVB_CORE && I2C
35 default m if DVB_FE_CUSTOMISE
36 help
37 A DVB-S tuner module. Say Y when you want to support this frontend.
38
39config DVB_S5H1420
40 tristate "Samsung S5H1420 based"
41 depends on DVB_CORE && I2C
42 default m if DVB_FE_CUSTOMISE
43 help
44 A DVB-S tuner module. Say Y when you want to support this frontend.
45
46config DVB_STV0299
47 tristate "ST STV0299 based"
34 depends on DVB_CORE && I2C 48 depends on DVB_CORE && I2C
35 default m if DVB_FE_CUSTOMISE 49 default m if DVB_FE_CUSTOMISE
36 help 50 help
@@ -43,8 +57,8 @@ config DVB_TDA8083
43 help 57 help
44 A DVB-S tuner module. Say Y when you want to support this frontend. 58 A DVB-S tuner module. Say Y when you want to support this frontend.
45 59
46config DVB_MT312 60config DVB_TDA10086
47 tristate "Zarlink VP310/MT312 based" 61 tristate "Philips TDA10086 based"
48 depends on DVB_CORE && I2C 62 depends on DVB_CORE && I2C
49 default m if DVB_FE_CUSTOMISE 63 default m if DVB_FE_CUSTOMISE
50 help 64 help
@@ -57,19 +71,26 @@ config DVB_VES1X93
57 help 71 help
58 A DVB-S tuner module. Say Y when you want to support this frontend. 72 A DVB-S tuner module. Say Y when you want to support this frontend.
59 73
60config DVB_S5H1420 74config DVB_TUNER_ITD1000
61 tristate "Samsung S5H1420 based" 75 tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
62 depends on DVB_CORE && I2C 76 depends on DVB_CORE && I2C
63 default m if DVB_FE_CUSTOMISE 77 default m if DVB_FE_CUSTOMISE
64 help 78 help
65 A DVB-S tuner module. Say Y when you want to support this frontend. 79 A DVB-S tuner module. Say Y when you want to support this frontend.
66 80
67config DVB_TDA10086 81config DVB_TDA826X
68 tristate "Philips TDA10086 based" 82 tristate "Philips TDA826X silicon tuner"
69 depends on DVB_CORE && I2C 83 depends on DVB_CORE && I2C
70 default m if DVB_FE_CUSTOMISE 84 default m if DVB_FE_CUSTOMISE
71 help 85 help
72 A DVB-S tuner module. Say Y when you want to support this frontend. 86 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
87
88config DVB_TUA6100
89 tristate "Infineon TUA6100 PLL"
90 depends on DVB_CORE && I2C
91 default m if DVB_FE_CUSTOMISE
92 help
93 A DVB-S PLL chip.
73 94
74comment "DVB-T (terrestrial) frontends" 95comment "DVB-T (terrestrial) frontends"
75 depends on DVB_CORE 96 depends on DVB_CORE
@@ -315,7 +336,7 @@ config DVB_S5H1411
315 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 336 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
316 to support this frontend. 337 to support this frontend.
317 338
318comment "Tuners/PLL support" 339comment "Digital terrestrial only tuners/PLL"
319 depends on DVB_CORE 340 depends on DVB_CORE
320 341
321config DVB_PLL 342config DVB_PLL
@@ -326,55 +347,6 @@ config DVB_PLL
326 This module drives a number of tuners based on PLL chips with a 347 This module drives a number of tuners based on PLL chips with a
327 common I2C interface. Say Y when you want to support these tuners. 348 common I2C interface. Say Y when you want to support these tuners.
328 349
329config DVB_TDA826X
330 tristate "Philips TDA826X silicon tuner"
331 depends on DVB_CORE && I2C
332 default m if DVB_FE_CUSTOMISE
333 help
334 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
335
336config DVB_TDA827X
337 tristate "Philips TDA827X silicon tuner"
338 depends on DVB_CORE && I2C
339 default m if DVB_FE_CUSTOMISE
340 help
341 A DVB-T silicon tuner module. Say Y when you want to support this tuner.
342
343config DVB_TDA18271
344 tristate "NXP TDA18271 silicon tuner"
345 depends on I2C
346 default m if DVB_FE_CUSTOMISE
347 help
348 A silicon tuner module. Say Y when you want to support this tuner.
349
350config DVB_TUNER_QT1010
351 tristate "Quantek QT1010 silicon tuner"
352 depends on DVB_CORE && I2C
353 default m if DVB_FE_CUSTOMISE
354 help
355 A driver for the silicon tuner QT1010 from Quantek.
356
357config DVB_TUNER_MT2060
358 tristate "Microtune MT2060 silicon IF tuner"
359 depends on I2C
360 default m if DVB_FE_CUSTOMISE
361 help
362 A driver for the silicon IF tuner MT2060 from Microtune.
363
364config DVB_TUNER_MT2266
365 tristate "Microtune MT2266 silicon tuner"
366 depends on I2C
367 default m if DVB_FE_CUSTOMISE
368 help
369 A driver for the silicon baseband tuner MT2266 from Microtune.
370
371config DVB_TUNER_MT2131
372 tristate "Microtune MT2131 silicon tuner"
373 depends on I2C
374 default m if DVB_FE_CUSTOMISE
375 help
376 A driver for the silicon baseband tuner MT2131 from Microtune.
377
378config DVB_TUNER_DIB0070 350config DVB_TUNER_DIB0070
379 tristate "DiBcom DiB0070 silicon base-band tuner" 351 tristate "DiBcom DiB0070 silicon base-band tuner"
380 depends on I2C 352 depends on I2C
@@ -384,21 +356,7 @@ config DVB_TUNER_DIB0070
384 This device is only used inside a SiP called togther with a 356 This device is only used inside a SiP called togther with a
385 demodulator for now. 357 demodulator for now.
386 358
387config DVB_TUNER_XC5000 359comment "SEC control devices for DVB-S"
388 tristate "Xceive XC5000 silicon tuner"
389 depends on I2C
390 default m if DVB_FE_CUSTOMISE
391 help
392 A driver for the silicon tuner XC5000 from Xceive.
393 This device is only used inside a SiP called togther with a
394 demodulator for now.
395
396config DVB_TUNER_ITD1000
397 tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
398 depends on DVB_CORE && I2C
399 default m if DVB_FE_CUSTOMISE
400
401comment "Miscellaneous devices"
402 depends on DVB_CORE 360 depends on DVB_CORE
403 361
404config DVB_LNBP21 362config DVB_LNBP21
@@ -422,11 +380,4 @@ config DVB_ISL6421
422 help 380 help
423 An SEC control chip. 381 An SEC control chip.
424 382
425config DVB_TUA6100
426 tristate "TUA6100 PLL"
427 depends on DVB_CORE && I2C
428 default m if DVB_FE_CUSTOMISE
429 help
430 A DVBS PLL chip.
431
432endmenu 383endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 9747c73dc826..a89dc0fc4c6f 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -3,9 +3,7 @@
3# 3#
4 4
5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ 5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
6EXTRA_CFLAGS += -Idrivers/media/video/ 6EXTRA_CFLAGS += -Idrivers/media/common/tuners/
7
8tda18271-objs := tda18271-tables.o tda18271-common.o tda18271-fe.o
9 7
10obj-$(CONFIG_DVB_PLL) += dvb-pll.o 8obj-$(CONFIG_DVB_PLL) += dvb-pll.o
11obj-$(CONFIG_DVB_STV0299) += stv0299.o 9obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -42,16 +40,9 @@ obj-$(CONFIG_DVB_ISL6405) += isl6405.o
42obj-$(CONFIG_DVB_ISL6421) += isl6421.o 40obj-$(CONFIG_DVB_ISL6421) += isl6421.o
43obj-$(CONFIG_DVB_TDA10086) += tda10086.o 41obj-$(CONFIG_DVB_TDA10086) += tda10086.o
44obj-$(CONFIG_DVB_TDA826X) += tda826x.o 42obj-$(CONFIG_DVB_TDA826X) += tda826x.o
45obj-$(CONFIG_DVB_TDA827X) += tda827x.o
46obj-$(CONFIG_DVB_TDA18271) += tda18271.o
47obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
48obj-$(CONFIG_DVB_TUNER_MT2266) += mt2266.o
49obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o 43obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
50obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
51obj-$(CONFIG_DVB_TUA6100) += tua6100.o 44obj-$(CONFIG_DVB_TUA6100) += tua6100.o
52obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o
53obj-$(CONFIG_DVB_S5H1409) += s5h1409.o 45obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
54obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o
55obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o 46obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
56obj-$(CONFIG_DVB_AU8522) += au8522.o 47obj-$(CONFIG_DVB_AU8522) += au8522.o
57obj-$(CONFIG_DVB_TDA10048) += tda10048.o 48obj-$(CONFIG_DVB_TDA10048) += tda10048.o
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 281e1cb2edc6..720ed9ff7c5f 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -481,7 +481,7 @@ static void s5h1420_setsymbolrate(struct s5h1420_state* state,
481 val *= 2; 481 val *= 2;
482 do_div(val, (state->fclk / 1000)); 482 do_div(val, (state->fclk / 1000));
483 483
484 dprintk("symbol rate register: %06llx\n", val); 484 dprintk("symbol rate register: %06llx\n", (unsigned long long)val);
485 485
486 v = s5h1420_readreg(state, Loop01); 486 v = s5h1420_readreg(state, Loop01);
487 s5h1420_writereg(state, Loop01, v & 0x7f); 487 s5h1420_writereg(state, Loop01, v & 0x7f);
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/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/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/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