aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-27 21:22:13 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-27 21:22:13 -0400
commit12e56b601f66a415f88e7d60f6b6707a19c430c9 (patch)
treec294adb1c5c1f80bbb2de82e6e41da97b3f5800f
parentca6f8792bd5281ebaf04bf23a43ed486e5e453a9 (diff)
parentc78059f0a948404fb515db6be4bca5ec93eecd2a (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (26 commits) V4L/DVB (4263): Fix warning when compiling on 64 bit machines V4L/DVB (4261): Included required header for in-kernel compilation V4L/DVB (4260): Stradis.c: make 2 functions static V4L/DVB (4259): Pass an explicit log prefix to cx2341x_log_status V4L/DVB (4257): Fix 64-bit compile warnings. V4L/DVB (4255): Tda9887 default TOP value is 0x10 V4L/DVB (4254): Remove obsoleted tuner_debug option. V4L/DVB (4253): IVTV VBI format description too long. V4L/DVB (4252): Remove duplicate 'tda9887' in info messages. V4L/DVB (4245): Reduce the amount of pvrusb2-sourced noise going into the system log V4L/DVB (4244): Implement use of cx2341x module in pvrusb2 driver V4L/DVB (4243): Exploit new V4L control features in pvrusb2 V4L/DVB (4242): Don't suspend encoder when changing its attributes (in pvrusb2) V4L/DVB (4241): Fix faulty encoder error recovery in pvrusb2 V4L/DVB (4240): Various V4L control enhancements in pvrusb2 V4L/DVB (4239): Handle boolean controls in pvrusb2 V4L/DVB (4238): Make sure flags field is initialized when quering a control in pvrusb2 V4L/DVB (4237): Move LOG_STATUS bracketing to a different part of the pvrusb2 driver V4L/DVB (4236): Rearrange things in pvrusb2 driver in preparation for using cx2341x module V4L/DVB (4235): Increase the maximum number of controls that pvrusb2-sysfs.c can handle. ...
-rw-r--r--Documentation/video4linux/README.pvrusb2212
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/Makefile1
-rw-r--r--drivers/media/video/cx2341x.c40
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c13
-rw-r--r--drivers/media/video/pvrusb2/Kconfig62
-rw-r--r--drivers/media/video/pvrusb2/Makefile18
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c204
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.h40
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.c230
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.h92
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.c593
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.h123
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c279
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h53
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debug.h67
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c478
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.h53
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-demod.c126
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-demod.h38
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-eeprom.c164
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-eeprom.h40
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c418
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.h42
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h384
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c3120
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h335
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c115
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c232
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h47
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c937
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.h96
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-io.c695
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-io.h102
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ioread.c513
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ioread.h50
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c172
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.c408
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.h60
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c865
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.h47
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-tuner.c122
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-tuner.h38
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-util.h63
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c1126
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.h40
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c253
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.h52
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.c170
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.h53
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2.h43
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c4
-rw-r--r--drivers/media/video/stradis.c4
-rw-r--r--drivers/media/video/tda9887.c31
-rw-r--r--drivers/media/video/tuner-core.c8
-rw-r--r--drivers/media/video/v4l2-common.c2
-rw-r--r--include/media/cx2341x.h4
57 files changed, 13528 insertions, 51 deletions
diff --git a/Documentation/video4linux/README.pvrusb2 b/Documentation/video4linux/README.pvrusb2
new file mode 100644
index 000000000000..c73a32c34528
--- /dev/null
+++ b/Documentation/video4linux/README.pvrusb2
@@ -0,0 +1,212 @@
1
2$Id$
3Mike Isely <isely@pobox.com>
4
5 pvrusb2 driver
6
7Background:
8
9 This driver is intended for the "Hauppauge WinTV PVR USB 2.0", which
10 is a USB 2.0 hosted TV Tuner. This driver is a work in progress.
11 Its history started with the reverse-engineering effort by Björn
12 Danielsson <pvrusb2@dax.nu> whose web page can be found here:
13
14 http://pvrusb2.dax.nu/
15
16 From there Aurelien Alleaume <slts@free.fr> began an effort to
17 create a video4linux compatible driver. I began with Aurelien's
18 last known snapshot and evolved the driver to the state it is in
19 here.
20
21 More information on this driver can be found at:
22
23 http://www.isely.net/pvrusb2.html
24
25
26 This driver has a strong separation of layers. They are very
27 roughly:
28
29 1a. Low level wire-protocol implementation with the device.
30
31 1b. I2C adaptor implementation and corresponding I2C client drivers
32 implemented elsewhere in V4L.
33
34 1c. High level hardware driver implementation which coordinates all
35 activities that ensure correct operation of the device.
36
37 2. A "context" layer which manages instancing of driver, setup,
38 tear-down, arbitration, and interaction with high level
39 interfaces appropriately as devices are hotplugged in the
40 system.
41
42 3. High level interfaces which glue the driver to various published
43 Linux APIs (V4L, sysfs, maybe DVB in the future).
44
45 The most important shearing layer is between the top 2 layers. A
46 lot of work went into the driver to ensure that any kind of
47 conceivable API can be laid on top of the core driver. (Yes, the
48 driver internally leverages V4L to do its work but that really has
49 nothing to do with the API published by the driver to the outside
50 world.) The architecture allows for different APIs to
51 simultaneously access the driver. I have a strong sense of fairness
52 about APIs and also feel that it is a good design principle to keep
53 implementation and interface isolated from each other. Thus while
54 right now the V4L high level interface is the most complete, the
55 sysfs high level interface will work equally well for similar
56 functions, and there's no reason I see right now why it shouldn't be
57 possible to produce a DVB high level interface that can sit right
58 alongside V4L.
59
60 NOTE: Complete documentation on the pvrusb2 driver is contained in
61 the html files within the doc directory; these are exactly the same
62 as what is on the web site at the time. Browse those files
63 (especially the FAQ) before asking questions.
64
65
66Building
67
68 To build these modules essentially amounts to just running "Make",
69 but you need the kernel source tree nearby and you will likely also
70 want to set a few controlling environment variables first in order
71 to link things up with that source tree. Please see the Makefile
72 here for comments that explain how to do that.
73
74
75Source file list / functional overview:
76
77 (Note: The term "module" used below generally refers to loosely
78 defined functional units within the pvrusb2 driver and bears no
79 relation to the Linux kernel's concept of a loadable module.)
80
81 pvrusb2-audio.[ch] - This is glue logic that resides between this
82 driver and the msp3400.ko I2C client driver (which is found
83 elsewhere in V4L).
84
85 pvrusb2-context.[ch] - This module implements the context for an
86 instance of the driver. Everything else eventually ties back to
87 or is otherwise instanced within the data structures implemented
88 here. Hotplugging is ultimately coordinated here. All high level
89 interfaces tie into the driver through this module. This module
90 helps arbitrate each interface's access to the actual driver core,
91 and is designed to allow concurrent access through multiple
92 instances of multiple interfaces (thus you can for example change
93 the tuner's frequency through sysfs while simultaneously streaming
94 video through V4L out to an instance of mplayer).
95
96 pvrusb2-debug.h - This header defines a printk() wrapper and a mask
97 of debugging bit definitions for the various kinds of debug
98 messages that can be enabled within the driver.
99
100 pvrusb2-debugifc.[ch] - This module implements a crude command line
101 oriented debug interface into the driver. Aside from being part
102 of the process for implementing manual firmware extraction (see
103 the pvrusb2 web site mentioned earlier), probably I'm the only one
104 who has ever used this. It is mainly a debugging aid.
105
106 pvrusb2-eeprom.[ch] - This is glue logic that resides between this
107 driver the tveeprom.ko module, which is itself implemented
108 elsewhere in V4L.
109
110 pvrusb2-encoder.[ch] - This module implements all protocol needed to
111 interact with the Conexant mpeg2 encoder chip within the pvrusb2
112 device. It is a crude echo of corresponding logic in ivtv,
113 however the design goals (strict isolation) and physical layer
114 (proxy through USB instead of PCI) are enough different that this
115 implementation had to be completely different.
116
117 pvrusb2-hdw-internal.h - This header defines the core data structure
118 in the driver used to track ALL internal state related to control
119 of the hardware. Nobody outside of the core hardware-handling
120 modules should have any business using this header. All external
121 access to the driver should be through one of the high level
122 interfaces (e.g. V4L, sysfs, etc), and in fact even those high
123 level interfaces are restricted to the API defined in
124 pvrusb2-hdw.h and NOT this header.
125
126 pvrusb2-hdw.h - This header defines the full internal API for
127 controlling the hardware. High level interfaces (e.g. V4L, sysfs)
128 will work through here.
129
130 pvrusb2-hdw.c - This module implements all the various bits of logic
131 that handle overall control of a specific pvrusb2 device.
132 (Policy, instantiation, and arbitration of pvrusb2 devices fall
133 within the jurisdiction of pvrusb-context not here).
134
135 pvrusb2-i2c-chips-*.c - These modules implement the glue logic to
136 tie together and configure various I2C modules as they attach to
137 the I2C bus. There are two versions of this file. The "v4l2"
138 version is intended to be used in-tree alongside V4L, where we
139 implement just the logic that makes sense for a pure V4L
140 environment. The "all" version is intended for use outside of
141 V4L, where we might encounter other possibly "challenging" modules
142 from ivtv or older kernel snapshots (or even the support modules
143 in the standalone snapshot).
144
145 pvrusb2-i2c-cmd-v4l1.[ch] - This module implements generic V4L1
146 compatible commands to the I2C modules. It is here where state
147 changes inside the pvrusb2 driver are translated into V4L1
148 commands that are in turn send to the various I2C modules.
149
150 pvrusb2-i2c-cmd-v4l2.[ch] - This module implements generic V4L2
151 compatible commands to the I2C modules. It is here where state
152 changes inside the pvrusb2 driver are translated into V4L2
153 commands that are in turn send to the various I2C modules.
154
155 pvrusb2-i2c-core.[ch] - This module provides an implementation of a
156 kernel-friendly I2C adaptor driver, through which other external
157 I2C client drivers (e.g. msp3400, tuner, lirc) may connect and
158 operate corresponding chips within the the pvrusb2 device. It is
159 through here that other V4L modules can reach into this driver to
160 operate specific pieces (and those modules are in turn driven by
161 glue logic which is coordinated by pvrusb2-hdw, doled out by
162 pvrusb2-context, and then ultimately made available to users
163 through one of the high level interfaces).
164
165 pvrusb2-io.[ch] - This module implements a very low level ring of
166 transfer buffers, required in order to stream data from the
167 device. This module is *very* low level. It only operates the
168 buffers and makes no attempt to define any policy or mechanism for
169 how such buffers might be used.
170
171 pvrusb2-ioread.[ch] - This module layers on top of pvrusb2-io.[ch]
172 to provide a streaming API usable by a read() system call style of
173 I/O. Right now this is the only layer on top of pvrusb2-io.[ch],
174 however the underlying architecture here was intended to allow for
175 other styles of I/O to be implemented with additonal modules, like
176 mmap()'ed buffers or something even more exotic.
177
178 pvrusb2-main.c - This is the top level of the driver. Module level
179 and USB core entry points are here. This is our "main".
180
181 pvrusb2-sysfs.[ch] - This is the high level interface which ties the
182 pvrusb2 driver into sysfs. Through this interface you can do
183 everything with the driver except actually stream data.
184
185 pvrusb2-tuner.[ch] - This is glue logic that resides between this
186 driver and the tuner.ko I2C client driver (which is found
187 elsewhere in V4L).
188
189 pvrusb2-util.h - This header defines some common macros used
190 throughout the driver. These macros are not really specific to
191 the driver, but they had to go somewhere.
192
193 pvrusb2-v4l2.[ch] - This is the high level interface which ties the
194 pvrusb2 driver into video4linux. It is through here that V4L
195 applications can open and operate the driver in the usual V4L
196 ways. Note that **ALL** V4L functionality is published only
197 through here and nowhere else.
198
199 pvrusb2-video-*.[ch] - This is glue logic that resides between this
200 driver and the saa711x.ko I2C client driver (which is found
201 elsewhere in V4L). Note that saa711x.ko used to be known as
202 saa7115.ko in ivtv. There are two versions of this; one is
203 selected depending on the particular saa711[5x].ko that is found.
204
205 pvrusb2.h - This header contains compile time tunable parameters
206 (and at the moment the driver has very little that needs to be
207 tuned).
208
209
210 -Mike Isely
211 isely@pobox.com
212
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index e4290491fa9e..6d532f170ce5 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -445,6 +445,8 @@ endmenu # encoder / decoder chips
445menu "V4L USB devices" 445menu "V4L USB devices"
446 depends on USB && VIDEO_DEV 446 depends on USB && VIDEO_DEV
447 447
448source "drivers/media/video/pvrusb2/Kconfig"
449
448source "drivers/media/video/em28xx/Kconfig" 450source "drivers/media/video/em28xx/Kconfig"
449 451
450config USB_DSBR 452config USB_DSBR
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 6c401b46398a..353d61cfac1b 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/
47obj-$(CONFIG_VIDEO_CX88) += cx88/ 47obj-$(CONFIG_VIDEO_CX88) += cx88/
48obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ 48obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
49obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o 49obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o
50obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
50obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o 51obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
51obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o 52obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
52obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o 53obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index 01b22eab5725..65f00fc08fa9 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -601,7 +601,7 @@ static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
601} 601}
602 602
603int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, 603int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
604 struct v4l2_ext_controls *ctrls, int cmd) 604 struct v4l2_ext_controls *ctrls, unsigned int cmd)
605{ 605{
606 int err = 0; 606 int err = 0;
607 int i; 607 int i;
@@ -847,22 +847,22 @@ invalid:
847 return "<invalid>"; 847 return "<invalid>";
848} 848}
849 849
850void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id) 850void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
851{ 851{
852 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; 852 int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
853 853
854 /* Stream */ 854 /* Stream */
855 printk(KERN_INFO "cx2341x-%d: Stream: %s\n", 855 printk(KERN_INFO "%s: Stream: %s\n",
856 card_id, 856 prefix,
857 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE)); 857 cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
858 858
859 /* Video */ 859 /* Video */
860 printk(KERN_INFO "cx2341x-%d: Video: %dx%d, %d fps\n", 860 printk(KERN_INFO "%s: Video: %dx%d, %d fps\n",
861 card_id, 861 prefix,
862 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1), 862 p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
863 p->is_50hz ? 25 : 30); 863 p->is_50hz ? 25 : 30);
864 printk(KERN_INFO "cx2341x-%d: Video: %s, %s, %s, %d", 864 printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
865 card_id, 865 prefix,
866 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING), 866 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
867 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT), 867 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
868 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE), 868 cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
@@ -871,19 +871,19 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id)
871 printk(", Peak %d", p->video_bitrate_peak); 871 printk(", Peak %d", p->video_bitrate_peak);
872 } 872 }
873 printk("\n"); 873 printk("\n");
874 printk(KERN_INFO "cx2341x-%d: Video: GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n", 874 printk(KERN_INFO "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n",
875 card_id, 875 prefix,
876 p->video_gop_size, p->video_b_frames, 876 p->video_gop_size, p->video_b_frames,
877 p->video_gop_closure ? "" : "No ", 877 p->video_gop_closure ? "" : "No ",
878 p->video_pulldown ? "" : "No "); 878 p->video_pulldown ? "" : "No ");
879 if (p->video_temporal_decimation) { 879 if (p->video_temporal_decimation) {
880 printk(KERN_INFO "cx2341x-%d: Video: Temporal Decimation %d\n", 880 printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
881 card_id, p->video_temporal_decimation); 881 prefix, p->video_temporal_decimation);
882 } 882 }
883 883
884 /* Audio */ 884 /* Audio */
885 printk(KERN_INFO "cx2341x-%d: Audio: %s, %s, %s, %s", 885 printk(KERN_INFO "%s: Audio: %s, %s, %s, %s",
886 card_id, 886 prefix,
887 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ), 887 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
888 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING), 888 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
889 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE), 889 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
@@ -897,18 +897,18 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id)
897 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC)); 897 cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
898 898
899 /* Encoding filters */ 899 /* Encoding filters */
900 printk(KERN_INFO "cx2341x-%d: Spatial Filter: %s, Luma %s, Chroma %s, %d\n", 900 printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
901 card_id, 901 prefix,
902 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE), 902 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
903 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE), 903 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
904 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), 904 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
905 p->video_spatial_filter); 905 p->video_spatial_filter);
906 printk(KERN_INFO "cx2341x-%d: Temporal Filter: %s, %d\n", 906 printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
907 card_id, 907 prefix,
908 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), 908 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
909 p->video_temporal_filter); 909 p->video_temporal_filter);
910 printk(KERN_INFO "cx2341x-%d: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", 910 printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
911 card_id, 911 prefix,
912 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE), 912 cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
913 p->video_luma_median_filter_bottom, 913 p->video_luma_median_filter_bottom,
914 p->video_luma_median_filter_top, 914 p->video_luma_median_filter_top,
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 78df66671ea2..4ff81582ec56 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -853,6 +853,19 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
853 fh->mpegq.field); 853 fh->mpegq.field);
854 return 0; 854 return 0;
855 } 855 }
856 case VIDIOC_LOG_STATUS:
857 {
858 char name[32 + 2];
859
860 snprintf(name, sizeof(name), "%s/2", core->name);
861 printk("%s/2: ============ START LOG STATUS ============\n",
862 core->name);
863 cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, 0);
864 cx2341x_log_status(&dev->params, name);
865 printk("%s/2: ============= END LOG STATUS =============\n",
866 core->name);
867 return 0;
868 }
856 869
857 default: 870 default:
858 return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); 871 return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl);
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
new file mode 100644
index 000000000000..7e727fe14b32
--- /dev/null
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -0,0 +1,62 @@
1config VIDEO_PVRUSB2
2 tristate "Hauppauge WinTV-PVR USB2 support"
3 depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL
4 select FW_LOADER
5 select VIDEO_TUNER
6 select VIDEO_TVEEPROM
7 select VIDEO_CX2341X
8 select VIDEO_SAA711X
9 select VIDEO_MSP3400
10 ---help---
11 This is a video4linux driver for Conexant 23416 based
12 usb2 personal video recorder devices.
13
14 To compile this driver as a module, choose M here: the
15 module will be called pvrusb2
16
17config VIDEO_PVRUSB2_24XXX
18 bool "Hauppauge WinTV-PVR USB2 support for 24xxx model series"
19 depends on VIDEO_PVRUSB2 && EXPERIMENTAL
20 select VIDEO_CX25840
21 select VIDEO_WM8775
22 ---help---
23 This option enables inclusion of additional logic to operate
24 newer WinTV-PVR USB2 devices whose model number is of the
25 form "24xxx" (leading prefix of "24" followed by 3 digits).
26 To see if you may need this option, examine the white
27 sticker on the underside of your device. Enabling this
28 option will not harm support for older devices, however it
29 is a separate option because of the experimental nature of
30 this new feature.
31
32 If you are in doubt, say N.
33
34 Note: This feature is _very_ experimental. You have been
35 warned.
36
37config VIDEO_PVRUSB2_SYSFS
38 bool "pvrusb2 sysfs support (EXPERIMENTAL)"
39 default y
40 depends on VIDEO_PVRUSB2 && SYSFS && EXPERIMENTAL
41 ---help---
42 This option enables the operation of a sysfs based
43 interface for query and control of the pvrusb2 driver.
44
45 This is not generally needed for v4l applications,
46 although certain applications are optimized to take
47 advantage of this feature.
48
49 If you are in doubt, say Y.
50
51 Note: This feature is experimental and subject to change.
52
53config VIDEO_PVRUSB2_DEBUGIFC
54 bool "pvrusb2 debug interface"
55 depends on VIDEO_PVRUSB2_SYSFS
56 ---help---
57 This option enables the inclusion of a debug interface
58 in the pvrusb2 driver, hosted through sysfs.
59
60 You do not need to select this option unless you plan
61 on debugging the driver or performing a manual firmware
62 extraction.
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
new file mode 100644
index 000000000000..fed603ad0a67
--- /dev/null
+++ b/drivers/media/video/pvrusb2/Makefile
@@ -0,0 +1,18 @@
1obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
2obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
3
4obj-pvrusb2-24xxx-$(CONFIG_VIDEO_PVRUSB2_24XXX) := \
5 pvrusb2-cx2584x-v4l.o \
6 pvrusb2-wm8775.o
7
8pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
9 pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
10 pvrusb2-encoder.o pvrusb2-video-v4l.o \
11 pvrusb2-eeprom.o pvrusb2-tuner.o pvrusb2-demod.o \
12 pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
13 pvrusb2-ctrl.o pvrusb2-std.o \
14 pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
15 $(obj-pvrusb2-24xxx-y) \
16 $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
17
18obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
new file mode 100644
index 000000000000..313d2dcf9e4b
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -0,0 +1,204 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include "pvrusb2-audio.h"
24#include "pvrusb2-hdw-internal.h"
25#include "pvrusb2-debug.h"
26#include <linux/videodev2.h>
27#include <media/msp3400.h>
28#include <media/v4l2-common.h>
29
30struct pvr2_msp3400_handler {
31 struct pvr2_hdw *hdw;
32 struct pvr2_i2c_client *client;
33 struct pvr2_i2c_handler i2c_handler;
34 struct pvr2_audio_stat astat;
35 unsigned long stale_mask;
36};
37
38
39/* This function selects the correct audio input source */
40static void set_stereo(struct pvr2_msp3400_handler *ctxt)
41{
42 struct pvr2_hdw *hdw = ctxt->hdw;
43 struct v4l2_routing route;
44
45 pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo");
46
47 if (hdw->input_val == PVR2_CVAL_INPUT_TV) {
48 struct v4l2_tuner vt;
49 memset(&vt,0,sizeof(vt));
50 vt.audmode = hdw->audiomode_val;
51 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_TUNER,&vt);
52 }
53
54 route.input = MSP_INPUT_DEFAULT;
55 route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
56 switch (hdw->input_val) {
57 case PVR2_CVAL_INPUT_TV:
58 break;
59 case PVR2_CVAL_INPUT_RADIO:
60 /* Assume that msp34xx also handle FM decoding, in which case
61 we're still using the tuner. */
62 /* HV: actually it is more likely to be the SCART2 input if
63 the ivtv experience is any indication. */
64 route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1,
65 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
66 break;
67 case PVR2_CVAL_INPUT_SVIDEO:
68 case PVR2_CVAL_INPUT_COMPOSITE:
69 /* SCART 1 input */
70 route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
71 MSP_DSP_IN_SCART, MSP_DSP_IN_SCART);
72 break;
73 }
74 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
75}
76
77
78static int check_stereo(struct pvr2_msp3400_handler *ctxt)
79{
80 struct pvr2_hdw *hdw = ctxt->hdw;
81 return (hdw->input_dirty ||
82 hdw->audiomode_dirty);
83}
84
85
86struct pvr2_msp3400_ops {
87 void (*update)(struct pvr2_msp3400_handler *);
88 int (*check)(struct pvr2_msp3400_handler *);
89};
90
91
92static const struct pvr2_msp3400_ops msp3400_ops[] = {
93 { .update = set_stereo, .check = check_stereo},
94};
95
96
97static int msp3400_check(struct pvr2_msp3400_handler *ctxt)
98{
99 unsigned long msk;
100 unsigned int idx;
101
102 for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]);
103 idx++) {
104 msk = 1 << idx;
105 if (ctxt->stale_mask & msk) continue;
106 if (msp3400_ops[idx].check(ctxt)) {
107 ctxt->stale_mask |= msk;
108 }
109 }
110 return ctxt->stale_mask != 0;
111}
112
113
114static void msp3400_update(struct pvr2_msp3400_handler *ctxt)
115{
116 unsigned long msk;
117 unsigned int idx;
118
119 for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]);
120 idx++) {
121 msk = 1 << idx;
122 if (!(ctxt->stale_mask & msk)) continue;
123 ctxt->stale_mask &= ~msk;
124 msp3400_ops[idx].update(ctxt);
125 }
126}
127
128
129/* This reads back the current signal type */
130static int get_audio_status(struct pvr2_msp3400_handler *ctxt)
131{
132 struct v4l2_tuner vt;
133 int stat;
134
135 memset(&vt,0,sizeof(vt));
136 stat = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
137 if (stat < 0) return stat;
138
139 ctxt->hdw->flag_stereo = (vt.audmode & V4L2_TUNER_MODE_STEREO) != 0;
140 ctxt->hdw->flag_bilingual =
141 (vt.audmode & V4L2_TUNER_MODE_LANG2) != 0;
142 return 0;
143}
144
145
146static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt)
147{
148 ctxt->client->handler = 0;
149 ctxt->hdw->audio_stat = 0;
150 kfree(ctxt);
151}
152
153
154static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt,
155 char *buf,unsigned int cnt)
156{
157 return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2");
158}
159
160
161const static struct pvr2_i2c_handler_functions msp3400_funcs = {
162 .detach = (void (*)(void *))pvr2_msp3400_detach,
163 .check = (int (*)(void *))msp3400_check,
164 .update = (void (*)(void *))msp3400_update,
165 .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe,
166};
167
168
169int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
170{
171 struct pvr2_msp3400_handler *ctxt;
172 if (hdw->audio_stat) return 0;
173 if (cp->handler) return 0;
174
175 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
176 if (!ctxt) return 0;
177 memset(ctxt,0,sizeof(*ctxt));
178
179 ctxt->i2c_handler.func_data = ctxt;
180 ctxt->i2c_handler.func_table = &msp3400_funcs;
181 ctxt->client = cp;
182 ctxt->hdw = hdw;
183 ctxt->astat.ctxt = ctxt;
184 ctxt->astat.status = (int (*)(void *))get_audio_status;
185 ctxt->astat.detach = (void (*)(void *))pvr2_msp3400_detach;
186 ctxt->stale_mask = (1 << (sizeof(msp3400_ops)/
187 sizeof(msp3400_ops[0]))) - 1;
188 cp->handler = &ctxt->i2c_handler;
189 hdw->audio_stat = &ctxt->astat;
190 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up",
191 cp->client->addr);
192 return !0;
193}
194
195
196/*
197 Stuff for Emacs to see, in order to encourage consistent editing style:
198 *** Local Variables: ***
199 *** mode: c ***
200 *** fill-column: 70 ***
201 *** tab-width: 8 ***
202 *** c-basic-offset: 8 ***
203 *** End: ***
204 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h
new file mode 100644
index 000000000000..536339b68843
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.h
@@ -0,0 +1,40 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef __PVRUSB2_AUDIO_H
24#define __PVRUSB2_AUDIO_H
25
26#include "pvrusb2-i2c-core.h"
27
28int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
29
30#endif /* __PVRUSB2_AUDIO_H */
31
32/*
33 Stuff for Emacs to see, in order to encourage consistent editing style:
34 *** Local Variables: ***
35 *** mode: c ***
36 *** fill-column: 70 ***
37 *** tab-width: 8 ***
38 *** c-basic-offset: 8 ***
39 *** End: ***
40 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c
new file mode 100644
index 000000000000..40dc59871a45
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.c
@@ -0,0 +1,230 @@
1/*
2 * $Id$
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.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
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include "pvrusb2-context.h"
22#include "pvrusb2-io.h"
23#include "pvrusb2-ioread.h"
24#include "pvrusb2-hdw.h"
25#include "pvrusb2-debug.h"
26#include <linux/errno.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include <asm/semaphore.h>
30
31
32static void pvr2_context_destroy(struct pvr2_context *mp)
33{
34 if (mp->hdw) pvr2_hdw_destroy(mp->hdw);
35 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp);
36 flush_workqueue(mp->workqueue);
37 destroy_workqueue(mp->workqueue);
38 kfree(mp);
39}
40
41
42static void pvr2_context_trigger_poll(struct pvr2_context *mp)
43{
44 queue_work(mp->workqueue,&mp->workpoll);
45}
46
47
48static void pvr2_context_poll(struct pvr2_context *mp)
49{
50 pvr2_context_enter(mp); do {
51 pvr2_hdw_poll(mp->hdw);
52 } while (0); pvr2_context_exit(mp);
53}
54
55
56static void pvr2_context_setup(struct pvr2_context *mp)
57{
58 pvr2_context_enter(mp); do {
59 if (!pvr2_hdw_dev_ok(mp->hdw)) break;
60 pvr2_hdw_setup(mp->hdw);
61 pvr2_hdw_setup_poll_trigger(
62 mp->hdw,
63 (void (*)(void *))pvr2_context_trigger_poll,
64 mp);
65 if (!pvr2_hdw_dev_ok(mp->hdw)) break;
66 if (!pvr2_hdw_init_ok(mp->hdw)) break;
67 mp->video_stream.stream = pvr2_hdw_get_video_stream(mp->hdw);
68 if (mp->setup_func) {
69 mp->setup_func(mp);
70 }
71 } while (0); pvr2_context_exit(mp);
72}
73
74
75struct pvr2_context *pvr2_context_create(
76 struct usb_interface *intf,
77 const struct usb_device_id *devid,
78 void (*setup_func)(struct pvr2_context *))
79{
80 struct pvr2_context *mp = 0;
81 mp = kmalloc(sizeof(*mp),GFP_KERNEL);
82 if (!mp) goto done;
83 memset(mp,0,sizeof(*mp));
84 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_main id=%p",mp);
85 mp->setup_func = setup_func;
86 mutex_init(&mp->mutex);
87 mp->hdw = pvr2_hdw_create(intf,devid);
88 if (!mp->hdw) {
89 pvr2_context_destroy(mp);
90 mp = 0;
91 goto done;
92 }
93
94 mp->workqueue = create_singlethread_workqueue("pvrusb2");
95 INIT_WORK(&mp->workinit,(void (*)(void*))pvr2_context_setup,mp);
96 INIT_WORK(&mp->workpoll,(void (*)(void*))pvr2_context_poll,mp);
97 queue_work(mp->workqueue,&mp->workinit);
98 done:
99 return mp;
100}
101
102
103void pvr2_context_enter(struct pvr2_context *mp)
104{
105 mutex_lock(&mp->mutex);
106 pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_enter(id=%p)",mp);
107}
108
109
110void pvr2_context_exit(struct pvr2_context *mp)
111{
112 int destroy_flag = 0;
113 if (!(mp->mc_first || !mp->disconnect_flag)) {
114 destroy_flag = !0;
115 }
116 pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_exit(id=%p) outside",mp);
117 mutex_unlock(&mp->mutex);
118 if (destroy_flag) pvr2_context_destroy(mp);
119}
120
121
122static void pvr2_context_run_checks(struct pvr2_context *mp)
123{
124 struct pvr2_channel *ch1,*ch2;
125 for (ch1 = mp->mc_first; ch1; ch1 = ch2) {
126 ch2 = ch1->mc_next;
127 if (ch1->check_func) {
128 ch1->check_func(ch1);
129 }
130 }
131}
132
133
134void pvr2_context_disconnect(struct pvr2_context *mp)
135{
136 pvr2_context_enter(mp); do {
137 pvr2_hdw_disconnect(mp->hdw);
138 mp->disconnect_flag = !0;
139 pvr2_context_run_checks(mp);
140 } while (0); pvr2_context_exit(mp);
141}
142
143
144void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp)
145{
146 cp->hdw = mp->hdw;
147 cp->mc_head = mp;
148 cp->mc_next = 0;
149 cp->mc_prev = mp->mc_last;
150 if (mp->mc_last) {
151 mp->mc_last->mc_next = cp;
152 } else {
153 mp->mc_first = cp;
154 }
155 mp->mc_last = cp;
156}
157
158
159static void pvr2_channel_disclaim_stream(struct pvr2_channel *cp)
160{
161 if (!cp->stream) return;
162 pvr2_stream_kill(cp->stream->stream);
163 cp->stream->user = 0;
164 cp->stream = 0;
165}
166
167
168void pvr2_channel_done(struct pvr2_channel *cp)
169{
170 struct pvr2_context *mp = cp->mc_head;
171 pvr2_channel_disclaim_stream(cp);
172 if (cp->mc_next) {
173 cp->mc_next->mc_prev = cp->mc_prev;
174 } else {
175 mp->mc_last = cp->mc_prev;
176 }
177 if (cp->mc_prev) {
178 cp->mc_prev->mc_next = cp->mc_next;
179 } else {
180 mp->mc_first = cp->mc_next;
181 }
182 cp->hdw = 0;
183}
184
185
186int pvr2_channel_claim_stream(struct pvr2_channel *cp,
187 struct pvr2_context_stream *sp)
188{
189 int code = 0;
190 pvr2_context_enter(cp->mc_head); do {
191 if (sp == cp->stream) break;
192 if (sp->user) {
193 code = -EBUSY;
194 break;
195 }
196 pvr2_channel_disclaim_stream(cp);
197 if (!sp) break;
198 sp->user = cp;
199 cp->stream = sp;
200 } while (0); pvr2_context_exit(cp->mc_head);
201 return code;
202}
203
204
205// This is the marker for the real beginning of a legitimate mpeg2 stream.
206static char stream_sync_key[] = {
207 0x00, 0x00, 0x01, 0xba,
208};
209
210struct pvr2_ioread *pvr2_channel_create_mpeg_stream(
211 struct pvr2_context_stream *sp)
212{
213 struct pvr2_ioread *cp;
214 cp = pvr2_ioread_create();
215 if (!cp) return 0;
216 pvr2_ioread_setup(cp,sp->stream);
217 pvr2_ioread_set_sync_key(cp,stream_sync_key,sizeof(stream_sync_key));
218 return cp;
219}
220
221
222/*
223 Stuff for Emacs to see, in order to encourage consistent editing style:
224 *** Local Variables: ***
225 *** mode: c ***
226 *** fill-column: 75 ***
227 *** tab-width: 8 ***
228 *** c-basic-offset: 8 ***
229 *** End: ***
230 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h
new file mode 100644
index 000000000000..6327fa1f7e4f
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.h
@@ -0,0 +1,92 @@
1/*
2 * $Id$
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.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
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20#ifndef __PVRUSB2_BASE_H
21#define __PVRUSB2_BASE_H
22
23#include <linux/mutex.h>
24#include <linux/usb.h>
25#include <linux/workqueue.h>
26
27struct pvr2_hdw; /* hardware interface - defined elsewhere */
28struct pvr2_stream; /* stream interface - defined elsewhere */
29
30struct pvr2_context; /* All central state */
31struct pvr2_channel; /* One I/O pathway to a user */
32struct pvr2_context_stream; /* Wrapper for a stream */
33struct pvr2_crit_reg; /* Critical region pointer */
34struct pvr2_ioread; /* Low level stream structure */
35
36struct pvr2_context_stream {
37 struct pvr2_channel *user;
38 struct pvr2_stream *stream;
39};
40
41struct pvr2_context {
42 struct pvr2_channel *mc_first;
43 struct pvr2_channel *mc_last;
44 struct pvr2_hdw *hdw;
45 struct pvr2_context_stream video_stream;
46 struct mutex mutex;
47 int disconnect_flag;
48
49 /* Called after pvr2_context initialization is complete */
50 void (*setup_func)(struct pvr2_context *);
51
52 /* Work queue overhead for out-of-line processing */
53 struct workqueue_struct *workqueue;
54 struct work_struct workinit;
55 struct work_struct workpoll;
56};
57
58struct pvr2_channel {
59 struct pvr2_context *mc_head;
60 struct pvr2_channel *mc_next;
61 struct pvr2_channel *mc_prev;
62 struct pvr2_context_stream *stream;
63 struct pvr2_hdw *hdw;
64 void (*check_func)(struct pvr2_channel *);
65};
66
67void pvr2_context_enter(struct pvr2_context *);
68void pvr2_context_exit(struct pvr2_context *);
69
70struct pvr2_context *pvr2_context_create(struct usb_interface *intf,
71 const struct usb_device_id *devid,
72 void (*setup_func)(struct pvr2_context *));
73void pvr2_context_disconnect(struct pvr2_context *);
74
75void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *);
76void pvr2_channel_done(struct pvr2_channel *);
77int pvr2_channel_claim_stream(struct pvr2_channel *,
78 struct pvr2_context_stream *);
79struct pvr2_ioread *pvr2_channel_create_mpeg_stream(
80 struct pvr2_context_stream *);
81
82
83#endif /* __PVRUSB2_CONTEXT_H */
84/*
85 Stuff for Emacs to see, in order to encourage consistent editing style:
86 *** Local Variables: ***
87 *** mode: c ***
88 *** fill-column: 75 ***
89 *** tab-width: 8 ***
90 *** c-basic-offset: 8 ***
91 *** End: ***
92 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
new file mode 100644
index 000000000000..d5df9fbeba2f
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -0,0 +1,593 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21
22#include "pvrusb2-ctrl.h"
23#include "pvrusb2-hdw-internal.h"
24#include <linux/errno.h>
25#include <linux/string.h>
26#include <linux/mutex.h>
27
28
29/* Set the given control. */
30int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val)
31{
32 return pvr2_ctrl_set_mask_value(cptr,~0,val);
33}
34
35
36/* Set/clear specific bits of the given control. */
37int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
38{
39 int ret = 0;
40 if (!cptr) return -EINVAL;
41 LOCK_TAKE(cptr->hdw->big_lock); do {
42 if (cptr->info->set_value != 0) {
43 if (cptr->info->type == pvr2_ctl_bitmask) {
44 mask &= cptr->info->def.type_bitmask.valid_bits;
45 } else if (cptr->info->type == pvr2_ctl_int) {
46 if (val < cptr->info->def.type_int.min_value) {
47 break;
48 }
49 if (val > cptr->info->def.type_int.max_value) {
50 break;
51 }
52 } else if (cptr->info->type == pvr2_ctl_enum) {
53 if (val >= cptr->info->def.type_enum.count) {
54 break;
55 }
56 } else if (cptr->info->type != pvr2_ctl_bool) {
57 break;
58 }
59 ret = cptr->info->set_value(cptr,mask,val);
60 } else {
61 ret = -EPERM;
62 }
63 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
64 return ret;
65}
66
67
68/* Get the current value of the given control. */
69int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr)
70{
71 int ret = 0;
72 if (!cptr) return -EINVAL;
73 LOCK_TAKE(cptr->hdw->big_lock); do {
74 ret = cptr->info->get_value(cptr,valptr);
75 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
76 return ret;
77}
78
79
80/* Retrieve control's type */
81enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
82{
83 if (!cptr) return pvr2_ctl_int;
84 return cptr->info->type;
85}
86
87
88/* Retrieve control's maximum value (int type) */
89int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr)
90{
91 int ret = 0;
92 if (!cptr) return 0;
93 LOCK_TAKE(cptr->hdw->big_lock); do {
94 if (cptr->info->type == pvr2_ctl_int) {
95 ret = cptr->info->def.type_int.max_value;
96 }
97 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
98 return ret;
99}
100
101
102/* Retrieve control's minimum value (int type) */
103int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
104{
105 int ret = 0;
106 if (!cptr) return 0;
107 LOCK_TAKE(cptr->hdw->big_lock); do {
108 if (cptr->info->type == pvr2_ctl_int) {
109 ret = cptr->info->def.type_int.min_value;
110 }
111 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
112 return ret;
113}
114
115
116/* Retrieve control's default value (any type) */
117int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr)
118{
119 int ret = 0;
120 if (!cptr) return 0;
121 LOCK_TAKE(cptr->hdw->big_lock); do {
122 if (cptr->info->type == pvr2_ctl_int) {
123 ret = cptr->info->default_value;
124 }
125 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
126 return ret;
127}
128
129
130/* Retrieve control's enumeration count (enum only) */
131int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr)
132{
133 int ret = 0;
134 if (!cptr) return 0;
135 LOCK_TAKE(cptr->hdw->big_lock); do {
136 if (cptr->info->type == pvr2_ctl_enum) {
137 ret = cptr->info->def.type_enum.count;
138 }
139 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
140 return ret;
141}
142
143
144/* Retrieve control's valid mask bits (bit mask only) */
145int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr)
146{
147 int ret = 0;
148 if (!cptr) return 0;
149 LOCK_TAKE(cptr->hdw->big_lock); do {
150 if (cptr->info->type == pvr2_ctl_bitmask) {
151 ret = cptr->info->def.type_bitmask.valid_bits;
152 }
153 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
154 return ret;
155}
156
157
158/* Retrieve the control's name */
159const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
160{
161 if (!cptr) return 0;
162 return cptr->info->name;
163}
164
165
166/* Retrieve the control's desc */
167const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr)
168{
169 if (!cptr) return 0;
170 return cptr->info->desc;
171}
172
173
174/* Retrieve a control enumeration or bit mask value */
175int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
176 char *bptr,unsigned int bmax,
177 unsigned int *blen)
178{
179 int ret = -EINVAL;
180 if (!cptr) return 0;
181 *blen = 0;
182 LOCK_TAKE(cptr->hdw->big_lock); do {
183 if (cptr->info->type == pvr2_ctl_enum) {
184 const char **names;
185 names = cptr->info->def.type_enum.value_names;
186 if ((val >= 0) &&
187 (val < cptr->info->def.type_enum.count)) {
188 if (names[val]) {
189 *blen = scnprintf(
190 bptr,bmax,"%s",
191 names[val]);
192 } else {
193 *blen = 0;
194 }
195 ret = 0;
196 }
197 } else if (cptr->info->type == pvr2_ctl_bitmask) {
198 const char **names;
199 unsigned int idx;
200 int msk;
201 names = cptr->info->def.type_bitmask.bit_names;
202 val &= cptr->info->def.type_bitmask.valid_bits;
203 for (idx = 0, msk = 1; val; idx++, msk <<= 1) {
204 if (val & msk) {
205 *blen = scnprintf(bptr,bmax,"%s",
206 names[idx]);
207 ret = 0;
208 break;
209 }
210 }
211 }
212 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
213 return ret;
214}
215
216
217/* Return V4L ID for this control or zero if none */
218int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr)
219{
220 if (!cptr) return 0;
221 return cptr->info->v4l_id;
222}
223
224
225unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr)
226{
227 unsigned int flags = 0;
228
229 if (cptr->info->get_v4lflags) {
230 flags = cptr->info->get_v4lflags(cptr);
231 }
232
233 if (cptr->info->set_value) {
234 flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
235 } else {
236 flags |= V4L2_CTRL_FLAG_READ_ONLY;
237 }
238
239 return flags;
240}
241
242
243/* Return true if control is writable */
244int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr)
245{
246 if (!cptr) return 0;
247 return cptr->info->set_value != 0;
248}
249
250
251/* Return true if control has custom symbolic representation */
252int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr)
253{
254 if (!cptr) return 0;
255 if (!cptr->info->val_to_sym) return 0;
256 if (!cptr->info->sym_to_val) return 0;
257 return !0;
258}
259
260
261/* Convert a given mask/val to a custom symbolic value */
262int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr,
263 int mask,int val,
264 char *buf,unsigned int maxlen,
265 unsigned int *len)
266{
267 if (!cptr) return -EINVAL;
268 if (!cptr->info->val_to_sym) return -EINVAL;
269 return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len);
270}
271
272
273/* Convert a symbolic value to a mask/value pair */
274int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr,
275 const char *buf,unsigned int len,
276 int *maskptr,int *valptr)
277{
278 if (!cptr) return -EINVAL;
279 if (!cptr->info->sym_to_val) return -EINVAL;
280 return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr);
281}
282
283
284static unsigned int gen_bitmask_string(int msk,int val,int msk_only,
285 const char **names,
286 char *ptr,unsigned int len)
287{
288 unsigned int idx;
289 long sm,um;
290 int spcFl;
291 unsigned int uc,cnt;
292 const char *idStr;
293
294 spcFl = 0;
295 uc = 0;
296 um = 0;
297 for (idx = 0, sm = 1; msk; idx++, sm <<= 1) {
298 if (sm & msk) {
299 msk &= ~sm;
300 idStr = names[idx];
301 if (idStr) {
302 cnt = scnprintf(ptr,len,"%s%s%s",
303 (spcFl ? " " : ""),
304 (msk_only ? "" :
305 ((val & sm) ? "+" : "-")),
306 idStr);
307 ptr += cnt; len -= cnt; uc += cnt;
308 spcFl = !0;
309 } else {
310 um |= sm;
311 }
312 }
313 }
314 if (um) {
315 if (msk_only) {
316 cnt = scnprintf(ptr,len,"%s0x%lx",
317 (spcFl ? " " : ""),
318 um);
319 ptr += cnt; len -= cnt; uc += cnt;
320 spcFl = !0;
321 } else if (um & val) {
322 cnt = scnprintf(ptr,len,"%s+0x%lx",
323 (spcFl ? " " : ""),
324 um & val);
325 ptr += cnt; len -= cnt; uc += cnt;
326 spcFl = !0;
327 } else if (um & ~val) {
328 cnt = scnprintf(ptr,len,"%s+0x%lx",
329 (spcFl ? " " : ""),
330 um & ~val);
331 ptr += cnt; len -= cnt; uc += cnt;
332 spcFl = !0;
333 }
334 }
335 return uc;
336}
337
338
339static const char *boolNames[] = {
340 "false",
341 "true",
342 "no",
343 "yes",
344};
345
346
347static int parse_token(const char *ptr,unsigned int len,
348 int *valptr,
349 const char **names,unsigned int namecnt)
350{
351 char buf[33];
352 unsigned int slen;
353 unsigned int idx;
354 int negfl;
355 char *p2;
356 *valptr = 0;
357 if (!names) namecnt = 0;
358 for (idx = 0; idx < namecnt; idx++) {
359 if (!names[idx]) continue;
360 slen = strlen(names[idx]);
361 if (slen != len) continue;
362 if (memcmp(names[idx],ptr,slen)) continue;
363 *valptr = idx;
364 return 0;
365 }
366 negfl = 0;
367 if ((*ptr == '-') || (*ptr == '+')) {
368 negfl = (*ptr == '-');
369 ptr++; len--;
370 }
371 if (len >= sizeof(buf)) return -EINVAL;
372 memcpy(buf,ptr,len);
373 buf[len] = 0;
374 *valptr = simple_strtol(buf,&p2,0);
375 if (negfl) *valptr = -(*valptr);
376 if (*p2) return -EINVAL;
377 return 1;
378}
379
380
381static int parse_mtoken(const char *ptr,unsigned int len,
382 int *valptr,
383 const char **names,int valid_bits)
384{
385 char buf[33];
386 unsigned int slen;
387 unsigned int idx;
388 char *p2;
389 int msk;
390 *valptr = 0;
391 for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) {
392 if (!msk & valid_bits) continue;
393 valid_bits &= ~msk;
394 if (!names[idx]) continue;
395 slen = strlen(names[idx]);
396 if (slen != len) continue;
397 if (memcmp(names[idx],ptr,slen)) continue;
398 *valptr = msk;
399 return 0;
400 }
401 if (len >= sizeof(buf)) return -EINVAL;
402 memcpy(buf,ptr,len);
403 buf[len] = 0;
404 *valptr = simple_strtol(buf,&p2,0);
405 if (*p2) return -EINVAL;
406 return 0;
407}
408
409
410static int parse_tlist(const char *ptr,unsigned int len,
411 int *maskptr,int *valptr,
412 const char **names,int valid_bits)
413{
414 unsigned int cnt;
415 int mask,val,kv,mode,ret;
416 mask = 0;
417 val = 0;
418 ret = 0;
419 while (len) {
420 cnt = 0;
421 while ((cnt < len) &&
422 ((ptr[cnt] <= 32) ||
423 (ptr[cnt] >= 127))) cnt++;
424 ptr += cnt;
425 len -= cnt;
426 mode = 0;
427 if ((*ptr == '-') || (*ptr == '+')) {
428 mode = (*ptr == '-') ? -1 : 1;
429 ptr++;
430 len--;
431 }
432 cnt = 0;
433 while (cnt < len) {
434 if (ptr[cnt] <= 32) break;
435 if (ptr[cnt] >= 127) break;
436 cnt++;
437 }
438 if (!cnt) break;
439 if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) {
440 ret = -EINVAL;
441 break;
442 }
443 ptr += cnt;
444 len -= cnt;
445 switch (mode) {
446 case 0:
447 mask = valid_bits;
448 val |= kv;
449 break;
450 case -1:
451 mask |= kv;
452 val &= ~kv;
453 break;
454 case 1:
455 mask |= kv;
456 val |= kv;
457 break;
458 default:
459 break;
460 }
461 }
462 *maskptr = mask;
463 *valptr = val;
464 return ret;
465}
466
467
468/* Convert a symbolic value to a mask/value pair */
469int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
470 const char *ptr,unsigned int len,
471 int *maskptr,int *valptr)
472{
473 int ret = -EINVAL;
474 unsigned int cnt;
475
476 *maskptr = 0;
477 *valptr = 0;
478
479 cnt = 0;
480 while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++;
481 len -= cnt; ptr += cnt;
482 cnt = 0;
483 while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) ||
484 (ptr[len-(cnt+1)] >= 127))) cnt++;
485 len -= cnt;
486
487 if (!len) return -EINVAL;
488
489 LOCK_TAKE(cptr->hdw->big_lock); do {
490 if (cptr->info->type == pvr2_ctl_int) {
491 ret = parse_token(ptr,len,valptr,0,0);
492 if ((ret >= 0) &&
493 ((*valptr < cptr->info->def.type_int.min_value) ||
494 (*valptr > cptr->info->def.type_int.max_value))) {
495 ret = -ERANGE;
496 }
497 if (maskptr) *maskptr = ~0;
498 } else if (cptr->info->type == pvr2_ctl_bool) {
499 ret = parse_token(
500 ptr,len,valptr,boolNames,
501 sizeof(boolNames)/sizeof(boolNames[0]));
502 if (ret == 1) {
503 *valptr = *valptr ? !0 : 0;
504 } else if (ret == 0) {
505 *valptr = (*valptr & 1) ? !0 : 0;
506 }
507 if (maskptr) *maskptr = 1;
508 } else if (cptr->info->type == pvr2_ctl_enum) {
509 ret = parse_token(
510 ptr,len,valptr,
511 cptr->info->def.type_enum.value_names,
512 cptr->info->def.type_enum.count);
513 if ((ret >= 0) &&
514 ((*valptr < 0) ||
515 (*valptr >= cptr->info->def.type_enum.count))) {
516 ret = -ERANGE;
517 }
518 if (maskptr) *maskptr = ~0;
519 } else if (cptr->info->type == pvr2_ctl_bitmask) {
520 ret = parse_tlist(
521 ptr,len,maskptr,valptr,
522 cptr->info->def.type_bitmask.bit_names,
523 cptr->info->def.type_bitmask.valid_bits);
524 }
525 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
526 return ret;
527}
528
529
530/* Convert a given mask/val to a symbolic value */
531int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
532 int mask,int val,
533 char *buf,unsigned int maxlen,
534 unsigned int *len)
535{
536 int ret = -EINVAL;
537
538 *len = 0;
539 if (cptr->info->type == pvr2_ctl_int) {
540 *len = scnprintf(buf,maxlen,"%d",val);
541 ret = 0;
542 } else if (cptr->info->type == pvr2_ctl_bool) {
543 *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false");
544 ret = 0;
545 } else if (cptr->info->type == pvr2_ctl_enum) {
546 const char **names;
547 names = cptr->info->def.type_enum.value_names;
548 if ((val >= 0) &&
549 (val < cptr->info->def.type_enum.count)) {
550 if (names[val]) {
551 *len = scnprintf(
552 buf,maxlen,"%s",
553 names[val]);
554 } else {
555 *len = 0;
556 }
557 ret = 0;
558 }
559 } else if (cptr->info->type == pvr2_ctl_bitmask) {
560 *len = gen_bitmask_string(
561 val & mask & cptr->info->def.type_bitmask.valid_bits,
562 ~0,!0,
563 cptr->info->def.type_bitmask.bit_names,
564 buf,maxlen);
565 }
566 return ret;
567}
568
569
570/* Convert a given mask/val to a symbolic value */
571int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr,
572 int mask,int val,
573 char *buf,unsigned int maxlen,
574 unsigned int *len)
575{
576 int ret;
577 LOCK_TAKE(cptr->hdw->big_lock); do {
578 ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val,
579 buf,maxlen,len);
580 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
581 return ret;
582}
583
584
585/*
586 Stuff for Emacs to see, in order to encourage consistent editing style:
587 *** Local Variables: ***
588 *** mode: c ***
589 *** fill-column: 75 ***
590 *** tab-width: 8 ***
591 *** c-basic-offset: 8 ***
592 *** End: ***
593 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
new file mode 100644
index 000000000000..c1680053cd64
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
@@ -0,0 +1,123 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_CTRL_H
22#define __PVRUSB2_CTRL_H
23
24struct pvr2_ctrl;
25
26enum pvr2_ctl_type {
27 pvr2_ctl_int = 0,
28 pvr2_ctl_enum = 1,
29 pvr2_ctl_bitmask = 2,
30 pvr2_ctl_bool = 3,
31};
32
33
34/* Set the given control. */
35int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val);
36
37/* Set/clear specific bits of the given control. */
38int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *,int mask,int val);
39
40/* Get the current value of the given control. */
41int pvr2_ctrl_get_value(struct pvr2_ctrl *,int *valptr);
42
43/* Retrieve control's type */
44enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *);
45
46/* Retrieve control's maximum value (int type) */
47int pvr2_ctrl_get_max(struct pvr2_ctrl *);
48
49/* Retrieve control's minimum value (int type) */
50int pvr2_ctrl_get_min(struct pvr2_ctrl *);
51
52/* Retrieve control's default value (any type) */
53int pvr2_ctrl_get_def(struct pvr2_ctrl *);
54
55/* Retrieve control's enumeration count (enum only) */
56int pvr2_ctrl_get_cnt(struct pvr2_ctrl *);
57
58/* Retrieve control's valid mask bits (bit mask only) */
59int pvr2_ctrl_get_mask(struct pvr2_ctrl *);
60
61/* Retrieve the control's name */
62const char *pvr2_ctrl_get_name(struct pvr2_ctrl *);
63
64/* Retrieve the control's desc */
65const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *);
66
67/* Retrieve a control enumeration or bit mask value */
68int pvr2_ctrl_get_valname(struct pvr2_ctrl *,int,char *,unsigned int,
69 unsigned int *);
70
71/* Return true if control is writable */
72int pvr2_ctrl_is_writable(struct pvr2_ctrl *);
73
74/* Return V4L flags value for control (or zero if there is no v4l control
75 actually under this control) */
76unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *);
77
78/* Return V4L ID for this control or zero if none */
79int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *);
80
81/* Return true if control has custom symbolic representation */
82int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *);
83
84/* Convert a given mask/val to a custom symbolic value */
85int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *,
86 int mask,int val,
87 char *buf,unsigned int maxlen,
88 unsigned int *len);
89
90/* Convert a symbolic value to a mask/value pair */
91int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *,
92 const char *buf,unsigned int len,
93 int *maskptr,int *valptr);
94
95/* Convert a given mask/val to a symbolic value */
96int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *,
97 int mask,int val,
98 char *buf,unsigned int maxlen,
99 unsigned int *len);
100
101/* Convert a symbolic value to a mask/value pair */
102int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *,
103 const char *buf,unsigned int len,
104 int *maskptr,int *valptr);
105
106/* Convert a given mask/val to a symbolic value - must already be
107 inside of critical region. */
108int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *,
109 int mask,int val,
110 char *buf,unsigned int maxlen,
111 unsigned int *len);
112
113#endif /* __PVRUSB2_CTRL_H */
114
115/*
116 Stuff for Emacs to see, in order to encourage consistent editing style:
117 *** Local Variables: ***
118 *** mode: c ***
119 *** fill-column: 75 ***
120 *** tab-width: 8 ***
121 *** c-basic-offset: 8 ***
122 *** End: ***
123 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
new file mode 100644
index 000000000000..27eadaff75a0
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -0,0 +1,279 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23/*
24
25 This source file is specifically designed to interface with the
26 cx2584x, in kernels 2.6.16 or newer.
27
28*/
29
30#include "pvrusb2-cx2584x-v4l.h"
31#include "pvrusb2-video-v4l.h"
32#include "pvrusb2-i2c-cmd-v4l2.h"
33
34
35#include "pvrusb2-hdw-internal.h"
36#include "pvrusb2-debug.h"
37#include <media/cx25840.h>
38#include <linux/videodev2.h>
39#include <media/v4l2-common.h>
40#include <linux/errno.h>
41#include <linux/slab.h>
42
43struct pvr2_v4l_cx2584x {
44 struct pvr2_i2c_handler handler;
45 struct pvr2_decoder_ctrl ctrl;
46 struct pvr2_i2c_client *client;
47 struct pvr2_hdw *hdw;
48 unsigned long stale_mask;
49};
50
51
52static void set_input(struct pvr2_v4l_cx2584x *ctxt)
53{
54 struct pvr2_hdw *hdw = ctxt->hdw;
55 struct v4l2_routing route;
56 enum cx25840_video_input vid_input;
57 enum cx25840_audio_input aud_input;
58
59 memset(&route,0,sizeof(route));
60
61 switch(hdw->input_val) {
62 case PVR2_CVAL_INPUT_TV:
63 vid_input = CX25840_COMPOSITE7;
64 aud_input = CX25840_AUDIO8;
65 break;
66 case PVR2_CVAL_INPUT_COMPOSITE:
67 vid_input = CX25840_COMPOSITE3;
68 aud_input = CX25840_AUDIO_SERIAL;
69 break;
70 case PVR2_CVAL_INPUT_SVIDEO:
71 vid_input = CX25840_SVIDEO1;
72 aud_input = CX25840_AUDIO_SERIAL;
73 break;
74 case PVR2_CVAL_INPUT_RADIO:
75 default:
76 // Just set it to be composite input for now...
77 vid_input = CX25840_COMPOSITE3;
78 aud_input = CX25840_AUDIO_SERIAL;
79 break;
80 }
81
82 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
83 vid_input,aud_input);
84 route.input = (u32)vid_input;
85 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
86 route.input = (u32)aud_input;
87 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
88}
89
90
91static int check_input(struct pvr2_v4l_cx2584x *ctxt)
92{
93 struct pvr2_hdw *hdw = ctxt->hdw;
94 return hdw->input_dirty != 0;
95}
96
97
98static void set_audio(struct pvr2_v4l_cx2584x *ctxt)
99{
100 u32 val;
101 struct pvr2_hdw *hdw = ctxt->hdw;
102
103 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d",
104 hdw->srate_val);
105 switch (hdw->srate_val) {
106 default:
107 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
108 val = 48000;
109 break;
110 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
111 val = 44100;
112 break;
113 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
114 val = 32000;
115 break;
116 }
117 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
118}
119
120
121static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
122{
123 struct pvr2_hdw *hdw = ctxt->hdw;
124 return hdw->srate_dirty != 0;
125}
126
127
128struct pvr2_v4l_cx2584x_ops {
129 void (*update)(struct pvr2_v4l_cx2584x *);
130 int (*check)(struct pvr2_v4l_cx2584x *);
131};
132
133
134static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
135 { .update = set_input, .check = check_input},
136 { .update = set_audio, .check = check_audio},
137};
138
139
140static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
141{
142 ctxt->client->handler = 0;
143 ctxt->hdw->decoder_ctrl = 0;
144 kfree(ctxt);
145}
146
147
148static int decoder_check(struct pvr2_v4l_cx2584x *ctxt)
149{
150 unsigned long msk;
151 unsigned int idx;
152
153 for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
154 idx++) {
155 msk = 1 << idx;
156 if (ctxt->stale_mask & msk) continue;
157 if (decoder_ops[idx].check(ctxt)) {
158 ctxt->stale_mask |= msk;
159 }
160 }
161 return ctxt->stale_mask != 0;
162}
163
164
165static void decoder_update(struct pvr2_v4l_cx2584x *ctxt)
166{
167 unsigned long msk;
168 unsigned int idx;
169
170 for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
171 idx++) {
172 msk = 1 << idx;
173 if (!(ctxt->stale_mask & msk)) continue;
174 ctxt->stale_mask &= ~msk;
175 decoder_ops[idx].update(ctxt);
176 }
177}
178
179
180static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
181{
182 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
183 pvr2_v4l2_cmd_stream(ctxt->client,fl);
184}
185
186
187static int decoder_detect(struct pvr2_i2c_client *cp)
188{
189 int ret;
190 /* Attempt to query the decoder - let's see if it will answer */
191 struct v4l2_queryctrl qc;
192
193 memset(&qc,0,sizeof(qc));
194
195 qc.id = V4L2_CID_BRIGHTNESS;
196
197 ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
198 return ret == 0; /* Return true if it answered */
199}
200
201
202static int decoder_is_tuned(struct pvr2_v4l_cx2584x *ctxt)
203{
204 struct v4l2_tuner vt;
205 int ret;
206
207 memset(&vt,0,sizeof(vt));
208 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
209 if (ret < 0) return -EINVAL;
210 return vt.signal ? 1 : 0;
211}
212
213
214static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
215 char *buf,unsigned int cnt)
216{
217 return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
218}
219
220
221static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
222{
223 int ret;
224 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0);
225 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
226}
227
228
229const static struct pvr2_i2c_handler_functions hfuncs = {
230 .detach = (void (*)(void *))decoder_detach,
231 .check = (int (*)(void *))decoder_check,
232 .update = (void (*)(void *))decoder_update,
233 .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
234};
235
236
237int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
238 struct pvr2_i2c_client *cp)
239{
240 struct pvr2_v4l_cx2584x *ctxt;
241
242 if (hdw->decoder_ctrl) return 0;
243 if (cp->handler) return 0;
244 if (!decoder_detect(cp)) return 0;
245
246 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
247 if (!ctxt) return 0;
248 memset(ctxt,0,sizeof(*ctxt));
249
250 ctxt->handler.func_data = ctxt;
251 ctxt->handler.func_table = &hfuncs;
252 ctxt->ctrl.ctxt = ctxt;
253 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
254 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
255 ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned;
256 ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
257 ctxt->client = cp;
258 ctxt->hdw = hdw;
259 ctxt->stale_mask = (1 << (sizeof(decoder_ops)/
260 sizeof(decoder_ops[0]))) - 1;
261 hdw->decoder_ctrl = &ctxt->ctrl;
262 cp->handler = &ctxt->handler;
263 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
264 cp->client->addr);
265 return !0;
266}
267
268
269
270
271/*
272 Stuff for Emacs to see, in order to encourage consistent editing style:
273 *** Local Variables: ***
274 *** mode: c ***
275 *** fill-column: 70 ***
276 *** tab-width: 8 ***
277 *** c-basic-offset: 8 ***
278 *** End: ***
279 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
new file mode 100644
index 000000000000..54b2844e7a71
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
@@ -0,0 +1,53 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef __PVRUSB2_CX2584X_V4L_H
24#define __PVRUSB2_CX2584X_V4L_H
25
26/*
27
28 This module connects the pvrusb2 driver to the I2C chip level
29 driver which handles combined device audio & video processing.
30 This interface is used internally by the driver; higher level code
31 should only interact through the interface provided by
32 pvrusb2-hdw.h.
33
34*/
35
36
37
38#include "pvrusb2-i2c-core.h"
39
40int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
41
42
43#endif /* __PVRUSB2_CX2584X_V4L_H */
44
45/*
46 Stuff for Emacs to see, in order to encourage consistent editing style:
47 *** Local Variables: ***
48 *** mode: c ***
49 *** fill-column: 70 ***
50 *** tab-width: 8 ***
51 *** c-basic-offset: 8 ***
52 *** End: ***
53 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h
new file mode 100644
index 000000000000..d95a8588e4f8
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-debug.h
@@ -0,0 +1,67 @@
1/*
2 * $Id$
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.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
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20#ifndef __PVRUSB2_DEBUG_H
21#define __PVRUSB2_DEBUG_H
22
23extern int pvrusb2_debug;
24
25#define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2: " fmt "\n", ##arg); } while (0)
26
27/* These are listed in *rough* order of decreasing usefulness and
28 increasing noise level. */
29#define PVR2_TRACE_INFO (1 << 0) // Normal messages
30#define PVR2_TRACE_ERROR_LEGS (1 << 1) // error messages
31#define PVR2_TRACE_TOLERANCE (1 << 2) // track tolerance-affected errors
32#define PVR2_TRACE_TRAP (1 << 3) // Trap & report misbehavior from app
33#define PVR2_TRACE_INIT (1 << 4) // misc initialization steps
34#define PVR2_TRACE_START_STOP (1 << 5) // Streaming start / stop
35#define PVR2_TRACE_CTL (1 << 6) // commit of control changes
36#define PVR2_TRACE_DEBUG (1 << 7) // Temporary debug code
37#define PVR2_TRACE_EEPROM (1 << 8) // eeprom parsing / report
38#define PVR2_TRACE_STRUCT (1 << 9) // internal struct creation
39#define PVR2_TRACE_OPEN_CLOSE (1 << 10) // application open / close
40#define PVR2_TRACE_CREG (1 << 11) // Main critical region entry / exit
41#define PVR2_TRACE_SYSFS (1 << 12) // Sysfs driven I/O
42#define PVR2_TRACE_FIRMWARE (1 << 13) // firmware upload actions
43#define PVR2_TRACE_CHIPS (1 << 14) // chip broadcast operation
44#define PVR2_TRACE_I2C (1 << 15) // I2C related stuff
45#define PVR2_TRACE_I2C_CMD (1 << 16) // Software commands to I2C modules
46#define PVR2_TRACE_I2C_CORE (1 << 17) // I2C core debugging
47#define PVR2_TRACE_I2C_TRAF (1 << 18) // I2C traffic through the adapter
48#define PVR2_TRACE_V4LIOCTL (1 << 19) // v4l ioctl details
49#define PVR2_TRACE_ENCODER (1 << 20) // mpeg2 encoder operation
50#define PVR2_TRACE_BUF_POOL (1 << 21) // Track buffer pool management
51#define PVR2_TRACE_BUF_FLOW (1 << 22) // Track buffer flow in system
52#define PVR2_TRACE_DATA_FLOW (1 << 23) // Track data flow
53#define PVR2_TRACE_DEBUGIFC (1 << 24) // Debug interface actions
54#define PVR2_TRACE_GPIO (1 << 25) // GPIO state bit changes
55
56
57#endif /* __PVRUSB2_HDW_INTERNAL_H */
58
59/*
60 Stuff for Emacs to see, in order to encourage consistent editing style:
61 *** Local Variables: ***
62 *** mode: c ***
63 *** fill-column: 75 ***
64 *** tab-width: 8 ***
65 *** c-basic-offset: 8 ***
66 *** End: ***
67 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
new file mode 100644
index 000000000000..586900e365ff
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -0,0 +1,478 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21
22#include <linux/string.h>
23#include <linux/slab.h>
24#include "pvrusb2-debugifc.h"
25#include "pvrusb2-hdw.h"
26#include "pvrusb2-debug.h"
27#include "pvrusb2-i2c-core.h"
28
29struct debugifc_mask_item {
30 const char *name;
31 unsigned long msk;
32};
33
34static struct debugifc_mask_item mask_items[] = {
35 {"ENC_FIRMWARE",(1<<PVR2_SUBSYS_B_ENC_FIRMWARE)},
36 {"ENC_CFG",(1<<PVR2_SUBSYS_B_ENC_CFG)},
37 {"DIG_RUN",(1<<PVR2_SUBSYS_B_DIGITIZER_RUN)},
38 {"USB_RUN",(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)},
39 {"ENC_RUN",(1<<PVR2_SUBSYS_B_ENC_RUN)},
40};
41
42
43static unsigned int debugifc_count_whitespace(const char *buf,
44 unsigned int count)
45{
46 unsigned int scnt;
47 char ch;
48
49 for (scnt = 0; scnt < count; scnt++) {
50 ch = buf[scnt];
51 if (ch == ' ') continue;
52 if (ch == '\t') continue;
53 if (ch == '\n') continue;
54 break;
55 }
56 return scnt;
57}
58
59
60static unsigned int debugifc_count_nonwhitespace(const char *buf,
61 unsigned int count)
62{
63 unsigned int scnt;
64 char ch;
65
66 for (scnt = 0; scnt < count; scnt++) {
67 ch = buf[scnt];
68 if (ch == ' ') break;
69 if (ch == '\t') break;
70 if (ch == '\n') break;
71 }
72 return scnt;
73}
74
75
76static unsigned int debugifc_isolate_word(const char *buf,unsigned int count,
77 const char **wstrPtr,
78 unsigned int *wlenPtr)
79{
80 const char *wptr;
81 unsigned int consume_cnt = 0;
82 unsigned int wlen;
83 unsigned int scnt;
84
85 wptr = 0;
86 wlen = 0;
87 scnt = debugifc_count_whitespace(buf,count);
88 consume_cnt += scnt; count -= scnt; buf += scnt;
89 if (!count) goto done;
90
91 scnt = debugifc_count_nonwhitespace(buf,count);
92 if (!scnt) goto done;
93 wptr = buf;
94 wlen = scnt;
95 consume_cnt += scnt; count -= scnt; buf += scnt;
96
97 done:
98 *wstrPtr = wptr;
99 *wlenPtr = wlen;
100 return consume_cnt;
101}
102
103
104static int debugifc_parse_unsigned_number(const char *buf,unsigned int count,
105 u32 *num_ptr)
106{
107 u32 result = 0;
108 u32 val;
109 int ch;
110 int radix = 10;
111 if ((count >= 2) && (buf[0] == '0') &&
112 ((buf[1] == 'x') || (buf[1] == 'X'))) {
113 radix = 16;
114 count -= 2;
115 buf += 2;
116 } else if ((count >= 1) && (buf[0] == '0')) {
117 radix = 8;
118 }
119
120 while (count--) {
121 ch = *buf++;
122 if ((ch >= '0') && (ch <= '9')) {
123 val = ch - '0';
124 } else if ((ch >= 'a') && (ch <= 'f')) {
125 val = ch - 'a' + 10;
126 } else if ((ch >= 'A') && (ch <= 'F')) {
127 val = ch - 'A' + 10;
128 } else {
129 return -EINVAL;
130 }
131 if (val >= radix) return -EINVAL;
132 result *= radix;
133 result += val;
134 }
135 *num_ptr = result;
136 return 0;
137}
138
139
140static int debugifc_match_keyword(const char *buf,unsigned int count,
141 const char *keyword)
142{
143 unsigned int kl;
144 if (!keyword) return 0;
145 kl = strlen(keyword);
146 if (kl != count) return 0;
147 return !memcmp(buf,keyword,kl);
148}
149
150
151static unsigned long debugifc_find_mask(const char *buf,unsigned int count)
152{
153 struct debugifc_mask_item *mip;
154 unsigned int idx;
155 for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) {
156 mip = mask_items + idx;
157 if (debugifc_match_keyword(buf,count,mip->name)) {
158 return mip->msk;
159 }
160 }
161 return 0;
162}
163
164
165static int debugifc_print_mask(char *buf,unsigned int sz,
166 unsigned long msk,unsigned long val)
167{
168 struct debugifc_mask_item *mip;
169 unsigned int idx;
170 int bcnt = 0;
171 int ccnt;
172 for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) {
173 mip = mask_items + idx;
174 if (!(mip->msk & msk)) continue;
175 ccnt = scnprintf(buf,sz,"%s%c%s",
176 (bcnt ? " " : ""),
177 ((mip->msk & val) ? '+' : '-'),
178 mip->name);
179 sz -= ccnt;
180 buf += ccnt;
181 bcnt += ccnt;
182 }
183 return bcnt;
184}
185
186static unsigned int debugifc_parse_subsys_mask(const char *buf,
187 unsigned int count,
188 unsigned long *mskPtr,
189 unsigned long *valPtr)
190{
191 const char *wptr;
192 unsigned int consume_cnt = 0;
193 unsigned int scnt;
194 unsigned int wlen;
195 int mode;
196 unsigned long m1,msk,val;
197
198 msk = 0;
199 val = 0;
200
201 while (count) {
202 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
203 if (!scnt) break;
204 consume_cnt += scnt; count -= scnt; buf += scnt;
205 if (!wptr) break;
206
207 mode = 0;
208 if (wlen) switch (wptr[0]) {
209 case '+':
210 wptr++;
211 wlen--;
212 break;
213 case '-':
214 mode = 1;
215 wptr++;
216 wlen--;
217 break;
218 }
219 if (!wlen) continue;
220 m1 = debugifc_find_mask(wptr,wlen);
221 if (!m1) break;
222 msk |= m1;
223 if (!mode) val |= m1;
224 }
225 *mskPtr = msk;
226 *valPtr = val;
227 return consume_cnt;
228}
229
230
231int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
232{
233 int bcnt = 0;
234 int ccnt;
235 struct pvr2_hdw_debug_info dbg;
236
237 pvr2_hdw_get_debug_info(hdw,&dbg);
238
239 ccnt = scnprintf(buf,acnt,"big lock %s; ctl lock %s",
240 (dbg.big_lock_held ? "held" : "free"),
241 (dbg.ctl_lock_held ? "held" : "free"));
242 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
243 if (dbg.ctl_lock_held) {
244 ccnt = scnprintf(buf,acnt,"; cmd_state=%d cmd_code=%d"
245 " cmd_wlen=%d cmd_rlen=%d"
246 " wpend=%d rpend=%d tmout=%d rstatus=%d"
247 " wstatus=%d",
248 dbg.cmd_debug_state,dbg.cmd_code,
249 dbg.cmd_debug_write_len,
250 dbg.cmd_debug_read_len,
251 dbg.cmd_debug_write_pend,
252 dbg.cmd_debug_read_pend,
253 dbg.cmd_debug_timeout,
254 dbg.cmd_debug_rstatus,
255 dbg.cmd_debug_wstatus);
256 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
257 }
258 ccnt = scnprintf(buf,acnt,"\n");
259 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
260 ccnt = scnprintf(
261 buf,acnt,"driver flags: %s %s %s\n",
262 (dbg.flag_init_ok ? "initialized" : "uninitialized"),
263 (dbg.flag_ok ? "ok" : "fail"),
264 (dbg.flag_disconnected ? "disconnected" : "connected"));
265 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
266 ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: ");
267 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
268 ccnt = debugifc_print_mask(buf,acnt,dbg.subsys_flags,dbg.subsys_flags);
269 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
270 ccnt = scnprintf(buf,acnt,"\n");
271 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
272 ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: ");
273 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
274 ccnt = debugifc_print_mask(buf,acnt,~dbg.subsys_flags,dbg.subsys_flags);
275 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
276 ccnt = scnprintf(buf,acnt,"\n");
277 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
278
279 ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n");
280 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
281 ccnt = pvr2_i2c_report(hdw,buf,acnt);
282 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
283
284 return bcnt;
285}
286
287
288int pvr2_debugifc_print_status(struct pvr2_hdw *hdw,
289 char *buf,unsigned int acnt)
290{
291 int bcnt = 0;
292 int ccnt;
293 unsigned long msk;
294 int ret;
295 u32 gpio_dir,gpio_in,gpio_out;
296
297 ret = pvr2_hdw_is_hsm(hdw);
298 ccnt = scnprintf(buf,acnt,"USB link speed: %s\n",
299 (ret < 0 ? "FAIL" : (ret ? "high" : "full")));
300 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
301
302 gpio_dir = 0; gpio_in = 0; gpio_out = 0;
303 pvr2_hdw_gpio_get_dir(hdw,&gpio_dir);
304 pvr2_hdw_gpio_get_out(hdw,&gpio_out);
305 pvr2_hdw_gpio_get_in(hdw,&gpio_in);
306 ccnt = scnprintf(buf,acnt,"GPIO state: dir=0x%x in=0x%x out=0x%x\n",
307 gpio_dir,gpio_in,gpio_out);
308 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
309
310 ccnt = scnprintf(buf,acnt,"Streaming is %s\n",
311 pvr2_hdw_get_streaming(hdw) ? "on" : "off");
312 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
313
314 msk = pvr2_hdw_subsys_get(hdw);
315 ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: ");
316 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
317 ccnt = debugifc_print_mask(buf,acnt,msk,msk);
318 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
319 ccnt = scnprintf(buf,acnt,"\n");
320 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
321 ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: ");
322 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
323 ccnt = debugifc_print_mask(buf,acnt,~msk,msk);
324 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
325 ccnt = scnprintf(buf,acnt,"\n");
326 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
327
328 msk = pvr2_hdw_subsys_stream_get(hdw);
329 ccnt = scnprintf(buf,acnt,"Subsystems stopped on stream shutdown: ");
330 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
331 ccnt = debugifc_print_mask(buf,acnt,msk,msk);
332 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
333 ccnt = scnprintf(buf,acnt,"\n");
334 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
335
336 return bcnt;
337}
338
339
340int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
341 unsigned int count)
342{
343 const char *wptr;
344 unsigned int wlen;
345 unsigned int scnt;
346
347 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
348 if (!scnt) return 0;
349 count -= scnt; buf += scnt;
350 if (!wptr) return 0;
351
352 pvr2_trace(PVR2_TRACE_DEBUGIFC,"debugifc cmd: \"%.*s\"",wlen,wptr);
353 if (debugifc_match_keyword(wptr,wlen,"reset")) {
354 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
355 if (!scnt) return -EINVAL;
356 count -= scnt; buf += scnt;
357 if (!wptr) return -EINVAL;
358 if (debugifc_match_keyword(wptr,wlen,"cpu")) {
359 pvr2_hdw_cpureset_assert(hdw,!0);
360 pvr2_hdw_cpureset_assert(hdw,0);
361 return 0;
362 } else if (debugifc_match_keyword(wptr,wlen,"bus")) {
363 pvr2_hdw_device_reset(hdw);
364 } else if (debugifc_match_keyword(wptr,wlen,"soft")) {
365 return pvr2_hdw_cmd_powerup(hdw);
366 } else if (debugifc_match_keyword(wptr,wlen,"deep")) {
367 return pvr2_hdw_cmd_deep_reset(hdw);
368 } else if (debugifc_match_keyword(wptr,wlen,"firmware")) {
369 return pvr2_upload_firmware2(hdw);
370 } else if (debugifc_match_keyword(wptr,wlen,"decoder")) {
371 return pvr2_hdw_cmd_decoder_reset(hdw);
372 }
373 return -EINVAL;
374 } else if (debugifc_match_keyword(wptr,wlen,"subsys_flags")) {
375 unsigned long msk = 0;
376 unsigned long val = 0;
377 if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) {
378 pvr2_trace(PVR2_TRACE_DEBUGIFC,
379 "debugifc parse error on subsys mask");
380 return -EINVAL;
381 }
382 pvr2_hdw_subsys_bit_chg(hdw,msk,val);
383 return 0;
384 } else if (debugifc_match_keyword(wptr,wlen,"stream_flags")) {
385 unsigned long msk = 0;
386 unsigned long val = 0;
387 if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) {
388 pvr2_trace(PVR2_TRACE_DEBUGIFC,
389 "debugifc parse error on stream mask");
390 return -EINVAL;
391 }
392 pvr2_hdw_subsys_stream_bit_chg(hdw,msk,val);
393 return 0;
394 } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) {
395 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
396 if (!scnt) return -EINVAL;
397 count -= scnt; buf += scnt;
398 if (!wptr) return -EINVAL;
399 if (debugifc_match_keyword(wptr,wlen,"fetch")) {
400 pvr2_hdw_cpufw_set_enabled(hdw,!0);
401 return 0;
402 } else if (debugifc_match_keyword(wptr,wlen,"done")) {
403 pvr2_hdw_cpufw_set_enabled(hdw,0);
404 return 0;
405 } else {
406 return -EINVAL;
407 }
408 } else if (debugifc_match_keyword(wptr,wlen,"gpio")) {
409 int dir_fl = 0;
410 int ret;
411 u32 msk,val;
412 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
413 if (!scnt) return -EINVAL;
414 count -= scnt; buf += scnt;
415 if (!wptr) return -EINVAL;
416 if (debugifc_match_keyword(wptr,wlen,"dir")) {
417 dir_fl = !0;
418 } else if (!debugifc_match_keyword(wptr,wlen,"out")) {
419 return -EINVAL;
420 }
421 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
422 if (!scnt) return -EINVAL;
423 count -= scnt; buf += scnt;
424 if (!wptr) return -EINVAL;
425 ret = debugifc_parse_unsigned_number(wptr,wlen,&msk);
426 if (ret) return ret;
427 scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
428 if (wptr) {
429 ret = debugifc_parse_unsigned_number(wptr,wlen,&val);
430 if (ret) return ret;
431 } else {
432 val = msk;
433 msk = 0xffffffff;
434 }
435 if (dir_fl) {
436 ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val);
437 } else {
438 ret = pvr2_hdw_gpio_chg_out(hdw,msk,val);
439 }
440 return ret;
441 }
442 pvr2_trace(PVR2_TRACE_DEBUGIFC,
443 "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr);
444 return -EINVAL;
445}
446
447
448int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf,
449 unsigned int count)
450{
451 unsigned int bcnt = 0;
452 int ret;
453
454 while (count) {
455 for (bcnt = 0; bcnt < count; bcnt++) {
456 if (buf[bcnt] == '\n') break;
457 }
458
459 ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt);
460 if (ret < 0) return ret;
461 if (bcnt < count) bcnt++;
462 buf += bcnt;
463 count -= bcnt;
464 }
465
466 return 0;
467}
468
469
470/*
471 Stuff for Emacs to see, in order to encourage consistent editing style:
472 *** Local Variables: ***
473 *** mode: c ***
474 *** fill-column: 75 ***
475 *** tab-width: 8 ***
476 *** c-basic-offset: 8 ***
477 *** End: ***
478 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
new file mode 100644
index 000000000000..990b02d35d36
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
@@ -0,0 +1,53 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_DEBUGIFC_H
22#define __PVRUSB2_DEBUGIFC_H
23
24struct pvr2_hdw;
25
26/* Non-intrusively print some useful debugging info from inside the
27 driver. This should work even if the driver appears to be
28 wedged. */
29int pvr2_debugifc_print_info(struct pvr2_hdw *,
30 char *buf_ptr,unsigned int buf_size);
31
32/* Print general status of driver. This will also trigger a probe of
33 the USB link. Unlike print_info(), this one synchronizes with the
34 driver so the information should be self-consistent (but it will
35 hang if the driver is wedged). */
36int pvr2_debugifc_print_status(struct pvr2_hdw *,
37 char *buf_ptr,unsigned int buf_size);
38
39/* Parse a string command into a driver action. */
40int pvr2_debugifc_docmd(struct pvr2_hdw *,
41 const char *buf_ptr,unsigned int buf_size);
42
43#endif /* __PVRUSB2_DEBUGIFC_H */
44
45/*
46 Stuff for Emacs to see, in order to encourage consistent editing style:
47 *** Local Variables: ***
48 *** mode: c ***
49 *** fill-column: 75 ***
50 *** tab-width: 8 ***
51 *** c-basic-offset: 8 ***
52 *** End: ***
53 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-demod.c b/drivers/media/video/pvrusb2/pvrusb2-demod.c
new file mode 100644
index 000000000000..9686569a11f6
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-demod.c
@@ -0,0 +1,126 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include "pvrusb2.h"
24#include "pvrusb2-util.h"
25#include "pvrusb2-demod.h"
26#include "pvrusb2-hdw-internal.h"
27#include "pvrusb2-debug.h"
28#include <linux/videodev2.h>
29#include <media/tuner.h>
30#include <media/v4l2-common.h>
31
32
33struct pvr2_demod_handler {
34 struct pvr2_hdw *hdw;
35 struct pvr2_i2c_client *client;
36 struct pvr2_i2c_handler i2c_handler;
37 int type_update_fl;
38};
39
40
41static void set_config(struct pvr2_demod_handler *ctxt)
42{
43 struct pvr2_hdw *hdw = ctxt->hdw;
44 int cfg = 0;
45
46 switch (hdw->tuner_type) {
47 case TUNER_PHILIPS_FM1216ME_MK3:
48 case TUNER_PHILIPS_FM1236_MK3:
49 cfg = TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE;
50 break;
51 default:
52 break;
53 }
54 pvr2_trace(PVR2_TRACE_CHIPS,"i2c demod set_config(0x%x)",cfg);
55 pvr2_i2c_client_cmd(ctxt->client,TDA9887_SET_CONFIG,&cfg);
56 ctxt->type_update_fl = 0;
57}
58
59
60static int demod_check(struct pvr2_demod_handler *ctxt)
61{
62 struct pvr2_hdw *hdw = ctxt->hdw;
63 if (hdw->tuner_updated) ctxt->type_update_fl = !0;
64 return ctxt->type_update_fl != 0;
65}
66
67
68static void demod_update(struct pvr2_demod_handler *ctxt)
69{
70 if (ctxt->type_update_fl) set_config(ctxt);
71}
72
73
74static void demod_detach(struct pvr2_demod_handler *ctxt)
75{
76 ctxt->client->handler = 0;
77 kfree(ctxt);
78}
79
80
81static unsigned int demod_describe(struct pvr2_demod_handler *ctxt,char *buf,unsigned int cnt)
82{
83 return scnprintf(buf,cnt,"handler: pvrusb2-demod");
84}
85
86
87const static struct pvr2_i2c_handler_functions tuner_funcs = {
88 .detach = (void (*)(void *))demod_detach,
89 .check = (int (*)(void *))demod_check,
90 .update = (void (*)(void *))demod_update,
91 .describe = (unsigned int (*)(void *,char *,unsigned int))demod_describe,
92};
93
94
95int pvr2_i2c_demod_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
96{
97 struct pvr2_demod_handler *ctxt;
98 if (cp->handler) return 0;
99
100 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
101 if (!ctxt) return 0;
102 memset(ctxt,0,sizeof(*ctxt));
103
104 ctxt->i2c_handler.func_data = ctxt;
105 ctxt->i2c_handler.func_table = &tuner_funcs;
106 ctxt->type_update_fl = !0;
107 ctxt->client = cp;
108 ctxt->hdw = hdw;
109 cp->handler = &ctxt->i2c_handler;
110 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tda9887 V4L2 handler set up",
111 cp->client->addr);
112 return !0;
113}
114
115
116
117
118/*
119 Stuff for Emacs to see, in order to encourage consistent editing style:
120 *** Local Variables: ***
121 *** mode: c ***
122 *** fill-column: 70 ***
123 *** tab-width: 8 ***
124 *** c-basic-offset: 8 ***
125 *** End: ***
126 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-demod.h b/drivers/media/video/pvrusb2/pvrusb2-demod.h
new file mode 100644
index 000000000000..4c4e40ffbf03
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-demod.h
@@ -0,0 +1,38 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_DEMOD_H
22#define __PVRUSB2_DEMOD_H
23
24#include "pvrusb2-i2c-core.h"
25
26int pvr2_i2c_demod_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
27
28#endif /* __PVRUSB2_DEMOD_H */
29
30/*
31 Stuff for Emacs to see, in order to encourage consistent editing style:
32 *** Local Variables: ***
33 *** mode: c ***
34 *** fill-column: 70 ***
35 *** tab-width: 8 ***
36 *** c-basic-offset: 8 ***
37 *** End: ***
38 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
new file mode 100644
index 000000000000..94d383ff9889
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
@@ -0,0 +1,164 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include "pvrusb2-eeprom.h"
24#include "pvrusb2-hdw-internal.h"
25#include "pvrusb2-debug.h"
26
27#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
28
29
30
31/*
32
33 Read and analyze data in the eeprom. Use tveeprom to figure out
34 the packet structure, since this is another Hauppauge device and
35 internally it has a family resemblence to ivtv-type devices
36
37*/
38
39#include <media/tveeprom.h>
40
41/* We seem to only be interested in the last 128 bytes of the EEPROM */
42#define EEPROM_SIZE 128
43
44/* Grab EEPROM contents, needed for direct method. */
45static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw)
46{
47 struct i2c_msg msg[2];
48 u8 *eeprom;
49 u8 iadd[2];
50 u8 addr;
51 u16 eepromSize;
52 unsigned int offs;
53 int ret;
54 int mode16 = 0;
55 unsigned pcnt,tcnt;
56 eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
57 if (!eeprom) {
58 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
59 "Failed to allocate memory"
60 " required to read eeprom");
61 return 0;
62 }
63
64 trace_eeprom("Value for eeprom addr from controller was 0x%x",
65 hdw->eeprom_addr);
66 addr = hdw->eeprom_addr;
67 /* Seems that if the high bit is set, then the *real* eeprom
68 address is shifted right now bit position (noticed this in
69 newer PVR USB2 hardware) */
70 if (addr & 0x80) addr >>= 1;
71
72 /* FX2 documentation states that a 16bit-addressed eeprom is
73 expected if the I2C address is an odd number (yeah, this is
74 strange but it's what they do) */
75 mode16 = (addr & 1);
76 eepromSize = (mode16 ? 4096 : 256);
77 trace_eeprom("Examining %d byte eeprom at location 0x%x"
78 " using %d bit addressing",eepromSize,addr,
79 mode16 ? 16 : 8);
80
81 msg[0].addr = addr;
82 msg[0].flags = 0;
83 msg[0].len = mode16 ? 2 : 1;
84 msg[0].buf = iadd;
85 msg[1].addr = addr;
86 msg[1].flags = I2C_M_RD;
87
88 /* We have to do the actual eeprom data fetch ourselves, because
89 (1) we're only fetching part of the eeprom, and (2) if we were
90 getting the whole thing our I2C driver can't grab it in one
91 pass - which is what tveeprom is otherwise going to attempt */
92 memset(eeprom,0,EEPROM_SIZE);
93 for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
94 pcnt = 16;
95 if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
96 offs = tcnt + (eepromSize - EEPROM_SIZE);
97 if (mode16) {
98 iadd[0] = offs >> 8;
99 iadd[1] = offs;
100 } else {
101 iadd[0] = offs;
102 }
103 msg[1].len = pcnt;
104 msg[1].buf = eeprom+tcnt;
105 if ((ret = i2c_transfer(
106 &hdw->i2c_adap,
107 msg,sizeof(msg)/sizeof(msg[0]))) != 2) {
108 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
109 "eeprom fetch set offs err=%d",ret);
110 kfree(eeprom);
111 return 0;
112 }
113 }
114 return eeprom;
115}
116
117
118/* Directly call eeprom analysis function within tveeprom. */
119int pvr2_eeprom_analyze(struct pvr2_hdw *hdw)
120{
121 u8 *eeprom;
122 struct tveeprom tvdata;
123
124 memset(&tvdata,0,sizeof(tvdata));
125
126 eeprom = pvr2_eeprom_fetch(hdw);
127 if (!eeprom) return -EINVAL;
128
129 {
130 struct i2c_client fake_client;
131 /* Newer version expects a useless client interface */
132 fake_client.addr = hdw->eeprom_addr;
133 fake_client.adapter = &hdw->i2c_adap;
134 tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom);
135 }
136
137 trace_eeprom("eeprom assumed v4l tveeprom module");
138 trace_eeprom("eeprom direct call results:");
139 trace_eeprom("has_radio=%d",tvdata.has_radio);
140 trace_eeprom("tuner_type=%d",tvdata.tuner_type);
141 trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats);
142 trace_eeprom("audio_processor=%d",tvdata.audio_processor);
143 trace_eeprom("model=%d",tvdata.model);
144 trace_eeprom("revision=%d",tvdata.revision);
145 trace_eeprom("serial_number=%d",tvdata.serial_number);
146 trace_eeprom("rev_str=%s",tvdata.rev_str);
147 hdw->tuner_type = tvdata.tuner_type;
148 hdw->serial_number = tvdata.serial_number;
149 hdw->std_mask_eeprom = tvdata.tuner_formats;
150
151 kfree(eeprom);
152
153 return 0;
154}
155
156/*
157 Stuff for Emacs to see, in order to encourage consistent editing style:
158 *** Local Variables: ***
159 *** mode: c ***
160 *** fill-column: 70 ***
161 *** tab-width: 8 ***
162 *** c-basic-offset: 8 ***
163 *** End: ***
164 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
new file mode 100644
index 000000000000..84242975dea7
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
@@ -0,0 +1,40 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef __PVRUSB2_EEPROM_H
24#define __PVRUSB2_EEPROM_H
25
26struct pvr2_hdw;
27
28int pvr2_eeprom_analyze(struct pvr2_hdw *);
29
30#endif /* __PVRUSB2_EEPROM_H */
31
32/*
33 Stuff for Emacs to see, in order to encourage consistent editing style:
34 *** Local Variables: ***
35 *** mode: c ***
36 *** fill-column: 70 ***
37 *** tab-width: 8 ***
38 *** c-basic-offset: 8 ***
39 *** End: ***
40 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
new file mode 100644
index 000000000000..2cc31695b435
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -0,0 +1,418 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <linux/device.h> // for linux/firmware.h
24#include <linux/firmware.h>
25#include "pvrusb2-util.h"
26#include "pvrusb2-encoder.h"
27#include "pvrusb2-hdw-internal.h"
28#include "pvrusb2-debug.h"
29
30
31
32/* Firmware mailbox flags - definitions found from ivtv */
33#define IVTV_MBOX_FIRMWARE_DONE 0x00000004
34#define IVTV_MBOX_DRIVER_DONE 0x00000002
35#define IVTV_MBOX_DRIVER_BUSY 0x00000001
36
37
38static int pvr2_encoder_write_words(struct pvr2_hdw *hdw,
39 const u32 *data, unsigned int dlen)
40{
41 unsigned int idx;
42 int ret;
43 unsigned int offs = 0;
44 unsigned int chunkCnt;
45
46 /*
47
48 Format: First byte must be 0x01. Remaining 32 bit words are
49 spread out into chunks of 7 bytes each, little-endian ordered,
50 offset at zero within each 2 blank bytes following and a
51 single byte that is 0x44 plus the offset of the word. Repeat
52 request for additional words, with offset adjusted
53 accordingly.
54
55 */
56 while (dlen) {
57 chunkCnt = 8;
58 if (chunkCnt > dlen) chunkCnt = dlen;
59 memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
60 hdw->cmd_buffer[0] = 0x01;
61 for (idx = 0; idx < chunkCnt; idx++) {
62 hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs;
63 PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7),
64 data[idx]);
65 }
66 ret = pvr2_send_request(hdw,
67 hdw->cmd_buffer,1+(chunkCnt*7),
68 0,0);
69 if (ret) return ret;
70 data += chunkCnt;
71 dlen -= chunkCnt;
72 offs += chunkCnt;
73 }
74
75 return 0;
76}
77
78
79static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,int statusFl,
80 u32 *data, unsigned int dlen)
81{
82 unsigned int idx;
83 int ret;
84 unsigned int offs = 0;
85 unsigned int chunkCnt;
86
87 /*
88
89 Format: First byte must be 0x02 (status check) or 0x28 (read
90 back block of 32 bit words). Next 6 bytes must be zero,
91 followed by a single byte of 0x44+offset for portion to be
92 read. Returned data is packed set of 32 bits words that were
93 read.
94
95 */
96
97 while (dlen) {
98 chunkCnt = 16;
99 if (chunkCnt > dlen) chunkCnt = dlen;
100 memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
101 hdw->cmd_buffer[0] = statusFl ? 0x02 : 0x28;
102 hdw->cmd_buffer[7] = 0x44 + offs;
103 ret = pvr2_send_request(hdw,
104 hdw->cmd_buffer,8,
105 hdw->cmd_buffer,chunkCnt * 4);
106 if (ret) return ret;
107
108 for (idx = 0; idx < chunkCnt; idx++) {
109 data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4);
110 }
111 data += chunkCnt;
112 dlen -= chunkCnt;
113 offs += chunkCnt;
114 }
115
116 return 0;
117}
118
119
120/* This prototype is set up to be compatible with the
121 cx2341x_mbox_func prototype in cx2341x.h, which should be in
122 kernels 2.6.18 or later. We do this so that we can enable
123 cx2341x.ko to write to our encoder (by handing it a pointer to this
124 function). For earlier kernels this doesn't really matter. */
125static int pvr2_encoder_cmd(void *ctxt,
126 int cmd,
127 int arg_cnt_send,
128 int arg_cnt_recv,
129 u32 *argp)
130{
131 unsigned int poll_count;
132 int ret = 0;
133 unsigned int idx;
134 /* These sizes look to be limited by the FX2 firmware implementation */
135 u32 wrData[16];
136 u32 rdData[16];
137 struct pvr2_hdw *hdw = (struct pvr2_hdw *)ctxt;
138
139
140 /*
141
142 The encoder seems to speak entirely using blocks 32 bit words.
143 In ivtv driver terms, this is a mailbox which we populate with
144 data and watch what the hardware does with it. The first word
145 is a set of flags used to control the transaction, the second
146 word is the command to execute, the third byte is zero (ivtv
147 driver suggests that this is some kind of return value), and
148 the fourth byte is a specified timeout (windows driver always
149 uses 0x00060000 except for one case when it is zero). All
150 successive words are the argument words for the command.
151
152 First, write out the entire set of words, with the first word
153 being zero.
154
155 Next, write out just the first word again, but set it to
156 IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which
157 probably means "go").
158
159 Next, read back 16 words as status. Check the first word,
160 which should have IVTV_MBOX_FIRMWARE_DONE set. If however
161 that bit is not set, then the command isn't done so repeat the
162 read.
163
164 Next, read back 32 words and compare with the original
165 arugments. Hopefully they will match.
166
167 Finally, write out just the first word again, but set it to
168 0x0 this time (which probably means "idle").
169
170 */
171
172 if (arg_cnt_send > (sizeof(wrData)/sizeof(wrData[0]))-4) {
173 pvr2_trace(
174 PVR2_TRACE_ERROR_LEGS,
175 "Failed to write cx23416 command"
176 " - too many input arguments"
177 " (was given %u limit %u)",
178 arg_cnt_send,
179 (unsigned int)(sizeof(wrData)/sizeof(wrData[0])) - 4);
180 return -EINVAL;
181 }
182
183 if (arg_cnt_recv > (sizeof(rdData)/sizeof(rdData[0]))-4) {
184 pvr2_trace(
185 PVR2_TRACE_ERROR_LEGS,
186 "Failed to write cx23416 command"
187 " - too many return arguments"
188 " (was given %u limit %u)",
189 arg_cnt_recv,
190 (unsigned int)(sizeof(rdData)/sizeof(rdData[0])) - 4);
191 return -EINVAL;
192 }
193
194
195 LOCK_TAKE(hdw->ctl_lock); do {
196
197 wrData[0] = 0;
198 wrData[1] = cmd;
199 wrData[2] = 0;
200 wrData[3] = 0x00060000;
201 for (idx = 0; idx < arg_cnt_send; idx++) {
202 wrData[idx+4] = argp[idx];
203 }
204 for (; idx < (sizeof(wrData)/sizeof(wrData[0]))-4; idx++) {
205 wrData[idx+4] = 0;
206 }
207
208 ret = pvr2_encoder_write_words(hdw,wrData,idx);
209 if (ret) break;
210 wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY;
211 ret = pvr2_encoder_write_words(hdw,wrData,1);
212 if (ret) break;
213 poll_count = 0;
214 while (1) {
215 if (poll_count < 10000000) poll_count++;
216 ret = pvr2_encoder_read_words(hdw,!0,rdData,1);
217 if (ret) break;
218 if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) {
219 break;
220 }
221 if (poll_count == 100) {
222 pvr2_trace(
223 PVR2_TRACE_ERROR_LEGS,
224 "***WARNING*** device's encoder"
225 " appears to be stuck"
226 " (status=0%08x)",rdData[0]);
227 pvr2_trace(
228 PVR2_TRACE_ERROR_LEGS,
229 "Encoder command: 0x%02x",cmd);
230 for (idx = 4; idx < arg_cnt_send; idx++) {
231 pvr2_trace(
232 PVR2_TRACE_ERROR_LEGS,
233 "Encoder arg%d: 0x%08x",
234 idx-3,wrData[idx]);
235 }
236 pvr2_trace(
237 PVR2_TRACE_ERROR_LEGS,
238 "Giving up waiting."
239 " It is likely that"
240 " this is a bad idea...");
241 ret = -EBUSY;
242 break;
243 }
244 }
245 if (ret) break;
246 wrData[0] = 0x7;
247 ret = pvr2_encoder_read_words(
248 hdw,0,rdData,
249 sizeof(rdData)/sizeof(rdData[0]));
250 if (ret) break;
251 for (idx = 0; idx < arg_cnt_recv; idx++) {
252 argp[idx] = rdData[idx+4];
253 }
254
255 wrData[0] = 0x0;
256 ret = pvr2_encoder_write_words(hdw,wrData,1);
257 if (ret) break;
258
259 } while(0); LOCK_GIVE(hdw->ctl_lock);
260
261 return ret;
262}
263
264
265static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd,
266 int args, ...)
267{
268 va_list vl;
269 unsigned int idx;
270 u32 data[12];
271
272 if (args > sizeof(data)/sizeof(data[0])) {
273 pvr2_trace(
274 PVR2_TRACE_ERROR_LEGS,
275 "Failed to write cx23416 command"
276 " - too many arguments"
277 " (was given %u limit %u)",
278 args,(unsigned int)(sizeof(data)/sizeof(data[0])));
279 return -EINVAL;
280 }
281
282 va_start(vl, args);
283 for (idx = 0; idx < args; idx++) {
284 data[idx] = va_arg(vl, u32);
285 }
286 va_end(vl);
287
288 return pvr2_encoder_cmd(hdw,cmd,args,0,data);
289}
290
291int pvr2_encoder_configure(struct pvr2_hdw *hdw)
292{
293 int ret;
294 pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure"
295 " (cx2341x module)");
296 hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING;
297 hdw->enc_ctl_state.width = hdw->res_hor_val;
298 hdw->enc_ctl_state.height = hdw->res_ver_val;
299 hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur &
300 (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ?
301 0 : 1);
302
303 ret = 0;
304
305 if (!ret) ret = pvr2_encoder_vcmd(
306 hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
307 0xf0, 0xf0);
308
309 /* setup firmware to notify us about some events (don't know why...) */
310 if (!ret) ret = pvr2_encoder_vcmd(
311 hdw,CX2341X_ENC_SET_EVENT_NOTIFICATION, 4,
312 0, 0, 0x10000000, 0xffffffff);
313
314 if (!ret) ret = pvr2_encoder_vcmd(
315 hdw,CX2341X_ENC_SET_VBI_LINE, 5,
316 0xffffffff,0,0,0,0);
317
318 if (ret) {
319 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
320 "Failed to configure cx32416");
321 return ret;
322 }
323
324 ret = cx2341x_update(hdw,pvr2_encoder_cmd,
325 (hdw->enc_cur_valid ? &hdw->enc_cur_state : 0),
326 &hdw->enc_ctl_state);
327 if (ret) {
328 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
329 "Error from cx2341x module code=%d",ret);
330 return ret;
331 }
332
333 ret = 0;
334
335 if (!ret) ret = pvr2_encoder_vcmd(
336 hdw, CX2341X_ENC_INITIALIZE_INPUT, 0);
337
338 if (ret) {
339 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
340 "Failed to initialize cx32416 video input");
341 return ret;
342 }
343
344 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
345 memcpy(&hdw->enc_cur_state,&hdw->enc_ctl_state,
346 sizeof(struct cx2341x_mpeg_params));
347 hdw->enc_cur_valid = !0;
348 return 0;
349}
350
351
352int pvr2_encoder_start(struct pvr2_hdw *hdw)
353{
354 int status;
355
356 /* unmask some interrupts */
357 pvr2_write_register(hdw, 0x0048, 0xbfffffff);
358
359 /* change some GPIO data */
360 pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000481);
361 pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000);
362
363 if (hdw->config == pvr2_config_vbi) {
364 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
365 0x01,0x14);
366 } else if (hdw->config == pvr2_config_mpeg) {
367 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
368 0,0x13);
369 } else {
370 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
371 0,0x13);
372 }
373 if (!status) {
374 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
375 }
376 return status;
377}
378
379int pvr2_encoder_stop(struct pvr2_hdw *hdw)
380{
381 int status;
382
383 /* mask all interrupts */
384 pvr2_write_register(hdw, 0x0048, 0xffffffff);
385
386 if (hdw->config == pvr2_config_vbi) {
387 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
388 0x01,0x01,0x14);
389 } else if (hdw->config == pvr2_config_mpeg) {
390 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
391 0x01,0,0x13);
392 } else {
393 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
394 0x01,0,0x13);
395 }
396
397 /* change some GPIO data */
398 /* Note: Bit d7 of dir appears to control the LED. So we shut it
399 off here. */
400 pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401);
401 pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000);
402
403 if (!status) {
404 hdw->subsys_enabled_mask &= ~(1<<PVR2_SUBSYS_B_ENC_RUN);
405 }
406 return status;
407}
408
409
410/*
411 Stuff for Emacs to see, in order to encourage consistent editing style:
412 *** Local Variables: ***
413 *** mode: c ***
414 *** fill-column: 70 ***
415 *** tab-width: 8 ***
416 *** c-basic-offset: 8 ***
417 *** End: ***
418 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.h b/drivers/media/video/pvrusb2/pvrusb2-encoder.h
new file mode 100644
index 000000000000..01b5a0b89c03
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.h
@@ -0,0 +1,42 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef __PVRUSB2_ENCODER_H
24#define __PVRUSB2_ENCODER_H
25
26struct pvr2_hdw;
27
28int pvr2_encoder_configure(struct pvr2_hdw *);
29int pvr2_encoder_start(struct pvr2_hdw *);
30int pvr2_encoder_stop(struct pvr2_hdw *);
31
32#endif /* __PVRUSB2_ENCODER_H */
33
34/*
35 Stuff for Emacs to see, in order to encourage consistent editing style:
36 *** Local Variables: ***
37 *** mode: c ***
38 *** fill-column: 70 ***
39 *** tab-width: 8 ***
40 *** c-basic-offset: 8 ***
41 *** End: ***
42 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
new file mode 100644
index 000000000000..ba2afbfe32c5
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -0,0 +1,384 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_HDW_INTERNAL_H
22#define __PVRUSB2_HDW_INTERNAL_H
23
24/*
25
26 This header sets up all the internal structures and definitions needed to
27 track and coordinate the driver's interaction with the hardware. ONLY
28 source files which actually implement part of that whole circus should be
29 including this header. Higher levels, like the external layers to the
30 various public APIs (V4L, sysfs, etc) should NOT ever include this
31 private, internal header. This means that pvrusb2-hdw, pvrusb2-encoder,
32 etc will include this, but pvrusb2-v4l should not.
33
34*/
35
36#include <linux/config.h>
37#include <linux/videodev2.h>
38#include <linux/i2c.h>
39#include <linux/mutex.h>
40#include "pvrusb2-hdw.h"
41#include "pvrusb2-io.h"
42#include <media/cx2341x.h>
43
44/* Legal values for the SRATE state variable */
45#define PVR2_CVAL_SRATE_48 0
46#define PVR2_CVAL_SRATE_44_1 1
47
48/* Legal values for the AUDIOBITRATE state variable */
49#define PVR2_CVAL_AUDIOBITRATE_384 0
50#define PVR2_CVAL_AUDIOBITRATE_320 1
51#define PVR2_CVAL_AUDIOBITRATE_256 2
52#define PVR2_CVAL_AUDIOBITRATE_224 3
53#define PVR2_CVAL_AUDIOBITRATE_192 4
54#define PVR2_CVAL_AUDIOBITRATE_160 5
55#define PVR2_CVAL_AUDIOBITRATE_128 6
56#define PVR2_CVAL_AUDIOBITRATE_112 7
57#define PVR2_CVAL_AUDIOBITRATE_96 8
58#define PVR2_CVAL_AUDIOBITRATE_80 9
59#define PVR2_CVAL_AUDIOBITRATE_64 10
60#define PVR2_CVAL_AUDIOBITRATE_56 11
61#define PVR2_CVAL_AUDIOBITRATE_48 12
62#define PVR2_CVAL_AUDIOBITRATE_32 13
63#define PVR2_CVAL_AUDIOBITRATE_VBR 14
64
65/* Legal values for the AUDIOEMPHASIS state variable */
66#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0
67#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1
68#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2
69
70/* Legal values for PVR2_CID_HSM */
71#define PVR2_CVAL_HSM_FAIL 0
72#define PVR2_CVAL_HSM_FULL 1
73#define PVR2_CVAL_HSM_HIGH 2
74
75#define PVR2_VID_ENDPOINT 0x84
76#define PVR2_UNK_ENDPOINT 0x86 /* maybe raw yuv ? */
77#define PVR2_VBI_ENDPOINT 0x88
78
79#define PVR2_CTL_BUFFSIZE 64
80
81#define FREQTABLE_SIZE 500
82
83#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0)
84#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0)
85
86struct pvr2_decoder;
87
88typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *);
89typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *);
90typedef int (*pvr2_ctlf_get_value)(struct pvr2_ctrl *,int *);
91typedef int (*pvr2_ctlf_set_value)(struct pvr2_ctrl *,int msk,int val);
92typedef int (*pvr2_ctlf_val_to_sym)(struct pvr2_ctrl *,int msk,int val,
93 char *,unsigned int,unsigned int *);
94typedef int (*pvr2_ctlf_sym_to_val)(struct pvr2_ctrl *,
95 const char *,unsigned int,
96 int *mskp,int *valp);
97typedef unsigned int (*pvr2_ctlf_get_v4lflags)(struct pvr2_ctrl *);
98
99/* This structure describes a specific control. A table of these is set up
100 in pvrusb2-hdw.c. */
101struct pvr2_ctl_info {
102 /* Control's name suitable for use as an identifier */
103 const char *name;
104
105 /* Short description of control */
106 const char *desc;
107
108 /* Control's implementation */
109 pvr2_ctlf_get_value get_value; /* Get its value */
110 pvr2_ctlf_set_value set_value; /* Set its value */
111 pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */
112 pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */
113 pvr2_ctlf_is_dirty is_dirty; /* Return true if dirty */
114 pvr2_ctlf_clear_dirty clear_dirty; /* Clear dirty state */
115 pvr2_ctlf_get_v4lflags get_v4lflags;/* Retrieve v4l flags */
116
117 /* Control's type (int, enum, bitmask) */
118 enum pvr2_ctl_type type;
119
120 /* Associated V4L control ID, if any */
121 int v4l_id;
122
123 /* Associated driver internal ID, if any */
124 int internal_id;
125
126 /* Don't implicitly initialize this control's value */
127 int skip_init;
128
129 /* Starting value for this control */
130 int default_value;
131
132 /* Type-specific control information */
133 union {
134 struct { /* Integer control */
135 long min_value; /* lower limit */
136 long max_value; /* upper limit */
137 } type_int;
138 struct { /* enumerated control */
139 unsigned int count; /* enum value count */
140 const char **value_names; /* symbol names */
141 } type_enum;
142 struct { /* bitmask control */
143 unsigned int valid_bits; /* bits in use */
144 const char **bit_names; /* symbol name/bit */
145 } type_bitmask;
146 } def;
147};
148
149
150/* Same as pvr2_ctl_info, but includes storage for the control description */
151#define PVR2_CTLD_INFO_DESC_SIZE 32
152struct pvr2_ctld_info {
153 struct pvr2_ctl_info info;
154 char desc[PVR2_CTLD_INFO_DESC_SIZE];
155};
156
157struct pvr2_ctrl {
158 const struct pvr2_ctl_info *info;
159 struct pvr2_hdw *hdw;
160};
161
162
163struct pvr2_audio_stat {
164 void *ctxt;
165 void (*detach)(void *);
166 int (*status)(void *);
167};
168
169struct pvr2_decoder_ctrl {
170 void *ctxt;
171 void (*detach)(void *);
172 void (*enable)(void *,int);
173 int (*tuned)(void *);
174 void (*force_reset)(void *);
175};
176
177#define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */
178#define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */
179#define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */
180#define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */
181
182#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\
183 PVR2_I2C_PEND_CLIENT |\
184 PVR2_I2C_PEND_REFRESH |\
185 PVR2_I2C_PEND_STALE)
186
187/* Disposition of firmware1 loading situation */
188#define FW1_STATE_UNKNOWN 0
189#define FW1_STATE_MISSING 1
190#define FW1_STATE_FAILED 2
191#define FW1_STATE_RELOAD 3
192#define FW1_STATE_OK 4
193
194/* Known major hardware variants, keyed from device ID */
195#define PVR2_HDW_TYPE_29XXX 0
196#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
197#define PVR2_HDW_TYPE_24XXX 1
198#endif
199
200typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16);
201#define PVR2_I2C_FUNC_CNT 128
202
203/* This structure contains all state data directly needed to
204 manipulate the hardware (as opposed to complying with a kernel
205 interface) */
206struct pvr2_hdw {
207 /* Underlying USB device handle */
208 struct usb_device *usb_dev;
209 struct usb_interface *usb_intf;
210
211 /* Device type, one of PVR2_HDW_TYPE_xxxxx */
212 unsigned int hdw_type;
213
214 /* Video spigot */
215 struct pvr2_stream *vid_stream;
216
217 /* Mutex for all hardware state control */
218 struct mutex big_lock_mutex;
219 int big_lock_held; /* For debugging */
220
221 void (*poll_trigger_func)(void *);
222 void *poll_trigger_data;
223
224 char name[32];
225
226 /* I2C stuff */
227 struct i2c_adapter i2c_adap;
228 struct i2c_algorithm i2c_algo;
229 pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
230 int i2c_cx25840_hack_state;
231 int i2c_linked;
232 unsigned int i2c_pend_types; /* Which types of update are needed */
233 unsigned long i2c_pend_mask; /* Change bits we need to scan */
234 unsigned long i2c_stale_mask; /* Pending broadcast change bits */
235 unsigned long i2c_active_mask; /* All change bits currently in use */
236 struct list_head i2c_clients;
237 struct mutex i2c_list_lock;
238
239 /* Frequency table */
240 unsigned int freqTable[FREQTABLE_SIZE];
241 unsigned int freqProgSlot;
242 unsigned int freqSlot;
243
244 /* Stuff for handling low level control interaction with device */
245 struct mutex ctl_lock_mutex;
246 int ctl_lock_held; /* For debugging */
247 struct urb *ctl_write_urb;
248 struct urb *ctl_read_urb;
249 unsigned char *ctl_write_buffer;
250 unsigned char *ctl_read_buffer;
251 volatile int ctl_write_pend_flag;
252 volatile int ctl_read_pend_flag;
253 volatile int ctl_timeout_flag;
254 struct completion ctl_done;
255 unsigned char cmd_buffer[PVR2_CTL_BUFFSIZE];
256 int cmd_debug_state; // Low level command debugging info
257 unsigned char cmd_debug_code; //
258 unsigned int cmd_debug_write_len; //
259 unsigned int cmd_debug_read_len; //
260
261 int flag_ok; // device in known good state
262 int flag_disconnected; // flag_ok == 0 due to disconnect
263 int flag_init_ok; // true if structure is fully initialized
264 int flag_streaming_enabled; // true if streaming should be on
265 int fw1_state; // current situation with fw1
266
267 int flag_decoder_is_tuned;
268
269 struct pvr2_decoder_ctrl *decoder_ctrl;
270
271 // CPU firmware info (used to help find / save firmware data)
272 char *fw_buffer;
273 unsigned int fw_size;
274
275 // Which subsystem pieces have been enabled / configured
276 unsigned long subsys_enabled_mask;
277
278 // Which subsystems are manipulated to enable streaming
279 unsigned long subsys_stream_mask;
280
281 // True if there is a request to trigger logging of state in each
282 // module.
283 int log_requested;
284
285 /* Tuner / frequency control stuff */
286 unsigned int tuner_type;
287 int tuner_updated;
288 unsigned int freqVal;
289 int freqDirty;
290
291 /* Video standard handling */
292 v4l2_std_id std_mask_eeprom; // Hardware supported selections
293 v4l2_std_id std_mask_avail; // Which standards we may select from
294 v4l2_std_id std_mask_cur; // Currently selected standard(s)
295 unsigned int std_enum_cnt; // # of enumerated standards
296 int std_enum_cur; // selected standard enumeration value
297 int std_dirty; // True if std_mask_cur has changed
298 struct pvr2_ctl_info std_info_enum;
299 struct pvr2_ctl_info std_info_avail;
300 struct pvr2_ctl_info std_info_cur;
301 struct v4l2_standard *std_defs;
302 const char **std_enum_names;
303
304 // Generated string names, one per actual V4L2 standard
305 const char *std_mask_ptrs[32];
306 char std_mask_names[32][10];
307
308 int unit_number; /* ID for driver instance */
309 unsigned long serial_number; /* ID for hardware itself */
310
311 /* Minor number used by v4l logic (yes, this is a hack, as there should
312 be no v4l junk here). Probably a better way to do this. */
313 int v4l_minor_number;
314
315 /* Location of eeprom or a negative number if none */
316 int eeprom_addr;
317
318 enum pvr2_config config;
319
320 /* Information about what audio signal we're hearing */
321 int flag_stereo;
322 int flag_bilingual;
323 struct pvr2_audio_stat *audio_stat;
324
325 /* Control state needed for cx2341x module */
326 struct cx2341x_mpeg_params enc_cur_state;
327 struct cx2341x_mpeg_params enc_ctl_state;
328 /* True if an encoder attribute has changed */
329 int enc_stale;
330 /* True if enc_cur_state is valid */
331 int enc_cur_valid;
332
333 /* Control state */
334#define VCREATE_DATA(lab) int lab##_val; int lab##_dirty
335 VCREATE_DATA(brightness);
336 VCREATE_DATA(contrast);
337 VCREATE_DATA(saturation);
338 VCREATE_DATA(hue);
339 VCREATE_DATA(volume);
340 VCREATE_DATA(balance);
341 VCREATE_DATA(bass);
342 VCREATE_DATA(treble);
343 VCREATE_DATA(mute);
344 VCREATE_DATA(input);
345 VCREATE_DATA(audiomode);
346 VCREATE_DATA(res_hor);
347 VCREATE_DATA(res_ver);
348 VCREATE_DATA(srate);
349#undef VCREATE_DATA
350
351 struct pvr2_ctld_info *mpeg_ctrl_info;
352
353 struct pvr2_ctrl *controls;
354 unsigned int control_cnt;
355};
356
357int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
358
359unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *);
360
361void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
362 unsigned long msk,unsigned long val);
363void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
364 unsigned long msk,
365 unsigned long val);
366
367void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
368void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
369
370int pvr2_i2c_basic_op(struct pvr2_hdw *,u8 i2c_addr,
371 u8 *wdata,u16 wlen,
372 u8 *rdata,u16 rlen);
373
374#endif /* __PVRUSB2_HDW_INTERNAL_H */
375
376/*
377 Stuff for Emacs to see, in order to encourage consistent editing style:
378 *** Local Variables: ***
379 *** mode: c ***
380 *** fill-column: 75 ***
381 *** tab-width: 8 ***
382 *** c-basic-offset: 8 ***
383 *** End: ***
384 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
new file mode 100644
index 000000000000..643c471375da
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -0,0 +1,3120 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21
22#include <linux/errno.h>
23#include <linux/string.h>
24#include <linux/slab.h>
25#include <linux/firmware.h>
26#include <linux/videodev2.h>
27#include <asm/semaphore.h>
28#include "pvrusb2.h"
29#include "pvrusb2-std.h"
30#include "pvrusb2-util.h"
31#include "pvrusb2-hdw.h"
32#include "pvrusb2-i2c-core.h"
33#include "pvrusb2-tuner.h"
34#include "pvrusb2-eeprom.h"
35#include "pvrusb2-hdw-internal.h"
36#include "pvrusb2-encoder.h"
37#include "pvrusb2-debug.h"
38
39struct usb_device_id pvr2_device_table[] = {
40 [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
41#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
42 [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
43#endif
44 { }
45};
46
47MODULE_DEVICE_TABLE(usb, pvr2_device_table);
48
49static const char *pvr2_device_names[] = {
50 [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
51#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
52 [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
53#endif
54};
55
56struct pvr2_string_table {
57 const char **lst;
58 unsigned int cnt;
59};
60
61#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
62// Names of other client modules to request for 24xxx model hardware
63static const char *pvr2_client_24xxx[] = {
64 "cx25840",
65 "tuner",
66 "tda9887",
67 "wm8775",
68};
69#endif
70
71// Names of other client modules to request for 29xxx model hardware
72static const char *pvr2_client_29xxx[] = {
73 "msp3400",
74 "saa7115",
75 "tuner",
76 "tda9887",
77};
78
79static struct pvr2_string_table pvr2_client_lists[] = {
80 [PVR2_HDW_TYPE_29XXX] = {
81 pvr2_client_29xxx,
82 sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]),
83 },
84#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
85 [PVR2_HDW_TYPE_24XXX] = {
86 pvr2_client_24xxx,
87 sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]),
88 },
89#endif
90};
91
92static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0};
93DECLARE_MUTEX(pvr2_unit_sem);
94
95static int ctlchg = 0;
96static int initusbreset = 1;
97static int procreload = 0;
98static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
99static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
100static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
101static int init_pause_msec = 0;
102
103module_param(ctlchg, int, S_IRUGO|S_IWUSR);
104MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
105module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
106MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
107module_param(initusbreset, int, S_IRUGO|S_IWUSR);
108MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
109module_param(procreload, int, S_IRUGO|S_IWUSR);
110MODULE_PARM_DESC(procreload,
111 "Attempt init failure recovery with firmware reload");
112module_param_array(tuner, int, NULL, 0444);
113MODULE_PARM_DESC(tuner,"specify installed tuner type");
114module_param_array(video_std, int, NULL, 0444);
115MODULE_PARM_DESC(video_std,"specify initial video standard");
116module_param_array(tolerance, int, NULL, 0444);
117MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
118
119#define PVR2_CTL_WRITE_ENDPOINT 0x01
120#define PVR2_CTL_READ_ENDPOINT 0x81
121
122#define PVR2_GPIO_IN 0x9008
123#define PVR2_GPIO_OUT 0x900c
124#define PVR2_GPIO_DIR 0x9020
125
126#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
127
128#define PVR2_FIRMWARE_ENDPOINT 0x02
129
130/* size of a firmware chunk */
131#define FIRMWARE_CHUNK_SIZE 0x2000
132
133/* Define the list of additional controls we'll dynamically construct based
134 on query of the cx2341x module. */
135struct pvr2_mpeg_ids {
136 const char *strid;
137 int id;
138};
139static const struct pvr2_mpeg_ids mpeg_ids[] = {
140 {
141 .strid = "audio_layer",
142 .id = V4L2_CID_MPEG_AUDIO_ENCODING,
143 },{
144 .strid = "audio_bitrate",
145 .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE,
146 },{
147 /* Already using audio_mode elsewhere :-( */
148 .strid = "mpeg_audio_mode",
149 .id = V4L2_CID_MPEG_AUDIO_MODE,
150 },{
151 .strid = "mpeg_audio_mode_extension",
152 .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
153 },{
154 .strid = "audio_emphasis",
155 .id = V4L2_CID_MPEG_AUDIO_EMPHASIS,
156 },{
157 .strid = "audio_crc",
158 .id = V4L2_CID_MPEG_AUDIO_CRC,
159 },{
160 .strid = "video_aspect",
161 .id = V4L2_CID_MPEG_VIDEO_ASPECT,
162 },{
163 .strid = "video_b_frames",
164 .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
165 },{
166 .strid = "video_gop_size",
167 .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
168 },{
169 .strid = "video_gop_closure",
170 .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
171 },{
172 .strid = "video_pulldown",
173 .id = V4L2_CID_MPEG_VIDEO_PULLDOWN,
174 },{
175 .strid = "video_bitrate_mode",
176 .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
177 },{
178 .strid = "video_bitrate",
179 .id = V4L2_CID_MPEG_VIDEO_BITRATE,
180 },{
181 .strid = "video_bitrate_peak",
182 .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
183 },{
184 .strid = "video_temporal_decimation",
185 .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
186 },{
187 .strid = "stream_type",
188 .id = V4L2_CID_MPEG_STREAM_TYPE,
189 },{
190 .strid = "video_spatial_filter_mode",
191 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
192 },{
193 .strid = "video_spatial_filter",
194 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
195 },{
196 .strid = "video_luma_spatial_filter_type",
197 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
198 },{
199 .strid = "video_chroma_spatial_filter_type",
200 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
201 },{
202 .strid = "video_temporal_filter_mode",
203 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
204 },{
205 .strid = "video_temporal_filter",
206 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
207 },{
208 .strid = "video_median_filter_type",
209 .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
210 },{
211 .strid = "video_luma_median_filter_top",
212 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
213 },{
214 .strid = "video_luma_median_filter_bottom",
215 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
216 },{
217 .strid = "video_chroma_median_filter_top",
218 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
219 },{
220 .strid = "video_chroma_median_filter_bottom",
221 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
222 }
223};
224#define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0]))
225
226static const char *control_values_srate[] = {
227 [PVR2_CVAL_SRATE_48] = "48KHz",
228 [PVR2_CVAL_SRATE_44_1] = "44.1KHz",
229};
230
231
232
233
234static const char *control_values_input[] = {
235 [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
236 [PVR2_CVAL_INPUT_RADIO] = "radio",
237 [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
238 [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
239};
240
241
242static const char *control_values_audiomode[] = {
243 [V4L2_TUNER_MODE_MONO] = "Mono",
244 [V4L2_TUNER_MODE_STEREO] = "Stereo",
245 [V4L2_TUNER_MODE_LANG1] = "Lang1",
246 [V4L2_TUNER_MODE_LANG2] = "Lang2",
247 [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
248};
249
250
251static const char *control_values_hsm[] = {
252 [PVR2_CVAL_HSM_FAIL] = "Fail",
253 [PVR2_CVAL_HSM_HIGH] = "High",
254 [PVR2_CVAL_HSM_FULL] = "Full",
255};
256
257
258static const char *control_values_subsystem[] = {
259 [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware",
260 [PVR2_SUBSYS_B_ENC_CFG] = "enc_config",
261 [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run",
262 [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run",
263 [PVR2_SUBSYS_B_ENC_RUN] = "enc_run",
264};
265
266
267static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
268{
269 struct pvr2_hdw *hdw = cptr->hdw;
270 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
271 *vp = hdw->freqTable[hdw->freqProgSlot-1];
272 } else {
273 *vp = 0;
274 }
275 return 0;
276}
277
278static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
279{
280 struct pvr2_hdw *hdw = cptr->hdw;
281 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
282 hdw->freqTable[hdw->freqProgSlot-1] = v;
283 }
284 return 0;
285}
286
287static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
288{
289 *vp = cptr->hdw->freqProgSlot;
290 return 0;
291}
292
293static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
294{
295 struct pvr2_hdw *hdw = cptr->hdw;
296 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
297 hdw->freqProgSlot = v;
298 }
299 return 0;
300}
301
302static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
303{
304 *vp = cptr->hdw->freqSlot;
305 return 0;
306}
307
308static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v)
309{
310 unsigned freq = 0;
311 struct pvr2_hdw *hdw = cptr->hdw;
312 hdw->freqSlot = v;
313 if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) {
314 freq = hdw->freqTable[hdw->freqSlot-1];
315 }
316 if (freq && (freq != hdw->freqVal)) {
317 hdw->freqVal = freq;
318 hdw->freqDirty = !0;
319 }
320 return 0;
321}
322
323static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
324{
325 *vp = cptr->hdw->freqVal;
326 return 0;
327}
328
329static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
330{
331 return cptr->hdw->freqDirty != 0;
332}
333
334static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
335{
336 cptr->hdw->freqDirty = 0;
337}
338
339static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
340{
341 struct pvr2_hdw *hdw = cptr->hdw;
342 hdw->freqVal = v;
343 hdw->freqDirty = !0;
344 hdw->freqSlot = 0;
345 return 0;
346}
347
348static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
349{
350 return cptr->hdw->enc_stale != 0;
351}
352
353static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
354{
355 cptr->hdw->enc_stale = 0;
356}
357
358static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
359{
360 int ret;
361 struct v4l2_ext_controls cs;
362 struct v4l2_ext_control c1;
363 memset(&cs,0,sizeof(cs));
364 memset(&c1,0,sizeof(c1));
365 cs.controls = &c1;
366 cs.count = 1;
367 c1.id = cptr->info->v4l_id;
368 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
369 VIDIOC_G_EXT_CTRLS);
370 if (ret) return ret;
371 *vp = c1.value;
372 return 0;
373}
374
375static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
376{
377 int ret;
378 struct v4l2_ext_controls cs;
379 struct v4l2_ext_control c1;
380 memset(&cs,0,sizeof(cs));
381 memset(&c1,0,sizeof(c1));
382 cs.controls = &c1;
383 cs.count = 1;
384 c1.id = cptr->info->v4l_id;
385 c1.value = v;
386 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
387 VIDIOC_S_EXT_CTRLS);
388 if (ret) return ret;
389 cptr->hdw->enc_stale = !0;
390 return 0;
391}
392
393static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
394{
395 struct v4l2_queryctrl qctrl;
396 struct pvr2_ctl_info *info;
397 qctrl.id = cptr->info->v4l_id;
398 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
399 /* Strip out the const so we can adjust a function pointer. It's
400 OK to do this here because we know this is a dynamically created
401 control, so the underlying storage for the info pointer is (a)
402 private to us, and (b) not in read-only storage. Either we do
403 this or we significantly complicate the underlying control
404 implementation. */
405 info = (struct pvr2_ctl_info *)(cptr->info);
406 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
407 if (info->set_value) {
408 info->set_value = 0;
409 }
410 } else {
411 if (!(info->set_value)) {
412 info->set_value = ctrl_cx2341x_set;
413 }
414 }
415 return qctrl.flags;
416}
417
418static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
419{
420 *vp = cptr->hdw->flag_streaming_enabled;
421 return 0;
422}
423
424static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
425{
426 int result = pvr2_hdw_is_hsm(cptr->hdw);
427 *vp = PVR2_CVAL_HSM_FULL;
428 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
429 if (result) *vp = PVR2_CVAL_HSM_HIGH;
430 return 0;
431}
432
433static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
434{
435 *vp = cptr->hdw->std_mask_avail;
436 return 0;
437}
438
439static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
440{
441 struct pvr2_hdw *hdw = cptr->hdw;
442 v4l2_std_id ns;
443 ns = hdw->std_mask_avail;
444 ns = (ns & ~m) | (v & m);
445 if (ns == hdw->std_mask_avail) return 0;
446 hdw->std_mask_avail = ns;
447 pvr2_hdw_internal_set_std_avail(hdw);
448 pvr2_hdw_internal_find_stdenum(hdw);
449 return 0;
450}
451
452static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
453 char *bufPtr,unsigned int bufSize,
454 unsigned int *len)
455{
456 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
457 return 0;
458}
459
460static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
461 const char *bufPtr,unsigned int bufSize,
462 int *mskp,int *valp)
463{
464 int ret;
465 v4l2_std_id id;
466 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
467 if (ret < 0) return ret;
468 if (mskp) *mskp = id;
469 if (valp) *valp = id;
470 return 0;
471}
472
473static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
474{
475 *vp = cptr->hdw->std_mask_cur;
476 return 0;
477}
478
479static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
480{
481 struct pvr2_hdw *hdw = cptr->hdw;
482 v4l2_std_id ns;
483 ns = hdw->std_mask_cur;
484 ns = (ns & ~m) | (v & m);
485 if (ns == hdw->std_mask_cur) return 0;
486 hdw->std_mask_cur = ns;
487 hdw->std_dirty = !0;
488 pvr2_hdw_internal_find_stdenum(hdw);
489 return 0;
490}
491
492static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
493{
494 return cptr->hdw->std_dirty != 0;
495}
496
497static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
498{
499 cptr->hdw->std_dirty = 0;
500}
501
502static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
503{
504 *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
505 PVR2_SIGNAL_OK) ? 1 : 0);
506 return 0;
507}
508
509static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
510{
511 *vp = cptr->hdw->subsys_enabled_mask;
512 return 0;
513}
514
515static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
516{
517 pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
518 return 0;
519}
520
521static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
522{
523 *vp = cptr->hdw->subsys_stream_mask;
524 return 0;
525}
526
527static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
528{
529 pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
530 return 0;
531}
532
533static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
534{
535 struct pvr2_hdw *hdw = cptr->hdw;
536 if (v < 0) return -EINVAL;
537 if (v > hdw->std_enum_cnt) return -EINVAL;
538 hdw->std_enum_cur = v;
539 if (!v) return 0;
540 v--;
541 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
542 hdw->std_mask_cur = hdw->std_defs[v].id;
543 hdw->std_dirty = !0;
544 return 0;
545}
546
547
548static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
549{
550 *vp = cptr->hdw->std_enum_cur;
551 return 0;
552}
553
554
555static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
556{
557 return cptr->hdw->std_dirty != 0;
558}
559
560
561static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
562{
563 cptr->hdw->std_dirty = 0;
564}
565
566
567#define DEFINT(vmin,vmax) \
568 .type = pvr2_ctl_int, \
569 .def.type_int.min_value = vmin, \
570 .def.type_int.max_value = vmax
571
572#define DEFENUM(tab) \
573 .type = pvr2_ctl_enum, \
574 .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \
575 .def.type_enum.value_names = tab
576
577#define DEFBOOL \
578 .type = pvr2_ctl_bool
579
580#define DEFMASK(msk,tab) \
581 .type = pvr2_ctl_bitmask, \
582 .def.type_bitmask.valid_bits = msk, \
583 .def.type_bitmask.bit_names = tab
584
585#define DEFREF(vname) \
586 .set_value = ctrl_set_##vname, \
587 .get_value = ctrl_get_##vname, \
588 .is_dirty = ctrl_isdirty_##vname, \
589 .clear_dirty = ctrl_cleardirty_##vname
590
591
592#define VCREATE_FUNCS(vname) \
593static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
594{*vp = cptr->hdw->vname##_val; return 0;} \
595static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
596{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
597static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
598{return cptr->hdw->vname##_dirty != 0;} \
599static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
600{cptr->hdw->vname##_dirty = 0;}
601
602VCREATE_FUNCS(brightness)
603VCREATE_FUNCS(contrast)
604VCREATE_FUNCS(saturation)
605VCREATE_FUNCS(hue)
606VCREATE_FUNCS(volume)
607VCREATE_FUNCS(balance)
608VCREATE_FUNCS(bass)
609VCREATE_FUNCS(treble)
610VCREATE_FUNCS(mute)
611VCREATE_FUNCS(input)
612VCREATE_FUNCS(audiomode)
613VCREATE_FUNCS(res_hor)
614VCREATE_FUNCS(res_ver)
615VCREATE_FUNCS(srate)
616
617#define MIN_FREQ 55250000L
618#define MAX_FREQ 850000000L
619
620/* Table definition of all controls which can be manipulated */
621static const struct pvr2_ctl_info control_defs[] = {
622 {
623 .v4l_id = V4L2_CID_BRIGHTNESS,
624 .desc = "Brightness",
625 .name = "brightness",
626 .default_value = 128,
627 DEFREF(brightness),
628 DEFINT(0,255),
629 },{
630 .v4l_id = V4L2_CID_CONTRAST,
631 .desc = "Contrast",
632 .name = "contrast",
633 .default_value = 68,
634 DEFREF(contrast),
635 DEFINT(0,127),
636 },{
637 .v4l_id = V4L2_CID_SATURATION,
638 .desc = "Saturation",
639 .name = "saturation",
640 .default_value = 64,
641 DEFREF(saturation),
642 DEFINT(0,127),
643 },{
644 .v4l_id = V4L2_CID_HUE,
645 .desc = "Hue",
646 .name = "hue",
647 .default_value = 0,
648 DEFREF(hue),
649 DEFINT(-128,127),
650 },{
651 .v4l_id = V4L2_CID_AUDIO_VOLUME,
652 .desc = "Volume",
653 .name = "volume",
654 .default_value = 65535,
655 DEFREF(volume),
656 DEFINT(0,65535),
657 },{
658 .v4l_id = V4L2_CID_AUDIO_BALANCE,
659 .desc = "Balance",
660 .name = "balance",
661 .default_value = 0,
662 DEFREF(balance),
663 DEFINT(-32768,32767),
664 },{
665 .v4l_id = V4L2_CID_AUDIO_BASS,
666 .desc = "Bass",
667 .name = "bass",
668 .default_value = 0,
669 DEFREF(bass),
670 DEFINT(-32768,32767),
671 },{
672 .v4l_id = V4L2_CID_AUDIO_TREBLE,
673 .desc = "Treble",
674 .name = "treble",
675 .default_value = 0,
676 DEFREF(treble),
677 DEFINT(-32768,32767),
678 },{
679 .v4l_id = V4L2_CID_AUDIO_MUTE,
680 .desc = "Mute",
681 .name = "mute",
682 .default_value = 0,
683 DEFREF(mute),
684 DEFBOOL,
685 },{
686 .desc = "Video Source",
687 .name = "input",
688 .internal_id = PVR2_CID_INPUT,
689 .default_value = PVR2_CVAL_INPUT_TV,
690 DEFREF(input),
691 DEFENUM(control_values_input),
692 },{
693 .desc = "Audio Mode",
694 .name = "audio_mode",
695 .internal_id = PVR2_CID_AUDIOMODE,
696 .default_value = V4L2_TUNER_MODE_STEREO,
697 DEFREF(audiomode),
698 DEFENUM(control_values_audiomode),
699 },{
700 .desc = "Horizontal capture resolution",
701 .name = "resolution_hor",
702 .internal_id = PVR2_CID_HRES,
703 .default_value = 720,
704 DEFREF(res_hor),
705 DEFINT(320,720),
706 },{
707 .desc = "Vertical capture resolution",
708 .name = "resolution_ver",
709 .internal_id = PVR2_CID_VRES,
710 .default_value = 480,
711 DEFREF(res_ver),
712 DEFINT(200,625),
713 },{
714 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
715 .desc = "Sample rate",
716 .name = "srate",
717 .default_value = PVR2_CVAL_SRATE_48,
718 DEFREF(srate),
719 DEFENUM(control_values_srate),
720 },{
721 .desc = "Tuner Frequency (Hz)",
722 .name = "frequency",
723 .internal_id = PVR2_CID_FREQUENCY,
724 .default_value = 175250000L,
725 .set_value = ctrl_freq_set,
726 .get_value = ctrl_freq_get,
727 .is_dirty = ctrl_freq_is_dirty,
728 .clear_dirty = ctrl_freq_clear_dirty,
729 DEFINT(MIN_FREQ,MAX_FREQ),
730 },{
731 .desc = "Channel",
732 .name = "channel",
733 .set_value = ctrl_channel_set,
734 .get_value = ctrl_channel_get,
735 DEFINT(0,FREQTABLE_SIZE),
736 },{
737 .desc = "Channel Program Frequency",
738 .name = "freq_table_value",
739 .set_value = ctrl_channelfreq_set,
740 .get_value = ctrl_channelfreq_get,
741 DEFINT(MIN_FREQ,MAX_FREQ),
742 },{
743 .desc = "Channel Program ID",
744 .name = "freq_table_channel",
745 .set_value = ctrl_channelprog_set,
746 .get_value = ctrl_channelprog_get,
747 DEFINT(0,FREQTABLE_SIZE),
748 },{
749 .desc = "Streaming Enabled",
750 .name = "streaming_enabled",
751 .get_value = ctrl_streamingenabled_get,
752 DEFBOOL,
753 },{
754 .desc = "USB Speed",
755 .name = "usb_speed",
756 .get_value = ctrl_hsm_get,
757 DEFENUM(control_values_hsm),
758 },{
759 .desc = "Signal Present",
760 .name = "signal_present",
761 .get_value = ctrl_signal_get,
762 DEFBOOL,
763 },{
764 .desc = "Video Standards Available Mask",
765 .name = "video_standard_mask_available",
766 .internal_id = PVR2_CID_STDAVAIL,
767 .skip_init = !0,
768 .get_value = ctrl_stdavail_get,
769 .set_value = ctrl_stdavail_set,
770 .val_to_sym = ctrl_std_val_to_sym,
771 .sym_to_val = ctrl_std_sym_to_val,
772 .type = pvr2_ctl_bitmask,
773 },{
774 .desc = "Video Standards In Use Mask",
775 .name = "video_standard_mask_active",
776 .internal_id = PVR2_CID_STDCUR,
777 .skip_init = !0,
778 .get_value = ctrl_stdcur_get,
779 .set_value = ctrl_stdcur_set,
780 .is_dirty = ctrl_stdcur_is_dirty,
781 .clear_dirty = ctrl_stdcur_clear_dirty,
782 .val_to_sym = ctrl_std_val_to_sym,
783 .sym_to_val = ctrl_std_sym_to_val,
784 .type = pvr2_ctl_bitmask,
785 },{
786 .desc = "Subsystem enabled mask",
787 .name = "debug_subsys_mask",
788 .skip_init = !0,
789 .get_value = ctrl_subsys_get,
790 .set_value = ctrl_subsys_set,
791 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
792 },{
793 .desc = "Subsystem stream mask",
794 .name = "debug_subsys_stream_mask",
795 .skip_init = !0,
796 .get_value = ctrl_subsys_stream_get,
797 .set_value = ctrl_subsys_stream_set,
798 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
799 },{
800 .desc = "Video Standard Name",
801 .name = "video_standard",
802 .internal_id = PVR2_CID_STDENUM,
803 .skip_init = !0,
804 .get_value = ctrl_stdenumcur_get,
805 .set_value = ctrl_stdenumcur_set,
806 .is_dirty = ctrl_stdenumcur_is_dirty,
807 .clear_dirty = ctrl_stdenumcur_clear_dirty,
808 .type = pvr2_ctl_enum,
809 }
810};
811
812#define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
813
814
815const char *pvr2_config_get_name(enum pvr2_config cfg)
816{
817 switch (cfg) {
818 case pvr2_config_empty: return "empty";
819 case pvr2_config_mpeg: return "mpeg";
820 case pvr2_config_vbi: return "vbi";
821 case pvr2_config_radio: return "radio";
822 }
823 return "<unknown>";
824}
825
826
827struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
828{
829 return hdw->usb_dev;
830}
831
832
833unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
834{
835 return hdw->serial_number;
836}
837
838
839struct pvr2_hdw *pvr2_hdw_find(int unit_number)
840{
841 if (unit_number < 0) return 0;
842 if (unit_number >= PVR_NUM) return 0;
843 return unit_pointers[unit_number];
844}
845
846
847int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
848{
849 return hdw->unit_number;
850}
851
852
853/* Attempt to locate one of the given set of files. Messages are logged
854 appropriate to what has been found. The return value will be 0 or
855 greater on success (it will be the index of the file name found) and
856 fw_entry will be filled in. Otherwise a negative error is returned on
857 failure. If the return value is -ENOENT then no viable firmware file
858 could be located. */
859static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
860 const struct firmware **fw_entry,
861 const char *fwtypename,
862 unsigned int fwcount,
863 const char *fwnames[])
864{
865 unsigned int idx;
866 int ret = -EINVAL;
867 for (idx = 0; idx < fwcount; idx++) {
868 ret = request_firmware(fw_entry,
869 fwnames[idx],
870 &hdw->usb_dev->dev);
871 if (!ret) {
872 trace_firmware("Located %s firmware: %s;"
873 " uploading...",
874 fwtypename,
875 fwnames[idx]);
876 return idx;
877 }
878 if (ret == -ENOENT) continue;
879 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
880 "request_firmware fatal error with code=%d",ret);
881 return ret;
882 }
883 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
884 "***WARNING***"
885 " Device %s firmware"
886 " seems to be missing.",
887 fwtypename);
888 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
889 "Did you install the pvrusb2 firmware files"
890 " in their proper location?");
891 if (fwcount == 1) {
892 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
893 "request_firmware unable to locate %s file %s",
894 fwtypename,fwnames[0]);
895 } else {
896 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
897 "request_firmware unable to locate"
898 " one of the following %s files:",
899 fwtypename);
900 for (idx = 0; idx < fwcount; idx++) {
901 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
902 "request_firmware: Failed to find %s",
903 fwnames[idx]);
904 }
905 }
906 return ret;
907}
908
909
910/*
911 * pvr2_upload_firmware1().
912 *
913 * Send the 8051 firmware to the device. After the upload, arrange for
914 * device to re-enumerate.
915 *
916 * NOTE : the pointer to the firmware data given by request_firmware()
917 * is not suitable for an usb transaction.
918 *
919 */
920int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
921{
922 const struct firmware *fw_entry = 0;
923 void *fw_ptr;
924 unsigned int pipe;
925 int ret;
926 u16 address;
927 static const char *fw_files_29xxx[] = {
928 "v4l-pvrusb2-29xxx-01.fw",
929 };
930#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
931 static const char *fw_files_24xxx[] = {
932 "v4l-pvrusb2-24xxx-01.fw",
933 };
934#endif
935 static const struct pvr2_string_table fw_file_defs[] = {
936 [PVR2_HDW_TYPE_29XXX] = {
937 fw_files_29xxx,
938 sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
939 },
940#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
941 [PVR2_HDW_TYPE_24XXX] = {
942 fw_files_24xxx,
943 sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]),
944 },
945#endif
946 };
947 hdw->fw1_state = FW1_STATE_FAILED; // default result
948
949 trace_firmware("pvr2_upload_firmware1");
950
951 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
952 fw_file_defs[hdw->hdw_type].cnt,
953 fw_file_defs[hdw->hdw_type].lst);
954 if (ret < 0) {
955 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
956 return ret;
957 }
958
959 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
960 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
961
962 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
963
964 if (fw_entry->size != 0x2000){
965 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
966 release_firmware(fw_entry);
967 return -ENOMEM;
968 }
969
970 fw_ptr = kmalloc(0x800, GFP_KERNEL);
971 if (fw_ptr == NULL){
972 release_firmware(fw_entry);
973 return -ENOMEM;
974 }
975
976 /* We have to hold the CPU during firmware upload. */
977 pvr2_hdw_cpureset_assert(hdw,1);
978
979 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
980 chunk. */
981
982 ret = 0;
983 for(address = 0; address < fw_entry->size; address += 0x800) {
984 memcpy(fw_ptr, fw_entry->data + address, 0x800);
985 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
986 0, fw_ptr, 0x800, HZ);
987 }
988
989 trace_firmware("Upload done, releasing device's CPU");
990
991 /* Now release the CPU. It will disconnect and reconnect later. */
992 pvr2_hdw_cpureset_assert(hdw,0);
993
994 kfree(fw_ptr);
995 release_firmware(fw_entry);
996
997 trace_firmware("Upload done (%d bytes sent)",ret);
998
999 /* We should have written 8192 bytes */
1000 if (ret == 8192) {
1001 hdw->fw1_state = FW1_STATE_RELOAD;
1002 return 0;
1003 }
1004
1005 return -EIO;
1006}
1007
1008
1009/*
1010 * pvr2_upload_firmware2()
1011 *
1012 * This uploads encoder firmware on endpoint 2.
1013 *
1014 */
1015
1016int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
1017{
1018 const struct firmware *fw_entry = 0;
1019 void *fw_ptr;
1020 unsigned int pipe, fw_len, fw_done;
1021 int actual_length;
1022 int ret = 0;
1023 int fwidx;
1024 static const char *fw_files[] = {
1025 CX2341X_FIRM_ENC_FILENAME,
1026 };
1027
1028 trace_firmware("pvr2_upload_firmware2");
1029
1030 ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
1031 sizeof(fw_files)/sizeof(fw_files[0]),
1032 fw_files);
1033 if (ret < 0) return ret;
1034 fwidx = ret;
1035 ret = 0;
1036 /* Since we're about to completely reinitialize the encoder,
1037 invalidate our cached copy of its configuration state. Next
1038 time we configure the encoder, then we'll fully configure it. */
1039 hdw->enc_cur_valid = 0;
1040
1041 /* First prepare firmware loading */
1042 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
1043 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
1044 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1045 ret |= pvr2_hdw_cmd_deep_reset(hdw);
1046 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
1047 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
1048 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1049 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
1050 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
1051 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
1052 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
1053 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
1054 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
1055 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
1056 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
1057 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
1058 ret |= pvr2_write_u8(hdw, 0x52, 0);
1059 ret |= pvr2_write_u16(hdw, 0x0600, 0);
1060
1061 if (ret) {
1062 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1063 "firmware2 upload prep failed, ret=%d",ret);
1064 release_firmware(fw_entry);
1065 return ret;
1066 }
1067
1068 /* Now send firmware */
1069
1070 fw_len = fw_entry->size;
1071
1072 if (fw_len % FIRMWARE_CHUNK_SIZE) {
1073 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1074 "size of %s firmware"
1075 " must be a multiple of 8192B",
1076 fw_files[fwidx]);
1077 release_firmware(fw_entry);
1078 return -1;
1079 }
1080
1081 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1082 if (fw_ptr == NULL){
1083 release_firmware(fw_entry);
1084 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1085 "failed to allocate memory for firmware2 upload");
1086 return -ENOMEM;
1087 }
1088
1089 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1090
1091 for (fw_done = 0 ; (fw_done < fw_len) && !ret ;
1092 fw_done += FIRMWARE_CHUNK_SIZE ) {
1093 int i;
1094 memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE);
1095 /* Usbsnoop log shows that we must swap bytes... */
1096 for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++)
1097 ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]);
1098
1099 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,
1100 FIRMWARE_CHUNK_SIZE,
1101 &actual_length, HZ);
1102 ret |= (actual_length != FIRMWARE_CHUNK_SIZE);
1103 }
1104
1105 trace_firmware("upload of %s : %i / %i ",
1106 fw_files[fwidx],fw_done,fw_len);
1107
1108 kfree(fw_ptr);
1109 release_firmware(fw_entry);
1110
1111 if (ret) {
1112 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1113 "firmware2 upload transfer failure");
1114 return ret;
1115 }
1116
1117 /* Finish upload */
1118
1119 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1120 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
1121 ret |= pvr2_write_u16(hdw, 0x0600, 0);
1122
1123 if (ret) {
1124 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1125 "firmware2 upload post-proc failure");
1126 } else {
1127 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
1128 }
1129 return ret;
1130}
1131
1132
1133#define FIRMWARE_RECOVERY_BITS \
1134 ((1<<PVR2_SUBSYS_B_ENC_CFG) | \
1135 (1<<PVR2_SUBSYS_B_ENC_RUN) | \
1136 (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \
1137 (1<<PVR2_SUBSYS_B_USBSTREAM_RUN))
1138
1139/*
1140
1141 This single function is key to pretty much everything. The pvrusb2
1142 device can logically be viewed as a series of subsystems which can be
1143 stopped / started or unconfigured / configured. To get things streaming,
1144 one must configure everything and start everything, but there may be
1145 various reasons over time to deconfigure something or stop something.
1146 This function handles all of this activity. Everything EVERYWHERE that
1147 must affect a subsystem eventually comes here to do the work.
1148
1149 The current state of all subsystems is represented by a single bit mask,
1150 known as subsys_enabled_mask. The bit positions are defined by the
1151 PVR2_SUBSYS_xxxx macros, with one subsystem per bit position. At any
1152 time the set of configured or active subsystems can be queried just by
1153 looking at that mask. To change bits in that mask, this function here
1154 must be called. The "msk" argument indicates which bit positions to
1155 change, and the "val" argument defines the new values for the positions
1156 defined by "msk".
1157
1158 There is a priority ordering of starting / stopping things, and for
1159 multiple requested changes, this function implements that ordering.
1160 (Thus we will act on a request to load encoder firmware before we
1161 configure the encoder.) In addition to priority ordering, there is a
1162 recovery strategy implemented here. If a particular step fails and we
1163 detect that failure, this function will clear the affected subsystem bits
1164 and restart. Thus we have a means for recovering from a dead encoder:
1165 Clear all bits that correspond to subsystems that we need to restart /
1166 reconfigure and start over.
1167
1168*/
1169void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
1170 unsigned long msk,unsigned long val)
1171{
1172 unsigned long nmsk;
1173 unsigned long vmsk;
1174 int ret;
1175 unsigned int tryCount = 0;
1176
1177 if (!hdw->flag_ok) return;
1178
1179 msk &= PVR2_SUBSYS_ALL;
1180 nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk);
1181 nmsk &= PVR2_SUBSYS_ALL;
1182
1183 for (;;) {
1184 tryCount++;
1185 if (!((nmsk ^ hdw->subsys_enabled_mask) &
1186 PVR2_SUBSYS_ALL)) break;
1187 if (tryCount > 4) {
1188 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1189 "Too many retries when configuring device;"
1190 " giving up");
1191 pvr2_hdw_render_useless(hdw);
1192 break;
1193 }
1194 if (tryCount > 1) {
1195 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1196 "Retrying device reconfiguration");
1197 }
1198 pvr2_trace(PVR2_TRACE_INIT,
1199 "subsys mask changing 0x%lx:0x%lx"
1200 " from 0x%lx to 0x%lx",
1201 msk,val,hdw->subsys_enabled_mask,nmsk);
1202
1203 vmsk = (nmsk ^ hdw->subsys_enabled_mask) &
1204 hdw->subsys_enabled_mask;
1205 if (vmsk) {
1206 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1207 pvr2_trace(PVR2_TRACE_CTL,
1208 "/*---TRACE_CTL----*/"
1209 " pvr2_encoder_stop");
1210 ret = pvr2_encoder_stop(hdw);
1211 if (ret) {
1212 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1213 "Error recovery initiated");
1214 hdw->subsys_enabled_mask &=
1215 ~FIRMWARE_RECOVERY_BITS;
1216 continue;
1217 }
1218 }
1219 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1220 pvr2_trace(PVR2_TRACE_CTL,
1221 "/*---TRACE_CTL----*/"
1222 " pvr2_hdw_cmd_usbstream(0)");
1223 pvr2_hdw_cmd_usbstream(hdw,0);
1224 }
1225 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1226 pvr2_trace(PVR2_TRACE_CTL,
1227 "/*---TRACE_CTL----*/"
1228 " decoder disable");
1229 if (hdw->decoder_ctrl) {
1230 hdw->decoder_ctrl->enable(
1231 hdw->decoder_ctrl->ctxt,0);
1232 } else {
1233 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1234 "WARNING:"
1235 " No decoder present");
1236 }
1237 hdw->subsys_enabled_mask &=
1238 ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1239 }
1240 if (vmsk & PVR2_SUBSYS_CFG_ALL) {
1241 hdw->subsys_enabled_mask &=
1242 ~(vmsk & PVR2_SUBSYS_CFG_ALL);
1243 }
1244 }
1245 vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk;
1246 if (vmsk) {
1247 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) {
1248 pvr2_trace(PVR2_TRACE_CTL,
1249 "/*---TRACE_CTL----*/"
1250 " pvr2_upload_firmware2");
1251 ret = pvr2_upload_firmware2(hdw);
1252 if (ret) {
1253 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1254 "Failure uploading encoder"
1255 " firmware");
1256 pvr2_hdw_render_useless(hdw);
1257 break;
1258 }
1259 }
1260 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) {
1261 pvr2_trace(PVR2_TRACE_CTL,
1262 "/*---TRACE_CTL----*/"
1263 " pvr2_encoder_configure");
1264 ret = pvr2_encoder_configure(hdw);
1265 if (ret) {
1266 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1267 "Error recovery initiated");
1268 hdw->subsys_enabled_mask &=
1269 ~FIRMWARE_RECOVERY_BITS;
1270 continue;
1271 }
1272 }
1273 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1274 pvr2_trace(PVR2_TRACE_CTL,
1275 "/*---TRACE_CTL----*/"
1276 " decoder enable");
1277 if (hdw->decoder_ctrl) {
1278 hdw->decoder_ctrl->enable(
1279 hdw->decoder_ctrl->ctxt,!0);
1280 } else {
1281 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1282 "WARNING:"
1283 " No decoder present");
1284 }
1285 hdw->subsys_enabled_mask |=
1286 (1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1287 }
1288 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1289 pvr2_trace(PVR2_TRACE_CTL,
1290 "/*---TRACE_CTL----*/"
1291 " pvr2_hdw_cmd_usbstream(1)");
1292 pvr2_hdw_cmd_usbstream(hdw,!0);
1293 }
1294 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1295 pvr2_trace(PVR2_TRACE_CTL,
1296 "/*---TRACE_CTL----*/"
1297 " pvr2_encoder_start");
1298 ret = pvr2_encoder_start(hdw);
1299 if (ret) {
1300 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1301 "Error recovery initiated");
1302 hdw->subsys_enabled_mask &=
1303 ~FIRMWARE_RECOVERY_BITS;
1304 continue;
1305 }
1306 }
1307 }
1308 }
1309}
1310
1311
1312void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
1313 unsigned long msk,unsigned long val)
1314{
1315 LOCK_TAKE(hdw->big_lock); do {
1316 pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val);
1317 } while (0); LOCK_GIVE(hdw->big_lock);
1318}
1319
1320
1321void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk)
1322{
1323 pvr2_hdw_subsys_bit_chg(hdw,msk,msk);
1324}
1325
1326
1327void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk)
1328{
1329 pvr2_hdw_subsys_bit_chg(hdw,msk,0);
1330}
1331
1332
1333unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw)
1334{
1335 return hdw->subsys_enabled_mask;
1336}
1337
1338
1339unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw)
1340{
1341 return hdw->subsys_stream_mask;
1342}
1343
1344
1345void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
1346 unsigned long msk,
1347 unsigned long val)
1348{
1349 unsigned long val2;
1350 msk &= PVR2_SUBSYS_ALL;
1351 val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk));
1352 pvr2_trace(PVR2_TRACE_INIT,
1353 "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx",
1354 msk,val,hdw->subsys_stream_mask,val2);
1355 hdw->subsys_stream_mask = val2;
1356}
1357
1358
1359void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
1360 unsigned long msk,
1361 unsigned long val)
1362{
1363 LOCK_TAKE(hdw->big_lock); do {
1364 pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val);
1365 } while (0); LOCK_GIVE(hdw->big_lock);
1366}
1367
1368
1369int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl)
1370{
1371 if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0;
1372 if (enableFl) {
1373 pvr2_trace(PVR2_TRACE_START_STOP,
1374 "/*--TRACE_STREAM--*/ enable");
1375 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0);
1376 } else {
1377 pvr2_trace(PVR2_TRACE_START_STOP,
1378 "/*--TRACE_STREAM--*/ disable");
1379 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1380 }
1381 if (!hdw->flag_ok) return -EIO;
1382 hdw->flag_streaming_enabled = enableFl != 0;
1383 return 0;
1384}
1385
1386
1387int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1388{
1389 return hdw->flag_streaming_enabled != 0;
1390}
1391
1392
1393int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1394{
1395 int ret;
1396 LOCK_TAKE(hdw->big_lock); do {
1397 ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag);
1398 } while (0); LOCK_GIVE(hdw->big_lock);
1399 return ret;
1400}
1401
1402
1403int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw,
1404 enum pvr2_config config)
1405{
1406 unsigned long sm = hdw->subsys_enabled_mask;
1407 if (!hdw->flag_ok) return -EIO;
1408 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1409 hdw->config = config;
1410 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm);
1411 return 0;
1412}
1413
1414
1415int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1416{
1417 int ret;
1418 if (!hdw->flag_ok) return -EIO;
1419 LOCK_TAKE(hdw->big_lock);
1420 ret = pvr2_hdw_set_stream_type_no_lock(hdw,config);
1421 LOCK_GIVE(hdw->big_lock);
1422 return ret;
1423}
1424
1425
1426static int get_default_tuner_type(struct pvr2_hdw *hdw)
1427{
1428 int unit_number = hdw->unit_number;
1429 int tp = -1;
1430 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1431 tp = tuner[unit_number];
1432 }
1433 if (tp < 0) return -EINVAL;
1434 hdw->tuner_type = tp;
1435 return 0;
1436}
1437
1438
1439static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1440{
1441 int unit_number = hdw->unit_number;
1442 int tp = 0;
1443 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1444 tp = video_std[unit_number];
1445 }
1446 return tp;
1447}
1448
1449
1450static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1451{
1452 int unit_number = hdw->unit_number;
1453 int tp = 0;
1454 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1455 tp = tolerance[unit_number];
1456 }
1457 return tp;
1458}
1459
1460
1461static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1462{
1463 /* Try a harmless request to fetch the eeprom's address over
1464 endpoint 1. See what happens. Only the full FX2 image can
1465 respond to this. If this probe fails then likely the FX2
1466 firmware needs be loaded. */
1467 int result;
1468 LOCK_TAKE(hdw->ctl_lock); do {
1469 hdw->cmd_buffer[0] = 0xeb;
1470 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1471 hdw->cmd_buffer,1,
1472 hdw->cmd_buffer,1);
1473 if (result < 0) break;
1474 } while(0); LOCK_GIVE(hdw->ctl_lock);
1475 if (result) {
1476 pvr2_trace(PVR2_TRACE_INIT,
1477 "Probe of device endpoint 1 result status %d",
1478 result);
1479 } else {
1480 pvr2_trace(PVR2_TRACE_INIT,
1481 "Probe of device endpoint 1 succeeded");
1482 }
1483 return result == 0;
1484}
1485
1486static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1487{
1488 char buf[40];
1489 unsigned int bcnt;
1490 v4l2_std_id std1,std2;
1491
1492 std1 = get_default_standard(hdw);
1493
1494 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
1495 pvr2_trace(PVR2_TRACE_INIT,
1496 "Supported video standard(s) reported by eeprom: %.*s",
1497 bcnt,buf);
1498
1499 hdw->std_mask_avail = hdw->std_mask_eeprom;
1500
1501 std2 = std1 & ~hdw->std_mask_avail;
1502 if (std2) {
1503 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
1504 pvr2_trace(PVR2_TRACE_INIT,
1505 "Expanding supported video standards"
1506 " to include: %.*s",
1507 bcnt,buf);
1508 hdw->std_mask_avail |= std2;
1509 }
1510
1511 pvr2_hdw_internal_set_std_avail(hdw);
1512
1513 if (std1) {
1514 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
1515 pvr2_trace(PVR2_TRACE_INIT,
1516 "Initial video standard forced to %.*s",
1517 bcnt,buf);
1518 hdw->std_mask_cur = std1;
1519 hdw->std_dirty = !0;
1520 pvr2_hdw_internal_find_stdenum(hdw);
1521 return;
1522 }
1523
1524 if (hdw->std_enum_cnt > 1) {
1525 // Autoselect the first listed standard
1526 hdw->std_enum_cur = 1;
1527 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1528 hdw->std_dirty = !0;
1529 pvr2_trace(PVR2_TRACE_INIT,
1530 "Initial video standard auto-selected to %s",
1531 hdw->std_defs[hdw->std_enum_cur-1].name);
1532 return;
1533 }
1534
1535 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1536 "Unable to select a viable initial video standard");
1537}
1538
1539
1540static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1541{
1542 int ret;
1543 unsigned int idx;
1544 struct pvr2_ctrl *cptr;
1545 int reloadFl = 0;
1546 if (!reloadFl) {
1547 reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1548 == 0);
1549 if (reloadFl) {
1550 pvr2_trace(PVR2_TRACE_INIT,
1551 "USB endpoint config looks strange"
1552 "; possibly firmware needs to be loaded");
1553 }
1554 }
1555 if (!reloadFl) {
1556 reloadFl = !pvr2_hdw_check_firmware(hdw);
1557 if (reloadFl) {
1558 pvr2_trace(PVR2_TRACE_INIT,
1559 "Check for FX2 firmware failed"
1560 "; possibly firmware needs to be loaded");
1561 }
1562 }
1563 if (reloadFl) {
1564 if (pvr2_upload_firmware1(hdw) != 0) {
1565 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1566 "Failure uploading firmware1");
1567 }
1568 return;
1569 }
1570 hdw->fw1_state = FW1_STATE_OK;
1571
1572 if (initusbreset) {
1573 pvr2_hdw_device_reset(hdw);
1574 }
1575 if (!pvr2_hdw_dev_ok(hdw)) return;
1576
1577 for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) {
1578 request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]);
1579 }
1580
1581 pvr2_hdw_cmd_powerup(hdw);
1582 if (!pvr2_hdw_dev_ok(hdw)) return;
1583
1584 if (pvr2_upload_firmware2(hdw)){
1585 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
1586 pvr2_hdw_render_useless(hdw);
1587 return;
1588 }
1589
1590 // This step MUST happen after the earlier powerup step.
1591 pvr2_i2c_core_init(hdw);
1592 if (!pvr2_hdw_dev_ok(hdw)) return;
1593
1594 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
1595 cptr = hdw->controls + idx;
1596 if (cptr->info->skip_init) continue;
1597 if (!cptr->info->set_value) continue;
1598 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1599 }
1600
1601 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1602 // thread-safe against the normal pvr2_send_request() mechanism.
1603 // (We should make it thread safe).
1604
1605 ret = pvr2_hdw_get_eeprom_addr(hdw);
1606 if (!pvr2_hdw_dev_ok(hdw)) return;
1607 if (ret < 0) {
1608 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1609 "Unable to determine location of eeprom, skipping");
1610 } else {
1611 hdw->eeprom_addr = ret;
1612 pvr2_eeprom_analyze(hdw);
1613 if (!pvr2_hdw_dev_ok(hdw)) return;
1614 }
1615
1616 pvr2_hdw_setup_std(hdw);
1617
1618 if (!get_default_tuner_type(hdw)) {
1619 pvr2_trace(PVR2_TRACE_INIT,
1620 "pvr2_hdw_setup: Tuner type overridden to %d",
1621 hdw->tuner_type);
1622 }
1623
1624 hdw->tuner_updated = !0;
1625 pvr2_i2c_core_check_stale(hdw);
1626 hdw->tuner_updated = 0;
1627
1628 if (!pvr2_hdw_dev_ok(hdw)) return;
1629
1630 pvr2_hdw_commit_ctl_internal(hdw);
1631 if (!pvr2_hdw_dev_ok(hdw)) return;
1632
1633 hdw->vid_stream = pvr2_stream_create();
1634 if (!pvr2_hdw_dev_ok(hdw)) return;
1635 pvr2_trace(PVR2_TRACE_INIT,
1636 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1637 if (hdw->vid_stream) {
1638 idx = get_default_error_tolerance(hdw);
1639 if (idx) {
1640 pvr2_trace(PVR2_TRACE_INIT,
1641 "pvr2_hdw_setup: video stream %p"
1642 " setting tolerance %u",
1643 hdw->vid_stream,idx);
1644 }
1645 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1646 PVR2_VID_ENDPOINT,idx);
1647 }
1648
1649 if (!pvr2_hdw_dev_ok(hdw)) return;
1650
1651 /* Make sure everything is up to date */
1652 pvr2_i2c_core_sync(hdw);
1653
1654 if (!pvr2_hdw_dev_ok(hdw)) return;
1655
1656 hdw->flag_init_ok = !0;
1657}
1658
1659
1660int pvr2_hdw_setup(struct pvr2_hdw *hdw)
1661{
1662 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
1663 LOCK_TAKE(hdw->big_lock); do {
1664 pvr2_hdw_setup_low(hdw);
1665 pvr2_trace(PVR2_TRACE_INIT,
1666 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
1667 hdw,hdw->flag_ok,hdw->flag_init_ok);
1668 if (pvr2_hdw_dev_ok(hdw)) {
1669 if (pvr2_hdw_init_ok(hdw)) {
1670 pvr2_trace(
1671 PVR2_TRACE_INFO,
1672 "Device initialization"
1673 " completed successfully.");
1674 break;
1675 }
1676 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1677 pvr2_trace(
1678 PVR2_TRACE_INFO,
1679 "Device microcontroller firmware"
1680 " (re)loaded; it should now reset"
1681 " and reconnect.");
1682 break;
1683 }
1684 pvr2_trace(
1685 PVR2_TRACE_ERROR_LEGS,
1686 "Device initialization was not successful.");
1687 if (hdw->fw1_state == FW1_STATE_MISSING) {
1688 pvr2_trace(
1689 PVR2_TRACE_ERROR_LEGS,
1690 "Giving up since device"
1691 " microcontroller firmware"
1692 " appears to be missing.");
1693 break;
1694 }
1695 }
1696 if (procreload) {
1697 pvr2_trace(
1698 PVR2_TRACE_ERROR_LEGS,
1699 "Attempting pvrusb2 recovery by reloading"
1700 " primary firmware.");
1701 pvr2_trace(
1702 PVR2_TRACE_ERROR_LEGS,
1703 "If this works, device should disconnect"
1704 " and reconnect in a sane state.");
1705 hdw->fw1_state = FW1_STATE_UNKNOWN;
1706 pvr2_upload_firmware1(hdw);
1707 } else {
1708 pvr2_trace(
1709 PVR2_TRACE_ERROR_LEGS,
1710 "***WARNING*** pvrusb2 device hardware"
1711 " appears to be jammed"
1712 " and I can't clear it.");
1713 pvr2_trace(
1714 PVR2_TRACE_ERROR_LEGS,
1715 "You might need to power cycle"
1716 " the pvrusb2 device"
1717 " in order to recover.");
1718 }
1719 } while (0); LOCK_GIVE(hdw->big_lock);
1720 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
1721 return hdw->flag_init_ok;
1722}
1723
1724
1725/* Create and return a structure for interacting with the underlying
1726 hardware */
1727struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1728 const struct usb_device_id *devid)
1729{
1730 unsigned int idx,cnt1,cnt2;
1731 struct pvr2_hdw *hdw;
1732 unsigned int hdw_type;
1733 int valid_std_mask;
1734 struct pvr2_ctrl *cptr;
1735 __u8 ifnum;
1736 struct v4l2_queryctrl qctrl;
1737 struct pvr2_ctl_info *ciptr;
1738
1739 hdw_type = devid - pvr2_device_table;
1740 if (hdw_type >=
1741 sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) {
1742 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1743 "Bogus device type of %u reported",hdw_type);
1744 return 0;
1745 }
1746
1747 hdw = kmalloc(sizeof(*hdw),GFP_KERNEL);
1748 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
1749 hdw,pvr2_device_names[hdw_type]);
1750 if (!hdw) goto fail;
1751 memset(hdw,0,sizeof(*hdw));
1752 cx2341x_fill_defaults(&hdw->enc_ctl_state);
1753
1754 hdw->control_cnt = CTRLDEF_COUNT;
1755 hdw->control_cnt += MPEGDEF_COUNT;
1756 hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
1757 GFP_KERNEL);
1758 if (!hdw->controls) goto fail;
1759 memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * hdw->control_cnt);
1760 hdw->hdw_type = hdw_type;
1761 for (idx = 0; idx < hdw->control_cnt; idx++) {
1762 cptr = hdw->controls + idx;
1763 cptr->hdw = hdw;
1764 }
1765 for (idx = 0; idx < 32; idx++) {
1766 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1767 }
1768 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
1769 cptr = hdw->controls + idx;
1770 cptr->info = control_defs+idx;
1771 }
1772 /* Define and configure additional controls from cx2341x module. */
1773 hdw->mpeg_ctrl_info = kmalloc(
1774 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
1775 if (!hdw->mpeg_ctrl_info) goto fail;
1776 memset(hdw->mpeg_ctrl_info,0,
1777 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT);
1778 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
1779 cptr = hdw->controls + idx + CTRLDEF_COUNT;
1780 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
1781 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
1782 ciptr->name = mpeg_ids[idx].strid;
1783 ciptr->v4l_id = mpeg_ids[idx].id;
1784 ciptr->skip_init = !0;
1785 ciptr->get_value = ctrl_cx2341x_get;
1786 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
1787 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
1788 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
1789 qctrl.id = ciptr->v4l_id;
1790 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
1791 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
1792 ciptr->set_value = ctrl_cx2341x_set;
1793 }
1794 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
1795 PVR2_CTLD_INFO_DESC_SIZE);
1796 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
1797 ciptr->default_value = qctrl.default_value;
1798 switch (qctrl.type) {
1799 default:
1800 case V4L2_CTRL_TYPE_INTEGER:
1801 ciptr->type = pvr2_ctl_int;
1802 ciptr->def.type_int.min_value = qctrl.minimum;
1803 ciptr->def.type_int.max_value = qctrl.maximum;
1804 break;
1805 case V4L2_CTRL_TYPE_BOOLEAN:
1806 ciptr->type = pvr2_ctl_bool;
1807 break;
1808 case V4L2_CTRL_TYPE_MENU:
1809 ciptr->type = pvr2_ctl_enum;
1810 ciptr->def.type_enum.value_names =
1811 cx2341x_ctrl_get_menu(ciptr->v4l_id);
1812 for (cnt1 = 0;
1813 ciptr->def.type_enum.value_names[cnt1] != NULL;
1814 cnt1++) { }
1815 ciptr->def.type_enum.count = cnt1;
1816 break;
1817 }
1818 cptr->info = ciptr;
1819 }
1820
1821 // Initialize video standard enum dynamic control
1822 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
1823 if (cptr) {
1824 memcpy(&hdw->std_info_enum,cptr->info,
1825 sizeof(hdw->std_info_enum));
1826 cptr->info = &hdw->std_info_enum;
1827
1828 }
1829 // Initialize control data regarding video standard masks
1830 valid_std_mask = pvr2_std_get_usable();
1831 for (idx = 0; idx < 32; idx++) {
1832 if (!(valid_std_mask & (1 << idx))) continue;
1833 cnt1 = pvr2_std_id_to_str(
1834 hdw->std_mask_names[idx],
1835 sizeof(hdw->std_mask_names[idx])-1,
1836 1 << idx);
1837 hdw->std_mask_names[idx][cnt1] = 0;
1838 }
1839 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
1840 if (cptr) {
1841 memcpy(&hdw->std_info_avail,cptr->info,
1842 sizeof(hdw->std_info_avail));
1843 cptr->info = &hdw->std_info_avail;
1844 hdw->std_info_avail.def.type_bitmask.bit_names =
1845 hdw->std_mask_ptrs;
1846 hdw->std_info_avail.def.type_bitmask.valid_bits =
1847 valid_std_mask;
1848 }
1849 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
1850 if (cptr) {
1851 memcpy(&hdw->std_info_cur,cptr->info,
1852 sizeof(hdw->std_info_cur));
1853 cptr->info = &hdw->std_info_cur;
1854 hdw->std_info_cur.def.type_bitmask.bit_names =
1855 hdw->std_mask_ptrs;
1856 hdw->std_info_avail.def.type_bitmask.valid_bits =
1857 valid_std_mask;
1858 }
1859
1860 hdw->eeprom_addr = -1;
1861 hdw->unit_number = -1;
1862 hdw->v4l_minor_number = -1;
1863 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
1864 if (!hdw->ctl_write_buffer) goto fail;
1865 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
1866 if (!hdw->ctl_read_buffer) goto fail;
1867 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
1868 if (!hdw->ctl_write_urb) goto fail;
1869 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
1870 if (!hdw->ctl_read_urb) goto fail;
1871
1872 down(&pvr2_unit_sem); do {
1873 for (idx = 0; idx < PVR_NUM; idx++) {
1874 if (unit_pointers[idx]) continue;
1875 hdw->unit_number = idx;
1876 unit_pointers[idx] = hdw;
1877 break;
1878 }
1879 } while (0); up(&pvr2_unit_sem);
1880
1881 cnt1 = 0;
1882 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
1883 cnt1 += cnt2;
1884 if (hdw->unit_number >= 0) {
1885 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
1886 ('a' + hdw->unit_number));
1887 cnt1 += cnt2;
1888 }
1889 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
1890 hdw->name[cnt1] = 0;
1891
1892 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
1893 hdw->unit_number,hdw->name);
1894
1895 hdw->tuner_type = -1;
1896 hdw->flag_ok = !0;
1897 /* Initialize the mask of subsystems that we will shut down when we
1898 stop streaming. */
1899 hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
1900 hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
1901
1902 pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
1903 hdw->subsys_stream_mask);
1904
1905 hdw->usb_intf = intf;
1906 hdw->usb_dev = interface_to_usbdev(intf);
1907
1908 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
1909 usb_set_interface(hdw->usb_dev,ifnum,0);
1910
1911 mutex_init(&hdw->ctl_lock_mutex);
1912 mutex_init(&hdw->big_lock_mutex);
1913
1914 return hdw;
1915 fail:
1916 if (hdw) {
1917 if (hdw->ctl_read_urb) usb_free_urb(hdw->ctl_read_urb);
1918 if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb);
1919 if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer);
1920 if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer);
1921 if (hdw->controls) kfree(hdw->controls);
1922 if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info);
1923 kfree(hdw);
1924 }
1925 return 0;
1926}
1927
1928
1929/* Remove _all_ associations between this driver and the underlying USB
1930 layer. */
1931void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
1932{
1933 if (hdw->flag_disconnected) return;
1934 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
1935 if (hdw->ctl_read_urb) {
1936 usb_kill_urb(hdw->ctl_read_urb);
1937 usb_free_urb(hdw->ctl_read_urb);
1938 hdw->ctl_read_urb = 0;
1939 }
1940 if (hdw->ctl_write_urb) {
1941 usb_kill_urb(hdw->ctl_write_urb);
1942 usb_free_urb(hdw->ctl_write_urb);
1943 hdw->ctl_write_urb = 0;
1944 }
1945 if (hdw->ctl_read_buffer) {
1946 kfree(hdw->ctl_read_buffer);
1947 hdw->ctl_read_buffer = 0;
1948 }
1949 if (hdw->ctl_write_buffer) {
1950 kfree(hdw->ctl_write_buffer);
1951 hdw->ctl_write_buffer = 0;
1952 }
1953 pvr2_hdw_render_useless_unlocked(hdw);
1954 hdw->flag_disconnected = !0;
1955 hdw->usb_dev = 0;
1956 hdw->usb_intf = 0;
1957}
1958
1959
1960/* Destroy hardware interaction structure */
1961void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
1962{
1963 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
1964 if (hdw->fw_buffer) {
1965 kfree(hdw->fw_buffer);
1966 hdw->fw_buffer = 0;
1967 }
1968 if (hdw->vid_stream) {
1969 pvr2_stream_destroy(hdw->vid_stream);
1970 hdw->vid_stream = 0;
1971 }
1972 if (hdw->audio_stat) {
1973 hdw->audio_stat->detach(hdw->audio_stat->ctxt);
1974 }
1975 if (hdw->decoder_ctrl) {
1976 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
1977 }
1978 pvr2_i2c_core_done(hdw);
1979 pvr2_hdw_remove_usb_stuff(hdw);
1980 down(&pvr2_unit_sem); do {
1981 if ((hdw->unit_number >= 0) &&
1982 (hdw->unit_number < PVR_NUM) &&
1983 (unit_pointers[hdw->unit_number] == hdw)) {
1984 unit_pointers[hdw->unit_number] = 0;
1985 }
1986 } while (0); up(&pvr2_unit_sem);
1987 if (hdw->controls) kfree(hdw->controls);
1988 if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info);
1989 if (hdw->std_defs) kfree(hdw->std_defs);
1990 if (hdw->std_enum_names) kfree(hdw->std_enum_names);
1991 kfree(hdw);
1992}
1993
1994
1995int pvr2_hdw_init_ok(struct pvr2_hdw *hdw)
1996{
1997 return hdw->flag_init_ok;
1998}
1999
2000
2001int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2002{
2003 return (hdw && hdw->flag_ok);
2004}
2005
2006
2007/* Called when hardware has been unplugged */
2008void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2009{
2010 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2011 LOCK_TAKE(hdw->big_lock);
2012 LOCK_TAKE(hdw->ctl_lock);
2013 pvr2_hdw_remove_usb_stuff(hdw);
2014 LOCK_GIVE(hdw->ctl_lock);
2015 LOCK_GIVE(hdw->big_lock);
2016}
2017
2018
2019// Attempt to autoselect an appropriate value for std_enum_cur given
2020// whatever is currently in std_mask_cur
2021void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
2022{
2023 unsigned int idx;
2024 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2025 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2026 hdw->std_enum_cur = idx;
2027 return;
2028 }
2029 }
2030 hdw->std_enum_cur = 0;
2031}
2032
2033
2034// Calculate correct set of enumerated standards based on currently known
2035// set of available standards bits.
2036void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
2037{
2038 struct v4l2_standard *newstd;
2039 unsigned int std_cnt;
2040 unsigned int idx;
2041
2042 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2043
2044 if (hdw->std_defs) {
2045 kfree(hdw->std_defs);
2046 hdw->std_defs = 0;
2047 }
2048 hdw->std_enum_cnt = 0;
2049 if (hdw->std_enum_names) {
2050 kfree(hdw->std_enum_names);
2051 hdw->std_enum_names = 0;
2052 }
2053
2054 if (!std_cnt) {
2055 pvr2_trace(
2056 PVR2_TRACE_ERROR_LEGS,
2057 "WARNING: Failed to identify any viable standards");
2058 }
2059 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2060 hdw->std_enum_names[0] = "none";
2061 for (idx = 0; idx < std_cnt; idx++) {
2062 hdw->std_enum_names[idx+1] =
2063 newstd[idx].name;
2064 }
2065 // Set up the dynamic control for this standard
2066 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2067 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2068 hdw->std_defs = newstd;
2069 hdw->std_enum_cnt = std_cnt+1;
2070 hdw->std_enum_cur = 0;
2071 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2072}
2073
2074
2075int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2076 struct v4l2_standard *std,
2077 unsigned int idx)
2078{
2079 int ret = -EINVAL;
2080 if (!idx) return ret;
2081 LOCK_TAKE(hdw->big_lock); do {
2082 if (idx >= hdw->std_enum_cnt) break;
2083 idx--;
2084 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2085 ret = 0;
2086 } while (0); LOCK_GIVE(hdw->big_lock);
2087 return ret;
2088}
2089
2090
2091/* Get the number of defined controls */
2092unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2093{
2094 return hdw->control_cnt;
2095}
2096
2097
2098/* Retrieve a control handle given its index (0..count-1) */
2099struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2100 unsigned int idx)
2101{
2102 if (idx >= hdw->control_cnt) return 0;
2103 return hdw->controls + idx;
2104}
2105
2106
2107/* Retrieve a control handle given its index (0..count-1) */
2108struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2109 unsigned int ctl_id)
2110{
2111 struct pvr2_ctrl *cptr;
2112 unsigned int idx;
2113 int i;
2114
2115 /* This could be made a lot more efficient, but for now... */
2116 for (idx = 0; idx < hdw->control_cnt; idx++) {
2117 cptr = hdw->controls + idx;
2118 i = cptr->info->internal_id;
2119 if (i && (i == ctl_id)) return cptr;
2120 }
2121 return 0;
2122}
2123
2124
2125/* Given a V4L ID, retrieve the control structure associated with it. */
2126struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2127{
2128 struct pvr2_ctrl *cptr;
2129 unsigned int idx;
2130 int i;
2131
2132 /* This could be made a lot more efficient, but for now... */
2133 for (idx = 0; idx < hdw->control_cnt; idx++) {
2134 cptr = hdw->controls + idx;
2135 i = cptr->info->v4l_id;
2136 if (i && (i == ctl_id)) return cptr;
2137 }
2138 return 0;
2139}
2140
2141
2142/* Given a V4L ID for its immediate predecessor, retrieve the control
2143 structure associated with it. */
2144struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2145 unsigned int ctl_id)
2146{
2147 struct pvr2_ctrl *cptr,*cp2;
2148 unsigned int idx;
2149 int i;
2150
2151 /* This could be made a lot more efficient, but for now... */
2152 cp2 = 0;
2153 for (idx = 0; idx < hdw->control_cnt; idx++) {
2154 cptr = hdw->controls + idx;
2155 i = cptr->info->v4l_id;
2156 if (!i) continue;
2157 if (i <= ctl_id) continue;
2158 if (cp2 && (cp2->info->v4l_id < i)) continue;
2159 cp2 = cptr;
2160 }
2161 return cp2;
2162 return 0;
2163}
2164
2165
2166static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2167{
2168 switch (tp) {
2169 case pvr2_ctl_int: return "integer";
2170 case pvr2_ctl_enum: return "enum";
2171 case pvr2_ctl_bool: return "boolean";
2172 case pvr2_ctl_bitmask: return "bitmask";
2173 }
2174 return "";
2175}
2176
2177
2178/* Commit all control changes made up to this point. Subsystems can be
2179 indirectly affected by these changes. For a given set of things being
2180 committed, we'll clear the affected subsystem bits and then once we're
2181 done committing everything we'll make a request to restore the subsystem
2182 state(s) back to their previous value before this function was called.
2183 Thus we can automatically reconfigure affected pieces of the driver as
2184 controls are changed. */
2185int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
2186{
2187 unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
2188 unsigned long stale_subsys_mask = 0;
2189 unsigned int idx;
2190 struct pvr2_ctrl *cptr;
2191 int value;
2192 int commit_flag = 0;
2193 char buf[100];
2194 unsigned int bcnt,ccnt;
2195
2196 for (idx = 0; idx < hdw->control_cnt; idx++) {
2197 cptr = hdw->controls + idx;
2198 if (cptr->info->is_dirty == 0) continue;
2199 if (!cptr->info->is_dirty(cptr)) continue;
2200 if (!commit_flag) {
2201 commit_flag = !0;
2202 }
2203
2204 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2205 cptr->info->name);
2206 value = 0;
2207 cptr->info->get_value(cptr,&value);
2208 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2209 buf+bcnt,
2210 sizeof(buf)-bcnt,&ccnt);
2211 bcnt += ccnt;
2212 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2213 get_ctrl_typename(cptr->info->type));
2214 pvr2_trace(PVR2_TRACE_CTL,
2215 "/*--TRACE_COMMIT--*/ %.*s",
2216 bcnt,buf);
2217 }
2218
2219 if (!commit_flag) {
2220 /* Nothing has changed */
2221 return 0;
2222 }
2223
2224 /* When video standard changes, reset the hres and vres values -
2225 but if the user has pending changes there, then let the changes
2226 take priority. */
2227 if (hdw->std_dirty) {
2228 /* Rewrite the vertical resolution to be appropriate to the
2229 video standard that has been selected. */
2230 int nvres;
2231 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2232 nvres = 480;
2233 } else {
2234 nvres = 576;
2235 }
2236 if (nvres != hdw->res_ver_val) {
2237 hdw->res_ver_val = nvres;
2238 hdw->res_ver_dirty = !0;
2239 }
2240 }
2241
2242 if (hdw->std_dirty ||
2243 0) {
2244 /* If any of this changes, then the encoder needs to be
2245 reconfigured, and we need to reset the stream. */
2246 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
2247 stale_subsys_mask |= hdw->subsys_stream_mask;
2248 }
2249
2250 if (hdw->srate_dirty) {
2251 /* Write new sample rate into control structure since
2252 * the master copy is stale. We must track srate
2253 * separate from the mpeg control structure because
2254 * other logic also uses this value. */
2255 struct v4l2_ext_controls cs;
2256 struct v4l2_ext_control c1;
2257 memset(&cs,0,sizeof(cs));
2258 memset(&c1,0,sizeof(c1));
2259 cs.controls = &c1;
2260 cs.count = 1;
2261 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2262 c1.value = hdw->srate_val;
2263 cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS);
2264 }
2265
2266 /* Scan i2c core at this point - before we clear all the dirty
2267 bits. Various parts of the i2c core will notice dirty bits as
2268 appropriate and arrange to broadcast or directly send updates to
2269 the client drivers in order to keep everything in sync */
2270 pvr2_i2c_core_check_stale(hdw);
2271
2272 for (idx = 0; idx < hdw->control_cnt; idx++) {
2273 cptr = hdw->controls + idx;
2274 if (!cptr->info->clear_dirty) continue;
2275 cptr->info->clear_dirty(cptr);
2276 }
2277
2278 /* Now execute i2c core update */
2279 pvr2_i2c_core_sync(hdw);
2280
2281 pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
2282 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
2283
2284 return 0;
2285}
2286
2287
2288int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2289{
2290 LOCK_TAKE(hdw->big_lock); do {
2291 pvr2_hdw_commit_ctl_internal(hdw);
2292 } while (0); LOCK_GIVE(hdw->big_lock);
2293 return 0;
2294}
2295
2296
2297void pvr2_hdw_poll(struct pvr2_hdw *hdw)
2298{
2299 LOCK_TAKE(hdw->big_lock); do {
2300 pvr2_i2c_core_sync(hdw);
2301 } while (0); LOCK_GIVE(hdw->big_lock);
2302}
2303
2304
2305void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
2306 void (*func)(void *),
2307 void *data)
2308{
2309 LOCK_TAKE(hdw->big_lock); do {
2310 hdw->poll_trigger_func = func;
2311 hdw->poll_trigger_data = data;
2312 } while (0); LOCK_GIVE(hdw->big_lock);
2313}
2314
2315
2316void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
2317{
2318 if (hdw->poll_trigger_func) {
2319 hdw->poll_trigger_func(hdw->poll_trigger_data);
2320 }
2321}
2322
2323
2324void pvr2_hdw_poll_trigger(struct pvr2_hdw *hdw)
2325{
2326 LOCK_TAKE(hdw->big_lock); do {
2327 pvr2_hdw_poll_trigger_unlocked(hdw);
2328 } while (0); LOCK_GIVE(hdw->big_lock);
2329}
2330
2331
2332/* Return name for this driver instance */
2333const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2334{
2335 return hdw->name;
2336}
2337
2338
2339/* Return bit mask indicating signal status */
2340unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
2341{
2342 unsigned int msk = 0;
2343 switch (hdw->input_val) {
2344 case PVR2_CVAL_INPUT_TV:
2345 case PVR2_CVAL_INPUT_RADIO:
2346 if (hdw->decoder_ctrl &&
2347 hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) {
2348 msk |= PVR2_SIGNAL_OK;
2349 if (hdw->audio_stat &&
2350 hdw->audio_stat->status(hdw->audio_stat->ctxt)) {
2351 if (hdw->flag_stereo) {
2352 msk |= PVR2_SIGNAL_STEREO;
2353 }
2354 if (hdw->flag_bilingual) {
2355 msk |= PVR2_SIGNAL_SAP;
2356 }
2357 }
2358 }
2359 break;
2360 default:
2361 msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO;
2362 }
2363 return msk;
2364}
2365
2366
2367int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2368{
2369 int result;
2370 LOCK_TAKE(hdw->ctl_lock); do {
2371 hdw->cmd_buffer[0] = 0x0b;
2372 result = pvr2_send_request(hdw,
2373 hdw->cmd_buffer,1,
2374 hdw->cmd_buffer,1);
2375 if (result < 0) break;
2376 result = (hdw->cmd_buffer[0] != 0);
2377 } while(0); LOCK_GIVE(hdw->ctl_lock);
2378 return result;
2379}
2380
2381
2382/* Return bit mask indicating signal status */
2383unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw)
2384{
2385 unsigned int msk = 0;
2386 LOCK_TAKE(hdw->big_lock); do {
2387 msk = pvr2_hdw_get_signal_status_internal(hdw);
2388 } while (0); LOCK_GIVE(hdw->big_lock);
2389 return msk;
2390}
2391
2392
2393/* Get handle to video output stream */
2394struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2395{
2396 return hp->vid_stream;
2397}
2398
2399
2400void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2401{
2402 int nr = pvr2_hdw_get_unit_number(hdw);
2403 LOCK_TAKE(hdw->big_lock); do {
2404 hdw->log_requested = !0;
2405 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
2406 pvr2_i2c_core_check_stale(hdw);
2407 hdw->log_requested = 0;
2408 pvr2_i2c_core_sync(hdw);
2409 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
2410 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
2411 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
2412 } while (0); LOCK_GIVE(hdw->big_lock);
2413}
2414
2415void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
2416{
2417 int ret;
2418 u16 address;
2419 unsigned int pipe;
2420 LOCK_TAKE(hdw->big_lock); do {
2421 if ((hdw->fw_buffer == 0) == !enable_flag) break;
2422
2423 if (!enable_flag) {
2424 pvr2_trace(PVR2_TRACE_FIRMWARE,
2425 "Cleaning up after CPU firmware fetch");
2426 kfree(hdw->fw_buffer);
2427 hdw->fw_buffer = 0;
2428 hdw->fw_size = 0;
2429 /* Now release the CPU. It will disconnect and
2430 reconnect later. */
2431 pvr2_hdw_cpureset_assert(hdw,0);
2432 break;
2433 }
2434
2435 pvr2_trace(PVR2_TRACE_FIRMWARE,
2436 "Preparing to suck out CPU firmware");
2437 hdw->fw_size = 0x2000;
2438 hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL);
2439 if (!hdw->fw_buffer) {
2440 hdw->fw_size = 0;
2441 break;
2442 }
2443
2444 memset(hdw->fw_buffer,0,hdw->fw_size);
2445
2446 /* We have to hold the CPU during firmware upload. */
2447 pvr2_hdw_cpureset_assert(hdw,1);
2448
2449 /* download the firmware from address 0000-1fff in 2048
2450 (=0x800) bytes chunk. */
2451
2452 pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
2453 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2454 for(address = 0; address < hdw->fw_size; address += 0x800) {
2455 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
2456 address,0,
2457 hdw->fw_buffer+address,0x800,HZ);
2458 if (ret < 0) break;
2459 }
2460
2461 pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
2462
2463 } while (0); LOCK_GIVE(hdw->big_lock);
2464}
2465
2466
2467/* Return true if we're in a mode for retrieval CPU firmware */
2468int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2469{
2470 return hdw->fw_buffer != 0;
2471}
2472
2473
2474int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2475 char *buf,unsigned int cnt)
2476{
2477 int ret = -EINVAL;
2478 LOCK_TAKE(hdw->big_lock); do {
2479 if (!buf) break;
2480 if (!cnt) break;
2481
2482 if (!hdw->fw_buffer) {
2483 ret = -EIO;
2484 break;
2485 }
2486
2487 if (offs >= hdw->fw_size) {
2488 pvr2_trace(PVR2_TRACE_FIRMWARE,
2489 "Read firmware data offs=%d EOF",
2490 offs);
2491 ret = 0;
2492 break;
2493 }
2494
2495 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2496
2497 memcpy(buf,hdw->fw_buffer+offs,cnt);
2498
2499 pvr2_trace(PVR2_TRACE_FIRMWARE,
2500 "Read firmware data offs=%d cnt=%d",
2501 offs,cnt);
2502 ret = cnt;
2503 } while (0); LOCK_GIVE(hdw->big_lock);
2504
2505 return ret;
2506}
2507
2508
2509int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw)
2510{
2511 return hdw->v4l_minor_number;
2512}
2513
2514
2515/* Store the v4l minor device number */
2516void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v)
2517{
2518 hdw->v4l_minor_number = v;
2519}
2520
2521
2522void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw)
2523{
2524 if (!hdw->usb_dev) return;
2525 usb_settoggle(hdw->usb_dev, PVR2_CTL_WRITE_ENDPOINT & 0xf,
2526 !(PVR2_CTL_WRITE_ENDPOINT & USB_DIR_IN), 0);
2527 usb_settoggle(hdw->usb_dev, PVR2_CTL_READ_ENDPOINT & 0xf,
2528 !(PVR2_CTL_READ_ENDPOINT & USB_DIR_IN), 0);
2529 usb_clear_halt(hdw->usb_dev,
2530 usb_rcvbulkpipe(hdw->usb_dev,
2531 PVR2_CTL_READ_ENDPOINT & 0x7f));
2532 usb_clear_halt(hdw->usb_dev,
2533 usb_sndbulkpipe(hdw->usb_dev,
2534 PVR2_CTL_WRITE_ENDPOINT & 0x7f));
2535}
2536
2537
2538static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs)
2539{
2540 struct pvr2_hdw *hdw = urb->context;
2541 hdw->ctl_write_pend_flag = 0;
2542 if (hdw->ctl_read_pend_flag) return;
2543 complete(&hdw->ctl_done);
2544}
2545
2546
2547static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs)
2548{
2549 struct pvr2_hdw *hdw = urb->context;
2550 hdw->ctl_read_pend_flag = 0;
2551 if (hdw->ctl_write_pend_flag) return;
2552 complete(&hdw->ctl_done);
2553}
2554
2555
2556static void pvr2_ctl_timeout(unsigned long data)
2557{
2558 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2559 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2560 hdw->ctl_timeout_flag = !0;
2561 if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) {
2562 usb_unlink_urb(hdw->ctl_write_urb);
2563 }
2564 if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) {
2565 usb_unlink_urb(hdw->ctl_read_urb);
2566 }
2567 }
2568}
2569
2570
2571int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2572 unsigned int timeout,int probe_fl,
2573 void *write_data,unsigned int write_len,
2574 void *read_data,unsigned int read_len)
2575{
2576 unsigned int idx;
2577 int status = 0;
2578 struct timer_list timer;
2579 if (!hdw->ctl_lock_held) {
2580 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2581 "Attempted to execute control transfer"
2582 " without lock!!");
2583 return -EDEADLK;
2584 }
2585 if ((!hdw->flag_ok) && !probe_fl) {
2586 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2587 "Attempted to execute control transfer"
2588 " when device not ok");
2589 return -EIO;
2590 }
2591 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2592 if (!probe_fl) {
2593 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2594 "Attempted to execute control transfer"
2595 " when USB is disconnected");
2596 }
2597 return -ENOTTY;
2598 }
2599
2600 /* Ensure that we have sane parameters */
2601 if (!write_data) write_len = 0;
2602 if (!read_data) read_len = 0;
2603 if (write_len > PVR2_CTL_BUFFSIZE) {
2604 pvr2_trace(
2605 PVR2_TRACE_ERROR_LEGS,
2606 "Attempted to execute %d byte"
2607 " control-write transfer (limit=%d)",
2608 write_len,PVR2_CTL_BUFFSIZE);
2609 return -EINVAL;
2610 }
2611 if (read_len > PVR2_CTL_BUFFSIZE) {
2612 pvr2_trace(
2613 PVR2_TRACE_ERROR_LEGS,
2614 "Attempted to execute %d byte"
2615 " control-read transfer (limit=%d)",
2616 write_len,PVR2_CTL_BUFFSIZE);
2617 return -EINVAL;
2618 }
2619 if ((!write_len) && (!read_len)) {
2620 pvr2_trace(
2621 PVR2_TRACE_ERROR_LEGS,
2622 "Attempted to execute null control transfer?");
2623 return -EINVAL;
2624 }
2625
2626
2627 hdw->cmd_debug_state = 1;
2628 if (write_len) {
2629 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2630 } else {
2631 hdw->cmd_debug_code = 0;
2632 }
2633 hdw->cmd_debug_write_len = write_len;
2634 hdw->cmd_debug_read_len = read_len;
2635
2636 /* Initialize common stuff */
2637 init_completion(&hdw->ctl_done);
2638 hdw->ctl_timeout_flag = 0;
2639 hdw->ctl_write_pend_flag = 0;
2640 hdw->ctl_read_pend_flag = 0;
2641 init_timer(&timer);
2642 timer.expires = jiffies + timeout;
2643 timer.data = (unsigned long)hdw;
2644 timer.function = pvr2_ctl_timeout;
2645
2646 if (write_len) {
2647 hdw->cmd_debug_state = 2;
2648 /* Transfer write data to internal buffer */
2649 for (idx = 0; idx < write_len; idx++) {
2650 hdw->ctl_write_buffer[idx] =
2651 ((unsigned char *)write_data)[idx];
2652 }
2653 /* Initiate a write request */
2654 usb_fill_bulk_urb(hdw->ctl_write_urb,
2655 hdw->usb_dev,
2656 usb_sndbulkpipe(hdw->usb_dev,
2657 PVR2_CTL_WRITE_ENDPOINT),
2658 hdw->ctl_write_buffer,
2659 write_len,
2660 pvr2_ctl_write_complete,
2661 hdw);
2662 hdw->ctl_write_urb->actual_length = 0;
2663 hdw->ctl_write_pend_flag = !0;
2664 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2665 if (status < 0) {
2666 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2667 "Failed to submit write-control"
2668 " URB status=%d",status);
2669 hdw->ctl_write_pend_flag = 0;
2670 goto done;
2671 }
2672 }
2673
2674 if (read_len) {
2675 hdw->cmd_debug_state = 3;
2676 memset(hdw->ctl_read_buffer,0x43,read_len);
2677 /* Initiate a read request */
2678 usb_fill_bulk_urb(hdw->ctl_read_urb,
2679 hdw->usb_dev,
2680 usb_rcvbulkpipe(hdw->usb_dev,
2681 PVR2_CTL_READ_ENDPOINT),
2682 hdw->ctl_read_buffer,
2683 read_len,
2684 pvr2_ctl_read_complete,
2685 hdw);
2686 hdw->ctl_read_urb->actual_length = 0;
2687 hdw->ctl_read_pend_flag = !0;
2688 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
2689 if (status < 0) {
2690 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2691 "Failed to submit read-control"
2692 " URB status=%d",status);
2693 hdw->ctl_read_pend_flag = 0;
2694 goto done;
2695 }
2696 }
2697
2698 /* Start timer */
2699 add_timer(&timer);
2700
2701 /* Now wait for all I/O to complete */
2702 hdw->cmd_debug_state = 4;
2703 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2704 wait_for_completion(&hdw->ctl_done);
2705 }
2706 hdw->cmd_debug_state = 5;
2707
2708 /* Stop timer */
2709 del_timer_sync(&timer);
2710
2711 hdw->cmd_debug_state = 6;
2712 status = 0;
2713
2714 if (hdw->ctl_timeout_flag) {
2715 status = -ETIMEDOUT;
2716 if (!probe_fl) {
2717 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2718 "Timed out control-write");
2719 }
2720 goto done;
2721 }
2722
2723 if (write_len) {
2724 /* Validate results of write request */
2725 if ((hdw->ctl_write_urb->status != 0) &&
2726 (hdw->ctl_write_urb->status != -ENOENT) &&
2727 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
2728 (hdw->ctl_write_urb->status != -ECONNRESET)) {
2729 /* USB subsystem is reporting some kind of failure
2730 on the write */
2731 status = hdw->ctl_write_urb->status;
2732 if (!probe_fl) {
2733 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2734 "control-write URB failure,"
2735 " status=%d",
2736 status);
2737 }
2738 goto done;
2739 }
2740 if (hdw->ctl_write_urb->actual_length < write_len) {
2741 /* Failed to write enough data */
2742 status = -EIO;
2743 if (!probe_fl) {
2744 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2745 "control-write URB short,"
2746 " expected=%d got=%d",
2747 write_len,
2748 hdw->ctl_write_urb->actual_length);
2749 }
2750 goto done;
2751 }
2752 }
2753 if (read_len) {
2754 /* Validate results of read request */
2755 if ((hdw->ctl_read_urb->status != 0) &&
2756 (hdw->ctl_read_urb->status != -ENOENT) &&
2757 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
2758 (hdw->ctl_read_urb->status != -ECONNRESET)) {
2759 /* USB subsystem is reporting some kind of failure
2760 on the read */
2761 status = hdw->ctl_read_urb->status;
2762 if (!probe_fl) {
2763 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2764 "control-read URB failure,"
2765 " status=%d",
2766 status);
2767 }
2768 goto done;
2769 }
2770 if (hdw->ctl_read_urb->actual_length < read_len) {
2771 /* Failed to read enough data */
2772 status = -EIO;
2773 if (!probe_fl) {
2774 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2775 "control-read URB short,"
2776 " expected=%d got=%d",
2777 read_len,
2778 hdw->ctl_read_urb->actual_length);
2779 }
2780 goto done;
2781 }
2782 /* Transfer retrieved data out from internal buffer */
2783 for (idx = 0; idx < read_len; idx++) {
2784 ((unsigned char *)read_data)[idx] =
2785 hdw->ctl_read_buffer[idx];
2786 }
2787 }
2788
2789 done:
2790
2791 hdw->cmd_debug_state = 0;
2792 if ((status < 0) && (!probe_fl)) {
2793 pvr2_hdw_render_useless_unlocked(hdw);
2794 }
2795 return status;
2796}
2797
2798
2799int pvr2_send_request(struct pvr2_hdw *hdw,
2800 void *write_data,unsigned int write_len,
2801 void *read_data,unsigned int read_len)
2802{
2803 return pvr2_send_request_ex(hdw,HZ*4,0,
2804 write_data,write_len,
2805 read_data,read_len);
2806}
2807
2808int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
2809{
2810 int ret;
2811
2812 LOCK_TAKE(hdw->ctl_lock);
2813
2814 hdw->cmd_buffer[0] = 0x04; /* write register prefix */
2815 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
2816 hdw->cmd_buffer[5] = 0;
2817 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2818 hdw->cmd_buffer[7] = reg & 0xff;
2819
2820
2821 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
2822
2823 LOCK_GIVE(hdw->ctl_lock);
2824
2825 return ret;
2826}
2827
2828
2829int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
2830{
2831 int ret = 0;
2832
2833 LOCK_TAKE(hdw->ctl_lock);
2834
2835 hdw->cmd_buffer[0] = 0x05; /* read register prefix */
2836 hdw->cmd_buffer[1] = 0;
2837 hdw->cmd_buffer[2] = 0;
2838 hdw->cmd_buffer[3] = 0;
2839 hdw->cmd_buffer[4] = 0;
2840 hdw->cmd_buffer[5] = 0;
2841 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2842 hdw->cmd_buffer[7] = reg & 0xff;
2843
2844 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
2845 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
2846
2847 LOCK_GIVE(hdw->ctl_lock);
2848
2849 return ret;
2850}
2851
2852
2853int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
2854{
2855 int ret;
2856
2857 LOCK_TAKE(hdw->ctl_lock);
2858
2859 hdw->cmd_buffer[0] = (data >> 8) & 0xff;
2860 hdw->cmd_buffer[1] = data & 0xff;
2861
2862 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
2863
2864 LOCK_GIVE(hdw->ctl_lock);
2865
2866 return ret;
2867}
2868
2869
2870int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
2871{
2872 int ret;
2873
2874 LOCK_TAKE(hdw->ctl_lock);
2875
2876 hdw->cmd_buffer[0] = data;
2877
2878 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
2879
2880 LOCK_GIVE(hdw->ctl_lock);
2881
2882 return ret;
2883}
2884
2885
2886void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
2887{
2888 if (!hdw->flag_ok) return;
2889 pvr2_trace(PVR2_TRACE_INIT,"render_useless");
2890 hdw->flag_ok = 0;
2891 if (hdw->vid_stream) {
2892 pvr2_stream_setup(hdw->vid_stream,0,0,0);
2893 }
2894 hdw->flag_streaming_enabled = 0;
2895 hdw->subsys_enabled_mask = 0;
2896}
2897
2898
2899void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
2900{
2901 LOCK_TAKE(hdw->ctl_lock);
2902 pvr2_hdw_render_useless_unlocked(hdw);
2903 LOCK_GIVE(hdw->ctl_lock);
2904}
2905
2906
2907void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
2908{
2909 int ret;
2910 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
2911 ret = usb_lock_device_for_reset(hdw->usb_dev,0);
2912 if (ret == 1) {
2913 ret = usb_reset_device(hdw->usb_dev);
2914 usb_unlock_device(hdw->usb_dev);
2915 } else {
2916 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2917 "Failed to lock USB device ret=%d",ret);
2918 }
2919 if (init_pause_msec) {
2920 pvr2_trace(PVR2_TRACE_INFO,
2921 "Waiting %u msec for hardware to settle",
2922 init_pause_msec);
2923 msleep(init_pause_msec);
2924 }
2925
2926}
2927
2928
2929void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
2930{
2931 char da[1];
2932 unsigned int pipe;
2933 int ret;
2934
2935 if (!hdw->usb_dev) return;
2936
2937 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
2938
2939 da[0] = val ? 0x01 : 0x00;
2940
2941 /* Write the CPUCS register on the 8051. The lsb of the register
2942 is the reset bit; a 1 asserts reset while a 0 clears it. */
2943 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
2944 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
2945 if (ret < 0) {
2946 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2947 "cpureset_assert(%d) error=%d",val,ret);
2948 pvr2_hdw_render_useless(hdw);
2949 }
2950}
2951
2952
2953int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
2954{
2955 int status;
2956 LOCK_TAKE(hdw->ctl_lock); do {
2957 pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
2958 hdw->flag_ok = !0;
2959 hdw->cmd_buffer[0] = 0xdd;
2960 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
2961 } while (0); LOCK_GIVE(hdw->ctl_lock);
2962 return status;
2963}
2964
2965
2966int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
2967{
2968 int status;
2969 LOCK_TAKE(hdw->ctl_lock); do {
2970 pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
2971 hdw->cmd_buffer[0] = 0xde;
2972 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
2973 } while (0); LOCK_GIVE(hdw->ctl_lock);
2974 return status;
2975}
2976
2977
2978int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
2979{
2980 if (!hdw->decoder_ctrl) {
2981 pvr2_trace(PVR2_TRACE_INIT,
2982 "Unable to reset decoder: nothing attached");
2983 return -ENOTTY;
2984 }
2985
2986 if (!hdw->decoder_ctrl->force_reset) {
2987 pvr2_trace(PVR2_TRACE_INIT,
2988 "Unable to reset decoder: not implemented");
2989 return -ENOTTY;
2990 }
2991
2992 pvr2_trace(PVR2_TRACE_INIT,
2993 "Requesting decoder reset");
2994 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
2995 return 0;
2996}
2997
2998
2999int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
3000{
3001 int status;
3002 LOCK_TAKE(hdw->ctl_lock); do {
3003 hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
3004 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
3005 } while (0); LOCK_GIVE(hdw->ctl_lock);
3006 if (!status) {
3007 hdw->subsys_enabled_mask =
3008 ((hdw->subsys_enabled_mask &
3009 ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
3010 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
3011 }
3012 return status;
3013}
3014
3015
3016void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
3017 struct pvr2_hdw_debug_info *ptr)
3018{
3019 ptr->big_lock_held = hdw->big_lock_held;
3020 ptr->ctl_lock_held = hdw->ctl_lock_held;
3021 ptr->flag_ok = hdw->flag_ok;
3022 ptr->flag_disconnected = hdw->flag_disconnected;
3023 ptr->flag_init_ok = hdw->flag_init_ok;
3024 ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
3025 ptr->subsys_flags = hdw->subsys_enabled_mask;
3026 ptr->cmd_debug_state = hdw->cmd_debug_state;
3027 ptr->cmd_code = hdw->cmd_debug_code;
3028 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
3029 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
3030 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
3031 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
3032 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
3033 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
3034 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
3035}
3036
3037
3038int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
3039{
3040 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
3041}
3042
3043
3044int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
3045{
3046 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
3047}
3048
3049
3050int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
3051{
3052 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
3053}
3054
3055
3056int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
3057{
3058 u32 cval,nval;
3059 int ret;
3060 if (~msk) {
3061 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
3062 if (ret) return ret;
3063 nval = (cval & ~msk) | (val & msk);
3064 pvr2_trace(PVR2_TRACE_GPIO,
3065 "GPIO direction changing 0x%x:0x%x"
3066 " from 0x%x to 0x%x",
3067 msk,val,cval,nval);
3068 } else {
3069 nval = val;
3070 pvr2_trace(PVR2_TRACE_GPIO,
3071 "GPIO direction changing to 0x%x",nval);
3072 }
3073 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
3074}
3075
3076
3077int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
3078{
3079 u32 cval,nval;
3080 int ret;
3081 if (~msk) {
3082 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
3083 if (ret) return ret;
3084 nval = (cval & ~msk) | (val & msk);
3085 pvr2_trace(PVR2_TRACE_GPIO,
3086 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
3087 msk,val,cval,nval);
3088 } else {
3089 nval = val;
3090 pvr2_trace(PVR2_TRACE_GPIO,
3091 "GPIO output changing to 0x%x",nval);
3092 }
3093 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
3094}
3095
3096
3097int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
3098{
3099 int result;
3100 LOCK_TAKE(hdw->ctl_lock); do {
3101 hdw->cmd_buffer[0] = 0xeb;
3102 result = pvr2_send_request(hdw,
3103 hdw->cmd_buffer,1,
3104 hdw->cmd_buffer,1);
3105 if (result < 0) break;
3106 result = hdw->cmd_buffer[0];
3107 } while(0); LOCK_GIVE(hdw->ctl_lock);
3108 return result;
3109}
3110
3111
3112/*
3113 Stuff for Emacs to see, in order to encourage consistent editing style:
3114 *** Local Variables: ***
3115 *** mode: c ***
3116 *** fill-column: 75 ***
3117 *** tab-width: 8 ***
3118 *** c-basic-offset: 8 ***
3119 *** End: ***
3120 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
new file mode 100644
index 000000000000..63f529154431
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -0,0 +1,335 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_HDW_H
22#define __PVRUSB2_HDW_H
23
24#include <linux/usb.h>
25#include <linux/videodev2.h>
26#include "pvrusb2-io.h"
27#include "pvrusb2-ctrl.h"
28
29
30/* Private internal control ids, look these up with
31 pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */
32#define PVR2_CID_STDENUM 1
33#define PVR2_CID_STDCUR 2
34#define PVR2_CID_STDAVAIL 3
35#define PVR2_CID_INPUT 4
36#define PVR2_CID_AUDIOMODE 5
37#define PVR2_CID_FREQUENCY 6
38#define PVR2_CID_HRES 7
39#define PVR2_CID_VRES 8
40
41/* Legal values for the INPUT state variable */
42#define PVR2_CVAL_INPUT_TV 0
43#define PVR2_CVAL_INPUT_SVIDEO 1
44#define PVR2_CVAL_INPUT_COMPOSITE 2
45#define PVR2_CVAL_INPUT_RADIO 3
46
47/* Values that pvr2_hdw_get_signal_status() returns */
48#define PVR2_SIGNAL_OK 0x0001
49#define PVR2_SIGNAL_STEREO 0x0002
50#define PVR2_SIGNAL_SAP 0x0004
51
52
53/* Subsystem definitions - these are various pieces that can be
54 independently stopped / started. Usually you don't want to mess with
55 this directly (let the driver handle things itself), but it is useful
56 for debugging. */
57#define PVR2_SUBSYS_B_ENC_FIRMWARE 0
58#define PVR2_SUBSYS_B_ENC_CFG 1
59#define PVR2_SUBSYS_B_DIGITIZER_RUN 2
60#define PVR2_SUBSYS_B_USBSTREAM_RUN 3
61#define PVR2_SUBSYS_B_ENC_RUN 4
62
63#define PVR2_SUBSYS_CFG_ALL ( \
64 (1 << PVR2_SUBSYS_B_ENC_FIRMWARE) | \
65 (1 << PVR2_SUBSYS_B_ENC_CFG) )
66#define PVR2_SUBSYS_RUN_ALL ( \
67 (1 << PVR2_SUBSYS_B_DIGITIZER_RUN) | \
68 (1 << PVR2_SUBSYS_B_USBSTREAM_RUN) | \
69 (1 << PVR2_SUBSYS_B_ENC_RUN) )
70#define PVR2_SUBSYS_ALL ( \
71 PVR2_SUBSYS_CFG_ALL | \
72 PVR2_SUBSYS_RUN_ALL )
73
74enum pvr2_config {
75 pvr2_config_empty,
76 pvr2_config_mpeg,
77 pvr2_config_vbi,
78 pvr2_config_radio,
79};
80
81const char *pvr2_config_get_name(enum pvr2_config);
82
83struct pvr2_hdw;
84
85/* Create and return a structure for interacting with the underlying
86 hardware */
87struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
88 const struct usb_device_id *devid);
89
90/* Poll for background activity (if any) */
91void pvr2_hdw_poll(struct pvr2_hdw *);
92
93/* Trigger a poll to take place later at a convenient time */
94void pvr2_hdw_poll_trigger(struct pvr2_hdw *);
95void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *);
96
97/* Register a callback used to trigger a future poll */
98void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *,
99 void (*func)(void *),
100 void *data);
101
102/* Get pointer to structure given unit number */
103struct pvr2_hdw *pvr2_hdw_find(int unit_number);
104
105/* Destroy hardware interaction structure */
106void pvr2_hdw_destroy(struct pvr2_hdw *);
107
108/* Set up the structure and attempt to put the device into a usable state.
109 This can be a time-consuming operation, which is why it is not done
110 internally as part of the create() step. Return value is exactly the
111 same as pvr2_hdw_init_ok(). */
112int pvr2_hdw_setup(struct pvr2_hdw *);
113
114/* Initialization succeeded */
115int pvr2_hdw_init_ok(struct pvr2_hdw *);
116
117/* Return true if in the ready (normal) state */
118int pvr2_hdw_dev_ok(struct pvr2_hdw *);
119
120/* Return small integer number [1..N] for logical instance number of this
121 device. This is useful for indexing array-valued module parameters. */
122int pvr2_hdw_get_unit_number(struct pvr2_hdw *);
123
124/* Get pointer to underlying USB device */
125struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *);
126
127/* Retrieve serial number of device */
128unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
129
130/* Called when hardware has been unplugged */
131void pvr2_hdw_disconnect(struct pvr2_hdw *);
132
133/* Get the number of defined controls */
134unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *);
135
136/* Retrieve a control handle given its index (0..count-1) */
137struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int);
138
139/* Retrieve a control handle given its internal ID (if any) */
140struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *,unsigned int);
141
142/* Retrieve a control handle given its V4L ID (if any) */
143struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *,unsigned int ctl_id);
144
145/* Retrieve a control handle given its immediate predecessor V4L ID (if any) */
146struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *,
147 unsigned int ctl_id);
148
149/* Commit all control changes made up to this point */
150int pvr2_hdw_commit_ctl(struct pvr2_hdw *);
151
152/* Return name for this driver instance */
153const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *);
154
155/* Return PVR2_SIGNAL_XXXX bit mask indicating signal status */
156unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *);
157
158/* Query device and see if it thinks it is on a high-speed USB link */
159int pvr2_hdw_is_hsm(struct pvr2_hdw *);
160
161/* Turn streaming on/off */
162int pvr2_hdw_set_streaming(struct pvr2_hdw *,int);
163
164/* Find out if streaming is on */
165int pvr2_hdw_get_streaming(struct pvr2_hdw *);
166
167/* Configure the type of stream to generate */
168int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config);
169
170/* Get handle to video output stream */
171struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *);
172
173/* Emit a video standard struct */
174int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std,
175 unsigned int idx);
176
177/* Enable / disable various pieces of hardware. Items to change are
178 identified by bit positions within msk, and new state for each item is
179 identified by corresponding bit positions within val. */
180void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
181 unsigned long msk,unsigned long val);
182
183/* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,msk) */
184void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk);
185
186/* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,0) */
187void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk);
188
189/* Retrieve mask indicating which pieces of hardware are currently enabled
190 / configured. */
191unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *);
192
193/* Adjust mask of what get shut down when streaming is stopped. This is a
194 debugging aid. */
195void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
196 unsigned long msk,unsigned long val);
197
198/* Retrieve mask indicating which pieces of hardware are disabled when
199 streaming is turned off. */
200unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *);
201
202
203/* Enable / disable retrieval of CPU firmware. This must be enabled before
204 pvr2_hdw_cpufw_get() will function. Note that doing this may prevent
205 the device from running (and leaving this mode may imply a device
206 reset). */
207void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, int enable_flag);
208
209/* Return true if we're in a mode for retrieval CPU firmware */
210int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *);
211
212/* Retrieve a piece of the CPU's firmware at the given offset. Return
213 value is the number of bytes retrieved or zero if we're past the end or
214 an error otherwise (e.g. if firmware retrieval is not enabled). */
215int pvr2_hdw_cpufw_get(struct pvr2_hdw *,unsigned int offs,
216 char *buf,unsigned int cnt);
217
218/* Retrieve previously stored v4l minor device number */
219int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *);
220
221/* Store the v4l minor device number */
222void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,int);
223
224
225/* The following entry points are all lower level things you normally don't
226 want to worry about. */
227
228/* Attempt to recover from a USB foul-up (in practice I find that if you
229 have to do this, then it's already too late). */
230void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw);
231
232/* Issue a command and get a response from the device. LOTS of higher
233 level stuff is built on this. */
234int pvr2_send_request(struct pvr2_hdw *,
235 void *write_ptr,unsigned int write_len,
236 void *read_ptr,unsigned int read_len);
237
238/* Issue a command and get a response from the device. This extended
239 version includes a probe flag (which if set means that device errors
240 should not be logged or treated as fatal) and a timeout in jiffies.
241 This can be used to non-lethally probe the health of endpoint 1. */
242int pvr2_send_request_ex(struct pvr2_hdw *,unsigned int timeout,int probe_fl,
243 void *write_ptr,unsigned int write_len,
244 void *read_ptr,unsigned int read_len);
245
246/* Slightly higher level device communication functions. */
247int pvr2_write_register(struct pvr2_hdw *, u16, u32);
248int pvr2_read_register(struct pvr2_hdw *, u16, u32 *);
249int pvr2_write_u16(struct pvr2_hdw *, u16, int);
250int pvr2_write_u8(struct pvr2_hdw *, u8, int);
251
252/* Call if for any reason we can't talk to the hardware anymore - this will
253 cause the driver to stop flailing on the device. */
254void pvr2_hdw_render_useless(struct pvr2_hdw *);
255void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *);
256
257/* Set / clear 8051's reset bit */
258void pvr2_hdw_cpureset_assert(struct pvr2_hdw *,int);
259
260/* Execute a USB-commanded device reset */
261void pvr2_hdw_device_reset(struct pvr2_hdw *);
262
263/* Execute hard reset command (after this point it's likely that the
264 encoder will have to be reconfigured). This also clears the "useless"
265 state. */
266int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *);
267
268/* Execute simple reset command */
269int pvr2_hdw_cmd_powerup(struct pvr2_hdw *);
270
271/* Order decoder to reset */
272int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *);
273
274/* Stop / start video stream transport */
275int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
276
277/* Find I2C address of eeprom */
278int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *);
279
280/* Direct manipulation of GPIO bits */
281int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *);
282int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *);
283int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *);
284int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val);
285int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val);
286
287/* This data structure is specifically for the next function... */
288struct pvr2_hdw_debug_info {
289 int big_lock_held;
290 int ctl_lock_held;
291 int flag_ok;
292 int flag_disconnected;
293 int flag_init_ok;
294 int flag_streaming_enabled;
295 unsigned long subsys_flags;
296 int cmd_debug_state;
297 int cmd_debug_write_len;
298 int cmd_debug_read_len;
299 int cmd_debug_write_pend;
300 int cmd_debug_read_pend;
301 int cmd_debug_timeout;
302 int cmd_debug_rstatus;
303 int cmd_debug_wstatus;
304 unsigned char cmd_code;
305};
306
307/* Non-intrusively retrieve internal state info - this is useful for
308 diagnosing lockups. Note that this operation is completed without any
309 kind of locking and so it is not atomic and may yield inconsistent
310 results. This is *purely* a debugging aid. */
311void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
312 struct pvr2_hdw_debug_info *);
313
314/* Cause modules to log their state once */
315void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw);
316
317/* Cause encoder firmware to be uploaded into the device. This is normally
318 done autonomously, but the interface is exported here because it is also
319 a debugging aid. */
320int pvr2_upload_firmware2(struct pvr2_hdw *hdw);
321
322/* List of device types that we can match */
323extern struct usb_device_id pvr2_device_table[];
324
325#endif /* __PVRUSB2_HDW_H */
326
327/*
328 Stuff for Emacs to see, in order to encourage consistent editing style:
329 *** Local Variables: ***
330 *** mode: c ***
331 *** fill-column: 75 ***
332 *** tab-width: 8 ***
333 *** c-basic-offset: 8 ***
334 *** End: ***
335 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
new file mode 100644
index 000000000000..1dd4f6249b99
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -0,0 +1,115 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21
22#include "pvrusb2-i2c-core.h"
23#include "pvrusb2-hdw-internal.h"
24#include "pvrusb2-debug.h"
25#include "pvrusb2-i2c-cmd-v4l2.h"
26#include "pvrusb2-audio.h"
27#include "pvrusb2-tuner.h"
28#include "pvrusb2-demod.h"
29#include "pvrusb2-video-v4l.h"
30#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
31#include "pvrusb2-cx2584x-v4l.h"
32#include "pvrusb2-wm8775.h"
33#endif
34
35#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
36
37#define OP_STANDARD 0
38#define OP_BCSH 1
39#define OP_VOLUME 2
40#define OP_FREQ 3
41#define OP_AUDIORATE 4
42#define OP_SIZE 5
43#define OP_LOG 6
44
45static const struct pvr2_i2c_op * const ops[] = {
46 [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard,
47 [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh,
48 [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume,
49 [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency,
50 [OP_SIZE] = &pvr2_i2c_op_v4l2_size,
51 [OP_LOG] = &pvr2_i2c_op_v4l2_log,
52};
53
54void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
55{
56 int id;
57 id = cp->client->driver->id;
58 cp->ctl_mask = ((1 << OP_STANDARD) |
59 (1 << OP_BCSH) |
60 (1 << OP_VOLUME) |
61 (1 << OP_FREQ) |
62 (1 << OP_SIZE) |
63 (1 << OP_LOG));
64
65 if (id == I2C_DRIVERID_MSP3400) {
66 if (pvr2_i2c_msp3400_setup(hdw,cp)) {
67 return;
68 }
69 }
70 if (id == I2C_DRIVERID_TUNER) {
71 if (pvr2_i2c_tuner_setup(hdw,cp)) {
72 return;
73 }
74 }
75#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
76 if (id == I2C_DRIVERID_CX25840) {
77 if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
78 return;
79 }
80 }
81 if (id == I2C_DRIVERID_WM8775) {
82 if (pvr2_i2c_wm8775_setup(hdw,cp)) {
83 return;
84 }
85 }
86#endif
87 if (id == I2C_DRIVERID_SAA711X) {
88 if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
89 return;
90 }
91 }
92 if (id == I2C_DRIVERID_TDA9887) {
93 if (pvr2_i2c_demod_setup(hdw,cp)) {
94 return;
95 }
96 }
97}
98
99
100const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
101{
102 if (idx >= sizeof(ops)/sizeof(ops[0])) return 0;
103 return ops[idx];
104}
105
106
107/*
108 Stuff for Emacs to see, in order to encourage consistent editing style:
109 *** Local Variables: ***
110 *** mode: c ***
111 *** fill-column: 75 ***
112 *** tab-width: 8 ***
113 *** c-basic-offset: 8 ***
114 *** End: ***
115 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
new file mode 100644
index 000000000000..9f81aff2b38a
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
@@ -0,0 +1,232 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include "pvrusb2-i2c-cmd-v4l2.h"
24#include "pvrusb2-hdw-internal.h"
25#include "pvrusb2-debug.h"
26#include <linux/videodev2.h>
27
28
29static void set_standard(struct pvr2_hdw *hdw)
30{
31 v4l2_std_id vs;
32 vs = hdw->std_mask_cur;
33 pvr2_trace(PVR2_TRACE_CHIPS,
34 "i2c v4l2 set_standard(0x%llx)",(__u64)vs);
35
36 pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
37}
38
39
40static int check_standard(struct pvr2_hdw *hdw)
41{
42 return hdw->std_dirty != 0;
43}
44
45
46const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = {
47 .check = check_standard,
48 .update = set_standard,
49 .name = "v4l2_standard",
50};
51
52
53static void set_bcsh(struct pvr2_hdw *hdw)
54{
55 struct v4l2_control ctrl;
56 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh"
57 " b=%d c=%d s=%d h=%d",
58 hdw->brightness_val,hdw->contrast_val,
59 hdw->saturation_val,hdw->hue_val);
60 memset(&ctrl,0,sizeof(ctrl));
61 ctrl.id = V4L2_CID_BRIGHTNESS;
62 ctrl.value = hdw->brightness_val;
63 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
64 ctrl.id = V4L2_CID_CONTRAST;
65 ctrl.value = hdw->contrast_val;
66 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
67 ctrl.id = V4L2_CID_SATURATION;
68 ctrl.value = hdw->saturation_val;
69 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
70 ctrl.id = V4L2_CID_HUE;
71 ctrl.value = hdw->hue_val;
72 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
73}
74
75
76static int check_bcsh(struct pvr2_hdw *hdw)
77{
78 return (hdw->brightness_dirty ||
79 hdw->contrast_dirty ||
80 hdw->saturation_dirty ||
81 hdw->hue_dirty);
82}
83
84
85const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = {
86 .check = check_bcsh,
87 .update = set_bcsh,
88 .name = "v4l2_bcsh",
89};
90
91
92static void set_volume(struct pvr2_hdw *hdw)
93{
94 struct v4l2_control ctrl;
95 pvr2_trace(PVR2_TRACE_CHIPS,
96 "i2c v4l2 set_volume"
97 "(vol=%d bal=%d bas=%d treb=%d mute=%d)",
98 hdw->volume_val,
99 hdw->balance_val,
100 hdw->bass_val,
101 hdw->treble_val,
102 hdw->mute_val);
103 memset(&ctrl,0,sizeof(ctrl));
104 ctrl.id = V4L2_CID_AUDIO_MUTE;
105 ctrl.value = hdw->mute_val ? 1 : 0;
106 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
107 ctrl.id = V4L2_CID_AUDIO_VOLUME;
108 ctrl.value = hdw->volume_val;
109 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
110 ctrl.id = V4L2_CID_AUDIO_BALANCE;
111 ctrl.value = hdw->balance_val;
112 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
113 ctrl.id = V4L2_CID_AUDIO_BASS;
114 ctrl.value = hdw->bass_val;
115 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
116 ctrl.id = V4L2_CID_AUDIO_TREBLE;
117 ctrl.value = hdw->treble_val;
118 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
119}
120
121
122static int check_volume(struct pvr2_hdw *hdw)
123{
124 return (hdw->volume_dirty ||
125 hdw->balance_dirty ||
126 hdw->bass_dirty ||
127 hdw->treble_dirty ||
128 hdw->mute_dirty);
129}
130
131
132const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = {
133 .check = check_volume,
134 .update = set_volume,
135 .name = "v4l2_volume",
136};
137
138
139static void set_frequency(struct pvr2_hdw *hdw)
140{
141 unsigned long fv;
142 struct v4l2_frequency freq;
143 fv = hdw->freqVal;
144 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv);
145 memset(&freq,0,sizeof(freq));
146 freq.frequency = fv / 62500;
147 freq.tuner = 0;
148 freq.type = V4L2_TUNER_ANALOG_TV;
149 pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq);
150}
151
152
153static int check_frequency(struct pvr2_hdw *hdw)
154{
155 return hdw->freqDirty != 0;
156}
157
158
159const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = {
160 .check = check_frequency,
161 .update = set_frequency,
162 .name = "v4l2_freq",
163};
164
165
166static void set_size(struct pvr2_hdw *hdw)
167{
168 struct v4l2_format fmt;
169
170 memset(&fmt,0,sizeof(fmt));
171
172 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
173 fmt.fmt.pix.width = hdw->res_hor_val;
174 fmt.fmt.pix.height = hdw->res_ver_val;
175
176 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)",
177 fmt.fmt.pix.width,fmt.fmt.pix.height);
178
179 pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt);
180}
181
182
183static int check_size(struct pvr2_hdw *hdw)
184{
185 return (hdw->res_hor_dirty || hdw->res_ver_dirty);
186}
187
188
189const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = {
190 .check = check_size,
191 .update = set_size,
192 .name = "v4l2_size",
193};
194
195
196static void do_log(struct pvr2_hdw *hdw)
197{
198 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()");
199 pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,0);
200
201}
202
203
204static int check_log(struct pvr2_hdw *hdw)
205{
206 return hdw->log_requested != 0;
207}
208
209
210const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = {
211 .check = check_log,
212 .update = do_log,
213 .name = "v4l2_log",
214};
215
216
217void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl)
218{
219 pvr2_i2c_client_cmd(cp,
220 (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),0);
221}
222
223
224/*
225 Stuff for Emacs to see, in order to encourage consistent editing style:
226 *** Local Variables: ***
227 *** mode: c ***
228 *** fill-column: 70 ***
229 *** tab-width: 8 ***
230 *** c-basic-offset: 8 ***
231 *** End: ***
232 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
new file mode 100644
index 000000000000..ecabddba1ec5
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
@@ -0,0 +1,47 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef __PVRUSB2_CMD_V4L2_H
24#define __PVRUSB2_CMD_V4L2_H
25
26#include "pvrusb2-i2c-core.h"
27
28extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard;
29extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh;
30extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume;
31extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency;
32extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size;
33extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log;
34
35void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int);
36
37#endif /* __PVRUSB2_CMD_V4L2_H */
38
39/*
40 Stuff for Emacs to see, in order to encourage consistent editing style:
41 *** Local Variables: ***
42 *** mode: c ***
43 *** fill-column: 70 ***
44 *** tab-width: 8 ***
45 *** c-basic-offset: 8 ***
46 *** End: ***
47 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
new file mode 100644
index 000000000000..c8d0bdee3ff1
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -0,0 +1,937 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21
22#include "pvrusb2-i2c-core.h"
23#include "pvrusb2-hdw-internal.h"
24#include "pvrusb2-debug.h"
25
26#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
27
28/*
29
30 This module attempts to implement a compliant I2C adapter for the pvrusb2
31 device. By doing this we can then make use of existing functionality in
32 V4L (e.g. tuner.c) rather than rolling our own.
33
34*/
35
36static unsigned int i2c_scan = 0;
37module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
38MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
39
40static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
41 u8 i2c_addr, /* I2C address we're talking to */
42 u8 *data, /* Data to write */
43 u16 length) /* Size of data to write */
44{
45 /* Return value - default 0 means success */
46 int ret;
47
48
49 if (!data) length = 0;
50 if (length > (sizeof(hdw->cmd_buffer) - 3)) {
51 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
52 "Killing an I2C write to %u that is too large"
53 " (desired=%u limit=%u)",
54 i2c_addr,
55 length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3));
56 return -ENOTSUPP;
57 }
58
59 LOCK_TAKE(hdw->ctl_lock);
60
61 /* Clear the command buffer (likely to be paranoia) */
62 memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
63
64 /* Set up command buffer for an I2C write */
65 hdw->cmd_buffer[0] = 0x08; /* write prefix */
66 hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */
67 hdw->cmd_buffer[2] = length; /* length of what follows */
68 if (length) memcpy(hdw->cmd_buffer + 3, data, length);
69
70 /* Do the operation */
71 ret = pvr2_send_request(hdw,
72 hdw->cmd_buffer,
73 length + 3,
74 hdw->cmd_buffer,
75 1);
76 if (!ret) {
77 if (hdw->cmd_buffer[0] != 8) {
78 ret = -EIO;
79 if (hdw->cmd_buffer[0] != 7) {
80 trace_i2c("unexpected status"
81 " from i2_write[%d]: %d",
82 i2c_addr,hdw->cmd_buffer[0]);
83 }
84 }
85 }
86
87 LOCK_GIVE(hdw->ctl_lock);
88
89 return ret;
90}
91
92static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */
93 u8 i2c_addr, /* I2C address we're talking to */
94 u8 *data, /* Data to write */
95 u16 dlen, /* Size of data to write */
96 u8 *res, /* Where to put data we read */
97 u16 rlen) /* Amount of data to read */
98{
99 /* Return value - default 0 means success */
100 int ret;
101
102
103 if (!data) dlen = 0;
104 if (dlen > (sizeof(hdw->cmd_buffer) - 4)) {
105 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
106 "Killing an I2C read to %u that has wlen too large"
107 " (desired=%u limit=%u)",
108 i2c_addr,
109 dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4));
110 return -ENOTSUPP;
111 }
112 if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) {
113 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
114 "Killing an I2C read to %u that has rlen too large"
115 " (desired=%u limit=%u)",
116 i2c_addr,
117 rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1));
118 return -ENOTSUPP;
119 }
120
121 LOCK_TAKE(hdw->ctl_lock);
122
123 /* Clear the command buffer (likely to be paranoia) */
124 memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
125
126 /* Set up command buffer for an I2C write followed by a read */
127 hdw->cmd_buffer[0] = 0x09; /* read prefix */
128 hdw->cmd_buffer[1] = dlen; /* arg length */
129 hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one
130 more byte (status). */
131 hdw->cmd_buffer[3] = i2c_addr; /* i2c addr of chip */
132 if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen);
133
134 /* Do the operation */
135 ret = pvr2_send_request(hdw,
136 hdw->cmd_buffer,
137 4 + dlen,
138 hdw->cmd_buffer,
139 rlen + 1);
140 if (!ret) {
141 if (hdw->cmd_buffer[0] != 8) {
142 ret = -EIO;
143 if (hdw->cmd_buffer[0] != 7) {
144 trace_i2c("unexpected status"
145 " from i2_read[%d]: %d",
146 i2c_addr,hdw->cmd_buffer[0]);
147 }
148 }
149 }
150
151 /* Copy back the result */
152 if (res && rlen) {
153 if (ret) {
154 /* Error, just blank out the return buffer */
155 memset(res, 0, rlen);
156 } else {
157 memcpy(res, hdw->cmd_buffer + 1, rlen);
158 }
159 }
160
161 LOCK_GIVE(hdw->ctl_lock);
162
163 return ret;
164}
165
166/* This is the common low level entry point for doing I2C operations to the
167 hardware. */
168int pvr2_i2c_basic_op(struct pvr2_hdw *hdw,
169 u8 i2c_addr,
170 u8 *wdata,
171 u16 wlen,
172 u8 *rdata,
173 u16 rlen)
174{
175 if (!rdata) rlen = 0;
176 if (!wdata) wlen = 0;
177 if (rlen || !wlen) {
178 return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen);
179 } else {
180 return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen);
181 }
182}
183
184#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
185
186/* This is a special entry point that is entered if an I2C operation is
187 attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this
188 part doesn't work, but we know it is really there. So let's look for
189 the autodetect attempt and just return success if we see that. */
190static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
191 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
192{
193 if (!(rlen || wlen)) {
194 // This is a probe attempt. Just let it succeed.
195 return 0;
196 }
197 return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
198}
199
200/* This is a special entry point that is entered if an I2C operation is
201 attempted to a cx25840 chip on model 24xxx hardware. This chip can
202 sometimes wedge itself. Worse still, when this happens msp3400 can
203 falsely detect this part and then the system gets hosed up after msp3400
204 gets confused and dies. What we want to do here is try to keep msp3400
205 away and also try to notice if the chip is wedged and send a warning to
206 the system log. */
207static int i2c_hack_cx25840(struct pvr2_hdw *hdw,
208 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
209{
210 int ret;
211 unsigned int subaddr;
212 u8 wbuf[2];
213 int state = hdw->i2c_cx25840_hack_state;
214
215 if (!(rlen || wlen)) {
216 // Probe attempt - always just succeed and don't bother the
217 // hardware (this helps to make the state machine further
218 // down somewhat easier).
219 return 0;
220 }
221
222 if (state == 3) {
223 return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
224 }
225
226 /* We're looking for the exact pattern where the revision register
227 is being read. The cx25840 module will always look at the
228 revision register first. Any other pattern of access therefore
229 has to be a probe attempt from somebody else so we'll reject it.
230 Normally we could just let each client just probe the part
231 anyway, but when the cx25840 is wedged, msp3400 will get a false
232 positive and that just screws things up... */
233
234 if (wlen == 0) {
235 switch (state) {
236 case 1: subaddr = 0x0100; break;
237 case 2: subaddr = 0x0101; break;
238 default: goto fail;
239 }
240 } else if (wlen == 2) {
241 subaddr = (wdata[0] << 8) | wdata[1];
242 switch (subaddr) {
243 case 0x0100: state = 1; break;
244 case 0x0101: state = 2; break;
245 default: goto fail;
246 }
247 } else {
248 goto fail;
249 }
250 if (!rlen) goto success;
251 state = 0;
252 if (rlen != 1) goto fail;
253
254 /* If we get to here then we have a legitimate read for one of the
255 two revision bytes, so pass it through. */
256 wbuf[0] = subaddr >> 8;
257 wbuf[1] = subaddr;
258 ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen);
259
260 if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) {
261 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
262 "WARNING: Detected a wedged cx25840 chip;"
263 " the device will not work.");
264 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
265 "WARNING: Try power cycling the pvrusb2 device.");
266 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
267 "WARNING: Disabling further access to the device"
268 " to prevent other foul-ups.");
269 // This blocks all further communication with the part.
270 hdw->i2c_func[0x44] = 0;
271 pvr2_hdw_render_useless(hdw);
272 goto fail;
273 }
274
275 /* Success! */
276 pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK.");
277 state = 3;
278
279 success:
280 hdw->i2c_cx25840_hack_state = state;
281 return 0;
282
283 fail:
284 hdw->i2c_cx25840_hack_state = state;
285 return -EIO;
286}
287
288#endif /* CONFIG_VIDEO_PVRUSB2_24XXX */
289
290/* This is a very, very limited I2C adapter implementation. We can only
291 support what we actually know will work on the device... */
292static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
293 struct i2c_msg msgs[],
294 int num)
295{
296 int ret = -ENOTSUPP;
297 pvr2_i2c_func funcp = 0;
298 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data);
299
300 if (!num) {
301 ret = -EINVAL;
302 goto done;
303 }
304 if ((msgs[0].flags & I2C_M_NOSTART)) {
305 trace_i2c("i2c refusing I2C_M_NOSTART");
306 goto done;
307 }
308 if (msgs[0].addr < PVR2_I2C_FUNC_CNT) {
309 funcp = hdw->i2c_func[msgs[0].addr];
310 }
311 if (!funcp) {
312 ret = -EIO;
313 goto done;
314 }
315
316 if (num == 1) {
317 if (msgs[0].flags & I2C_M_RD) {
318 /* Simple read */
319 u16 tcnt,bcnt,offs;
320 if (!msgs[0].len) {
321 /* Length == 0 read. This is a probe. */
322 if (funcp(hdw,msgs[0].addr,0,0,0,0)) {
323 ret = -EIO;
324 goto done;
325 }
326 ret = 1;
327 goto done;
328 }
329 /* If the read is short enough we'll do the whole
330 thing atomically. Otherwise we have no choice
331 but to break apart the reads. */
332 tcnt = msgs[0].len;
333 offs = 0;
334 while (tcnt) {
335 bcnt = tcnt;
336 if (bcnt > sizeof(hdw->cmd_buffer)-1) {
337 bcnt = sizeof(hdw->cmd_buffer)-1;
338 }
339 if (funcp(hdw,msgs[0].addr,0,0,
340 msgs[0].buf+offs,bcnt)) {
341 ret = -EIO;
342 goto done;
343 }
344 offs += bcnt;
345 tcnt -= bcnt;
346 }
347 ret = 1;
348 goto done;
349 } else {
350 /* Simple write */
351 ret = 1;
352 if (funcp(hdw,msgs[0].addr,
353 msgs[0].buf,msgs[0].len,0,0)) {
354 ret = -EIO;
355 }
356 goto done;
357 }
358 } else if (num == 2) {
359 if (msgs[0].addr != msgs[1].addr) {
360 trace_i2c("i2c refusing 2 phase transfer with"
361 " conflicting target addresses");
362 ret = -ENOTSUPP;
363 goto done;
364 }
365 if ((!((msgs[0].flags & I2C_M_RD))) &&
366 (msgs[1].flags & I2C_M_RD)) {
367 u16 tcnt,bcnt,wcnt,offs;
368 /* Write followed by atomic read. If the read
369 portion is short enough we'll do the whole thing
370 atomically. Otherwise we have no choice but to
371 break apart the reads. */
372 tcnt = msgs[1].len;
373 wcnt = msgs[0].len;
374 offs = 0;
375 while (tcnt || wcnt) {
376 bcnt = tcnt;
377 if (bcnt > sizeof(hdw->cmd_buffer)-1) {
378 bcnt = sizeof(hdw->cmd_buffer)-1;
379 }
380 if (funcp(hdw,msgs[0].addr,
381 msgs[0].buf,wcnt,
382 msgs[1].buf+offs,bcnt)) {
383 ret = -EIO;
384 goto done;
385 }
386 offs += bcnt;
387 tcnt -= bcnt;
388 wcnt = 0;
389 }
390 ret = 2;
391 goto done;
392 } else {
393 trace_i2c("i2c refusing complex transfer"
394 " read0=%d read1=%d",
395 (msgs[0].flags & I2C_M_RD),
396 (msgs[1].flags & I2C_M_RD));
397 }
398 } else {
399 trace_i2c("i2c refusing %d phase transfer",num);
400 }
401
402 done:
403 if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) {
404 unsigned int idx,offs,cnt;
405 for (idx = 0; idx < num; idx++) {
406 cnt = msgs[idx].len;
407 printk(KERN_INFO
408 "pvrusb2 i2c xfer %u/%u:"
409 " addr=0x%x len=%d %s%s",
410 idx+1,num,
411 msgs[idx].addr,
412 cnt,
413 (msgs[idx].flags & I2C_M_RD ?
414 "read" : "write"),
415 (msgs[idx].flags & I2C_M_NOSTART ?
416 " nostart" : ""));
417 if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
418 if (cnt > 8) cnt = 8;
419 printk(" [");
420 for (offs = 0; offs < (cnt>8?8:cnt); offs++) {
421 if (offs) printk(" ");
422 printk("%02x",msgs[idx].buf[offs]);
423 }
424 if (offs < cnt) printk(" ...");
425 printk("]");
426 }
427 if (idx+1 == num) {
428 printk(" result=%d",ret);
429 }
430 printk("\n");
431 }
432 if (!num) {
433 printk(KERN_INFO
434 "pvrusb2 i2c xfer null transfer result=%d\n",
435 ret);
436 }
437 }
438 return ret;
439}
440
441static int pvr2_i2c_control(struct i2c_adapter *adapter,
442 unsigned int cmd, unsigned long arg)
443{
444 return 0;
445}
446
447static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
448{
449 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA;
450}
451
452static int pvr2_i2c_core_singleton(struct i2c_client *cp,
453 unsigned int cmd,void *arg)
454{
455 int stat;
456 if (!cp) return -EINVAL;
457 if (!(cp->driver)) return -EINVAL;
458 if (!(cp->driver->command)) return -EINVAL;
459 if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN;
460 stat = cp->driver->command(cp,cmd,arg);
461 module_put(cp->driver->driver.owner);
462 return stat;
463}
464
465int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg)
466{
467 int stat;
468 if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
469 char buf[100];
470 unsigned int cnt;
471 cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
472 buf,sizeof(buf));
473 pvr2_trace(PVR2_TRACE_I2C_CMD,
474 "i2c COMMAND (code=%u 0x%x) to %.*s",
475 cmd,cmd,cnt,buf);
476 }
477 stat = pvr2_i2c_core_singleton(cp->client,cmd,arg);
478 if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
479 char buf[100];
480 unsigned int cnt;
481 cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
482 buf,sizeof(buf));
483 pvr2_trace(PVR2_TRACE_I2C_CMD,
484 "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat);
485 }
486 return stat;
487}
488
489int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg)
490{
491 struct list_head *item,*nc;
492 struct pvr2_i2c_client *cp;
493 int stat = -EINVAL;
494
495 if (!hdw) return stat;
496
497 mutex_lock(&hdw->i2c_list_lock);
498 list_for_each_safe(item,nc,&hdw->i2c_clients) {
499 cp = list_entry(item,struct pvr2_i2c_client,list);
500 if (!cp->recv_enable) continue;
501 mutex_unlock(&hdw->i2c_list_lock);
502 stat = pvr2_i2c_client_cmd(cp,cmd,arg);
503 mutex_lock(&hdw->i2c_list_lock);
504 }
505 mutex_unlock(&hdw->i2c_list_lock);
506 return stat;
507}
508
509
510static int handler_check(struct pvr2_i2c_client *cp)
511{
512 struct pvr2_i2c_handler *hp = cp->handler;
513 if (!hp) return 0;
514 if (!hp->func_table->check) return 0;
515 return hp->func_table->check(hp->func_data) != 0;
516}
517
518#define BUFSIZE 500
519
520void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
521{
522 unsigned long msk;
523 unsigned int idx;
524 struct list_head *item,*nc;
525 struct pvr2_i2c_client *cp;
526
527 if (!hdw->i2c_linked) return;
528 if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) {
529 return;
530 }
531 mutex_lock(&hdw->i2c_list_lock); do {
532 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN");
533 if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) {
534 /* One or more I2C clients have attached since we
535 last synced. So scan the list and identify the
536 new clients. */
537 char *buf;
538 unsigned int cnt;
539 unsigned long amask = 0;
540 buf = kmalloc(BUFSIZE,GFP_KERNEL);
541 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT");
542 hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT;
543 list_for_each(item,&hdw->i2c_clients) {
544 cp = list_entry(item,struct pvr2_i2c_client,
545 list);
546 if (!cp->detected_flag) {
547 cp->ctl_mask = 0;
548 pvr2_i2c_probe(hdw,cp);
549 cp->detected_flag = !0;
550 msk = cp->ctl_mask;
551 cnt = 0;
552 if (buf) {
553 cnt = pvr2_i2c_client_describe(
554 cp,
555 PVR2_I2C_DETAIL_ALL,
556 buf,BUFSIZE);
557 }
558 trace_i2c("Probed: %.*s",cnt,buf);
559 if (handler_check(cp)) {
560 hdw->i2c_pend_types |=
561 PVR2_I2C_PEND_CLIENT;
562 }
563 cp->pend_mask = msk;
564 hdw->i2c_pend_mask |= msk;
565 hdw->i2c_pend_types |=
566 PVR2_I2C_PEND_REFRESH;
567 }
568 amask |= cp->ctl_mask;
569 }
570 hdw->i2c_active_mask = amask;
571 if (buf) kfree(buf);
572 }
573 if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) {
574 /* Need to do one or more global updates. Arrange
575 for this to happen. */
576 unsigned long m2;
577 pvr2_trace(PVR2_TRACE_I2C_CORE,
578 "i2c: PEND_STALE (0x%lx)",
579 hdw->i2c_stale_mask);
580 hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE;
581 list_for_each(item,&hdw->i2c_clients) {
582 cp = list_entry(item,struct pvr2_i2c_client,
583 list);
584 m2 = hdw->i2c_stale_mask;
585 m2 &= cp->ctl_mask;
586 m2 &= ~cp->pend_mask;
587 if (m2) {
588 pvr2_trace(PVR2_TRACE_I2C_CORE,
589 "i2c: cp=%p setting 0x%lx",
590 cp,m2);
591 cp->pend_mask |= m2;
592 }
593 }
594 hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
595 hdw->i2c_stale_mask = 0;
596 hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH;
597 }
598 if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) {
599 /* One or more client handlers are asking for an
600 update. Run through the list of known clients
601 and update each one. */
602 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT");
603 hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT;
604 list_for_each_safe(item,nc,&hdw->i2c_clients) {
605 cp = list_entry(item,struct pvr2_i2c_client,
606 list);
607 if (!cp->handler) continue;
608 if (!cp->handler->func_table->update) continue;
609 pvr2_trace(PVR2_TRACE_I2C_CORE,
610 "i2c: cp=%p update",cp);
611 mutex_unlock(&hdw->i2c_list_lock);
612 cp->handler->func_table->update(
613 cp->handler->func_data);
614 mutex_lock(&hdw->i2c_list_lock);
615 /* If client's update function set some
616 additional pending bits, account for that
617 here. */
618 if (cp->pend_mask & ~hdw->i2c_pend_mask) {
619 hdw->i2c_pend_mask |= cp->pend_mask;
620 hdw->i2c_pend_types |=
621 PVR2_I2C_PEND_REFRESH;
622 }
623 }
624 }
625 if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) {
626 const struct pvr2_i2c_op *opf;
627 unsigned long pm;
628 /* Some actual updates are pending. Walk through
629 each update type and perform it. */
630 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH"
631 " (0x%lx)",hdw->i2c_pend_mask);
632 hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH;
633 pm = hdw->i2c_pend_mask;
634 hdw->i2c_pend_mask = 0;
635 for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
636 if (!(pm & msk)) continue;
637 pm &= ~msk;
638 list_for_each(item,&hdw->i2c_clients) {
639 cp = list_entry(item,
640 struct pvr2_i2c_client,
641 list);
642 if (cp->pend_mask & msk) {
643 cp->pend_mask &= ~msk;
644 cp->recv_enable = !0;
645 } else {
646 cp->recv_enable = 0;
647 }
648 }
649 opf = pvr2_i2c_get_op(idx);
650 if (!opf) continue;
651 mutex_unlock(&hdw->i2c_list_lock);
652 opf->update(hdw);
653 mutex_lock(&hdw->i2c_list_lock);
654 }
655 }
656 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END");
657 } while (0); mutex_unlock(&hdw->i2c_list_lock);
658}
659
660int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
661{
662 unsigned long msk,sm,pm;
663 unsigned int idx;
664 const struct pvr2_i2c_op *opf;
665 struct list_head *item;
666 struct pvr2_i2c_client *cp;
667 unsigned int pt = 0;
668
669 pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN");
670
671 pm = hdw->i2c_active_mask;
672 sm = 0;
673 for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
674 if (!(msk & pm)) continue;
675 pm &= ~msk;
676 opf = pvr2_i2c_get_op(idx);
677 if (!opf) continue;
678 if (opf->check(hdw)) {
679 sm |= msk;
680 }
681 }
682 if (sm) pt |= PVR2_I2C_PEND_STALE;
683
684 list_for_each(item,&hdw->i2c_clients) {
685 cp = list_entry(item,struct pvr2_i2c_client,list);
686 if (!handler_check(cp)) continue;
687 pt |= PVR2_I2C_PEND_CLIENT;
688 }
689
690 if (pt) {
691 mutex_lock(&hdw->i2c_list_lock); do {
692 hdw->i2c_pend_types |= pt;
693 hdw->i2c_stale_mask |= sm;
694 hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
695 } while (0); mutex_unlock(&hdw->i2c_list_lock);
696 }
697
698 pvr2_trace(PVR2_TRACE_I2C_CORE,
699 "i2c: types=0x%x stale=0x%lx pend=0x%lx",
700 hdw->i2c_pend_types,
701 hdw->i2c_stale_mask,
702 hdw->i2c_pend_mask);
703 pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END");
704
705 return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0;
706}
707
708unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
709 unsigned int detail,
710 char *buf,unsigned int maxlen)
711{
712 unsigned int ccnt,bcnt;
713 int spcfl = 0;
714 const struct pvr2_i2c_op *opf;
715
716 ccnt = 0;
717 if (detail & PVR2_I2C_DETAIL_DEBUG) {
718 bcnt = scnprintf(buf,maxlen,
719 "ctxt=%p ctl_mask=0x%lx",
720 cp,cp->ctl_mask);
721 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
722 spcfl = !0;
723 }
724 bcnt = scnprintf(buf,maxlen,
725 "%s%s @ 0x%x",
726 (spcfl ? " " : ""),
727 cp->client->name,
728 cp->client->addr);
729 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
730 if ((detail & PVR2_I2C_DETAIL_HANDLER) &&
731 cp->handler && cp->handler->func_table->describe) {
732 bcnt = scnprintf(buf,maxlen," (");
733 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
734 bcnt = cp->handler->func_table->describe(
735 cp->handler->func_data,buf,maxlen);
736 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
737 bcnt = scnprintf(buf,maxlen,")");
738 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
739 }
740 if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) {
741 unsigned int idx;
742 unsigned long msk,sm;
743 int spcfl;
744 bcnt = scnprintf(buf,maxlen," [");
745 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
746 sm = 0;
747 spcfl = 0;
748 for (idx = 0, msk = 1; msk; idx++, msk <<= 1) {
749 if (!(cp->ctl_mask & msk)) continue;
750 opf = pvr2_i2c_get_op(idx);
751 if (opf) {
752 bcnt = scnprintf(buf,maxlen,"%s%s",
753 spcfl ? " " : "",
754 opf->name);
755 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
756 spcfl = !0;
757 } else {
758 sm |= msk;
759 }
760 }
761 if (sm) {
762 bcnt = scnprintf(buf,maxlen,"%s%lx",
763 idx != 0 ? " " : "",sm);
764 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
765 }
766 bcnt = scnprintf(buf,maxlen,"]");
767 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
768 }
769 return ccnt;
770}
771
772unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw,
773 char *buf,unsigned int maxlen)
774{
775 unsigned int ccnt,bcnt;
776 struct list_head *item;
777 struct pvr2_i2c_client *cp;
778 ccnt = 0;
779 mutex_lock(&hdw->i2c_list_lock); do {
780 list_for_each(item,&hdw->i2c_clients) {
781 cp = list_entry(item,struct pvr2_i2c_client,list);
782 bcnt = pvr2_i2c_client_describe(
783 cp,
784 (PVR2_I2C_DETAIL_HANDLER|
785 PVR2_I2C_DETAIL_CTLMASK),
786 buf,maxlen);
787 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
788 bcnt = scnprintf(buf,maxlen,"\n");
789 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
790 }
791 } while (0); mutex_unlock(&hdw->i2c_list_lock);
792 return ccnt;
793}
794
795static int pvr2_i2c_attach_inform(struct i2c_client *client)
796{
797 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
798 struct pvr2_i2c_client *cp;
799 int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL);
800 cp = kmalloc(sizeof(*cp),GFP_KERNEL);
801 trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]",
802 client->name,
803 client->addr,cp);
804 if (!cp) return -ENOMEM;
805 memset(cp,0,sizeof(*cp));
806 INIT_LIST_HEAD(&cp->list);
807 cp->client = client;
808 mutex_lock(&hdw->i2c_list_lock); do {
809 list_add_tail(&cp->list,&hdw->i2c_clients);
810 hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT;
811 } while (0); mutex_unlock(&hdw->i2c_list_lock);
812 if (fl) pvr2_hdw_poll_trigger_unlocked(hdw);
813 return 0;
814}
815
816static int pvr2_i2c_detach_inform(struct i2c_client *client)
817{
818 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
819 struct pvr2_i2c_client *cp;
820 struct list_head *item,*nc;
821 unsigned long amask = 0;
822 int foundfl = 0;
823 mutex_lock(&hdw->i2c_list_lock); do {
824 list_for_each_safe(item,nc,&hdw->i2c_clients) {
825 cp = list_entry(item,struct pvr2_i2c_client,list);
826 if (cp->client == client) {
827 trace_i2c("pvr2_i2c_detach"
828 " [client=%s @ 0x%x ctxt=%p]",
829 client->name,
830 client->addr,cp);
831 if (cp->handler &&
832 cp->handler->func_table->detach) {
833 cp->handler->func_table->detach(
834 cp->handler->func_data);
835 }
836 list_del(&cp->list);
837 kfree(cp);
838 foundfl = !0;
839 continue;
840 }
841 amask |= cp->ctl_mask;
842 }
843 hdw->i2c_active_mask = amask;
844 } while (0); mutex_unlock(&hdw->i2c_list_lock);
845 if (!foundfl) {
846 trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]",
847 client->name,
848 client->addr);
849 }
850 return 0;
851}
852
853static struct i2c_algorithm pvr2_i2c_algo_template = {
854 .master_xfer = pvr2_i2c_xfer,
855 .algo_control = pvr2_i2c_control,
856 .functionality = pvr2_i2c_functionality,
857};
858
859static struct i2c_adapter pvr2_i2c_adap_template = {
860 .owner = THIS_MODULE,
861 .class = I2C_CLASS_TV_ANALOG,
862 .id = I2C_HW_B_BT848,
863 .client_register = pvr2_i2c_attach_inform,
864 .client_unregister = pvr2_i2c_detach_inform,
865};
866
867static void do_i2c_scan(struct pvr2_hdw *hdw)
868{
869 struct i2c_msg msg[1];
870 int i,rc;
871 msg[0].addr = 0;
872 msg[0].flags = I2C_M_RD;
873 msg[0].len = 0;
874 msg[0].buf = 0;
875 printk("%s: i2c scan beginning\n",hdw->name);
876 for (i = 0; i < 128; i++) {
877 msg[0].addr = i;
878 rc = i2c_transfer(&hdw->i2c_adap,msg,
879 sizeof(msg)/sizeof(msg[0]));
880 if (rc != 1) continue;
881 printk("%s: i2c scan: found device @ 0x%x\n",hdw->name,i);
882 }
883 printk("%s: i2c scan done.\n",hdw->name);
884}
885
886void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
887{
888 unsigned int idx;
889
890 // The default action for all possible I2C addresses is just to do
891 // the transfer normally.
892 for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) {
893 hdw->i2c_func[idx] = pvr2_i2c_basic_op;
894 }
895
896#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
897 // If however we're dealing with new hardware, insert some hacks in
898 // the I2C transfer stack to let things work better.
899 if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
900 hdw->i2c_func[0x1b] = i2c_hack_wm8775;
901 hdw->i2c_func[0x44] = i2c_hack_cx25840;
902 }
903#endif
904
905 // Configure the adapter and set up everything else related to it.
906 memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
907 memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo));
908 strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name));
909 hdw->i2c_adap.algo = &hdw->i2c_algo;
910 hdw->i2c_adap.algo_data = hdw;
911 hdw->i2c_pend_mask = 0;
912 hdw->i2c_stale_mask = 0;
913 hdw->i2c_active_mask = 0;
914 INIT_LIST_HEAD(&hdw->i2c_clients);
915 mutex_init(&hdw->i2c_list_lock);
916 hdw->i2c_linked = !0;
917 i2c_add_adapter(&hdw->i2c_adap);
918 if (i2c_scan) do_i2c_scan(hdw);
919}
920
921void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
922{
923 if (hdw->i2c_linked) {
924 i2c_del_adapter(&hdw->i2c_adap);
925 hdw->i2c_linked = 0;
926 }
927}
928
929/*
930 Stuff for Emacs to see, in order to encourage consistent editing style:
931 *** Local Variables: ***
932 *** mode: c ***
933 *** fill-column: 75 ***
934 *** tab-width: 8 ***
935 *** c-basic-offset: 8 ***
936 *** End: ***
937 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
new file mode 100644
index 000000000000..e8af5b0ed3ce
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
@@ -0,0 +1,96 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_I2C_CORE_H
22#define __PVRUSB2_I2C_CORE_H
23
24#include <linux/list.h>
25#include <linux/i2c.h>
26
27struct pvr2_hdw;
28struct pvr2_i2c_client;
29struct pvr2_i2c_handler;
30struct pvr2_i2c_handler_functions;
31struct pvr2_i2c_op;
32struct pvr2_i2c_op_functions;
33
34struct pvr2_i2c_client {
35 struct i2c_client *client;
36 struct pvr2_i2c_handler *handler;
37 struct list_head list;
38 int detected_flag;
39 int recv_enable;
40 unsigned long pend_mask;
41 unsigned long ctl_mask;
42};
43
44struct pvr2_i2c_handler {
45 void *func_data;
46 const struct pvr2_i2c_handler_functions *func_table;
47};
48
49struct pvr2_i2c_handler_functions {
50 void (*detach)(void *);
51 int (*check)(void *);
52 void (*update)(void *);
53 unsigned int (*describe)(void *,char *,unsigned int);
54};
55
56struct pvr2_i2c_op {
57 int (*check)(struct pvr2_hdw *);
58 void (*update)(struct pvr2_hdw *);
59 const char *name;
60};
61
62void pvr2_i2c_core_init(struct pvr2_hdw *);
63void pvr2_i2c_core_done(struct pvr2_hdw *);
64
65int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg);
66int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg);
67
68int pvr2_i2c_core_check_stale(struct pvr2_hdw *);
69void pvr2_i2c_core_sync(struct pvr2_hdw *);
70unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen);
71#define PVR2_I2C_DETAIL_DEBUG 0x0001
72#define PVR2_I2C_DETAIL_HANDLER 0x0002
73#define PVR2_I2C_DETAIL_CTLMASK 0x0004
74#define PVR2_I2C_DETAIL_ALL (\
75 PVR2_I2C_DETAIL_DEBUG |\
76 PVR2_I2C_DETAIL_HANDLER |\
77 PVR2_I2C_DETAIL_CTLMASK)
78unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *,
79 unsigned int detail_mask,
80 char *buf,unsigned int maxlen);
81
82void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *);
83const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx);
84
85#endif /* __PVRUSB2_I2C_CORE_H */
86
87
88/*
89 Stuff for Emacs to see, in order to encourage consistent editing style:
90 *** Local Variables: ***
91 *** mode: c ***
92 *** fill-column: 75 ***
93 *** tab-width: 8 ***
94 *** c-basic-offset: 8 ***
95 *** End: ***
96 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c
new file mode 100644
index 000000000000..a984c91f571c
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-io.c
@@ -0,0 +1,695 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21
22#include "pvrusb2-io.h"
23#include "pvrusb2-debug.h"
24#include <linux/errno.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27#include <linux/mutex.h>
28
29#define BUFFER_SIG 0x47653271
30
31// #define SANITY_CHECK_BUFFERS
32
33
34#ifdef SANITY_CHECK_BUFFERS
35#define BUFFER_CHECK(bp) do { \
36 if ((bp)->signature != BUFFER_SIG) { \
37 pvr2_trace(PVR2_TRACE_ERROR_LEGS, \
38 "Buffer %p is bad at %s:%d", \
39 (bp),__FILE__,__LINE__); \
40 pvr2_buffer_describe(bp,"BadSig"); \
41 BUG(); \
42 } \
43} while (0)
44#else
45#define BUFFER_CHECK(bp) do {} while(0)
46#endif
47
48struct pvr2_stream {
49 /* Buffers queued for reading */
50 struct list_head queued_list;
51 unsigned int q_count;
52 unsigned int q_bcount;
53 /* Buffers with retrieved data */
54 struct list_head ready_list;
55 unsigned int r_count;
56 unsigned int r_bcount;
57 /* Buffers available for use */
58 struct list_head idle_list;
59 unsigned int i_count;
60 unsigned int i_bcount;
61 /* Pointers to all buffers */
62 struct pvr2_buffer **buffers;
63 /* Array size of buffers */
64 unsigned int buffer_slot_count;
65 /* Total buffers actually in circulation */
66 unsigned int buffer_total_count;
67 /* Designed number of buffers to be in circulation */
68 unsigned int buffer_target_count;
69 /* Executed when ready list become non-empty */
70 pvr2_stream_callback callback_func;
71 void *callback_data;
72 /* Context for transfer endpoint */
73 struct usb_device *dev;
74 int endpoint;
75 /* Overhead for mutex enforcement */
76 spinlock_t list_lock;
77 struct mutex mutex;
78 /* Tracking state for tolerating errors */
79 unsigned int fail_count;
80 unsigned int fail_tolerance;
81};
82
83struct pvr2_buffer {
84 int id;
85 int signature;
86 enum pvr2_buffer_state state;
87 void *ptr; /* Pointer to storage area */
88 unsigned int max_count; /* Size of storage area */
89 unsigned int used_count; /* Amount of valid data in storage area */
90 int status; /* Transfer result status */
91 struct pvr2_stream *stream;
92 struct list_head list_overhead;
93 struct urb *purb;
94};
95
96const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st)
97{
98 switch (st) {
99 case pvr2_buffer_state_none: return "none";
100 case pvr2_buffer_state_idle: return "idle";
101 case pvr2_buffer_state_queued: return "queued";
102 case pvr2_buffer_state_ready: return "ready";
103 }
104 return "unknown";
105}
106
107void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg)
108{
109 pvr2_trace(PVR2_TRACE_INFO,
110 "buffer%s%s %p state=%s id=%d status=%d"
111 " stream=%p purb=%p sig=0x%x",
112 (msg ? " " : ""),
113 (msg ? msg : ""),
114 bp,
115 (bp ? pvr2_buffer_state_decode(bp->state) : "(invalid)"),
116 (bp ? bp->id : 0),
117 (bp ? bp->status : 0),
118 (bp ? bp->stream : 0),
119 (bp ? bp->purb : 0),
120 (bp ? bp->signature : 0));
121}
122
123static void pvr2_buffer_remove(struct pvr2_buffer *bp)
124{
125 unsigned int *cnt;
126 unsigned int *bcnt;
127 unsigned int ccnt;
128 struct pvr2_stream *sp = bp->stream;
129 switch (bp->state) {
130 case pvr2_buffer_state_idle:
131 cnt = &sp->i_count;
132 bcnt = &sp->i_bcount;
133 ccnt = bp->max_count;
134 break;
135 case pvr2_buffer_state_queued:
136 cnt = &sp->q_count;
137 bcnt = &sp->q_bcount;
138 ccnt = bp->max_count;
139 break;
140 case pvr2_buffer_state_ready:
141 cnt = &sp->r_count;
142 bcnt = &sp->r_bcount;
143 ccnt = bp->used_count;
144 break;
145 default:
146 return;
147 }
148 list_del_init(&bp->list_overhead);
149 (*cnt)--;
150 (*bcnt) -= ccnt;
151 pvr2_trace(PVR2_TRACE_BUF_FLOW,
152 "/*---TRACE_FLOW---*/"
153 " bufferPool %8s dec cap=%07d cnt=%02d",
154 pvr2_buffer_state_decode(bp->state),*bcnt,*cnt);
155 bp->state = pvr2_buffer_state_none;
156}
157
158static void pvr2_buffer_set_none(struct pvr2_buffer *bp)
159{
160 unsigned long irq_flags;
161 struct pvr2_stream *sp;
162 BUFFER_CHECK(bp);
163 sp = bp->stream;
164 pvr2_trace(PVR2_TRACE_BUF_FLOW,
165 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
166 bp,
167 pvr2_buffer_state_decode(bp->state),
168 pvr2_buffer_state_decode(pvr2_buffer_state_none));
169 spin_lock_irqsave(&sp->list_lock,irq_flags);
170 pvr2_buffer_remove(bp);
171 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
172}
173
174static int pvr2_buffer_set_ready(struct pvr2_buffer *bp)
175{
176 int fl;
177 unsigned long irq_flags;
178 struct pvr2_stream *sp;
179 BUFFER_CHECK(bp);
180 sp = bp->stream;
181 pvr2_trace(PVR2_TRACE_BUF_FLOW,
182 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
183 bp,
184 pvr2_buffer_state_decode(bp->state),
185 pvr2_buffer_state_decode(pvr2_buffer_state_ready));
186 spin_lock_irqsave(&sp->list_lock,irq_flags);
187 fl = (sp->r_count == 0);
188 pvr2_buffer_remove(bp);
189 list_add_tail(&bp->list_overhead,&sp->ready_list);
190 bp->state = pvr2_buffer_state_ready;
191 (sp->r_count)++;
192 sp->r_bcount += bp->used_count;
193 pvr2_trace(PVR2_TRACE_BUF_FLOW,
194 "/*---TRACE_FLOW---*/"
195 " bufferPool %8s inc cap=%07d cnt=%02d",
196 pvr2_buffer_state_decode(bp->state),
197 sp->r_bcount,sp->r_count);
198 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
199 return fl;
200}
201
202static void pvr2_buffer_set_idle(struct pvr2_buffer *bp)
203{
204 unsigned long irq_flags;
205 struct pvr2_stream *sp;
206 BUFFER_CHECK(bp);
207 sp = bp->stream;
208 pvr2_trace(PVR2_TRACE_BUF_FLOW,
209 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
210 bp,
211 pvr2_buffer_state_decode(bp->state),
212 pvr2_buffer_state_decode(pvr2_buffer_state_idle));
213 spin_lock_irqsave(&sp->list_lock,irq_flags);
214 pvr2_buffer_remove(bp);
215 list_add_tail(&bp->list_overhead,&sp->idle_list);
216 bp->state = pvr2_buffer_state_idle;
217 (sp->i_count)++;
218 sp->i_bcount += bp->max_count;
219 pvr2_trace(PVR2_TRACE_BUF_FLOW,
220 "/*---TRACE_FLOW---*/"
221 " bufferPool %8s inc cap=%07d cnt=%02d",
222 pvr2_buffer_state_decode(bp->state),
223 sp->i_bcount,sp->i_count);
224 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
225}
226
227static void pvr2_buffer_set_queued(struct pvr2_buffer *bp)
228{
229 unsigned long irq_flags;
230 struct pvr2_stream *sp;
231 BUFFER_CHECK(bp);
232 sp = bp->stream;
233 pvr2_trace(PVR2_TRACE_BUF_FLOW,
234 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
235 bp,
236 pvr2_buffer_state_decode(bp->state),
237 pvr2_buffer_state_decode(pvr2_buffer_state_queued));
238 spin_lock_irqsave(&sp->list_lock,irq_flags);
239 pvr2_buffer_remove(bp);
240 list_add_tail(&bp->list_overhead,&sp->queued_list);
241 bp->state = pvr2_buffer_state_queued;
242 (sp->q_count)++;
243 sp->q_bcount += bp->max_count;
244 pvr2_trace(PVR2_TRACE_BUF_FLOW,
245 "/*---TRACE_FLOW---*/"
246 " bufferPool %8s inc cap=%07d cnt=%02d",
247 pvr2_buffer_state_decode(bp->state),
248 sp->q_bcount,sp->q_count);
249 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
250}
251
252static void pvr2_buffer_wipe(struct pvr2_buffer *bp)
253{
254 if (bp->state == pvr2_buffer_state_queued) {
255 usb_kill_urb(bp->purb);
256 }
257}
258
259static int pvr2_buffer_init(struct pvr2_buffer *bp,
260 struct pvr2_stream *sp,
261 unsigned int id)
262{
263 memset(bp,0,sizeof(*bp));
264 bp->signature = BUFFER_SIG;
265 bp->id = id;
266 pvr2_trace(PVR2_TRACE_BUF_POOL,
267 "/*---TRACE_FLOW---*/ bufferInit %p stream=%p",bp,sp);
268 bp->stream = sp;
269 bp->state = pvr2_buffer_state_none;
270 INIT_LIST_HEAD(&bp->list_overhead);
271 bp->purb = usb_alloc_urb(0,GFP_KERNEL);
272 if (! bp->purb) return -ENOMEM;
273#ifdef SANITY_CHECK_BUFFERS
274 pvr2_buffer_describe(bp,"create");
275#endif
276 return 0;
277}
278
279static void pvr2_buffer_done(struct pvr2_buffer *bp)
280{
281#ifdef SANITY_CHECK_BUFFERS
282 pvr2_buffer_describe(bp,"delete");
283#endif
284 pvr2_buffer_wipe(bp);
285 pvr2_buffer_set_none(bp);
286 bp->signature = 0;
287 bp->stream = 0;
288 if (bp->purb) usb_free_urb(bp->purb);
289 pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/"
290 " bufferDone %p",bp);
291}
292
293static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
294{
295 int ret;
296 unsigned int scnt;
297
298 /* Allocate buffers pointer array in multiples of 32 entries */
299 if (cnt == sp->buffer_total_count) return 0;
300
301 pvr2_trace(PVR2_TRACE_BUF_POOL,
302 "/*---TRACE_FLOW---*/ poolResize "
303 " stream=%p cur=%d adj=%+d",
304 sp,
305 sp->buffer_total_count,
306 cnt-sp->buffer_total_count);
307
308 scnt = cnt & ~0x1f;
309 if (cnt > scnt) scnt += 0x20;
310
311 if (cnt > sp->buffer_total_count) {
312 if (scnt > sp->buffer_slot_count) {
313 struct pvr2_buffer **nb;
314 nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
315 if (!nb) return -ENOMEM;
316 if (sp->buffer_slot_count) {
317 memcpy(nb,sp->buffers,
318 sp->buffer_slot_count * sizeof(*nb));
319 kfree(sp->buffers);
320 }
321 sp->buffers = nb;
322 sp->buffer_slot_count = scnt;
323 }
324 while (sp->buffer_total_count < cnt) {
325 struct pvr2_buffer *bp;
326 bp = kmalloc(sizeof(*bp),GFP_KERNEL);
327 if (!bp) return -ENOMEM;
328 ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count);
329 if (ret) {
330 kfree(bp);
331 return -ENOMEM;
332 }
333 sp->buffers[sp->buffer_total_count] = bp;
334 (sp->buffer_total_count)++;
335 pvr2_buffer_set_idle(bp);
336 }
337 } else {
338 while (sp->buffer_total_count > cnt) {
339 struct pvr2_buffer *bp;
340 bp = sp->buffers[sp->buffer_total_count - 1];
341 /* Paranoia */
342 sp->buffers[sp->buffer_total_count - 1] = 0;
343 (sp->buffer_total_count)--;
344 pvr2_buffer_done(bp);
345 kfree(bp);
346 }
347 if (scnt < sp->buffer_slot_count) {
348 struct pvr2_buffer **nb = 0;
349 if (scnt) {
350 nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
351 if (!nb) return -ENOMEM;
352 memcpy(nb,sp->buffers,scnt * sizeof(*nb));
353 }
354 kfree(sp->buffers);
355 sp->buffers = nb;
356 sp->buffer_slot_count = scnt;
357 }
358 }
359 return 0;
360}
361
362static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp)
363{
364 struct pvr2_buffer *bp;
365 unsigned int cnt;
366
367 if (sp->buffer_total_count == sp->buffer_target_count) return 0;
368
369 pvr2_trace(PVR2_TRACE_BUF_POOL,
370 "/*---TRACE_FLOW---*/"
371 " poolCheck stream=%p cur=%d tgt=%d",
372 sp,sp->buffer_total_count,sp->buffer_target_count);
373
374 if (sp->buffer_total_count < sp->buffer_target_count) {
375 return pvr2_stream_buffer_count(sp,sp->buffer_target_count);
376 }
377
378 cnt = 0;
379 while ((sp->buffer_total_count - cnt) > sp->buffer_target_count) {
380 bp = sp->buffers[sp->buffer_total_count - (cnt + 1)];
381 if (bp->state != pvr2_buffer_state_idle) break;
382 cnt++;
383 }
384 if (cnt) {
385 pvr2_stream_buffer_count(sp,sp->buffer_total_count - cnt);
386 }
387
388 return 0;
389}
390
391static void pvr2_stream_internal_flush(struct pvr2_stream *sp)
392{
393 struct list_head *lp;
394 struct pvr2_buffer *bp1;
395 while ((lp = sp->queued_list.next) != &sp->queued_list) {
396 bp1 = list_entry(lp,struct pvr2_buffer,list_overhead);
397 pvr2_buffer_wipe(bp1);
398 /* At this point, we should be guaranteed that no
399 completion callback may happen on this buffer. But it's
400 possible that it might have completed after we noticed
401 it but before we wiped it. So double check its status
402 here first. */
403 if (bp1->state != pvr2_buffer_state_queued) continue;
404 pvr2_buffer_set_idle(bp1);
405 }
406 if (sp->buffer_total_count != sp->buffer_target_count) {
407 pvr2_stream_achieve_buffer_count(sp);
408 }
409}
410
411static void pvr2_stream_init(struct pvr2_stream *sp)
412{
413 spin_lock_init(&sp->list_lock);
414 mutex_init(&sp->mutex);
415 INIT_LIST_HEAD(&sp->queued_list);
416 INIT_LIST_HEAD(&sp->ready_list);
417 INIT_LIST_HEAD(&sp->idle_list);
418}
419
420static void pvr2_stream_done(struct pvr2_stream *sp)
421{
422 mutex_lock(&sp->mutex); do {
423 pvr2_stream_internal_flush(sp);
424 pvr2_stream_buffer_count(sp,0);
425 } while (0); mutex_unlock(&sp->mutex);
426}
427
428static void buffer_complete(struct urb *urb, struct pt_regs *regs)
429{
430 struct pvr2_buffer *bp = urb->context;
431 struct pvr2_stream *sp;
432 unsigned long irq_flags;
433 BUFFER_CHECK(bp);
434 sp = bp->stream;
435 bp->used_count = 0;
436 bp->status = 0;
437 pvr2_trace(PVR2_TRACE_BUF_FLOW,
438 "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d",
439 bp,urb->status,urb->actual_length);
440 spin_lock_irqsave(&sp->list_lock,irq_flags);
441 if ((!(urb->status)) ||
442 (urb->status == -ENOENT) ||
443 (urb->status == -ECONNRESET) ||
444 (urb->status == -ESHUTDOWN)) {
445 bp->used_count = urb->actual_length;
446 if (sp->fail_count) {
447 pvr2_trace(PVR2_TRACE_TOLERANCE,
448 "stream %p transfer ok"
449 " - fail count reset",sp);
450 sp->fail_count = 0;
451 }
452 } else if (sp->fail_count < sp->fail_tolerance) {
453 // We can tolerate this error, because we're below the
454 // threshold...
455 (sp->fail_count)++;
456 pvr2_trace(PVR2_TRACE_TOLERANCE,
457 "stream %p ignoring error %d"
458 " - fail count increased to %u",
459 sp,urb->status,sp->fail_count);
460 } else {
461 bp->status = urb->status;
462 }
463 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
464 pvr2_buffer_set_ready(bp);
465 if (sp && sp->callback_func) {
466 sp->callback_func(sp->callback_data);
467 }
468}
469
470struct pvr2_stream *pvr2_stream_create(void)
471{
472 struct pvr2_stream *sp;
473 sp = kmalloc(sizeof(*sp),GFP_KERNEL);
474 if (!sp) return sp;
475 memset(sp,0,sizeof(*sp));
476 pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp);
477 pvr2_stream_init(sp);
478 return sp;
479}
480
481void pvr2_stream_destroy(struct pvr2_stream *sp)
482{
483 if (!sp) return;
484 pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp);
485 pvr2_stream_done(sp);
486 kfree(sp);
487}
488
489void pvr2_stream_setup(struct pvr2_stream *sp,
490 struct usb_device *dev,
491 int endpoint,
492 unsigned int tolerance)
493{
494 mutex_lock(&sp->mutex); do {
495 pvr2_stream_internal_flush(sp);
496 sp->dev = dev;
497 sp->endpoint = endpoint;
498 sp->fail_tolerance = tolerance;
499 } while(0); mutex_unlock(&sp->mutex);
500}
501
502void pvr2_stream_set_callback(struct pvr2_stream *sp,
503 pvr2_stream_callback func,
504 void *data)
505{
506 unsigned long irq_flags;
507 mutex_lock(&sp->mutex); do {
508 spin_lock_irqsave(&sp->list_lock,irq_flags);
509 sp->callback_data = data;
510 sp->callback_func = func;
511 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
512 } while(0); mutex_unlock(&sp->mutex);
513}
514
515/* Query / set the nominal buffer count */
516int pvr2_stream_get_buffer_count(struct pvr2_stream *sp)
517{
518 return sp->buffer_target_count;
519}
520
521int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
522{
523 int ret;
524 if (sp->buffer_target_count == cnt) return 0;
525 mutex_lock(&sp->mutex); do {
526 sp->buffer_target_count = cnt;
527 ret = pvr2_stream_achieve_buffer_count(sp);
528 } while(0); mutex_unlock(&sp->mutex);
529 return ret;
530}
531
532struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp)
533{
534 struct list_head *lp = sp->idle_list.next;
535 if (lp == &sp->idle_list) return 0;
536 return list_entry(lp,struct pvr2_buffer,list_overhead);
537}
538
539struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp)
540{
541 struct list_head *lp = sp->ready_list.next;
542 if (lp == &sp->ready_list) return 0;
543 return list_entry(lp,struct pvr2_buffer,list_overhead);
544}
545
546struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id)
547{
548 if (id < 0) return 0;
549 if (id >= sp->buffer_total_count) return 0;
550 return sp->buffers[id];
551}
552
553int pvr2_stream_get_ready_count(struct pvr2_stream *sp)
554{
555 return sp->r_count;
556}
557
558int pvr2_stream_get_idle_count(struct pvr2_stream *sp)
559{
560 return sp->i_count;
561}
562
563void pvr2_stream_flush(struct pvr2_stream *sp)
564{
565 mutex_lock(&sp->mutex); do {
566 pvr2_stream_internal_flush(sp);
567 } while(0); mutex_unlock(&sp->mutex);
568}
569
570void pvr2_stream_kill(struct pvr2_stream *sp)
571{
572 struct pvr2_buffer *bp;
573 mutex_lock(&sp->mutex); do {
574 pvr2_stream_internal_flush(sp);
575 while ((bp = pvr2_stream_get_ready_buffer(sp)) != 0) {
576 pvr2_buffer_set_idle(bp);
577 }
578 if (sp->buffer_total_count != sp->buffer_target_count) {
579 pvr2_stream_achieve_buffer_count(sp);
580 }
581 } while(0); mutex_unlock(&sp->mutex);
582}
583
584int pvr2_buffer_queue(struct pvr2_buffer *bp)
585{
586#undef SEED_BUFFER
587#ifdef SEED_BUFFER
588 unsigned int idx;
589 unsigned int val;
590#endif
591 int ret = 0;
592 struct pvr2_stream *sp;
593 if (!bp) return -EINVAL;
594 sp = bp->stream;
595 mutex_lock(&sp->mutex); do {
596 pvr2_buffer_wipe(bp);
597 if (!sp->dev) {
598 ret = -EIO;
599 break;
600 }
601 pvr2_buffer_set_queued(bp);
602#ifdef SEED_BUFFER
603 for (idx = 0; idx < (bp->max_count) / 4; idx++) {
604 val = bp->id << 24;
605 val |= idx;
606 ((unsigned int *)(bp->ptr))[idx] = val;
607 }
608#endif
609 bp->status = -EINPROGRESS;
610 usb_fill_bulk_urb(bp->purb, // struct urb *urb
611 sp->dev, // struct usb_device *dev
612 // endpoint (below)
613 usb_rcvbulkpipe(sp->dev,sp->endpoint),
614 bp->ptr, // void *transfer_buffer
615 bp->max_count, // int buffer_length
616 buffer_complete,
617 bp);
618 usb_submit_urb(bp->purb,GFP_KERNEL);
619 } while(0); mutex_unlock(&sp->mutex);
620 return ret;
621}
622
623int pvr2_buffer_idle(struct pvr2_buffer *bp)
624{
625 struct pvr2_stream *sp;
626 if (!bp) return -EINVAL;
627 sp = bp->stream;
628 mutex_lock(&sp->mutex); do {
629 pvr2_buffer_wipe(bp);
630 pvr2_buffer_set_idle(bp);
631 if (sp->buffer_total_count != sp->buffer_target_count) {
632 pvr2_stream_achieve_buffer_count(sp);
633 }
634 } while(0); mutex_unlock(&sp->mutex);
635 return 0;
636}
637
638int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt)
639{
640 int ret = 0;
641 unsigned long irq_flags;
642 struct pvr2_stream *sp;
643 if (!bp) return -EINVAL;
644 sp = bp->stream;
645 mutex_lock(&sp->mutex); do {
646 spin_lock_irqsave(&sp->list_lock,irq_flags);
647 if (bp->state != pvr2_buffer_state_idle) {
648 ret = -EPERM;
649 } else {
650 bp->ptr = ptr;
651 bp->stream->i_bcount -= bp->max_count;
652 bp->max_count = cnt;
653 bp->stream->i_bcount += bp->max_count;
654 pvr2_trace(PVR2_TRACE_BUF_FLOW,
655 "/*---TRACE_FLOW---*/ bufferPool "
656 " %8s cap cap=%07d cnt=%02d",
657 pvr2_buffer_state_decode(
658 pvr2_buffer_state_idle),
659 bp->stream->i_bcount,bp->stream->i_count);
660 }
661 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
662 } while(0); mutex_unlock(&sp->mutex);
663 return ret;
664}
665
666unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp)
667{
668 return bp->used_count;
669}
670
671int pvr2_buffer_get_status(struct pvr2_buffer *bp)
672{
673 return bp->status;
674}
675
676enum pvr2_buffer_state pvr2_buffer_get_state(struct pvr2_buffer *bp)
677{
678 return bp->state;
679}
680
681int pvr2_buffer_get_id(struct pvr2_buffer *bp)
682{
683 return bp->id;
684}
685
686
687/*
688 Stuff for Emacs to see, in order to encourage consistent editing style:
689 *** Local Variables: ***
690 *** mode: c ***
691 *** fill-column: 75 ***
692 *** tab-width: 8 ***
693 *** c-basic-offset: 8 ***
694 *** End: ***
695 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h
new file mode 100644
index 000000000000..65e11385b2b3
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-io.h
@@ -0,0 +1,102 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_IO_H
22#define __PVRUSB2_IO_H
23
24#include <linux/usb.h>
25#include <linux/list.h>
26
27typedef void (*pvr2_stream_callback)(void *);
28
29enum pvr2_buffer_state {
30 pvr2_buffer_state_none = 0, // Not on any list
31 pvr2_buffer_state_idle = 1, // Buffer is ready to be used again
32 pvr2_buffer_state_queued = 2, // Buffer has been queued for filling
33 pvr2_buffer_state_ready = 3, // Buffer has data available
34};
35
36struct pvr2_stream;
37struct pvr2_buffer;
38
39const char *pvr2_buffer_state_decode(enum pvr2_buffer_state);
40
41/* Initialize / tear down stream structure */
42struct pvr2_stream *pvr2_stream_create(void);
43void pvr2_stream_destroy(struct pvr2_stream *);
44void pvr2_stream_setup(struct pvr2_stream *,
45 struct usb_device *dev,int endpoint,
46 unsigned int tolerance);
47void pvr2_stream_set_callback(struct pvr2_stream *,
48 pvr2_stream_callback func,
49 void *data);
50
51/* Query / set the nominal buffer count */
52int pvr2_stream_get_buffer_count(struct pvr2_stream *);
53int pvr2_stream_set_buffer_count(struct pvr2_stream *,unsigned int);
54
55/* Get a pointer to a buffer that is either idle, ready, or is specified
56 named. */
57struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *);
58struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *);
59struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id);
60
61/* Find out how many buffers are idle or ready */
62int pvr2_stream_get_idle_count(struct pvr2_stream *);
63int pvr2_stream_get_ready_count(struct pvr2_stream *);
64
65/* Kill all pending operations */
66void pvr2_stream_flush(struct pvr2_stream *);
67
68/* Kill all pending buffers and throw away any ready buffers as well */
69void pvr2_stream_kill(struct pvr2_stream *);
70
71/* Set up the actual storage for a buffer */
72int pvr2_buffer_set_buffer(struct pvr2_buffer *,void *ptr,unsigned int cnt);
73
74/* Find out size of data in the given ready buffer */
75unsigned int pvr2_buffer_get_count(struct pvr2_buffer *);
76
77/* Retrieve completion code for given ready buffer */
78int pvr2_buffer_get_status(struct pvr2_buffer *);
79
80/* Retrieve state of given buffer */
81enum pvr2_buffer_state pvr2_buffer_get_state(struct pvr2_buffer *);
82
83/* Retrieve ID of given buffer */
84int pvr2_buffer_get_id(struct pvr2_buffer *);
85
86/* Start reading into given buffer (kill it if needed) */
87int pvr2_buffer_queue(struct pvr2_buffer *);
88
89/* Move buffer back to idle pool (kill it if needed) */
90int pvr2_buffer_idle(struct pvr2_buffer *);
91
92#endif /* __PVRUSB2_IO_H */
93
94/*
95 Stuff for Emacs to see, in order to encourage consistent editing style:
96 *** Local Variables: ***
97 *** mode: c ***
98 *** fill-column: 75 ***
99 *** tab-width: 8 ***
100 *** c-basic-offset: 8 ***
101 *** End: ***
102 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
new file mode 100644
index 000000000000..49da062e3271
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
@@ -0,0 +1,513 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21
22#include "pvrusb2-ioread.h"
23#include "pvrusb2-debug.h"
24#include <linux/errno.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27#include <linux/mutex.h>
28#include <asm/uaccess.h>
29
30#define BUFFER_COUNT 32
31#define BUFFER_SIZE PAGE_ALIGN(0x4000)
32
33struct pvr2_ioread {
34 struct pvr2_stream *stream;
35 char *buffer_storage[BUFFER_COUNT];
36 char *sync_key_ptr;
37 unsigned int sync_key_len;
38 unsigned int sync_buf_offs;
39 unsigned int sync_state;
40 unsigned int sync_trashed_count;
41 int enabled; // Streaming is on
42 int spigot_open; // OK to pass data to client
43 int stream_running; // Passing data to client now
44
45 /* State relevant to current buffer being read */
46 struct pvr2_buffer *c_buf;
47 char *c_data_ptr;
48 unsigned int c_data_len;
49 unsigned int c_data_offs;
50 struct mutex mutex;
51};
52
53static int pvr2_ioread_init(struct pvr2_ioread *cp)
54{
55 unsigned int idx;
56
57 cp->stream = 0;
58 mutex_init(&cp->mutex);
59
60 for (idx = 0; idx < BUFFER_COUNT; idx++) {
61 cp->buffer_storage[idx] = kmalloc(BUFFER_SIZE,GFP_KERNEL);
62 if (!(cp->buffer_storage[idx])) break;
63 }
64
65 if (idx < BUFFER_COUNT) {
66 // An allocation appears to have failed
67 for (idx = 0; idx < BUFFER_COUNT; idx++) {
68 if (!(cp->buffer_storage[idx])) continue;
69 kfree(cp->buffer_storage[idx]);
70 }
71 return -ENOMEM;
72 }
73 return 0;
74}
75
76static void pvr2_ioread_done(struct pvr2_ioread *cp)
77{
78 unsigned int idx;
79
80 pvr2_ioread_setup(cp,0);
81 for (idx = 0; idx < BUFFER_COUNT; idx++) {
82 if (!(cp->buffer_storage[idx])) continue;
83 kfree(cp->buffer_storage[idx]);
84 }
85}
86
87struct pvr2_ioread *pvr2_ioread_create(void)
88{
89 struct pvr2_ioread *cp;
90 cp = kmalloc(sizeof(*cp),GFP_KERNEL);
91 if (!cp) return 0;
92 pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp);
93 memset(cp,0,sizeof(*cp));
94 if (pvr2_ioread_init(cp) < 0) {
95 kfree(cp);
96 return 0;
97 }
98 return cp;
99}
100
101void pvr2_ioread_destroy(struct pvr2_ioread *cp)
102{
103 if (!cp) return;
104 pvr2_ioread_done(cp);
105 pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_destroy id=%p",cp);
106 if (cp->sync_key_ptr) {
107 kfree(cp->sync_key_ptr);
108 cp->sync_key_ptr = 0;
109 }
110 kfree(cp);
111}
112
113void pvr2_ioread_set_sync_key(struct pvr2_ioread *cp,
114 const char *sync_key_ptr,
115 unsigned int sync_key_len)
116{
117 if (!cp) return;
118
119 if (!sync_key_ptr) sync_key_len = 0;
120 if ((sync_key_len == cp->sync_key_len) &&
121 ((!sync_key_len) ||
122 (!memcmp(sync_key_ptr,cp->sync_key_ptr,sync_key_len)))) return;
123
124 if (sync_key_len != cp->sync_key_len) {
125 if (cp->sync_key_ptr) {
126 kfree(cp->sync_key_ptr);
127 cp->sync_key_ptr = 0;
128 }
129 cp->sync_key_len = 0;
130 if (sync_key_len) {
131 cp->sync_key_ptr = kmalloc(sync_key_len,GFP_KERNEL);
132 if (cp->sync_key_ptr) {
133 cp->sync_key_len = sync_key_len;
134 }
135 }
136 }
137 if (!cp->sync_key_len) return;
138 memcpy(cp->sync_key_ptr,sync_key_ptr,cp->sync_key_len);
139}
140
141static void pvr2_ioread_stop(struct pvr2_ioread *cp)
142{
143 if (!(cp->enabled)) return;
144 pvr2_trace(PVR2_TRACE_START_STOP,
145 "/*---TRACE_READ---*/ pvr2_ioread_stop id=%p",cp);
146 pvr2_stream_kill(cp->stream);
147 cp->c_buf = 0;
148 cp->c_data_ptr = 0;
149 cp->c_data_len = 0;
150 cp->c_data_offs = 0;
151 cp->enabled = 0;
152 cp->stream_running = 0;
153 cp->spigot_open = 0;
154 if (cp->sync_state) {
155 pvr2_trace(PVR2_TRACE_DATA_FLOW,
156 "/*---TRACE_READ---*/ sync_state <== 0");
157 cp->sync_state = 0;
158 }
159}
160
161static int pvr2_ioread_start(struct pvr2_ioread *cp)
162{
163 int stat;
164 struct pvr2_buffer *bp;
165 if (cp->enabled) return 0;
166 if (!(cp->stream)) return 0;
167 pvr2_trace(PVR2_TRACE_START_STOP,
168 "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp);
169 while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != 0) {
170 stat = pvr2_buffer_queue(bp);
171 if (stat < 0) {
172 pvr2_trace(PVR2_TRACE_DATA_FLOW,
173 "/*---TRACE_READ---*/"
174 " pvr2_ioread_start id=%p"
175 " error=%d",
176 cp,stat);
177 pvr2_ioread_stop(cp);
178 return stat;
179 }
180 }
181 cp->enabled = !0;
182 cp->c_buf = 0;
183 cp->c_data_ptr = 0;
184 cp->c_data_len = 0;
185 cp->c_data_offs = 0;
186 cp->stream_running = 0;
187 if (cp->sync_key_len) {
188 pvr2_trace(PVR2_TRACE_DATA_FLOW,
189 "/*---TRACE_READ---*/ sync_state <== 1");
190 cp->sync_state = 1;
191 cp->sync_trashed_count = 0;
192 cp->sync_buf_offs = 0;
193 }
194 cp->spigot_open = 0;
195 return 0;
196}
197
198struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *cp)
199{
200 return cp->stream;
201}
202
203int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp)
204{
205 int ret;
206 unsigned int idx;
207 struct pvr2_buffer *bp;
208
209 mutex_lock(&cp->mutex); do {
210 if (cp->stream) {
211 pvr2_trace(PVR2_TRACE_START_STOP,
212 "/*---TRACE_READ---*/"
213 " pvr2_ioread_setup (tear-down) id=%p",cp);
214 pvr2_ioread_stop(cp);
215 pvr2_stream_kill(cp->stream);
216 pvr2_stream_set_buffer_count(cp->stream,0);
217 cp->stream = 0;
218 }
219 if (sp) {
220 pvr2_trace(PVR2_TRACE_START_STOP,
221 "/*---TRACE_READ---*/"
222 " pvr2_ioread_setup (setup) id=%p",cp);
223 pvr2_stream_kill(sp);
224 ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT);
225 if (ret < 0) return ret;
226 for (idx = 0; idx < BUFFER_COUNT; idx++) {
227 bp = pvr2_stream_get_buffer(sp,idx);
228 pvr2_buffer_set_buffer(bp,
229 cp->buffer_storage[idx],
230 BUFFER_SIZE);
231 }
232 cp->stream = sp;
233 }
234 } while (0); mutex_unlock(&cp->mutex);
235
236 return 0;
237}
238
239int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl)
240{
241 int ret = 0;
242 if ((!fl) == (!(cp->enabled))) return ret;
243
244 mutex_lock(&cp->mutex); do {
245 if (fl) {
246 ret = pvr2_ioread_start(cp);
247 } else {
248 pvr2_ioread_stop(cp);
249 }
250 } while (0); mutex_unlock(&cp->mutex);
251 return ret;
252}
253
254int pvr2_ioread_get_enabled(struct pvr2_ioread *cp)
255{
256 return cp->enabled != 0;
257}
258
259int pvr2_ioread_get_buffer(struct pvr2_ioread *cp)
260{
261 int stat;
262
263 while (cp->c_data_len <= cp->c_data_offs) {
264 if (cp->c_buf) {
265 // Flush out current buffer first.
266 stat = pvr2_buffer_queue(cp->c_buf);
267 if (stat < 0) {
268 // Streaming error...
269 pvr2_trace(PVR2_TRACE_DATA_FLOW,
270 "/*---TRACE_READ---*/"
271 " pvr2_ioread_read id=%p"
272 " queue_error=%d",
273 cp,stat);
274 pvr2_ioread_stop(cp);
275 return 0;
276 }
277 cp->c_buf = 0;
278 cp->c_data_ptr = 0;
279 cp->c_data_len = 0;
280 cp->c_data_offs = 0;
281 }
282 // Now get a freshly filled buffer.
283 cp->c_buf = pvr2_stream_get_ready_buffer(cp->stream);
284 if (!cp->c_buf) break; // Nothing ready; done.
285 cp->c_data_len = pvr2_buffer_get_count(cp->c_buf);
286 if (!cp->c_data_len) {
287 // Nothing transferred. Was there an error?
288 stat = pvr2_buffer_get_status(cp->c_buf);
289 if (stat < 0) {
290 // Streaming error...
291 pvr2_trace(PVR2_TRACE_DATA_FLOW,
292 "/*---TRACE_READ---*/"
293 " pvr2_ioread_read id=%p"
294 " buffer_error=%d",
295 cp,stat);
296 pvr2_ioread_stop(cp);
297 // Give up.
298 return 0;
299 }
300 // Start over...
301 continue;
302 }
303 cp->c_data_offs = 0;
304 cp->c_data_ptr = cp->buffer_storage[
305 pvr2_buffer_get_id(cp->c_buf)];
306 }
307 return !0;
308}
309
310void pvr2_ioread_filter(struct pvr2_ioread *cp)
311{
312 unsigned int idx;
313 if (!cp->enabled) return;
314 if (cp->sync_state != 1) return;
315
316 // Search the stream for our synchronization key. This is made
317 // complicated by the fact that in order to be honest with
318 // ourselves here we must search across buffer boundaries...
319 mutex_lock(&cp->mutex); while (1) {
320 // Ensure we have a buffer
321 if (!pvr2_ioread_get_buffer(cp)) break;
322 if (!cp->c_data_len) break;
323
324 // Now walk the buffer contents until we match the key or
325 // run out of buffer data.
326 for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) {
327 if (cp->sync_buf_offs >= cp->sync_key_len) break;
328 if (cp->c_data_ptr[idx] ==
329 cp->sync_key_ptr[cp->sync_buf_offs]) {
330 // Found the next key byte
331 (cp->sync_buf_offs)++;
332 } else {
333 // Whoops, mismatched. Start key over...
334 cp->sync_buf_offs = 0;
335 }
336 }
337
338 // Consume what we've walked through
339 cp->c_data_offs += idx;
340 cp->sync_trashed_count += idx;
341
342 // If we've found the key, then update state and get out.
343 if (cp->sync_buf_offs >= cp->sync_key_len) {
344 cp->sync_trashed_count -= cp->sync_key_len;
345 pvr2_trace(PVR2_TRACE_DATA_FLOW,
346 "/*---TRACE_READ---*/"
347 " sync_state <== 2 (skipped %u bytes)",
348 cp->sync_trashed_count);
349 cp->sync_state = 2;
350 cp->sync_buf_offs = 0;
351 break;
352 }
353
354 if (cp->c_data_offs < cp->c_data_len) {
355 // Sanity check - should NEVER get here
356 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
357 "ERROR: pvr2_ioread filter sync problem"
358 " len=%u offs=%u",
359 cp->c_data_len,cp->c_data_offs);
360 // Get out so we don't get stuck in an infinite
361 // loop.
362 break;
363 }
364
365 continue; // (for clarity)
366 } mutex_unlock(&cp->mutex);
367}
368
369int pvr2_ioread_avail(struct pvr2_ioread *cp)
370{
371 int ret;
372 if (!(cp->enabled)) {
373 // Stream is not enabled; so this is an I/O error
374 return -EIO;
375 }
376
377 if (cp->sync_state == 1) {
378 pvr2_ioread_filter(cp);
379 if (cp->sync_state == 1) return -EAGAIN;
380 }
381
382 ret = 0;
383 if (cp->stream_running) {
384 if (!pvr2_stream_get_ready_count(cp->stream)) {
385 // No data available at all right now.
386 ret = -EAGAIN;
387 }
388 } else {
389 if (pvr2_stream_get_ready_count(cp->stream) < BUFFER_COUNT/2) {
390 // Haven't buffered up enough yet; try again later
391 ret = -EAGAIN;
392 }
393 }
394
395 if ((!(cp->spigot_open)) != (!(ret == 0))) {
396 cp->spigot_open = (ret == 0);
397 pvr2_trace(PVR2_TRACE_DATA_FLOW,
398 "/*---TRACE_READ---*/ data is %s",
399 cp->spigot_open ? "available" : "pending");
400 }
401
402 return ret;
403}
404
405int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt)
406{
407 unsigned int copied_cnt;
408 unsigned int bcnt;
409 const char *src;
410 int stat;
411 int ret = 0;
412 unsigned int req_cnt = cnt;
413
414 if (!cnt) {
415 pvr2_trace(PVR2_TRACE_TRAP,
416 "/*---TRACE_READ---*/ pvr2_ioread_read id=%p"
417 " ZERO Request? Returning zero.",cp);
418 return 0;
419 }
420
421 stat = pvr2_ioread_avail(cp);
422 if (stat < 0) return stat;
423
424 cp->stream_running = !0;
425
426 mutex_lock(&cp->mutex); do {
427
428 // Suck data out of the buffers and copy to the user
429 copied_cnt = 0;
430 if (!buf) cnt = 0;
431 while (1) {
432 if (!pvr2_ioread_get_buffer(cp)) {
433 ret = -EIO;
434 break;
435 }
436
437 if (!cnt) break;
438
439 if (cp->sync_state == 2) {
440 // We're repeating the sync key data into
441 // the stream.
442 src = cp->sync_key_ptr + cp->sync_buf_offs;
443 bcnt = cp->sync_key_len - cp->sync_buf_offs;
444 } else {
445 // Normal buffer copy
446 src = cp->c_data_ptr + cp->c_data_offs;
447 bcnt = cp->c_data_len - cp->c_data_offs;
448 }
449
450 if (!bcnt) break;
451
452 // Don't run past user's buffer
453 if (bcnt > cnt) bcnt = cnt;
454
455 if (copy_to_user(buf,src,bcnt)) {
456 // User supplied a bad pointer?
457 // Give up - this *will* cause data
458 // to be lost.
459 ret = -EFAULT;
460 break;
461 }
462 cnt -= bcnt;
463 buf += bcnt;
464 copied_cnt += bcnt;
465
466 if (cp->sync_state == 2) {
467 // Update offset inside sync key that we're
468 // repeating back out.
469 cp->sync_buf_offs += bcnt;
470 if (cp->sync_buf_offs >= cp->sync_key_len) {
471 // Consumed entire key; switch mode
472 // to normal.
473 pvr2_trace(PVR2_TRACE_DATA_FLOW,
474 "/*---TRACE_READ---*/"
475 " sync_state <== 0");
476 cp->sync_state = 0;
477 }
478 } else {
479 // Update buffer offset.
480 cp->c_data_offs += bcnt;
481 }
482 }
483
484 } while (0); mutex_unlock(&cp->mutex);
485
486 if (!ret) {
487 if (copied_cnt) {
488 // If anything was copied, return that count
489 ret = copied_cnt;
490 } else {
491 // Nothing copied; suggest to caller that another
492 // attempt should be tried again later
493 ret = -EAGAIN;
494 }
495 }
496
497 pvr2_trace(PVR2_TRACE_DATA_FLOW,
498 "/*---TRACE_READ---*/ pvr2_ioread_read"
499 " id=%p request=%d result=%d",
500 cp,req_cnt,ret);
501 return ret;
502}
503
504
505/*
506 Stuff for Emacs to see, in order to encourage consistent editing style:
507 *** Local Variables: ***
508 *** mode: c ***
509 *** fill-column: 75 ***
510 *** tab-width: 8 ***
511 *** c-basic-offset: 8 ***
512 *** End: ***
513 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/drivers/media/video/pvrusb2/pvrusb2-ioread.h
new file mode 100644
index 000000000000..6b002597f5de
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.h
@@ -0,0 +1,50 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_IOREAD_H
22#define __PVRUSB2_IOREAD_H
23
24#include "pvrusb2-io.h"
25
26struct pvr2_ioread;
27
28struct pvr2_ioread *pvr2_ioread_create(void);
29void pvr2_ioread_destroy(struct pvr2_ioread *);
30int pvr2_ioread_setup(struct pvr2_ioread *,struct pvr2_stream *);
31struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *);
32void pvr2_ioread_set_sync_key(struct pvr2_ioread *,
33 const char *sync_key_ptr,
34 unsigned int sync_key_len);
35int pvr2_ioread_set_enabled(struct pvr2_ioread *,int fl);
36int pvr2_ioread_get_enabled(struct pvr2_ioread *);
37int pvr2_ioread_read(struct pvr2_ioread *,void __user *buf,unsigned int cnt);
38int pvr2_ioread_avail(struct pvr2_ioread *);
39
40#endif /* __PVRUSB2_IOREAD_H */
41
42/*
43 Stuff for Emacs to see, in order to encourage consistent editing style:
44 *** Local Variables: ***
45 *** mode: c ***
46 *** fill-column: 75 ***
47 *** tab-width: 8 ***
48 *** c-basic-offset: 8 ***
49 *** End: ***
50 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
new file mode 100644
index 000000000000..b95248274ed0
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -0,0 +1,172 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <linux/config.h>
24#include <linux/kernel.h>
25#include <linux/errno.h>
26#include <linux/slab.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/smp_lock.h>
30#include <linux/usb.h>
31#include <linux/videodev2.h>
32
33#include "pvrusb2-hdw.h"
34#include "pvrusb2-context.h"
35#include "pvrusb2-debug.h"
36#include "pvrusb2-v4l2.h"
37#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
38#include "pvrusb2-sysfs.h"
39#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
40
41#define DRIVER_AUTHOR "Mike Isely <isely@pobox.com>"
42#define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner"
43#define DRIVER_VERSION "V4L in-tree version"
44
45#define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \
46 PVR2_TRACE_INFO| \
47 PVR2_TRACE_TOLERANCE| \
48 PVR2_TRACE_TRAP| \
49 0)
50
51int pvrusb2_debug = DEFAULT_DEBUG_MASK;
52
53module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR);
54MODULE_PARM_DESC(debug, "Debug trace mask");
55
56#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
57static struct pvr2_sysfs_class *class_ptr = 0;
58#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
59
60static void pvr_setup_attach(struct pvr2_context *pvr)
61{
62 /* Create association with v4l layer */
63 pvr2_v4l2_create(pvr);
64#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
65 pvr2_sysfs_create(pvr,class_ptr);
66#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
67}
68
69static int pvr_probe(struct usb_interface *intf,
70 const struct usb_device_id *devid)
71{
72 struct pvr2_context *pvr;
73
74 /* Create underlying hardware interface */
75 pvr = pvr2_context_create(intf,devid,pvr_setup_attach);
76 if (!pvr) {
77 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
78 "Failed to create hdw handler");
79 return -ENOMEM;
80 }
81
82 pvr2_trace(PVR2_TRACE_INIT,"pvr_probe(pvr=%p)",pvr);
83
84 usb_set_intfdata(intf, pvr);
85
86 return 0;
87}
88
89/*
90 * pvr_disconnect()
91 *
92 */
93static void pvr_disconnect(struct usb_interface *intf)
94{
95 struct pvr2_context *pvr = usb_get_intfdata(intf);
96
97 pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr);
98
99 usb_set_intfdata (intf, NULL);
100 pvr2_context_disconnect(pvr);
101
102 pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) DONE",pvr);
103
104}
105
106static struct usb_driver pvr_driver = {
107 name: "pvrusb2",
108 id_table: pvr2_device_table,
109 probe: pvr_probe,
110 disconnect: pvr_disconnect
111};
112
113/*
114 * pvr_init() / pvr_exit()
115 *
116 * This code is run to initialize/exit the driver.
117 *
118 */
119static int __init pvr_init(void)
120{
121 int ret;
122
123 pvr2_trace(PVR2_TRACE_INIT,"pvr_init");
124
125#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
126 class_ptr = pvr2_sysfs_class_create();
127#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
128
129 ret = usb_register(&pvr_driver);
130
131 if (ret == 0)
132 info(DRIVER_DESC " : " DRIVER_VERSION);
133 if (pvrusb2_debug) info("Debug mask is %d (0x%x)",
134 pvrusb2_debug,pvrusb2_debug);
135
136 return ret;
137}
138
139static void __exit pvr_exit(void)
140{
141
142 pvr2_trace(PVR2_TRACE_INIT,"pvr_exit");
143
144#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
145 pvr2_sysfs_class_destroy(class_ptr);
146#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
147
148 usb_deregister(&pvr_driver);
149}
150
151module_init(pvr_init);
152module_exit(pvr_exit);
153
154/* Mike Isely <mcisely@pobox.com> 11-Mar-2006: See pvrusb2-hdw.c for
155 MODULE_DEVICE_TABLE(). We have to declare that attribute there
156 because that's where the device table actually is now and it seems
157 that certain gcc configurations get angry if MODULE_DEVICE_TABLE()
158 is used on what ends up being an external symbol. */
159MODULE_AUTHOR(DRIVER_AUTHOR);
160MODULE_DESCRIPTION(DRIVER_DESC);
161MODULE_LICENSE("GPL");
162
163
164/*
165 Stuff for Emacs to see, in order to encourage consistent editing style:
166 *** Local Variables: ***
167 *** mode: c ***
168 *** fill-column: 70 ***
169 *** tab-width: 8 ***
170 *** c-basic-offset: 8 ***
171 *** End: ***
172 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c
new file mode 100644
index 000000000000..134063693643
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.c
@@ -0,0 +1,408 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21
22#include "pvrusb2-std.h"
23#include "pvrusb2-debug.h"
24#include <asm/string.h>
25#include <linux/slab.h>
26
27struct std_name {
28 const char *name;
29 v4l2_std_id id;
30};
31
32
33#define CSTD_PAL \
34 (V4L2_STD_PAL_B| \
35 V4L2_STD_PAL_B1| \
36 V4L2_STD_PAL_G| \
37 V4L2_STD_PAL_H| \
38 V4L2_STD_PAL_I| \
39 V4L2_STD_PAL_D| \
40 V4L2_STD_PAL_D1| \
41 V4L2_STD_PAL_K| \
42 V4L2_STD_PAL_M| \
43 V4L2_STD_PAL_N| \
44 V4L2_STD_PAL_Nc| \
45 V4L2_STD_PAL_60)
46
47#define CSTD_NTSC \
48 (V4L2_STD_NTSC_M| \
49 V4L2_STD_NTSC_M_JP| \
50 V4L2_STD_NTSC_M_KR| \
51 V4L2_STD_NTSC_443)
52
53#define CSTD_SECAM \
54 (V4L2_STD_SECAM_B| \
55 V4L2_STD_SECAM_D| \
56 V4L2_STD_SECAM_G| \
57 V4L2_STD_SECAM_H| \
58 V4L2_STD_SECAM_K| \
59 V4L2_STD_SECAM_K1| \
60 V4L2_STD_SECAM_L| \
61 V4L2_STD_SECAM_LC)
62
63#define TSTD_B (V4L2_STD_PAL_B|V4L2_STD_SECAM_B)
64#define TSTD_B1 (V4L2_STD_PAL_B1)
65#define TSTD_D (V4L2_STD_PAL_D|V4L2_STD_SECAM_D)
66#define TSTD_D1 (V4L2_STD_PAL_D1)
67#define TSTD_G (V4L2_STD_PAL_G|V4L2_STD_SECAM_G)
68#define TSTD_H (V4L2_STD_PAL_H|V4L2_STD_SECAM_H)
69#define TSTD_I (V4L2_STD_PAL_I)
70#define TSTD_K (V4L2_STD_PAL_K|V4L2_STD_SECAM_K)
71#define TSTD_K1 (V4L2_STD_SECAM_K1)
72#define TSTD_L (V4L2_STD_SECAM_L)
73#define TSTD_M (V4L2_STD_PAL_M|V4L2_STD_NTSC_M)
74#define TSTD_N (V4L2_STD_PAL_N)
75#define TSTD_Nc (V4L2_STD_PAL_Nc)
76#define TSTD_60 (V4L2_STD_PAL_60)
77
78#define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_SECAM)
79
80/* Mapping of standard bits to color system */
81const static struct std_name std_groups[] = {
82 {"PAL",CSTD_PAL},
83 {"NTSC",CSTD_NTSC},
84 {"SECAM",CSTD_SECAM},
85};
86
87/* Mapping of standard bits to modulation system */
88const static struct std_name std_items[] = {
89 {"B",TSTD_B},
90 {"B1",TSTD_B1},
91 {"D",TSTD_D},
92 {"D1",TSTD_D1},
93 {"G",TSTD_G},
94 {"H",TSTD_H},
95 {"I",TSTD_I},
96 {"K",TSTD_K},
97 {"K1",TSTD_K1},
98 {"L",TSTD_L},
99 {"LC",V4L2_STD_SECAM_LC},
100 {"M",TSTD_M},
101 {"Mj",V4L2_STD_NTSC_M_JP},
102 {"443",V4L2_STD_NTSC_443},
103 {"Mk",V4L2_STD_NTSC_M_KR},
104 {"N",TSTD_N},
105 {"Nc",TSTD_Nc},
106 {"60",TSTD_60},
107};
108
109
110// Search an array of std_name structures and return a pointer to the
111// element with the matching name.
112static const struct std_name *find_std_name(const struct std_name *arrPtr,
113 unsigned int arrSize,
114 const char *bufPtr,
115 unsigned int bufSize)
116{
117 unsigned int idx;
118 const struct std_name *p;
119 for (idx = 0; idx < arrSize; idx++) {
120 p = arrPtr + idx;
121 if (strlen(p->name) != bufSize) continue;
122 if (!memcmp(bufPtr,p->name,bufSize)) return p;
123 }
124 return 0;
125}
126
127
128int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr,
129 unsigned int bufSize)
130{
131 v4l2_std_id id = 0;
132 v4l2_std_id cmsk = 0;
133 v4l2_std_id t;
134 int mMode = 0;
135 unsigned int cnt;
136 char ch;
137 const struct std_name *sp;
138
139 while (bufSize) {
140 if (!mMode) {
141 cnt = 0;
142 while ((cnt < bufSize) && (bufPtr[cnt] != '-')) cnt++;
143 if (cnt >= bufSize) return 0; // No more characters
144 sp = find_std_name(
145 std_groups,
146 sizeof(std_groups)/sizeof(std_groups[0]),
147 bufPtr,cnt);
148 if (!sp) return 0; // Illegal color system name
149 cnt++;
150 bufPtr += cnt;
151 bufSize -= cnt;
152 mMode = !0;
153 cmsk = sp->id;
154 continue;
155 }
156 cnt = 0;
157 while (cnt < bufSize) {
158 ch = bufPtr[cnt];
159 if (ch == ';') {
160 mMode = 0;
161 break;
162 }
163 if (ch == '/') break;
164 cnt++;
165 }
166 sp = find_std_name(std_items,
167 sizeof(std_items)/sizeof(std_items[0]),
168 bufPtr,cnt);
169 if (!sp) return 0; // Illegal modulation system ID
170 t = sp->id & cmsk;
171 if (!t) return 0; // Specific color + modulation system illegal
172 id |= t;
173 if (cnt < bufSize) cnt++;
174 bufPtr += cnt;
175 bufSize -= cnt;
176 }
177
178 if (idPtr) *idPtr = id;
179 return !0;
180}
181
182
183unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize,
184 v4l2_std_id id)
185{
186 unsigned int idx1,idx2;
187 const struct std_name *ip,*gp;
188 int gfl,cfl;
189 unsigned int c1,c2;
190 cfl = 0;
191 c1 = 0;
192 for (idx1 = 0;
193 idx1 < sizeof(std_groups)/sizeof(std_groups[0]);
194 idx1++) {
195 gp = std_groups + idx1;
196 gfl = 0;
197 for (idx2 = 0;
198 idx2 < sizeof(std_items)/sizeof(std_items[0]);
199 idx2++) {
200 ip = std_items + idx2;
201 if (!(gp->id & ip->id & id)) continue;
202 if (!gfl) {
203 if (cfl) {
204 c2 = scnprintf(bufPtr,bufSize,";");
205 c1 += c2;
206 bufSize -= c2;
207 bufPtr += c2;
208 }
209 cfl = !0;
210 c2 = scnprintf(bufPtr,bufSize,
211 "%s-",gp->name);
212 gfl = !0;
213 } else {
214 c2 = scnprintf(bufPtr,bufSize,"/");
215 }
216 c1 += c2;
217 bufSize -= c2;
218 bufPtr += c2;
219 c2 = scnprintf(bufPtr,bufSize,
220 ip->name);
221 c1 += c2;
222 bufSize -= c2;
223 bufPtr += c2;
224 }
225 }
226 return c1;
227}
228
229
230// Template data for possible enumerated video standards. Here we group
231// standards which share common frame rates and resolution.
232static struct v4l2_standard generic_standards[] = {
233 {
234 .id = (TSTD_B|TSTD_B1|
235 TSTD_D|TSTD_D1|
236 TSTD_G|
237 TSTD_H|
238 TSTD_I|
239 TSTD_K|TSTD_K1|
240 TSTD_L|
241 V4L2_STD_SECAM_LC |
242 TSTD_N|TSTD_Nc),
243 .frameperiod =
244 {
245 .numerator = 1,
246 .denominator= 25
247 },
248 .framelines = 625,
249 .reserved = {0,0,0,0}
250 }, {
251 .id = (TSTD_M|
252 V4L2_STD_NTSC_M_JP|
253 V4L2_STD_NTSC_M_KR),
254 .frameperiod =
255 {
256 .numerator = 1001,
257 .denominator= 30000
258 },
259 .framelines = 525,
260 .reserved = {0,0,0,0}
261 }, { // This is a total wild guess
262 .id = (TSTD_60),
263 .frameperiod =
264 {
265 .numerator = 1001,
266 .denominator= 30000
267 },
268 .framelines = 525,
269 .reserved = {0,0,0,0}
270 }, { // This is total wild guess
271 .id = V4L2_STD_NTSC_443,
272 .frameperiod =
273 {
274 .numerator = 1001,
275 .denominator= 30000
276 },
277 .framelines = 525,
278 .reserved = {0,0,0,0}
279 }
280};
281
282#define generic_standards_cnt (sizeof(generic_standards)/sizeof(generic_standards[0]))
283
284static struct v4l2_standard *match_std(v4l2_std_id id)
285{
286 unsigned int idx;
287 for (idx = 0; idx < generic_standards_cnt; idx++) {
288 if (generic_standards[idx].id & id) {
289 return generic_standards + idx;
290 }
291 }
292 return 0;
293}
294
295static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id)
296{
297 struct v4l2_standard *template;
298 int idx;
299 unsigned int bcnt;
300 template = match_std(id);
301 if (!template) return 0;
302 idx = std->index;
303 memcpy(std,template,sizeof(*template));
304 std->index = idx;
305 std->id = id;
306 bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id);
307 std->name[bcnt] = 0;
308 pvr2_trace(PVR2_TRACE_INIT,"Set up standard idx=%u name=%s",
309 std->index,std->name);
310 return !0;
311}
312
313/* These are special cases of combined standards that we should enumerate
314 separately if the component pieces are present. */
315static v4l2_std_id std_mixes[] = {
316 V4L2_STD_PAL_B | V4L2_STD_PAL_G,
317 V4L2_STD_PAL_D | V4L2_STD_PAL_K,
318 V4L2_STD_SECAM_B | V4L2_STD_SECAM_G,
319 V4L2_STD_SECAM_D | V4L2_STD_SECAM_K,
320};
321
322struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
323 v4l2_std_id id)
324{
325 unsigned int std_cnt = 0;
326 unsigned int idx,bcnt,idx2;
327 v4l2_std_id idmsk,cmsk,fmsk;
328 struct v4l2_standard *stddefs;
329
330 if (pvrusb2_debug & PVR2_TRACE_INIT) {
331 char buf[50];
332 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id);
333 pvr2_trace(
334 PVR2_TRACE_INIT,"Mapping standards mask=0x%x (%.*s)",
335 (int)id,bcnt,buf);
336 }
337
338 *countptr = 0;
339 std_cnt = 0;
340 fmsk = 0;
341 for (idmsk = 1, cmsk = id; cmsk; idmsk <<= 1) {
342 if (!(idmsk & cmsk)) continue;
343 cmsk &= ~idmsk;
344 if (match_std(idmsk)) {
345 std_cnt++;
346 continue;
347 }
348 fmsk |= idmsk;
349 }
350
351 for (idx2 = 0; idx2 < sizeof(std_mixes)/sizeof(std_mixes[0]); idx2++) {
352 if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++;
353 }
354
355 if (fmsk) {
356 char buf[50];
357 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk);
358 pvr2_trace(
359 PVR2_TRACE_ERROR_LEGS,
360 "WARNING:"
361 " Failed to classify the following standard(s): %.*s",
362 bcnt,buf);
363 }
364
365 pvr2_trace(PVR2_TRACE_INIT,"Setting up %u unique standard(s)",
366 std_cnt);
367 if (!std_cnt) return 0; // paranoia
368
369 stddefs = kmalloc(sizeof(struct v4l2_standard) * std_cnt,
370 GFP_KERNEL);
371 memset(stddefs,0,sizeof(struct v4l2_standard) * std_cnt);
372 for (idx = 0; idx < std_cnt; idx++) stddefs[idx].index = idx;
373
374 idx = 0;
375
376 /* Enumerate potential special cases */
377 for (idx2 = 0; ((idx2 < sizeof(std_mixes)/sizeof(std_mixes[0])) &&
378 (idx < std_cnt)); idx2++) {
379 if (!(id & std_mixes[idx2])) continue;
380 if (pvr2_std_fill(stddefs+idx,std_mixes[idx2])) idx++;
381 }
382 /* Now enumerate individual pieces */
383 for (idmsk = 1, cmsk = id; cmsk && (idx < std_cnt); idmsk <<= 1) {
384 if (!(idmsk & cmsk)) continue;
385 cmsk &= ~idmsk;
386 if (!pvr2_std_fill(stddefs+idx,idmsk)) continue;
387 idx++;
388 }
389
390 *countptr = std_cnt;
391 return stddefs;
392}
393
394v4l2_std_id pvr2_std_get_usable(void)
395{
396 return CSTD_ALL;
397}
398
399
400/*
401 Stuff for Emacs to see, in order to encourage consistent editing style:
402 *** Local Variables: ***
403 *** mode: c ***
404 *** fill-column: 75 ***
405 *** tab-width: 8 ***
406 *** c-basic-offset: 8 ***
407 *** End: ***
408 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.h b/drivers/media/video/pvrusb2/pvrusb2-std.h
new file mode 100644
index 000000000000..07c399375341
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.h
@@ -0,0 +1,60 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_STD_H
22#define __PVRUSB2_STD_H
23
24#include <linux/videodev2.h>
25
26// Convert string describing one or more video standards into a mask of V4L
27// standard bits. Return true if conversion succeeds otherwise return
28// false. String is expected to be of the form: C1-x/y;C2-a/b where C1 and
29// C2 are color system names (e.g. "PAL", "NTSC") and x, y, a, and b are
30// modulation schemes (e.g. "M", "B", "G", etc).
31int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr,
32 unsigned int bufSize);
33
34// Convert any arbitrary set of video standard bits into an unambiguous
35// readable string. Return value is the number of bytes consumed in the
36// buffer. The formatted string is of a form that can be parsed by our
37// sibling std_std_to_id() function.
38unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize,
39 v4l2_std_id id);
40
41// Create an array of suitable v4l2_standard structures given a bit mask of
42// video standards to support. The array is allocated from the heap, and
43// the number of elements is returned in the first argument.
44struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
45 v4l2_std_id id);
46
47// Return mask of which video standard bits are valid
48v4l2_std_id pvr2_std_get_usable(void);
49
50#endif /* __PVRUSB2_STD_H */
51
52/*
53 Stuff for Emacs to see, in order to encourage consistent editing style:
54 *** Local Variables: ***
55 *** mode: c ***
56 *** fill-column: 75 ***
57 *** tab-width: 8 ***
58 *** c-basic-offset: 8 ***
59 *** End: ***
60 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
new file mode 100644
index 000000000000..c6e6523d74b4
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -0,0 +1,865 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21
22#include <linux/config.h>
23#include <linux/string.h>
24#include <linux/slab.h>
25#include <asm/semaphore.h>
26#include "pvrusb2-sysfs.h"
27#include "pvrusb2-hdw.h"
28#include "pvrusb2-debug.h"
29#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
30#include "pvrusb2-debugifc.h"
31#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
32
33#define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
34
35struct pvr2_sysfs {
36 struct pvr2_channel channel;
37 struct class_device *class_dev;
38#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
39 struct pvr2_sysfs_debugifc *debugifc;
40#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
41 struct pvr2_sysfs_ctl_item *item_first;
42 struct pvr2_sysfs_ctl_item *item_last;
43 struct sysfs_ops kops;
44 struct kobj_type ktype;
45 struct class_device_attribute attr_v4l_minor_number;
46 struct class_device_attribute attr_unit_number;
47};
48
49#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
50struct pvr2_sysfs_debugifc {
51 struct class_device_attribute attr_debugcmd;
52 struct class_device_attribute attr_debuginfo;
53};
54#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
55
56struct pvr2_sysfs_ctl_item {
57 struct class_device_attribute attr_name;
58 struct class_device_attribute attr_type;
59 struct class_device_attribute attr_min;
60 struct class_device_attribute attr_max;
61 struct class_device_attribute attr_enum;
62 struct class_device_attribute attr_bits;
63 struct class_device_attribute attr_val;
64 struct class_device_attribute attr_custom;
65 struct pvr2_ctrl *cptr;
66 struct pvr2_sysfs *chptr;
67 struct pvr2_sysfs_ctl_item *item_next;
68 struct attribute *attr_gen[7];
69 struct attribute_group grp;
70 char name[80];
71};
72
73struct pvr2_sysfs_class {
74 struct class class;
75};
76
77static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
78{
79 struct pvr2_ctrl *cptr;
80 struct pvr2_sysfs *sfp;
81 const char *name;
82
83 sfp = (struct pvr2_sysfs *)class_dev->class_data;
84 if (!sfp) return -EINVAL;
85 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
86 if (!cptr) return -EINVAL;
87
88 name = pvr2_ctrl_get_desc(cptr);
89 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name);
90
91 if (!name) return -EINVAL;
92
93 return scnprintf(buf,PAGE_SIZE,"%s\n",name);
94}
95
96static ssize_t show_type(int id,struct class_device *class_dev,char *buf)
97{
98 struct pvr2_ctrl *cptr;
99 struct pvr2_sysfs *sfp;
100 const char *name;
101 enum pvr2_ctl_type tp;
102
103 sfp = (struct pvr2_sysfs *)class_dev->class_data;
104 if (!sfp) return -EINVAL;
105 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
106 if (!cptr) return -EINVAL;
107
108 tp = pvr2_ctrl_get_type(cptr);
109 switch (tp) {
110 case pvr2_ctl_int: name = "integer"; break;
111 case pvr2_ctl_enum: name = "enum"; break;
112 case pvr2_ctl_bitmask: name = "bitmask"; break;
113 case pvr2_ctl_bool: name = "boolean"; break;
114 default: name = "?"; break;
115 }
116 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name);
117
118 if (!name) return -EINVAL;
119
120 return scnprintf(buf,PAGE_SIZE,"%s\n",name);
121}
122
123static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
124{
125 struct pvr2_ctrl *cptr;
126 struct pvr2_sysfs *sfp;
127 long val;
128
129 sfp = (struct pvr2_sysfs *)class_dev->class_data;
130 if (!sfp) return -EINVAL;
131 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
132 if (!cptr) return -EINVAL;
133 val = pvr2_ctrl_get_min(cptr);
134
135 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val);
136
137 return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
138}
139
140static ssize_t show_max(int id,struct class_device *class_dev,char *buf)
141{
142 struct pvr2_ctrl *cptr;
143 struct pvr2_sysfs *sfp;
144 long val;
145
146 sfp = (struct pvr2_sysfs *)class_dev->class_data;
147 if (!sfp) return -EINVAL;
148 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
149 if (!cptr) return -EINVAL;
150 val = pvr2_ctrl_get_max(cptr);
151
152 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val);
153
154 return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
155}
156
157static ssize_t show_val_norm(int id,struct class_device *class_dev,char *buf)
158{
159 struct pvr2_ctrl *cptr;
160 struct pvr2_sysfs *sfp;
161 int val,ret;
162 unsigned int cnt = 0;
163
164 sfp = (struct pvr2_sysfs *)class_dev->class_data;
165 if (!sfp) return -EINVAL;
166 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
167 if (!cptr) return -EINVAL;
168
169 ret = pvr2_ctrl_get_value(cptr,&val);
170 if (ret < 0) return ret;
171
172 ret = pvr2_ctrl_value_to_sym(cptr,~0,val,
173 buf,PAGE_SIZE-1,&cnt);
174
175 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
176 sfp,id,cnt,buf,val);
177 buf[cnt] = '\n';
178 return cnt+1;
179}
180
181static ssize_t show_val_custom(int id,struct class_device *class_dev,char *buf)
182{
183 struct pvr2_ctrl *cptr;
184 struct pvr2_sysfs *sfp;
185 int val,ret;
186 unsigned int cnt = 0;
187
188 sfp = (struct pvr2_sysfs *)class_dev->class_data;
189 if (!sfp) return -EINVAL;
190 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
191 if (!cptr) return -EINVAL;
192
193 ret = pvr2_ctrl_get_value(cptr,&val);
194 if (ret < 0) return ret;
195
196 ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val,
197 buf,PAGE_SIZE-1,&cnt);
198
199 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
200 sfp,id,cnt,buf,val);
201 buf[cnt] = '\n';
202 return cnt+1;
203}
204
205static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
206{
207 struct pvr2_ctrl *cptr;
208 struct pvr2_sysfs *sfp;
209 long val;
210 unsigned int bcnt,ccnt,ecnt;
211
212 sfp = (struct pvr2_sysfs *)class_dev->class_data;
213 if (!sfp) return -EINVAL;
214 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
215 if (!cptr) return -EINVAL;
216 ecnt = pvr2_ctrl_get_cnt(cptr);
217 bcnt = 0;
218 for (val = 0; val < ecnt; val++) {
219 pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
220 if (!ccnt) continue;
221 bcnt += ccnt;
222 if (bcnt >= PAGE_SIZE) break;
223 buf[bcnt] = '\n';
224 bcnt++;
225 }
226 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id);
227 return bcnt;
228}
229
230static ssize_t show_bits(int id,struct class_device *class_dev,char *buf)
231{
232 struct pvr2_ctrl *cptr;
233 struct pvr2_sysfs *sfp;
234 int valid_bits,msk;
235 unsigned int bcnt,ccnt;
236
237 sfp = (struct pvr2_sysfs *)class_dev->class_data;
238 if (!sfp) return -EINVAL;
239 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
240 if (!cptr) return -EINVAL;
241 valid_bits = pvr2_ctrl_get_mask(cptr);
242 bcnt = 0;
243 for (msk = 1; valid_bits; msk <<= 1) {
244 if (!(msk & valid_bits)) continue;
245 valid_bits &= ~msk;
246 pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
247 bcnt += ccnt;
248 if (bcnt >= PAGE_SIZE) break;
249 buf[bcnt] = '\n';
250 bcnt++;
251 }
252 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id);
253 return bcnt;
254}
255
256static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp,
257 const char *buf,unsigned int count)
258{
259 struct pvr2_ctrl *cptr;
260 int ret;
261 int mask,val;
262
263 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
264 if (customfl) {
265 ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val);
266 } else {
267 ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val);
268 }
269 if (ret < 0) return ret;
270 ret = pvr2_ctrl_set_mask_value(cptr,mask,val);
271 pvr2_hdw_commit_ctl(sfp->channel.hdw);
272 return ret;
273}
274
275static ssize_t store_val_norm(int id,struct class_device *class_dev,
276 const char *buf,size_t count)
277{
278 struct pvr2_sysfs *sfp;
279 int ret;
280 sfp = (struct pvr2_sysfs *)class_dev->class_data;
281 ret = store_val_any(id,0,sfp,buf,count);
282 if (!ret) ret = count;
283 return ret;
284}
285
286static ssize_t store_val_custom(int id,struct class_device *class_dev,
287 const char *buf,size_t count)
288{
289 struct pvr2_sysfs *sfp;
290 int ret;
291 sfp = (struct pvr2_sysfs *)class_dev->class_data;
292 ret = store_val_any(id,1,sfp,buf,count);
293 if (!ret) ret = count;
294 return ret;
295}
296
297/*
298 Mike Isely <isely@pobox.com> 30-April-2005
299
300 This next batch of horrible preprocessor hackery is needed because the
301 kernel's class_device_attribute mechanism fails to pass the actual
302 attribute through to the show / store functions, which means we have no
303 way to package up any attribute-specific parameters, like for example the
304 control id. So we work around this brain-damage by encoding the control
305 id into the show / store functions themselves and pick the function based
306 on the control id we're setting up. These macros try to ease the pain.
307 Yuck.
308*/
309
310#define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \
311static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,char *buf) \
312{ return sf_name(ctl_id,class_dev,buf); }
313
314#define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
315static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf,size_t count) \
316{ return sf_name(ctl_id,class_dev,buf,count); }
317
318#define CREATE_BATCH(ctl_id) \
319CREATE_SHOW_INSTANCE(show_name,ctl_id) \
320CREATE_SHOW_INSTANCE(show_type,ctl_id) \
321CREATE_SHOW_INSTANCE(show_min,ctl_id) \
322CREATE_SHOW_INSTANCE(show_max,ctl_id) \
323CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
324CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \
325CREATE_SHOW_INSTANCE(show_enum,ctl_id) \
326CREATE_SHOW_INSTANCE(show_bits,ctl_id) \
327CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \
328CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \
329
330CREATE_BATCH(0)
331CREATE_BATCH(1)
332CREATE_BATCH(2)
333CREATE_BATCH(3)
334CREATE_BATCH(4)
335CREATE_BATCH(5)
336CREATE_BATCH(6)
337CREATE_BATCH(7)
338CREATE_BATCH(8)
339CREATE_BATCH(9)
340CREATE_BATCH(10)
341CREATE_BATCH(11)
342CREATE_BATCH(12)
343CREATE_BATCH(13)
344CREATE_BATCH(14)
345CREATE_BATCH(15)
346CREATE_BATCH(16)
347CREATE_BATCH(17)
348CREATE_BATCH(18)
349CREATE_BATCH(19)
350CREATE_BATCH(20)
351CREATE_BATCH(21)
352CREATE_BATCH(22)
353CREATE_BATCH(23)
354CREATE_BATCH(24)
355CREATE_BATCH(25)
356CREATE_BATCH(26)
357CREATE_BATCH(27)
358CREATE_BATCH(28)
359CREATE_BATCH(29)
360CREATE_BATCH(30)
361CREATE_BATCH(31)
362CREATE_BATCH(32)
363CREATE_BATCH(33)
364CREATE_BATCH(34)
365CREATE_BATCH(35)
366CREATE_BATCH(36)
367CREATE_BATCH(37)
368CREATE_BATCH(38)
369CREATE_BATCH(39)
370CREATE_BATCH(40)
371CREATE_BATCH(41)
372CREATE_BATCH(42)
373CREATE_BATCH(43)
374CREATE_BATCH(44)
375CREATE_BATCH(45)
376CREATE_BATCH(46)
377CREATE_BATCH(47)
378CREATE_BATCH(48)
379CREATE_BATCH(49)
380CREATE_BATCH(50)
381CREATE_BATCH(51)
382CREATE_BATCH(52)
383CREATE_BATCH(53)
384CREATE_BATCH(54)
385CREATE_BATCH(55)
386CREATE_BATCH(56)
387CREATE_BATCH(57)
388CREATE_BATCH(58)
389CREATE_BATCH(59)
390
391struct pvr2_sysfs_func_set {
392 ssize_t (*show_name)(struct class_device *,char *);
393 ssize_t (*show_type)(struct class_device *,char *);
394 ssize_t (*show_min)(struct class_device *,char *);
395 ssize_t (*show_max)(struct class_device *,char *);
396 ssize_t (*show_enum)(struct class_device *,char *);
397 ssize_t (*show_bits)(struct class_device *,char *);
398 ssize_t (*show_val_norm)(struct class_device *,char *);
399 ssize_t (*store_val_norm)(struct class_device *,
400 const char *,size_t);
401 ssize_t (*show_val_custom)(struct class_device *,char *);
402 ssize_t (*store_val_custom)(struct class_device *,
403 const char *,size_t);
404};
405
406#define INIT_BATCH(ctl_id) \
407[ctl_id] = { \
408 .show_name = show_name_##ctl_id, \
409 .show_type = show_type_##ctl_id, \
410 .show_min = show_min_##ctl_id, \
411 .show_max = show_max_##ctl_id, \
412 .show_enum = show_enum_##ctl_id, \
413 .show_bits = show_bits_##ctl_id, \
414 .show_val_norm = show_val_norm_##ctl_id, \
415 .store_val_norm = store_val_norm_##ctl_id, \
416 .show_val_custom = show_val_custom_##ctl_id, \
417 .store_val_custom = store_val_custom_##ctl_id, \
418} \
419
420static struct pvr2_sysfs_func_set funcs[] = {
421 INIT_BATCH(0),
422 INIT_BATCH(1),
423 INIT_BATCH(2),
424 INIT_BATCH(3),
425 INIT_BATCH(4),
426 INIT_BATCH(5),
427 INIT_BATCH(6),
428 INIT_BATCH(7),
429 INIT_BATCH(8),
430 INIT_BATCH(9),
431 INIT_BATCH(10),
432 INIT_BATCH(11),
433 INIT_BATCH(12),
434 INIT_BATCH(13),
435 INIT_BATCH(14),
436 INIT_BATCH(15),
437 INIT_BATCH(16),
438 INIT_BATCH(17),
439 INIT_BATCH(18),
440 INIT_BATCH(19),
441 INIT_BATCH(20),
442 INIT_BATCH(21),
443 INIT_BATCH(22),
444 INIT_BATCH(23),
445 INIT_BATCH(24),
446 INIT_BATCH(25),
447 INIT_BATCH(26),
448 INIT_BATCH(27),
449 INIT_BATCH(28),
450 INIT_BATCH(29),
451 INIT_BATCH(30),
452 INIT_BATCH(31),
453 INIT_BATCH(32),
454 INIT_BATCH(33),
455 INIT_BATCH(34),
456 INIT_BATCH(35),
457 INIT_BATCH(36),
458 INIT_BATCH(37),
459 INIT_BATCH(38),
460 INIT_BATCH(39),
461 INIT_BATCH(40),
462 INIT_BATCH(41),
463 INIT_BATCH(42),
464 INIT_BATCH(43),
465 INIT_BATCH(44),
466 INIT_BATCH(45),
467 INIT_BATCH(46),
468 INIT_BATCH(47),
469 INIT_BATCH(48),
470 INIT_BATCH(49),
471 INIT_BATCH(50),
472 INIT_BATCH(51),
473 INIT_BATCH(52),
474 INIT_BATCH(53),
475 INIT_BATCH(54),
476 INIT_BATCH(55),
477 INIT_BATCH(56),
478 INIT_BATCH(57),
479 INIT_BATCH(58),
480 INIT_BATCH(59),
481};
482
483
484static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
485{
486 struct pvr2_sysfs_ctl_item *cip;
487 struct pvr2_sysfs_func_set *fp;
488 struct pvr2_ctrl *cptr;
489 unsigned int cnt,acnt;
490
491 if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) {
492 return;
493 }
494
495 fp = funcs + ctl_id;
496 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
497 if (!cptr) return;
498
499 cip = kmalloc(sizeof(*cip),GFP_KERNEL);
500 if (!cip) return;
501 memset(cip,0,sizeof(*cip));
502 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
503
504 cip->cptr = cptr;
505
506 cip->chptr = sfp;
507 cip->item_next = 0;
508 if (sfp->item_last) {
509 sfp->item_last->item_next = cip;
510 } else {
511 sfp->item_first = cip;
512 }
513 sfp->item_last = cip;
514
515 cip->attr_name.attr.owner = THIS_MODULE;
516 cip->attr_name.attr.name = "name";
517 cip->attr_name.attr.mode = S_IRUGO;
518 cip->attr_name.show = fp->show_name;
519
520 cip->attr_type.attr.owner = THIS_MODULE;
521 cip->attr_type.attr.name = "type";
522 cip->attr_type.attr.mode = S_IRUGO;
523 cip->attr_type.show = fp->show_type;
524
525 cip->attr_min.attr.owner = THIS_MODULE;
526 cip->attr_min.attr.name = "min_val";
527 cip->attr_min.attr.mode = S_IRUGO;
528 cip->attr_min.show = fp->show_min;
529
530 cip->attr_max.attr.owner = THIS_MODULE;
531 cip->attr_max.attr.name = "max_val";
532 cip->attr_max.attr.mode = S_IRUGO;
533 cip->attr_max.show = fp->show_max;
534
535 cip->attr_val.attr.owner = THIS_MODULE;
536 cip->attr_val.attr.name = "cur_val";
537 cip->attr_val.attr.mode = S_IRUGO;
538
539 cip->attr_custom.attr.owner = THIS_MODULE;
540 cip->attr_custom.attr.name = "custom_val";
541 cip->attr_custom.attr.mode = S_IRUGO;
542
543 cip->attr_enum.attr.owner = THIS_MODULE;
544 cip->attr_enum.attr.name = "enum_val";
545 cip->attr_enum.attr.mode = S_IRUGO;
546 cip->attr_enum.show = fp->show_enum;
547
548 cip->attr_bits.attr.owner = THIS_MODULE;
549 cip->attr_bits.attr.name = "bit_val";
550 cip->attr_bits.attr.mode = S_IRUGO;
551 cip->attr_bits.show = fp->show_bits;
552
553 if (pvr2_ctrl_is_writable(cptr)) {
554 cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
555 cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP;
556 }
557
558 acnt = 0;
559 cip->attr_gen[acnt++] = &cip->attr_name.attr;
560 cip->attr_gen[acnt++] = &cip->attr_type.attr;
561 cip->attr_gen[acnt++] = &cip->attr_val.attr;
562 cip->attr_val.show = fp->show_val_norm;
563 cip->attr_val.store = fp->store_val_norm;
564 if (pvr2_ctrl_has_custom_symbols(cptr)) {
565 cip->attr_gen[acnt++] = &cip->attr_custom.attr;
566 cip->attr_custom.show = fp->show_val_custom;
567 cip->attr_custom.store = fp->store_val_custom;
568 }
569 switch (pvr2_ctrl_get_type(cptr)) {
570 case pvr2_ctl_enum:
571 // Control is an enumeration
572 cip->attr_gen[acnt++] = &cip->attr_enum.attr;
573 break;
574 case pvr2_ctl_int:
575 // Control is an integer
576 cip->attr_gen[acnt++] = &cip->attr_min.attr;
577 cip->attr_gen[acnt++] = &cip->attr_max.attr;
578 break;
579 case pvr2_ctl_bitmask:
580 // Control is an bitmask
581 cip->attr_gen[acnt++] = &cip->attr_bits.attr;
582 break;
583 default: break;
584 }
585
586 cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
587 pvr2_ctrl_get_name(cptr));
588 cip->name[cnt] = 0;
589 cip->grp.name = cip->name;
590 cip->grp.attrs = cip->attr_gen;
591
592 sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
593}
594
595#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
596static ssize_t debuginfo_show(struct class_device *,char *);
597static ssize_t debugcmd_show(struct class_device *,char *);
598static ssize_t debugcmd_store(struct class_device *,const char *,size_t count);
599
600static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
601{
602 struct pvr2_sysfs_debugifc *dip;
603 dip = kmalloc(sizeof(*dip),GFP_KERNEL);
604 if (!dip) return;
605 memset(dip,0,sizeof(*dip));
606 dip->attr_debugcmd.attr.owner = THIS_MODULE;
607 dip->attr_debugcmd.attr.name = "debugcmd";
608 dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
609 dip->attr_debugcmd.show = debugcmd_show;
610 dip->attr_debugcmd.store = debugcmd_store;
611 dip->attr_debuginfo.attr.owner = THIS_MODULE;
612 dip->attr_debuginfo.attr.name = "debuginfo";
613 dip->attr_debuginfo.attr.mode = S_IRUGO;
614 dip->attr_debuginfo.show = debuginfo_show;
615 sfp->debugifc = dip;
616 class_device_create_file(sfp->class_dev,&dip->attr_debugcmd);
617 class_device_create_file(sfp->class_dev,&dip->attr_debuginfo);
618}
619
620
621static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
622{
623 if (!sfp->debugifc) return;
624 class_device_remove_file(sfp->class_dev,
625 &sfp->debugifc->attr_debuginfo);
626 class_device_remove_file(sfp->class_dev,&sfp->debugifc->attr_debugcmd);
627 kfree(sfp->debugifc);
628 sfp->debugifc = 0;
629}
630#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
631
632
633static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
634{
635 unsigned int idx,cnt;
636 cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw);
637 for (idx = 0; idx < cnt; idx++) {
638 pvr2_sysfs_add_control(sfp,idx);
639 }
640}
641
642
643static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
644{
645 struct pvr2_sysfs_ctl_item *cip1,*cip2;
646 for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
647 cip2 = cip1->item_next;
648 sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
649 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
650 kfree(cip1);
651 }
652}
653
654
655static void pvr2_sysfs_class_release(struct class *class)
656{
657 struct pvr2_sysfs_class *clp;
658 clp = container_of(class,struct pvr2_sysfs_class,class);
659 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp);
660 kfree(clp);
661}
662
663
664static void pvr2_sysfs_release(struct class_device *class_dev)
665{
666 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev);
667 kfree(class_dev);
668}
669
670
671static void class_dev_destroy(struct pvr2_sysfs *sfp)
672{
673 if (!sfp->class_dev) return;
674#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
675 pvr2_sysfs_tear_down_debugifc(sfp);
676#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
677 pvr2_sysfs_tear_down_controls(sfp);
678 class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
679 class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number);
680 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
681 sfp->class_dev->class_data = 0;
682 class_device_unregister(sfp->class_dev);
683 sfp->class_dev = 0;
684}
685
686
687static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf)
688{
689 struct pvr2_sysfs *sfp;
690 sfp = (struct pvr2_sysfs *)class_dev->class_data;
691 if (!sfp) return -EINVAL;
692 return scnprintf(buf,PAGE_SIZE,"%d\n",
693 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw));
694}
695
696
697static ssize_t unit_number_show(struct class_device *class_dev,char *buf)
698{
699 struct pvr2_sysfs *sfp;
700 sfp = (struct pvr2_sysfs *)class_dev->class_data;
701 if (!sfp) return -EINVAL;
702 return scnprintf(buf,PAGE_SIZE,"%d\n",
703 pvr2_hdw_get_unit_number(sfp->channel.hdw));
704}
705
706
707static void class_dev_create(struct pvr2_sysfs *sfp,
708 struct pvr2_sysfs_class *class_ptr)
709{
710 struct usb_device *usb_dev;
711 struct class_device *class_dev;
712 usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw);
713 if (!usb_dev) return;
714 class_dev = kmalloc(sizeof(*class_dev),GFP_KERNEL);
715 if (!class_dev) return;
716 memset(class_dev,0,sizeof(*class_dev));
717
718 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
719
720 class_dev->class = &class_ptr->class;
721 if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
722 snprintf(class_dev->class_id,BUS_ID_SIZE,"sn-%lu",
723 pvr2_hdw_get_sn(sfp->channel.hdw));
724 } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
725 snprintf(class_dev->class_id,BUS_ID_SIZE,"unit-%c",
726 pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
727 } else {
728 kfree(class_dev);
729 return;
730 }
731
732 class_dev->dev = &usb_dev->dev;
733
734 sfp->class_dev = class_dev;
735 class_dev->class_data = sfp;
736 class_device_register(class_dev);
737
738 sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE;
739 sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
740 sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
741 sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
742 sfp->attr_v4l_minor_number.store = 0;
743 class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
744 sfp->attr_unit_number.attr.owner = THIS_MODULE;
745 sfp->attr_unit_number.attr.name = "unit_number";
746 sfp->attr_unit_number.attr.mode = S_IRUGO;
747 sfp->attr_unit_number.show = unit_number_show;
748 sfp->attr_unit_number.store = 0;
749 class_device_create_file(sfp->class_dev,&sfp->attr_unit_number);
750
751 pvr2_sysfs_add_controls(sfp);
752#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
753 pvr2_sysfs_add_debugifc(sfp);
754#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
755}
756
757
758static void pvr2_sysfs_internal_check(struct pvr2_channel *chp)
759{
760 struct pvr2_sysfs *sfp;
761 sfp = container_of(chp,struct pvr2_sysfs,channel);
762 if (!sfp->channel.mc_head->disconnect_flag) return;
763 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp);
764 class_dev_destroy(sfp);
765 pvr2_channel_done(&sfp->channel);
766 kfree(sfp);
767}
768
769
770struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
771 struct pvr2_sysfs_class *class_ptr)
772{
773 struct pvr2_sysfs *sfp;
774 sfp = kmalloc(sizeof(*sfp),GFP_KERNEL);
775 if (!sfp) return sfp;
776 memset(sfp,0,sizeof(*sfp));
777 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp);
778 pvr2_channel_init(&sfp->channel,mp);
779 sfp->channel.check_func = pvr2_sysfs_internal_check;
780
781 class_dev_create(sfp,class_ptr);
782 return sfp;
783}
784
785
786static int pvr2_sysfs_hotplug(struct class_device *cd,char **envp,
787 int numenvp,char *buf,int size)
788{
789 /* Even though we don't do anything here, we still need this function
790 because sysfs will still try to call it. */
791 return 0;
792}
793
794struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
795{
796 struct pvr2_sysfs_class *clp;
797 clp = kmalloc(sizeof(*clp),GFP_KERNEL);
798 if (!clp) return clp;
799 memset(clp,0,sizeof(*clp));
800 pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp);
801 clp->class.name = "pvrusb2";
802 clp->class.class_release = pvr2_sysfs_class_release;
803 clp->class.release = pvr2_sysfs_release;
804 clp->class.uevent = pvr2_sysfs_hotplug;
805 if (class_register(&clp->class)) {
806 pvr2_sysfs_trace(
807 "Registration failed for pvr2_sysfs_class id=%p",clp);
808 kfree(clp);
809 clp = 0;
810 }
811 return clp;
812}
813
814
815void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
816{
817 class_unregister(&clp->class);
818}
819
820
821#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
822static ssize_t debuginfo_show(struct class_device *class_dev,char *buf)
823{
824 struct pvr2_sysfs *sfp;
825 sfp = (struct pvr2_sysfs *)class_dev->class_data;
826 if (!sfp) return -EINVAL;
827 pvr2_hdw_trigger_module_log(sfp->channel.hdw);
828 return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
829}
830
831
832static ssize_t debugcmd_show(struct class_device *class_dev,char *buf)
833{
834 struct pvr2_sysfs *sfp;
835 sfp = (struct pvr2_sysfs *)class_dev->class_data;
836 if (!sfp) return -EINVAL;
837 return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
838}
839
840
841static ssize_t debugcmd_store(struct class_device *class_dev,
842 const char *buf,size_t count)
843{
844 struct pvr2_sysfs *sfp;
845 int ret;
846
847 sfp = (struct pvr2_sysfs *)class_dev->class_data;
848 if (!sfp) return -EINVAL;
849
850 ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
851 if (ret < 0) return ret;
852 return count;
853}
854#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
855
856
857/*
858 Stuff for Emacs to see, in order to encourage consistent editing style:
859 *** Local Variables: ***
860 *** mode: c ***
861 *** fill-column: 75 ***
862 *** tab-width: 8 ***
863 *** c-basic-offset: 8 ***
864 *** End: ***
865 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
new file mode 100644
index 000000000000..ff9373b47f8f
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
@@ -0,0 +1,47 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_SYSFS_H
22#define __PVRUSB2_SYSFS_H
23
24#include <linux/list.h>
25#include <linux/sysfs.h>
26#include "pvrusb2-context.h"
27
28struct pvr2_sysfs;
29struct pvr2_sysfs_class;
30
31struct pvr2_sysfs_class *pvr2_sysfs_class_create(void);
32void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *);
33
34struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *,
35 struct pvr2_sysfs_class *);
36
37#endif /* __PVRUSB2_SYSFS_H */
38
39/*
40 Stuff for Emacs to see, in order to encourage consistent editing style:
41 *** Local Variables: ***
42 *** mode: c ***
43 *** fill-column: 75 ***
44 *** tab-width: 8 ***
45 *** c-basic-offset: 8 ***
46 *** End: ***
47 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
new file mode 100644
index 000000000000..f4aba8144ce0
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
@@ -0,0 +1,122 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include "pvrusb2.h"
24#include "pvrusb2-util.h"
25#include "pvrusb2-tuner.h"
26#include "pvrusb2-hdw-internal.h"
27#include "pvrusb2-debug.h"
28#include <linux/videodev2.h>
29#include <media/tuner.h>
30#include <media/v4l2-common.h>
31
32struct pvr2_tuner_handler {
33 struct pvr2_hdw *hdw;
34 struct pvr2_i2c_client *client;
35 struct pvr2_i2c_handler i2c_handler;
36 int type_update_fl;
37};
38
39
40static void set_type(struct pvr2_tuner_handler *ctxt)
41{
42 struct pvr2_hdw *hdw = ctxt->hdw;
43 struct tuner_setup setup;
44 pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type);
45 if (((int)(hdw->tuner_type)) < 0) return;
46
47 setup.addr = ADDR_UNSET;
48 setup.type = hdw->tuner_type;
49 setup.mode_mask = T_RADIO | T_ANALOG_TV;
50 /* We may really want mode_mask to be T_ANALOG_TV for now */
51 pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup);
52 ctxt->type_update_fl = 0;
53}
54
55
56static int tuner_check(struct pvr2_tuner_handler *ctxt)
57{
58 struct pvr2_hdw *hdw = ctxt->hdw;
59 if (hdw->tuner_updated) ctxt->type_update_fl = !0;
60 return ctxt->type_update_fl != 0;
61}
62
63
64static void tuner_update(struct pvr2_tuner_handler *ctxt)
65{
66 if (ctxt->type_update_fl) set_type(ctxt);
67}
68
69
70static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt)
71{
72 ctxt->client->handler = 0;
73 kfree(ctxt);
74}
75
76
77static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt)
78{
79 return scnprintf(buf,cnt,"handler: pvrusb2-tuner");
80}
81
82
83const static struct pvr2_i2c_handler_functions tuner_funcs = {
84 .detach = (void (*)(void *))pvr2_tuner_detach,
85 .check = (int (*)(void *))tuner_check,
86 .update = (void (*)(void *))tuner_update,
87 .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe,
88};
89
90
91int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
92{
93 struct pvr2_tuner_handler *ctxt;
94 if (cp->handler) return 0;
95
96 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
97 if (!ctxt) return 0;
98 memset(ctxt,0,sizeof(*ctxt));
99
100 ctxt->i2c_handler.func_data = ctxt;
101 ctxt->i2c_handler.func_table = &tuner_funcs;
102 ctxt->type_update_fl = !0;
103 ctxt->client = cp;
104 ctxt->hdw = hdw;
105 cp->handler = &ctxt->i2c_handler;
106 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up",
107 cp->client->addr);
108 return !0;
109}
110
111
112
113
114/*
115 Stuff for Emacs to see, in order to encourage consistent editing style:
116 *** Local Variables: ***
117 *** mode: c ***
118 *** fill-column: 70 ***
119 *** tab-width: 8 ***
120 *** c-basic-offset: 8 ***
121 *** End: ***
122 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/drivers/media/video/pvrusb2/pvrusb2-tuner.h
new file mode 100644
index 000000000000..556f12aa9160
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.h
@@ -0,0 +1,38 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_TUNER_H
22#define __PVRUSB2_TUNER_H
23
24#include "pvrusb2-i2c-core.h"
25
26int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
27
28#endif /* __PVRUSB2_TUNER_H */
29
30/*
31 Stuff for Emacs to see, in order to encourage consistent editing style:
32 *** Local Variables: ***
33 *** mode: c ***
34 *** fill-column: 70 ***
35 *** tab-width: 8 ***
36 *** c-basic-offset: 8 ***
37 *** End: ***
38 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-util.h b/drivers/media/video/pvrusb2/pvrusb2-util.h
new file mode 100644
index 000000000000..e53aee416f56
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-util.h
@@ -0,0 +1,63 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_UTIL_H
22#define __PVRUSB2_UTIL_H
23
24#define PVR2_DECOMPOSE_LE(t,i,d) \
25 do { \
26 (t)[i] = (d) & 0xff;\
27 (t)[i+1] = ((d) >> 8) & 0xff;\
28 (t)[i+2] = ((d) >> 16) & 0xff;\
29 (t)[i+3] = ((d) >> 24) & 0xff;\
30 } while(0)
31
32#define PVR2_DECOMPOSE_BE(t,i,d) \
33 do { \
34 (t)[i+3] = (d) & 0xff;\
35 (t)[i+2] = ((d) >> 8) & 0xff;\
36 (t)[i+1] = ((d) >> 16) & 0xff;\
37 (t)[i] = ((d) >> 24) & 0xff;\
38 } while(0)
39
40#define PVR2_COMPOSE_LE(t,i) \
41 ((((u32)((t)[i+3])) << 24) | \
42 (((u32)((t)[i+2])) << 16) | \
43 (((u32)((t)[i+1])) << 8) | \
44 ((u32)((t)[i])))
45
46#define PVR2_COMPOSE_BE(t,i) \
47 ((((u32)((t)[i])) << 24) | \
48 (((u32)((t)[i+1])) << 16) | \
49 (((u32)((t)[i+2])) << 8) | \
50 ((u32)((t)[i+3])))
51
52
53#endif /* __PVRUSB2_UTIL_H */
54
55/*
56 Stuff for Emacs to see, in order to encourage consistent editing style:
57 *** Local Variables: ***
58 *** mode: c ***
59 *** fill-column: 75 ***
60 *** tab-width: 8 ***
61 *** c-basic-offset: 8 ***
62 *** End: ***
63 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
new file mode 100644
index 000000000000..961951010c27
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -0,0 +1,1126 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <linux/kernel.h>
24#include <linux/version.h>
25#include "pvrusb2-context.h"
26#include "pvrusb2-hdw.h"
27#include "pvrusb2.h"
28#include "pvrusb2-debug.h"
29#include "pvrusb2-v4l2.h"
30#include "pvrusb2-ioread.h"
31#include <linux/videodev2.h>
32#include <media/v4l2-common.h>
33
34struct pvr2_v4l2_dev;
35struct pvr2_v4l2_fh;
36struct pvr2_v4l2;
37
38/* V4L no longer provide the ability to set / get a private context pointer
39 (i.e. video_get_drvdata / video_set_drvdata), which means we have to
40 concoct our own context locating mechanism. Supposedly this is intended
41 to simplify driver implementation. It's not clear to me how that can
42 possibly be true. Our solution here is to maintain a lookup table of
43 our context instances, indexed by the minor device number of the V4L
44 device. See pvr2_v4l2_open() for some implications of this approach. */
45static struct pvr2_v4l2_dev *devices[256];
46static DEFINE_MUTEX(device_lock);
47
48struct pvr2_v4l2_dev {
49 struct pvr2_v4l2 *v4lp;
50 struct video_device *vdev;
51 struct pvr2_context_stream *stream;
52 int ctxt_idx;
53 enum pvr2_config config;
54};
55
56struct pvr2_v4l2_fh {
57 struct pvr2_channel channel;
58 struct pvr2_v4l2_dev *dev_info;
59 enum v4l2_priority prio;
60 struct pvr2_ioread *rhp;
61 struct file *file;
62 struct pvr2_v4l2 *vhead;
63 struct pvr2_v4l2_fh *vnext;
64 struct pvr2_v4l2_fh *vprev;
65 wait_queue_head_t wait_data;
66 int fw_mode_flag;
67};
68
69struct pvr2_v4l2 {
70 struct pvr2_channel channel;
71 struct pvr2_v4l2_fh *vfirst;
72 struct pvr2_v4l2_fh *vlast;
73
74 struct v4l2_prio_state prio;
75
76 /* streams */
77 struct pvr2_v4l2_dev video_dev;
78};
79
80static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
81module_param_array(video_nr, int, NULL, 0444);
82MODULE_PARM_DESC(video_nr, "Offset for device's minor");
83
84struct v4l2_capability pvr_capability ={
85 .driver = "pvrusb2",
86 .card = "Hauppauge WinTV pvr-usb2",
87 .bus_info = "usb",
88 .version = KERNEL_VERSION(0,8,0),
89 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
90 V4L2_CAP_TUNER | V4L2_CAP_AUDIO |
91 V4L2_CAP_READWRITE),
92 .reserved = {0,0,0,0}
93};
94
95static struct v4l2_tuner pvr_v4l2_tuners[]= {
96 {
97 .index = 0,
98 .name = "TV Tuner",
99 .type = V4L2_TUNER_ANALOG_TV,
100 .capability = (V4L2_TUNER_CAP_NORM |
101 V4L2_TUNER_CAP_STEREO |
102 V4L2_TUNER_CAP_LANG1 |
103 V4L2_TUNER_CAP_LANG2),
104 .rangelow = 0,
105 .rangehigh = 0,
106 .rxsubchans = V4L2_TUNER_SUB_STEREO,
107 .audmode = V4L2_TUNER_MODE_STEREO,
108 .signal = 0,
109 .afc = 0,
110 .reserved = {0,0,0,0}
111 }
112};
113
114struct v4l2_fmtdesc pvr_fmtdesc [] = {
115 {
116 .index = 0,
117 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
118 .flags = V4L2_FMT_FLAG_COMPRESSED,
119 .description = "MPEG1/2",
120 // This should really be V4L2_PIX_FMT_MPEG, but xawtv
121 // breaks when I do that.
122 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
123 .reserved = { 0, 0, 0, 0 }
124 }
125};
126
127#define PVR_FORMAT_PIX 0
128#define PVR_FORMAT_VBI 1
129
130struct v4l2_format pvr_format [] = {
131 [PVR_FORMAT_PIX] = {
132 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
133 .fmt = {
134 .pix = {
135 .width = 720,
136 .height = 576,
137 // This should really be V4L2_PIX_FMT_MPEG,
138 // but xawtv breaks when I do that.
139 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
140 .field = V4L2_FIELD_INTERLACED,
141 .bytesperline = 0, // doesn't make sense
142 // here
143 //FIXME : Don't know what to put here...
144 .sizeimage = (32*1024),
145 .colorspace = 0, // doesn't make sense here
146 .priv = 0
147 }
148 }
149 },
150 [PVR_FORMAT_VBI] = {
151 .type = V4L2_BUF_TYPE_VBI_CAPTURE,
152 .fmt = {
153 .vbi = {
154 .sampling_rate = 27000000,
155 .offset = 248,
156 .samples_per_line = 1443,
157 .sample_format = V4L2_PIX_FMT_GREY,
158 .start = { 0, 0 },
159 .count = { 0, 0 },
160 .flags = 0,
161 .reserved = { 0, 0 }
162 }
163 }
164 }
165};
166
167/*
168 * pvr_ioctl()
169 *
170 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
171 *
172 */
173static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
174 unsigned int cmd, void *arg)
175{
176 struct pvr2_v4l2_fh *fh = file->private_data;
177 struct pvr2_v4l2 *vp = fh->vhead;
178 struct pvr2_v4l2_dev *dev_info = fh->dev_info;
179 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
180 int ret = -EINVAL;
181
182 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
183 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd);
184 }
185
186 if (!pvr2_hdw_dev_ok(hdw)) {
187 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
188 "ioctl failed - bad or no context");
189 return -EFAULT;
190 }
191
192 /* check priority */
193 switch (cmd) {
194 case VIDIOC_S_CTRL:
195 case VIDIOC_S_STD:
196 case VIDIOC_S_INPUT:
197 case VIDIOC_S_TUNER:
198 case VIDIOC_S_FREQUENCY:
199 ret = v4l2_prio_check(&vp->prio, &fh->prio);
200 if (ret)
201 return ret;
202 }
203
204 switch (cmd) {
205 case VIDIOC_QUERYCAP:
206 {
207 struct v4l2_capability *cap = arg;
208
209 memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
210
211 ret = 0;
212 break;
213 }
214
215 case VIDIOC_G_PRIORITY:
216 {
217 enum v4l2_priority *p = arg;
218
219 *p = v4l2_prio_max(&vp->prio);
220 ret = 0;
221 break;
222 }
223
224 case VIDIOC_S_PRIORITY:
225 {
226 enum v4l2_priority *prio = arg;
227
228 ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio);
229 break;
230 }
231
232 case VIDIOC_ENUMSTD:
233 {
234 struct v4l2_standard *vs = (struct v4l2_standard *)arg;
235 int idx = vs->index;
236 ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1);
237 break;
238 }
239
240 case VIDIOC_G_STD:
241 {
242 int val = 0;
243 ret = pvr2_ctrl_get_value(
244 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val);
245 *(v4l2_std_id *)arg = val;
246 break;
247 }
248
249 case VIDIOC_S_STD:
250 {
251 ret = pvr2_ctrl_set_value(
252 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
253 *(v4l2_std_id *)arg);
254 break;
255 }
256
257 case VIDIOC_ENUMINPUT:
258 {
259 struct pvr2_ctrl *cptr;
260 struct v4l2_input *vi = (struct v4l2_input *)arg;
261 struct v4l2_input tmp;
262 unsigned int cnt;
263
264 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
265
266 memset(&tmp,0,sizeof(tmp));
267 tmp.index = vi->index;
268 ret = 0;
269 switch (vi->index) {
270 case PVR2_CVAL_INPUT_TV:
271 case PVR2_CVAL_INPUT_RADIO:
272 tmp.type = V4L2_INPUT_TYPE_TUNER;
273 break;
274 case PVR2_CVAL_INPUT_SVIDEO:
275 case PVR2_CVAL_INPUT_COMPOSITE:
276 tmp.type = V4L2_INPUT_TYPE_CAMERA;
277 break;
278 default:
279 ret = -EINVAL;
280 break;
281 }
282 if (ret < 0) break;
283
284 cnt = 0;
285 pvr2_ctrl_get_valname(cptr,vi->index,
286 tmp.name,sizeof(tmp.name)-1,&cnt);
287 tmp.name[cnt] = 0;
288
289 /* Don't bother with audioset, since this driver currently
290 always switches the audio whenever the video is
291 switched. */
292
293 /* Handling std is a tougher problem. It doesn't make
294 sense in cases where a device might be multi-standard.
295 We could just copy out the current value for the
296 standard, but it can change over time. For now just
297 leave it zero. */
298
299 memcpy(vi, &tmp, sizeof(tmp));
300
301 ret = 0;
302 break;
303 }
304
305 case VIDIOC_G_INPUT:
306 {
307 struct pvr2_ctrl *cptr;
308 struct v4l2_input *vi = (struct v4l2_input *)arg;
309 int val;
310 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
311 val = 0;
312 ret = pvr2_ctrl_get_value(cptr,&val);
313 vi->index = val;
314 break;
315 }
316
317 case VIDIOC_S_INPUT:
318 {
319 struct v4l2_input *vi = (struct v4l2_input *)arg;
320 ret = pvr2_ctrl_set_value(
321 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
322 vi->index);
323 break;
324 }
325
326 case VIDIOC_ENUMAUDIO:
327 {
328 ret = -EINVAL;
329 break;
330 }
331
332 case VIDIOC_G_AUDIO:
333 {
334 ret = -EINVAL;
335 break;
336 }
337
338 case VIDIOC_S_AUDIO:
339 {
340 ret = -EINVAL;
341 break;
342 }
343 case VIDIOC_G_TUNER:
344 {
345 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
346 unsigned int status_mask;
347 int val;
348 if (vt->index !=0) break;
349
350 status_mask = pvr2_hdw_get_signal_status(hdw);
351
352 memcpy(vt, &pvr_v4l2_tuners[vt->index],
353 sizeof(struct v4l2_tuner));
354
355 vt->signal = 0;
356 if (status_mask & PVR2_SIGNAL_OK) {
357 if (status_mask & PVR2_SIGNAL_STEREO) {
358 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
359 } else {
360 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
361 }
362 if (status_mask & PVR2_SIGNAL_SAP) {
363 vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 |
364 V4L2_TUNER_SUB_LANG2);
365 }
366 vt->signal = 65535;
367 }
368
369 val = 0;
370 ret = pvr2_ctrl_get_value(
371 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
372 &val);
373 vt->audmode = val;
374 break;
375 }
376
377 case VIDIOC_S_TUNER:
378 {
379 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
380
381 if (vt->index != 0)
382 break;
383
384 ret = pvr2_ctrl_set_value(
385 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
386 vt->audmode);
387 }
388
389 case VIDIOC_S_FREQUENCY:
390 {
391 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
392 ret = pvr2_ctrl_set_value(
393 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
394 vf->frequency * 62500);
395 break;
396 }
397
398 case VIDIOC_G_FREQUENCY:
399 {
400 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
401 int val = 0;
402 ret = pvr2_ctrl_get_value(
403 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
404 &val);
405 val /= 62500;
406 vf->frequency = val;
407 break;
408 }
409
410 case VIDIOC_ENUM_FMT:
411 {
412 struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg;
413
414 /* Only one format is supported : mpeg.*/
415 if (fd->index != 0)
416 break;
417
418 memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
419 ret = 0;
420 break;
421 }
422
423 case VIDIOC_G_FMT:
424 {
425 struct v4l2_format *vf = (struct v4l2_format *)arg;
426 int val;
427 switch(vf->type) {
428 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
429 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
430 sizeof(struct v4l2_format));
431 val = 0;
432 pvr2_ctrl_get_value(
433 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES),
434 &val);
435 vf->fmt.pix.width = val;
436 val = 0;
437 pvr2_ctrl_get_value(
438 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES),
439 &val);
440 vf->fmt.pix.height = val;
441 ret = 0;
442 break;
443 case V4L2_BUF_TYPE_VBI_CAPTURE:
444 // ????? Still need to figure out to do VBI correctly
445 ret = -EINVAL;
446 break;
447 default:
448 ret = -EINVAL;
449 break;
450 }
451 break;
452 }
453
454 case VIDIOC_TRY_FMT:
455 case VIDIOC_S_FMT:
456 {
457 struct v4l2_format *vf = (struct v4l2_format *)arg;
458
459 ret = 0;
460 switch(vf->type) {
461 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
462 int h = vf->fmt.pix.height;
463 int w = vf->fmt.pix.width;
464
465 if (h < 200) {
466 h = 200;
467 } else if (h > 625) {
468 h = 625;
469 }
470 if (w < 320) {
471 w = 320;
472 } else if (w > 720) {
473 w = 720;
474 }
475
476 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
477 sizeof(struct v4l2_format));
478 vf->fmt.pix.width = w;
479 vf->fmt.pix.height = h;
480
481 if (cmd == VIDIOC_S_FMT) {
482 pvr2_ctrl_set_value(
483 pvr2_hdw_get_ctrl_by_id(hdw,
484 PVR2_CID_HRES),
485 vf->fmt.pix.width);
486 pvr2_ctrl_set_value(
487 pvr2_hdw_get_ctrl_by_id(hdw,
488 PVR2_CID_VRES),
489 vf->fmt.pix.height);
490 }
491 } break;
492 case V4L2_BUF_TYPE_VBI_CAPTURE:
493 // ????? Still need to figure out to do VBI correctly
494 ret = -EINVAL;
495 break;
496 default:
497 ret = -EINVAL;
498 break;
499 }
500 break;
501 }
502
503 case VIDIOC_STREAMON:
504 {
505 ret = pvr2_hdw_set_stream_type(hdw,dev_info->config);
506 if (ret < 0) return ret;
507 ret = pvr2_hdw_set_streaming(hdw,!0);
508 break;
509 }
510
511 case VIDIOC_STREAMOFF:
512 {
513 ret = pvr2_hdw_set_streaming(hdw,0);
514 break;
515 }
516
517 case VIDIOC_QUERYCTRL:
518 {
519 struct pvr2_ctrl *cptr;
520 struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg;
521 ret = 0;
522 if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
523 cptr = pvr2_hdw_get_ctrl_nextv4l(
524 hdw,(vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
525 if (cptr) vc->id = pvr2_ctrl_get_v4lid(cptr);
526 } else {
527 cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id);
528 }
529 if (!cptr) {
530 pvr2_trace(PVR2_TRACE_V4LIOCTL,
531 "QUERYCTRL id=0x%x not implemented here",
532 vc->id);
533 ret = -EINVAL;
534 break;
535 }
536
537 pvr2_trace(PVR2_TRACE_V4LIOCTL,
538 "QUERYCTRL id=0x%x mapping name=%s (%s)",
539 vc->id,pvr2_ctrl_get_name(cptr),
540 pvr2_ctrl_get_desc(cptr));
541 strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name));
542 vc->flags = pvr2_ctrl_get_v4lflags(cptr);
543 vc->default_value = pvr2_ctrl_get_def(cptr);
544 switch (pvr2_ctrl_get_type(cptr)) {
545 case pvr2_ctl_enum:
546 vc->type = V4L2_CTRL_TYPE_MENU;
547 vc->minimum = 0;
548 vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
549 vc->step = 1;
550 break;
551 case pvr2_ctl_bool:
552 vc->type = V4L2_CTRL_TYPE_BOOLEAN;
553 vc->minimum = 0;
554 vc->maximum = 1;
555 vc->step = 1;
556 break;
557 case pvr2_ctl_int:
558 vc->type = V4L2_CTRL_TYPE_INTEGER;
559 vc->minimum = pvr2_ctrl_get_min(cptr);
560 vc->maximum = pvr2_ctrl_get_max(cptr);
561 vc->step = 1;
562 break;
563 default:
564 pvr2_trace(PVR2_TRACE_V4LIOCTL,
565 "QUERYCTRL id=0x%x name=%s not mappable",
566 vc->id,pvr2_ctrl_get_name(cptr));
567 ret = -EINVAL;
568 break;
569 }
570 break;
571 }
572
573 case VIDIOC_QUERYMENU:
574 {
575 struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg;
576 unsigned int cnt = 0;
577 ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id),
578 vm->index,
579 vm->name,sizeof(vm->name)-1,
580 &cnt);
581 vm->name[cnt] = 0;
582 break;
583 }
584
585 case VIDIOC_G_CTRL:
586 {
587 struct v4l2_control *vc = (struct v4l2_control *)arg;
588 int val = 0;
589 ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
590 &val);
591 vc->value = val;
592 break;
593 }
594
595 case VIDIOC_S_CTRL:
596 {
597 struct v4l2_control *vc = (struct v4l2_control *)arg;
598 ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
599 vc->value);
600 break;
601 }
602
603 case VIDIOC_G_EXT_CTRLS:
604 {
605 struct v4l2_ext_controls *ctls =
606 (struct v4l2_ext_controls *)arg;
607 struct v4l2_ext_control *ctrl;
608 unsigned int idx;
609 int val;
610 for (idx = 0; idx < ctls->count; idx++) {
611 ctrl = ctls->controls + idx;
612 ret = pvr2_ctrl_get_value(
613 pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),&val);
614 if (ret) {
615 ctls->error_idx = idx;
616 break;
617 }
618 /* Ensure that if read as a 64 bit value, the user
619 will still get a hopefully sane value */
620 ctrl->value64 = 0;
621 ctrl->value = val;
622 }
623 break;
624 }
625
626 case VIDIOC_S_EXT_CTRLS:
627 {
628 struct v4l2_ext_controls *ctls =
629 (struct v4l2_ext_controls *)arg;
630 struct v4l2_ext_control *ctrl;
631 unsigned int idx;
632 for (idx = 0; idx < ctls->count; idx++) {
633 ctrl = ctls->controls + idx;
634 ret = pvr2_ctrl_set_value(
635 pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),
636 ctrl->value);
637 if (ret) {
638 ctls->error_idx = idx;
639 break;
640 }
641 }
642 break;
643 }
644
645 case VIDIOC_TRY_EXT_CTRLS:
646 {
647 struct v4l2_ext_controls *ctls =
648 (struct v4l2_ext_controls *)arg;
649 struct v4l2_ext_control *ctrl;
650 struct pvr2_ctrl *pctl;
651 unsigned int idx;
652 /* For the moment just validate that the requested control
653 actually exists. */
654 for (idx = 0; idx < ctls->count; idx++) {
655 ctrl = ctls->controls + idx;
656 pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id);
657 if (!pctl) {
658 ret = -EINVAL;
659 ctls->error_idx = idx;
660 break;
661 }
662 }
663 break;
664 }
665
666 case VIDIOC_LOG_STATUS:
667 {
668 pvr2_hdw_trigger_module_log(hdw);
669 ret = 0;
670 break;
671 }
672
673 default :
674 ret = v4l_compat_translate_ioctl(inode,file,cmd,
675 arg,pvr2_v4l2_do_ioctl);
676 }
677
678 pvr2_hdw_commit_ctl(hdw);
679
680 if (ret < 0) {
681 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
682 pvr2_trace(PVR2_TRACE_V4LIOCTL,
683 "pvr2_v4l2_do_ioctl failure, ret=%d",ret);
684 } else {
685 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
686 pvr2_trace(PVR2_TRACE_V4LIOCTL,
687 "pvr2_v4l2_do_ioctl failure, ret=%d"
688 " command was:",ret);
689 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
690 cmd);
691 }
692 }
693 } else {
694 pvr2_trace(PVR2_TRACE_V4LIOCTL,
695 "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)",
696 ret,ret);
697 }
698 return ret;
699}
700
701
702static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
703{
704 pvr2_trace(PVR2_TRACE_INIT,
705 "unregistering device video%d [%s]",
706 dip->vdev->minor,pvr2_config_get_name(dip->config));
707 if (dip->ctxt_idx >= 0) {
708 mutex_lock(&device_lock);
709 devices[dip->ctxt_idx] = NULL;
710 dip->ctxt_idx = -1;
711 mutex_unlock(&device_lock);
712 }
713 video_unregister_device(dip->vdev);
714}
715
716
717static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
718{
719 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1);
720 pvr2_v4l2_dev_destroy(&vp->video_dev);
721
722 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
723 pvr2_channel_done(&vp->channel);
724 kfree(vp);
725}
726
727
728void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
729{
730 struct pvr2_v4l2 *vp;
731 vp = container_of(chp,struct pvr2_v4l2,channel);
732 if (!vp->channel.mc_head->disconnect_flag) return;
733 if (vp->vfirst) return;
734 pvr2_v4l2_destroy_no_lock(vp);
735}
736
737
738int pvr2_v4l2_ioctl(struct inode *inode, struct file *file,
739 unsigned int cmd, unsigned long arg)
740{
741
742/* Temporary hack : use ivtv api until a v4l2 one is available. */
743#define IVTV_IOC_G_CODEC 0xFFEE7703
744#define IVTV_IOC_S_CODEC 0xFFEE7704
745 if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
746 return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl);
747}
748
749
750int pvr2_v4l2_release(struct inode *inode, struct file *file)
751{
752 struct pvr2_v4l2_fh *fhp = file->private_data;
753 struct pvr2_v4l2 *vp = fhp->vhead;
754 struct pvr2_context *mp = fhp->vhead->channel.mc_head;
755
756 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
757
758 if (fhp->rhp) {
759 struct pvr2_stream *sp;
760 struct pvr2_hdw *hdw;
761 hdw = fhp->channel.mc_head->hdw;
762 pvr2_hdw_set_streaming(hdw,0);
763 sp = pvr2_ioread_get_stream(fhp->rhp);
764 if (sp) pvr2_stream_set_callback(sp,0,0);
765 pvr2_ioread_destroy(fhp->rhp);
766 fhp->rhp = 0;
767 }
768 v4l2_prio_close(&vp->prio, &fhp->prio);
769 file->private_data = NULL;
770
771 pvr2_context_enter(mp); do {
772 if (fhp->vnext) {
773 fhp->vnext->vprev = fhp->vprev;
774 } else {
775 vp->vlast = fhp->vprev;
776 }
777 if (fhp->vprev) {
778 fhp->vprev->vnext = fhp->vnext;
779 } else {
780 vp->vfirst = fhp->vnext;
781 }
782 fhp->vnext = 0;
783 fhp->vprev = 0;
784 fhp->vhead = 0;
785 pvr2_channel_done(&fhp->channel);
786 pvr2_trace(PVR2_TRACE_STRUCT,
787 "Destroying pvr_v4l2_fh id=%p",fhp);
788 kfree(fhp);
789 if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
790 pvr2_v4l2_destroy_no_lock(vp);
791 }
792 } while (0); pvr2_context_exit(mp);
793 return 0;
794}
795
796
797int pvr2_v4l2_open(struct inode *inode, struct file *file)
798{
799 struct pvr2_v4l2_dev *dip = 0; /* Our own context pointer */
800 struct pvr2_v4l2_fh *fhp;
801 struct pvr2_v4l2 *vp;
802 struct pvr2_hdw *hdw;
803
804 mutex_lock(&device_lock);
805 /* MCI 7-Jun-2006 Even though we're just doing what amounts to an
806 atomic read of the device mapping array here, we still need the
807 mutex. The problem is that there is a tiny race possible when
808 we register the device. We can't update the device mapping
809 array until after the device has been registered, owing to the
810 fact that we can't know the minor device number until after the
811 registration succeeds. And if another thread tries to open the
812 device in the window of time after registration but before the
813 map is updated, then it will get back an erroneous null pointer
814 and the open will result in a spurious failure. The only way to
815 prevent that is to (a) be inside the mutex here before we access
816 the array, and (b) cover the entire registration process later
817 on with this same mutex. Thus if we get inside the mutex here,
818 then we can be assured that the registration process actually
819 completed correctly. This is an unhappy complication from the
820 use of global data in a driver that lives in a preemptible
821 environment. It sure would be nice if the video device itself
822 had a means for storing and retrieving a local context pointer.
823 Oh wait. It did. But now it's gone. Silly me. */
824 {
825 unsigned int midx = iminor(file->f_dentry->d_inode);
826 if (midx < sizeof(devices)/sizeof(devices[0])) {
827 dip = devices[midx];
828 }
829 }
830 mutex_unlock(&device_lock);
831
832 if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
833
834 vp = dip->v4lp;
835 hdw = vp->channel.hdw;
836
837 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
838
839 if (!pvr2_hdw_dev_ok(hdw)) {
840 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
841 "pvr2_v4l2_open: hardware not ready");
842 return -EIO;
843 }
844
845 fhp = kmalloc(sizeof(*fhp),GFP_KERNEL);
846 if (!fhp) {
847 return -ENOMEM;
848 }
849 memset(fhp,0,sizeof(*fhp));
850
851 init_waitqueue_head(&fhp->wait_data);
852 fhp->dev_info = dip;
853
854 pvr2_context_enter(vp->channel.mc_head); do {
855 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
856 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
857 fhp->vnext = 0;
858 fhp->vprev = vp->vlast;
859 if (vp->vlast) {
860 vp->vlast->vnext = fhp;
861 } else {
862 vp->vfirst = fhp;
863 }
864 vp->vlast = fhp;
865 fhp->vhead = vp;
866 } while (0); pvr2_context_exit(vp->channel.mc_head);
867
868 fhp->file = file;
869 file->private_data = fhp;
870 v4l2_prio_open(&vp->prio,&fhp->prio);
871
872 fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
873
874 return 0;
875}
876
877
878static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
879{
880 wake_up(&fhp->wait_data);
881}
882
883static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
884{
885 int ret;
886 struct pvr2_stream *sp;
887 struct pvr2_hdw *hdw;
888 if (fh->rhp) return 0;
889
890 /* First read() attempt. Try to claim the stream and start
891 it... */
892 if ((ret = pvr2_channel_claim_stream(&fh->channel,
893 fh->dev_info->stream)) != 0) {
894 /* Someone else must already have it */
895 return ret;
896 }
897
898 fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream);
899 if (!fh->rhp) {
900 pvr2_channel_claim_stream(&fh->channel,0);
901 return -ENOMEM;
902 }
903
904 hdw = fh->channel.mc_head->hdw;
905 sp = fh->dev_info->stream->stream;
906 pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
907 pvr2_hdw_set_stream_type(hdw,fh->dev_info->config);
908 pvr2_hdw_set_streaming(hdw,!0);
909 ret = pvr2_ioread_set_enabled(fh->rhp,!0);
910
911 return ret;
912}
913
914
915static ssize_t pvr2_v4l2_read(struct file *file,
916 char __user *buff, size_t count, loff_t *ppos)
917{
918 struct pvr2_v4l2_fh *fh = file->private_data;
919 int ret;
920
921 if (fh->fw_mode_flag) {
922 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
923 char *tbuf;
924 int c1,c2;
925 int tcnt = 0;
926 unsigned int offs = *ppos;
927
928 tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
929 if (!tbuf) return -ENOMEM;
930
931 while (count) {
932 c1 = count;
933 if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
934 c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
935 if (c2 < 0) {
936 tcnt = c2;
937 break;
938 }
939 if (!c2) break;
940 if (copy_to_user(buff,tbuf,c2)) {
941 tcnt = -EFAULT;
942 break;
943 }
944 offs += c2;
945 tcnt += c2;
946 buff += c2;
947 count -= c2;
948 *ppos += c2;
949 }
950 kfree(tbuf);
951 return tcnt;
952 }
953
954 if (!fh->rhp) {
955 ret = pvr2_v4l2_iosetup(fh);
956 if (ret) {
957 return ret;
958 }
959 }
960
961 for (;;) {
962 ret = pvr2_ioread_read(fh->rhp,buff,count);
963 if (ret >= 0) break;
964 if (ret != -EAGAIN) break;
965 if (file->f_flags & O_NONBLOCK) break;
966 /* Doing blocking I/O. Wait here. */
967 ret = wait_event_interruptible(
968 fh->wait_data,
969 pvr2_ioread_avail(fh->rhp) >= 0);
970 if (ret < 0) break;
971 }
972
973 return ret;
974}
975
976
977static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
978{
979 unsigned int mask = 0;
980 struct pvr2_v4l2_fh *fh = file->private_data;
981 int ret;
982
983 if (fh->fw_mode_flag) {
984 mask |= POLLIN | POLLRDNORM;
985 return mask;
986 }
987
988 if (!fh->rhp) {
989 ret = pvr2_v4l2_iosetup(fh);
990 if (ret) return POLLERR;
991 }
992
993 poll_wait(file,&fh->wait_data,wait);
994
995 if (pvr2_ioread_avail(fh->rhp) >= 0) {
996 mask |= POLLIN | POLLRDNORM;
997 }
998
999 return mask;
1000}
1001
1002
1003static struct file_operations vdev_fops = {
1004 .owner = THIS_MODULE,
1005 .open = pvr2_v4l2_open,
1006 .release = pvr2_v4l2_release,
1007 .read = pvr2_v4l2_read,
1008 .ioctl = pvr2_v4l2_ioctl,
1009 .llseek = no_llseek,
1010 .poll = pvr2_v4l2_poll,
1011};
1012
1013
1014#define VID_HARDWARE_PVRUSB2 38 /* FIXME : need a good value */
1015
1016static struct video_device vdev_template = {
1017 .owner = THIS_MODULE,
1018 .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
1019 .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
1020 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO
1021 | V4L2_CAP_READWRITE),
1022 .hardware = VID_HARDWARE_PVRUSB2,
1023 .fops = &vdev_fops,
1024};
1025
1026
1027static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1028 struct pvr2_v4l2 *vp,
1029 enum pvr2_config cfg)
1030{
1031 int mindevnum;
1032 int unit_number;
1033 int v4l_type;
1034 dip->v4lp = vp;
1035 dip->config = cfg;
1036
1037
1038 switch (cfg) {
1039 case pvr2_config_mpeg:
1040 v4l_type = VFL_TYPE_GRABBER;
1041 dip->stream = &vp->channel.mc_head->video_stream;
1042 break;
1043 case pvr2_config_vbi:
1044 v4l_type = VFL_TYPE_VBI;
1045 break;
1046 case pvr2_config_radio:
1047 v4l_type = VFL_TYPE_RADIO;
1048 break;
1049 default:
1050 /* Bail out (this should be impossible) */
1051 err("Failed to set up pvrusb2 v4l dev"
1052 " due to unrecognized config");
1053 return;
1054 }
1055
1056 if (!dip->stream) {
1057 err("Failed to set up pvrusb2 v4l dev"
1058 " due to missing stream instance");
1059 return;
1060 }
1061
1062 dip->vdev = video_device_alloc();
1063 if (!dip->vdev) {
1064 err("Alloc of pvrusb2 v4l video device failed");
1065 return;
1066 }
1067
1068 memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
1069 dip->vdev->release = video_device_release;
1070 mutex_lock(&device_lock);
1071
1072 mindevnum = -1;
1073 unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
1074 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1075 mindevnum = video_nr[unit_number];
1076 }
1077 if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) &&
1078 (video_register_device(dip->vdev, v4l_type, -1) < 0)) {
1079 err("Failed to register pvrusb2 v4l video device");
1080 } else {
1081 pvr2_trace(PVR2_TRACE_INIT,
1082 "registered device video%d [%s]",
1083 dip->vdev->minor,pvr2_config_get_name(dip->config));
1084 }
1085
1086 if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) &&
1087 (devices[dip->vdev->minor] == NULL)) {
1088 dip->ctxt_idx = dip->vdev->minor;
1089 devices[dip->ctxt_idx] = dip;
1090 }
1091 mutex_unlock(&device_lock);
1092
1093 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
1094 dip->vdev->minor);
1095}
1096
1097
1098struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1099{
1100 struct pvr2_v4l2 *vp;
1101
1102 vp = kmalloc(sizeof(*vp),GFP_KERNEL);
1103 if (!vp) return vp;
1104 memset(vp,0,sizeof(*vp));
1105 vp->video_dev.ctxt_idx = -1;
1106 pvr2_channel_init(&vp->channel,mnp);
1107 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1108
1109 vp->channel.check_func = pvr2_v4l2_internal_check;
1110
1111 /* register streams */
1112 pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg);
1113
1114
1115 return vp;
1116}
1117
1118/*
1119 Stuff for Emacs to see, in order to encourage consistent editing style:
1120 *** Local Variables: ***
1121 *** mode: c ***
1122 *** fill-column: 75 ***
1123 *** tab-width: 8 ***
1124 *** c-basic-offset: 8 ***
1125 *** End: ***
1126 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
new file mode 100644
index 000000000000..9a995e2d2256
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
@@ -0,0 +1,40 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
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 02111-1307 USA
19 *
20 */
21#ifndef __PVRUSB2_V4L2_H
22#define __PVRUSB2_V4L2_H
23
24#include "pvrusb2-context.h"
25
26struct pvr2_v4l2;
27
28struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *);
29
30#endif /* __PVRUSB2_V4L2_H */
31
32/*
33 Stuff for Emacs to see, in order to encourage consistent editing style:
34 *** Local Variables: ***
35 *** mode: c ***
36 *** fill-column: 75 ***
37 *** tab-width: 8 ***
38 *** c-basic-offset: 8 ***
39 *** End: ***
40 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
new file mode 100644
index 000000000000..e4ec7f25194c
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -0,0 +1,253 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23/*
24
25 This source file is specifically designed to interface with the
26 saa711x support that is available in the v4l available starting
27 with linux 2.6.15.
28
29*/
30
31#include "pvrusb2-video-v4l.h"
32#include "pvrusb2-i2c-cmd-v4l2.h"
33
34
35#include "pvrusb2-hdw-internal.h"
36#include "pvrusb2-debug.h"
37#include <linux/videodev2.h>
38#include <media/v4l2-common.h>
39#include <media/saa7115.h>
40#include <linux/errno.h>
41#include <linux/slab.h>
42
43struct pvr2_v4l_decoder {
44 struct pvr2_i2c_handler handler;
45 struct pvr2_decoder_ctrl ctrl;
46 struct pvr2_i2c_client *client;
47 struct pvr2_hdw *hdw;
48 unsigned long stale_mask;
49};
50
51
52static void set_input(struct pvr2_v4l_decoder *ctxt)
53{
54 struct pvr2_hdw *hdw = ctxt->hdw;
55 struct v4l2_routing route;
56
57 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val);
58 switch(hdw->input_val) {
59 case PVR2_CVAL_INPUT_TV:
60 route.input = SAA7115_COMPOSITE4;
61 break;
62 case PVR2_CVAL_INPUT_COMPOSITE:
63 route.input = SAA7115_COMPOSITE5;
64 break;
65 case PVR2_CVAL_INPUT_SVIDEO:
66 route.input = SAA7115_SVIDEO2;
67 break;
68 case PVR2_CVAL_INPUT_RADIO:
69 // ????? No idea yet what to do here
70 default:
71 return;
72 }
73 route.output = 0;
74 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
75}
76
77
78static int check_input(struct pvr2_v4l_decoder *ctxt)
79{
80 struct pvr2_hdw *hdw = ctxt->hdw;
81 return hdw->input_dirty != 0;
82}
83
84
85static void set_audio(struct pvr2_v4l_decoder *ctxt)
86{
87 u32 val;
88 struct pvr2_hdw *hdw = ctxt->hdw;
89
90 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d",
91 hdw->srate_val);
92 switch (hdw->srate_val) {
93 default:
94 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
95 val = 48000;
96 break;
97 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
98 val = 44100;
99 break;
100 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
101 val = 32000;
102 break;
103 }
104 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
105}
106
107
108static int check_audio(struct pvr2_v4l_decoder *ctxt)
109{
110 struct pvr2_hdw *hdw = ctxt->hdw;
111 return hdw->srate_dirty != 0;
112}
113
114
115struct pvr2_v4l_decoder_ops {
116 void (*update)(struct pvr2_v4l_decoder *);
117 int (*check)(struct pvr2_v4l_decoder *);
118};
119
120
121static const struct pvr2_v4l_decoder_ops decoder_ops[] = {
122 { .update = set_input, .check = check_input},
123 { .update = set_audio, .check = check_audio},
124};
125
126
127static void decoder_detach(struct pvr2_v4l_decoder *ctxt)
128{
129 ctxt->client->handler = 0;
130 ctxt->hdw->decoder_ctrl = 0;
131 kfree(ctxt);
132}
133
134
135static int decoder_check(struct pvr2_v4l_decoder *ctxt)
136{
137 unsigned long msk;
138 unsigned int idx;
139
140 for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
141 idx++) {
142 msk = 1 << idx;
143 if (ctxt->stale_mask & msk) continue;
144 if (decoder_ops[idx].check(ctxt)) {
145 ctxt->stale_mask |= msk;
146 }
147 }
148 return ctxt->stale_mask != 0;
149}
150
151
152static void decoder_update(struct pvr2_v4l_decoder *ctxt)
153{
154 unsigned long msk;
155 unsigned int idx;
156
157 for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
158 idx++) {
159 msk = 1 << idx;
160 if (!(ctxt->stale_mask & msk)) continue;
161 ctxt->stale_mask &= ~msk;
162 decoder_ops[idx].update(ctxt);
163 }
164}
165
166
167static int decoder_detect(struct pvr2_i2c_client *cp)
168{
169 /* Attempt to query the decoder - let's see if it will answer */
170 struct v4l2_tuner vt;
171 int ret;
172
173 memset(&vt,0,sizeof(vt));
174 ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt);
175 return ret == 0; /* Return true if it answered */
176}
177
178
179static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl)
180{
181 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl);
182 pvr2_v4l2_cmd_stream(ctxt->client,fl);
183}
184
185
186static int decoder_is_tuned(struct pvr2_v4l_decoder *ctxt)
187{
188 struct v4l2_tuner vt;
189 int ret;
190
191 memset(&vt,0,sizeof(vt));
192 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
193 if (ret < 0) return -EINVAL;
194 return vt.signal ? 1 : 0;
195}
196
197
198static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt)
199{
200 return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l");
201}
202
203
204const static struct pvr2_i2c_handler_functions hfuncs = {
205 .detach = (void (*)(void *))decoder_detach,
206 .check = (int (*)(void *))decoder_check,
207 .update = (void (*)(void *))decoder_update,
208 .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
209};
210
211
212int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
213 struct pvr2_i2c_client *cp)
214{
215 struct pvr2_v4l_decoder *ctxt;
216
217 if (hdw->decoder_ctrl) return 0;
218 if (cp->handler) return 0;
219 if (!decoder_detect(cp)) return 0;
220
221 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
222 if (!ctxt) return 0;
223 memset(ctxt,0,sizeof(*ctxt));
224
225 ctxt->handler.func_data = ctxt;
226 ctxt->handler.func_table = &hfuncs;
227 ctxt->ctrl.ctxt = ctxt;
228 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
229 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
230 ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned;
231 ctxt->client = cp;
232 ctxt->hdw = hdw;
233 ctxt->stale_mask = (1 << (sizeof(decoder_ops)/
234 sizeof(decoder_ops[0]))) - 1;
235 hdw->decoder_ctrl = &ctxt->ctrl;
236 cp->handler = &ctxt->handler;
237 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up",
238 cp->client->addr);
239 return !0;
240}
241
242
243
244
245/*
246 Stuff for Emacs to see, in order to encourage consistent editing style:
247 *** Local Variables: ***
248 *** mode: c ***
249 *** fill-column: 70 ***
250 *** tab-width: 8 ***
251 *** c-basic-offset: 8 ***
252 *** End: ***
253 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
new file mode 100644
index 000000000000..2b917fda02e4
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
@@ -0,0 +1,52 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef __PVRUSB2_VIDEO_V4L_H
24#define __PVRUSB2_VIDEO_V4L_H
25
26/*
27
28 This module connects the pvrusb2 driver to the I2C chip level
29 driver which handles device video processing. This interface is
30 used internally by the driver; higher level code should only
31 interact through the interface provided by pvrusb2-hdw.h.
32
33*/
34
35
36
37#include "pvrusb2-i2c-core.h"
38
39int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
40
41
42#endif /* __PVRUSB2_VIDEO_V4L_H */
43
44/*
45 Stuff for Emacs to see, in order to encourage consistent editing style:
46 *** Local Variables: ***
47 *** mode: c ***
48 *** fill-column: 70 ***
49 *** tab-width: 8 ***
50 *** c-basic-offset: 8 ***
51 *** End: ***
52 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
new file mode 100644
index 000000000000..fcad346e3955
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -0,0 +1,170 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23/*
24
25 This source file is specifically designed to interface with the
26 wm8775.
27
28*/
29
30#include "pvrusb2-wm8775.h"
31#include "pvrusb2-i2c-cmd-v4l2.h"
32
33
34#include "pvrusb2-hdw-internal.h"
35#include "pvrusb2-debug.h"
36#include <linux/videodev2.h>
37#include <media/v4l2-common.h>
38#include <linux/errno.h>
39#include <linux/slab.h>
40
41struct pvr2_v4l_wm8775 {
42 struct pvr2_i2c_handler handler;
43 struct pvr2_i2c_client *client;
44 struct pvr2_hdw *hdw;
45 unsigned long stale_mask;
46};
47
48
49static void set_input(struct pvr2_v4l_wm8775 *ctxt)
50{
51 struct v4l2_routing route;
52 struct pvr2_hdw *hdw = ctxt->hdw;
53 int msk = 0;
54
55 memset(&route,0,sizeof(route));
56
57 pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d msk=0x%x)",
58 hdw->input_val,msk);
59
60 // Always point to input #1 no matter what
61 route.input = 2;
62 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
63}
64
65static int check_input(struct pvr2_v4l_wm8775 *ctxt)
66{
67 struct pvr2_hdw *hdw = ctxt->hdw;
68 return hdw->input_dirty != 0;
69}
70
71
72struct pvr2_v4l_wm8775_ops {
73 void (*update)(struct pvr2_v4l_wm8775 *);
74 int (*check)(struct pvr2_v4l_wm8775 *);
75};
76
77
78static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = {
79 { .update = set_input, .check = check_input},
80};
81
82
83static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt,
84 char *buf,unsigned int cnt)
85{
86 return scnprintf(buf,cnt,"handler: pvrusb2-wm8775");
87}
88
89
90static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt)
91{
92 ctxt->client->handler = 0;
93 kfree(ctxt);
94}
95
96
97static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt)
98{
99 unsigned long msk;
100 unsigned int idx;
101
102 for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]);
103 idx++) {
104 msk = 1 << idx;
105 if (ctxt->stale_mask & msk) continue;
106 if (wm8775_ops[idx].check(ctxt)) {
107 ctxt->stale_mask |= msk;
108 }
109 }
110 return ctxt->stale_mask != 0;
111}
112
113
114static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt)
115{
116 unsigned long msk;
117 unsigned int idx;
118
119 for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]);
120 idx++) {
121 msk = 1 << idx;
122 if (!(ctxt->stale_mask & msk)) continue;
123 ctxt->stale_mask &= ~msk;
124 wm8775_ops[idx].update(ctxt);
125 }
126}
127
128
129const static struct pvr2_i2c_handler_functions hfuncs = {
130 .detach = (void (*)(void *))wm8775_detach,
131 .check = (int (*)(void *))wm8775_check,
132 .update = (void (*)(void *))wm8775_update,
133 .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe,
134};
135
136
137int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
138{
139 struct pvr2_v4l_wm8775 *ctxt;
140
141 if (cp->handler) return 0;
142
143 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
144 if (!ctxt) return 0;
145 memset(ctxt,0,sizeof(*ctxt));
146
147 ctxt->handler.func_data = ctxt;
148 ctxt->handler.func_table = &hfuncs;
149 ctxt->client = cp;
150 ctxt->hdw = hdw;
151 ctxt->stale_mask = (1 << (sizeof(wm8775_ops)/
152 sizeof(wm8775_ops[0]))) - 1;
153 cp->handler = &ctxt->handler;
154 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up",
155 cp->client->addr);
156 return !0;
157}
158
159
160
161
162/*
163 Stuff for Emacs to see, in order to encourage consistent editing style:
164 *** Local Variables: ***
165 *** mode: c ***
166 *** fill-column: 70 ***
167 *** tab-width: 8 ***
168 *** c-basic-offset: 8 ***
169 *** End: ***
170 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
new file mode 100644
index 000000000000..8aaeff4e1e20
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
@@ -0,0 +1,53 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef __PVRUSB2_WM8775_H
24#define __PVRUSB2_WM8775_H
25
26/*
27
28 This module connects the pvrusb2 driver to the I2C chip level
29 driver which performs analog -> digital audio conversion for
30 external audio inputs. This interface is used internally by the
31 driver; higher level code should only interact through the
32 interface provided by pvrusb2-hdw.h.
33
34*/
35
36
37
38#include "pvrusb2-i2c-core.h"
39
40int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
41
42
43#endif /* __PVRUSB2_WM8775_H */
44
45/*
46 Stuff for Emacs to see, in order to encourage consistent editing style:
47 *** Local Variables: ***
48 *** mode: c ***
49 *** fill-column: 70 ***
50 *** tab-width: 8 ***
51 *** c-basic-offset: 8 ***
52 *** End: ***
53 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2.h b/drivers/media/video/pvrusb2/pvrusb2.h
new file mode 100644
index 000000000000..074533e9c21e
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2.h
@@ -0,0 +1,43 @@
1/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef __PVRUSB2_H
24#define __PVRUSB2_H
25
26/* Maximum number of pvrusb2 instances we can track at once. You
27 might want to increase this - however the driver operation will not
28 be impaired if it is too small. Instead additional units just
29 won't have an ID assigned and it might not be possible to specify
30 module paramters for those extra units. */
31#define PVR_NUM 20
32
33#endif /* __PVRUSB2_H */
34
35/*
36 Stuff for Emacs to see, in order to encourage consistent editing style:
37 *** Local Variables: ***
38 *** mode: c ***
39 *** fill-column: 70 ***
40 *** tab-width: 8 ***
41 *** c-basic-offset: 8 ***
42 *** End: ***
43 */
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index de7b9e6e932a..afc8f352b8e7 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -432,10 +432,10 @@ static void saa6752hs_old_set_params(struct i2c_client* client,
432} 432}
433 433
434static int handle_ctrl(struct saa6752hs_mpeg_params *params, 434static int handle_ctrl(struct saa6752hs_mpeg_params *params,
435 struct v4l2_ext_control *ctrl, int cmd) 435 struct v4l2_ext_control *ctrl, unsigned int cmd)
436{ 436{
437 int old = 0, new; 437 int old = 0, new;
438 int set = cmd == VIDIOC_S_EXT_CTRLS; 438 int set = (cmd == VIDIOC_S_EXT_CTRLS);
439 439
440 new = ctrl->value; 440 new = ctrl->value;
441 switch (ctrl->id) { 441 switch (ctrl->id) {
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index 6be9c1131e1f..c18b31d9928c 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -2190,7 +2190,7 @@ static struct pci_driver stradis_driver = {
2190 .remove = __devexit_p(stradis_remove) 2190 .remove = __devexit_p(stradis_remove)
2191}; 2191};
2192 2192
2193int __init stradis_init(void) 2193static int __init stradis_init(void)
2194{ 2194{
2195 int retval; 2195 int retval;
2196 2196
@@ -2203,7 +2203,7 @@ int __init stradis_init(void)
2203 return retval; 2203 return retval;
2204} 2204}
2205 2205
2206void __exit stradis_exit(void) 2206static void __exit stradis_exit(void)
2207{ 2207{
2208 pci_unregister_driver(&stradis_driver); 2208 pci_unregister_driver(&stradis_driver);
2209 printk(KERN_INFO "stradis: module cleanup complete\n"); 2209 printk(KERN_INFO "stradis: module cleanup complete\n");
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index b6ae969563b2..2fadabf99688 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -22,11 +22,11 @@
22*/ 22*/
23 23
24#define tda9887_info(fmt, arg...) do {\ 24#define tda9887_info(fmt, arg...) do {\
25 printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \ 25 printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \
26 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) 26 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
27#define tda9887_dbg(fmt, arg...) do {\ 27#define tda9887_dbg(fmt, arg...) do {\
28 if (tuner_debug) \ 28 if (tuner_debug) \
29 printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \ 29 printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \
30 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) 30 i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
31 31
32 32
@@ -84,8 +84,7 @@ struct tvnorm {
84#define cAudioGain6 0x80 // bit c7 84#define cAudioGain6 0x80 // bit c7
85 85
86#define cTopMask 0x1f // bit c0:4 86#define cTopMask 0x1f // bit c0:4
87#define cTopPalSecamDefault 0x14 // bit c0:4 87#define cTopDefault 0x10 // bit c0:4
88#define cTopNtscRadioDefault 0x10 // bit c0:4
89 88
90//// third reg (e) 89//// third reg (e)
91#define cAudioIF_4_5 0x00 // bit e0:1 90#define cAudioIF_4_5 0x00 // bit e0:1
@@ -123,7 +122,7 @@ static struct tvnorm tvnorms[] = {
123 cQSS ), 122 cQSS ),
124 .c = ( cDeemphasisON | 123 .c = ( cDeemphasisON |
125 cDeemphasis50 | 124 cDeemphasis50 |
126 cTopPalSecamDefault), 125 cTopDefault),
127 .e = ( cGating_36 | 126 .e = ( cGating_36 |
128 cAudioIF_5_5 | 127 cAudioIF_5_5 |
129 cVideoIF_38_90 ), 128 cVideoIF_38_90 ),
@@ -134,7 +133,7 @@ static struct tvnorm tvnorms[] = {
134 cQSS ), 133 cQSS ),
135 .c = ( cDeemphasisON | 134 .c = ( cDeemphasisON |
136 cDeemphasis50 | 135 cDeemphasis50 |
137 cTopPalSecamDefault), 136 cTopDefault),
138 .e = ( cGating_36 | 137 .e = ( cGating_36 |
139 cAudioIF_6_0 | 138 cAudioIF_6_0 |
140 cVideoIF_38_90 ), 139 cVideoIF_38_90 ),
@@ -145,7 +144,7 @@ static struct tvnorm tvnorms[] = {
145 cQSS ), 144 cQSS ),
146 .c = ( cDeemphasisON | 145 .c = ( cDeemphasisON |
147 cDeemphasis50 | 146 cDeemphasis50 |
148 cTopPalSecamDefault), 147 cTopDefault),
149 .e = ( cGating_36 | 148 .e = ( cGating_36 |
150 cAudioIF_6_5 | 149 cAudioIF_6_5 |
151 cVideoIF_38_90 ), 150 cVideoIF_38_90 ),
@@ -156,7 +155,7 @@ static struct tvnorm tvnorms[] = {
156 cQSS ), 155 cQSS ),
157 .c = ( cDeemphasisON | 156 .c = ( cDeemphasisON |
158 cDeemphasis75 | 157 cDeemphasis75 |
159 cTopNtscRadioDefault), 158 cTopDefault),
160 .e = ( cGating_36 | 159 .e = ( cGating_36 |
161 cAudioIF_4_5 | 160 cAudioIF_4_5 |
162 cVideoIF_45_75 ), 161 cVideoIF_45_75 ),
@@ -165,7 +164,7 @@ static struct tvnorm tvnorms[] = {
165 .name = "SECAM-BGH", 164 .name = "SECAM-BGH",
166 .b = ( cPositiveAmTV | 165 .b = ( cPositiveAmTV |
167 cQSS ), 166 cQSS ),
168 .c = ( cTopPalSecamDefault), 167 .c = ( cTopDefault),
169 .e = ( cGating_36 | 168 .e = ( cGating_36 |
170 cAudioIF_5_5 | 169 cAudioIF_5_5 |
171 cVideoIF_38_90 ), 170 cVideoIF_38_90 ),
@@ -174,7 +173,7 @@ static struct tvnorm tvnorms[] = {
174 .name = "SECAM-L", 173 .name = "SECAM-L",
175 .b = ( cPositiveAmTV | 174 .b = ( cPositiveAmTV |
176 cQSS ), 175 cQSS ),
177 .c = ( cTopPalSecamDefault), 176 .c = ( cTopDefault),
178 .e = ( cGating_36 | 177 .e = ( cGating_36 |
179 cAudioIF_6_5 | 178 cAudioIF_6_5 |
180 cVideoIF_38_90 ), 179 cVideoIF_38_90 ),
@@ -184,7 +183,7 @@ static struct tvnorm tvnorms[] = {
184 .b = ( cOutputPort2Inactive | 183 .b = ( cOutputPort2Inactive |
185 cPositiveAmTV | 184 cPositiveAmTV |
186 cQSS ), 185 cQSS ),
187 .c = ( cTopPalSecamDefault), 186 .c = ( cTopDefault),
188 .e = ( cGating_36 | 187 .e = ( cGating_36 |
189 cAudioIF_6_5 | 188 cAudioIF_6_5 |
190 cVideoIF_33_90 ), 189 cVideoIF_33_90 ),
@@ -195,7 +194,7 @@ static struct tvnorm tvnorms[] = {
195 cQSS ), 194 cQSS ),
196 .c = ( cDeemphasisON | 195 .c = ( cDeemphasisON |
197 cDeemphasis50 | 196 cDeemphasis50 |
198 cTopPalSecamDefault), 197 cTopDefault),
199 .e = ( cGating_36 | 198 .e = ( cGating_36 |
200 cAudioIF_6_5 | 199 cAudioIF_6_5 |
201 cVideoIF_38_90 ), 200 cVideoIF_38_90 ),
@@ -206,7 +205,7 @@ static struct tvnorm tvnorms[] = {
206 cQSS ), 205 cQSS ),
207 .c = ( cDeemphasisON | 206 .c = ( cDeemphasisON |
208 cDeemphasis75 | 207 cDeemphasis75 |
209 cTopNtscRadioDefault), 208 cTopDefault),
210 .e = ( cGating_36 | 209 .e = ( cGating_36 |
211 cAudioIF_4_5 | 210 cAudioIF_4_5 |
212 cVideoIF_45_75 ), 211 cVideoIF_45_75 ),
@@ -217,7 +216,7 @@ static struct tvnorm tvnorms[] = {
217 cQSS ), 216 cQSS ),
218 .c = ( cDeemphasisON | 217 .c = ( cDeemphasisON |
219 cDeemphasis50 | 218 cDeemphasis50 |
220 cTopNtscRadioDefault), 219 cTopDefault),
221 .e = ( cGating_36 | 220 .e = ( cGating_36 |
222 cAudioIF_4_5 | 221 cAudioIF_4_5 |
223 cVideoIF_58_75 ), 222 cVideoIF_58_75 ),
@@ -230,7 +229,7 @@ static struct tvnorm radio_stereo = {
230 cQSS ), 229 cQSS ),
231 .c = ( cDeemphasisOFF | 230 .c = ( cDeemphasisOFF |
232 cAudioGain6 | 231 cAudioGain6 |
233 cTopNtscRadioDefault), 232 cTopDefault),
234 .e = ( cTunerGainLow | 233 .e = ( cTunerGainLow |
235 cAudioIF_5_5 | 234 cAudioIF_5_5 |
236 cRadioIF_38_90 ), 235 cRadioIF_38_90 ),
@@ -242,7 +241,7 @@ static struct tvnorm radio_mono = {
242 cQSS ), 241 cQSS ),
243 .c = ( cDeemphasisON | 242 .c = ( cDeemphasisON |
244 cDeemphasis75 | 243 cDeemphasis75 |
245 cTopNtscRadioDefault), 244 cTopDefault),
246 .e = ( cTunerGainLow | 245 .e = ( cTunerGainLow |
247 cAudioIF_5_5 | 246 cAudioIF_5_5 |
248 cRadioIF_38_90 ), 247 cRadioIF_38_90 ),
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index a26ded7d6fae..011413cf34a8 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -40,7 +40,6 @@ static unsigned int no_autodetect = 0;
40static unsigned int show_i2c = 0; 40static unsigned int show_i2c = 0;
41 41
42/* insmod options used at runtime => read/write */ 42/* insmod options used at runtime => read/write */
43static unsigned int tuner_debug_old = 0;
44int tuner_debug = 0; 43int tuner_debug = 0;
45 44
46static unsigned int tv_range[2] = { 44, 958 }; 45static unsigned int tv_range[2] = { 44, 958 };
@@ -54,8 +53,6 @@ static char ntsc[] = "-";
54module_param(addr, int, 0444); 53module_param(addr, int, 0444);
55module_param(no_autodetect, int, 0444); 54module_param(no_autodetect, int, 0444);
56module_param(show_i2c, int, 0444); 55module_param(show_i2c, int, 0444);
57/* Note: tuner_debug is deprecated and will be removed in 2.6.17 */
58module_param_named(tuner_debug,tuner_debug_old, int, 0444);
59module_param_named(debug,tuner_debug, int, 0644); 56module_param_named(debug,tuner_debug, int, 0644);
60module_param_string(pal, pal, sizeof(pal), 0644); 57module_param_string(pal, pal, sizeof(pal), 0644);
61module_param_string(secam, secam, sizeof(secam), 0644); 58module_param_string(secam, secam, sizeof(secam), 0644);
@@ -442,11 +439,6 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
442 t->audmode = V4L2_TUNER_MODE_STEREO; 439 t->audmode = V4L2_TUNER_MODE_STEREO;
443 t->mode_mask = T_UNINITIALIZED; 440 t->mode_mask = T_UNINITIALIZED;
444 t->tuner_status = tuner_status; 441 t->tuner_status = tuner_status;
445 if (tuner_debug_old) {
446 tuner_debug = tuner_debug_old;
447 printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n");
448 printk(KERN_ERR "tuner: use the debug option instead.\n");
449 }
450 442
451 if (show_i2c) { 443 if (show_i2c) {
452 unsigned char buffer[16]; 444 unsigned char buffer[16];
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index f4b3d64ebf73..97f946db8597 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -1103,7 +1103,7 @@ const char **v4l2_ctrl_get_menu(u32 id)
1103 }; 1103 };
1104 static const char *mpeg_stream_vbi_fmt[] = { 1104 static const char *mpeg_stream_vbi_fmt[] = {
1105 "No VBI", 1105 "No VBI",
1106 "VBI in private packets, IVTV format", 1106 "Private packet, IVTV format",
1107 NULL 1107 NULL
1108 }; 1108 };
1109 1109
diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h
index 074c4008ad52..d91d88f93c8b 100644
--- a/include/media/cx2341x.h
+++ b/include/media/cx2341x.h
@@ -89,9 +89,9 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
89 struct v4l2_queryctrl *qctrl); 89 struct v4l2_queryctrl *qctrl);
90const char **cx2341x_ctrl_get_menu(u32 id); 90const char **cx2341x_ctrl_get_menu(u32 id);
91int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, 91int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
92 struct v4l2_ext_controls *ctrls, int cmd); 92 struct v4l2_ext_controls *ctrls, unsigned int cmd);
93void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p); 93void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p);
94void cx2341x_log_status(struct cx2341x_mpeg_params *p, int cardid); 94void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix);
95 95
96/* Firmware names */ 96/* Firmware names */
97#define CX2341X_FIRM_ENC_FILENAME "v4l-cx2341x-enc.fw" 97#define CX2341X_FIRM_ENC_FILENAME "v4l-cx2341x-enc.fw"