aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMike Isely <isely@isely.net>2006-06-26 19:58:46 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-06-26 23:17:15 -0400
commitd855497edbfbf9e19a17f4a1154bca69cb4bd9ba (patch)
treeb39bef23fc00c91dac73ae171ad6ba7261170918 /drivers/media
parenteb99adde31b7d85c67a5e1c2fa5e098e1056dd79 (diff)
V4L/DVB (4228a): pvrusb2 to kernel 2.6.18
Implement V4L2 driver for the Hauppauge PVR USB2 TV tuner. The Hauppauge PVR USB2 is a USB connected TV tuner with an embedded cx23416 hardware MPEG2 encoder. There are two major variants of this device; this driver handles both. Any V4L2 application which understands MPEG2 video stream data should be able to work with this device. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/Makefile1
-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.c544
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.h115
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c276
-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.c499
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.h42
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h371
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c2949
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h342
-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.c180
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.c406
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.h60
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c775
-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.c1056
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.h40
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c250
-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
48 files changed, 12948 insertions, 0 deletions
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/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..3577d5bfa007
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -0,0 +1,544 @@
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 }
57 ret = cptr->info->set_value(cptr,mask,val);
58 } else {
59 ret = -EPERM;
60 }
61 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
62 return ret;
63}
64
65
66/* Get the current value of the given control. */
67int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr)
68{
69 int ret = 0;
70 if (!cptr) return -EINVAL;
71 LOCK_TAKE(cptr->hdw->big_lock); do {
72 ret = cptr->info->get_value(cptr,valptr);
73 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
74 return ret;
75}
76
77
78/* Retrieve control's type */
79enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr)
80{
81 if (!cptr) return pvr2_ctl_int;
82 return cptr->info->type;
83}
84
85
86/* Retrieve control's maximum value (int type) */
87int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr)
88{
89 int ret = 0;
90 if (!cptr) return 0;
91 LOCK_TAKE(cptr->hdw->big_lock); do {
92 if (cptr->info->type == pvr2_ctl_int) {
93 ret = cptr->info->def.type_int.max_value;
94 }
95 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
96 return ret;
97}
98
99
100/* Retrieve control's minimum value (int type) */
101int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
102{
103 int ret = 0;
104 if (!cptr) return 0;
105 LOCK_TAKE(cptr->hdw->big_lock); do {
106 if (cptr->info->type == pvr2_ctl_int) {
107 ret = cptr->info->def.type_int.min_value;
108 }
109 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
110 return ret;
111}
112
113
114/* Retrieve control's default value (any type) */
115int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr)
116{
117 int ret = 0;
118 if (!cptr) return 0;
119 LOCK_TAKE(cptr->hdw->big_lock); do {
120 if (cptr->info->type == pvr2_ctl_int) {
121 ret = cptr->info->default_value;
122 }
123 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
124 return ret;
125}
126
127
128/* Retrieve control's enumeration count (enum only) */
129int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr)
130{
131 int ret = 0;
132 if (!cptr) return 0;
133 LOCK_TAKE(cptr->hdw->big_lock); do {
134 if (cptr->info->type == pvr2_ctl_enum) {
135 ret = cptr->info->def.type_enum.count;
136 }
137 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
138 return ret;
139}
140
141
142/* Retrieve control's valid mask bits (bit mask only) */
143int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr)
144{
145 int ret = 0;
146 if (!cptr) return 0;
147 LOCK_TAKE(cptr->hdw->big_lock); do {
148 if (cptr->info->type == pvr2_ctl_bitmask) {
149 ret = cptr->info->def.type_bitmask.valid_bits;
150 }
151 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
152 return ret;
153}
154
155
156/* Retrieve the control's name */
157const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr)
158{
159 if (!cptr) return 0;
160 return cptr->info->name;
161}
162
163
164/* Retrieve the control's desc */
165const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr)
166{
167 if (!cptr) return 0;
168 return cptr->info->desc;
169}
170
171
172/* Retrieve a control enumeration or bit mask value */
173int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
174 char *bptr,unsigned int bmax,
175 unsigned int *blen)
176{
177 int ret = -EINVAL;
178 if (!cptr) return 0;
179 *blen = 0;
180 LOCK_TAKE(cptr->hdw->big_lock); do {
181 if (cptr->info->type == pvr2_ctl_enum) {
182 const char **names;
183 names = cptr->info->def.type_enum.value_names;
184 if ((val >= 0) &&
185 (val < cptr->info->def.type_enum.count)) {
186 if (names[val]) {
187 *blen = scnprintf(
188 bptr,bmax,"%s",
189 names[val]);
190 } else {
191 *blen = 0;
192 }
193 ret = 0;
194 }
195 } else if (cptr->info->type == pvr2_ctl_bitmask) {
196 const char **names;
197 unsigned int idx;
198 int msk;
199 names = cptr->info->def.type_bitmask.bit_names;
200 val &= cptr->info->def.type_bitmask.valid_bits;
201 for (idx = 0, msk = 1; val; idx++, msk <<= 1) {
202 if (val & msk) {
203 *blen = scnprintf(bptr,bmax,"%s",
204 names[idx]);
205 ret = 0;
206 break;
207 }
208 }
209 }
210 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
211 return ret;
212}
213
214
215/* Return true if control is writable */
216int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr)
217{
218 if (!cptr) return 0;
219 return cptr->info->set_value != 0;
220}
221
222
223/* Return true if control has custom symbolic representation */
224int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr)
225{
226 if (!cptr) return 0;
227 if (!cptr->info->val_to_sym) return 0;
228 if (!cptr->info->sym_to_val) return 0;
229 return !0;
230}
231
232
233/* Convert a given mask/val to a custom symbolic value */
234int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr,
235 int mask,int val,
236 char *buf,unsigned int maxlen,
237 unsigned int *len)
238{
239 if (!cptr) return -EINVAL;
240 if (!cptr->info->val_to_sym) return -EINVAL;
241 return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len);
242}
243
244
245/* Convert a symbolic value to a mask/value pair */
246int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr,
247 const char *buf,unsigned int len,
248 int *maskptr,int *valptr)
249{
250 if (!cptr) return -EINVAL;
251 if (!cptr->info->sym_to_val) return -EINVAL;
252 return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr);
253}
254
255
256static unsigned int gen_bitmask_string(int msk,int val,int msk_only,
257 const char **names,
258 char *ptr,unsigned int len)
259{
260 unsigned int idx;
261 long sm,um;
262 int spcFl;
263 unsigned int uc,cnt;
264 const char *idStr;
265
266 spcFl = 0;
267 uc = 0;
268 um = 0;
269 for (idx = 0, sm = 1; msk; idx++, sm <<= 1) {
270 if (sm & msk) {
271 msk &= ~sm;
272 idStr = names[idx];
273 if (idStr) {
274 cnt = scnprintf(ptr,len,"%s%s%s",
275 (spcFl ? " " : ""),
276 (msk_only ? "" :
277 ((val & sm) ? "+" : "-")),
278 idStr);
279 ptr += cnt; len -= cnt; uc += cnt;
280 spcFl = !0;
281 } else {
282 um |= sm;
283 }
284 }
285 }
286 if (um) {
287 if (msk_only) {
288 cnt = scnprintf(ptr,len,"%s0x%lx",
289 (spcFl ? " " : ""),
290 um);
291 ptr += cnt; len -= cnt; uc += cnt;
292 spcFl = !0;
293 } else if (um & val) {
294 cnt = scnprintf(ptr,len,"%s+0x%lx",
295 (spcFl ? " " : ""),
296 um & val);
297 ptr += cnt; len -= cnt; uc += cnt;
298 spcFl = !0;
299 } else if (um & ~val) {
300 cnt = scnprintf(ptr,len,"%s+0x%lx",
301 (spcFl ? " " : ""),
302 um & ~val);
303 ptr += cnt; len -= cnt; uc += cnt;
304 spcFl = !0;
305 }
306 }
307 return uc;
308}
309
310
311static int parse_token(const char *ptr,unsigned int len,
312 int *valptr,
313 const char **names,unsigned int namecnt)
314{
315 char buf[33];
316 unsigned int slen;
317 unsigned int idx;
318 int negfl;
319 char *p2;
320 *valptr = 0;
321 if (!names) namecnt = 0;
322 for (idx = 0; idx < namecnt; idx++) {
323 if (!names[idx]) continue;
324 slen = strlen(names[idx]);
325 if (slen != len) continue;
326 if (memcmp(names[idx],ptr,slen)) continue;
327 *valptr = idx;
328 return 0;
329 }
330 negfl = 0;
331 if ((*ptr == '-') || (*ptr == '+')) {
332 negfl = (*ptr == '-');
333 ptr++; len--;
334 }
335 if (len >= sizeof(buf)) return -EINVAL;
336 memcpy(buf,ptr,len);
337 buf[len] = 0;
338 *valptr = simple_strtol(buf,&p2,0);
339 if (negfl) *valptr = -(*valptr);
340 if (*p2) return -EINVAL;
341 return 0;
342}
343
344
345static int parse_mtoken(const char *ptr,unsigned int len,
346 int *valptr,
347 const char **names,int valid_bits)
348{
349 char buf[33];
350 unsigned int slen;
351 unsigned int idx;
352 char *p2;
353 int msk;
354 *valptr = 0;
355 for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) {
356 if (!msk & valid_bits) continue;
357 valid_bits &= ~msk;
358 if (!names[idx]) continue;
359 slen = strlen(names[idx]);
360 if (slen != len) continue;
361 if (memcmp(names[idx],ptr,slen)) continue;
362 *valptr = msk;
363 return 0;
364 }
365 if (len >= sizeof(buf)) return -EINVAL;
366 memcpy(buf,ptr,len);
367 buf[len] = 0;
368 *valptr = simple_strtol(buf,&p2,0);
369 if (*p2) return -EINVAL;
370 return 0;
371}
372
373
374static int parse_tlist(const char *ptr,unsigned int len,
375 int *maskptr,int *valptr,
376 const char **names,int valid_bits)
377{
378 unsigned int cnt;
379 int mask,val,kv,mode,ret;
380 mask = 0;
381 val = 0;
382 ret = 0;
383 while (len) {
384 cnt = 0;
385 while ((cnt < len) &&
386 ((ptr[cnt] <= 32) ||
387 (ptr[cnt] >= 127))) cnt++;
388 ptr += cnt;
389 len -= cnt;
390 mode = 0;
391 if ((*ptr == '-') || (*ptr == '+')) {
392 mode = (*ptr == '-') ? -1 : 1;
393 ptr++;
394 len--;
395 }
396 cnt = 0;
397 while (cnt < len) {
398 if (ptr[cnt] <= 32) break;
399 if (ptr[cnt] >= 127) break;
400 cnt++;
401 }
402 if (!cnt) break;
403 if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) {
404 ret = -EINVAL;
405 break;
406 }
407 ptr += cnt;
408 len -= cnt;
409 switch (mode) {
410 case 0:
411 mask = valid_bits;
412 val |= kv;
413 break;
414 case -1:
415 mask |= kv;
416 val &= ~kv;
417 break;
418 case 1:
419 mask |= kv;
420 val |= kv;
421 break;
422 default:
423 break;
424 }
425 }
426 *maskptr = mask;
427 *valptr = val;
428 return ret;
429}
430
431
432/* Convert a symbolic value to a mask/value pair */
433int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
434 const char *ptr,unsigned int len,
435 int *maskptr,int *valptr)
436{
437 int ret = -EINVAL;
438 unsigned int cnt;
439
440 *maskptr = 0;
441 *valptr = 0;
442
443 cnt = 0;
444 while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++;
445 len -= cnt; ptr += cnt;
446 cnt = 0;
447 while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) ||
448 (ptr[len-(cnt+1)] >= 127))) cnt++;
449 len -= cnt;
450
451 if (!len) return -EINVAL;
452
453 LOCK_TAKE(cptr->hdw->big_lock); do {
454 if (cptr->info->type == pvr2_ctl_int) {
455 ret = parse_token(ptr,len,valptr,0,0);
456 if ((ret == 0) &&
457 ((*valptr < cptr->info->def.type_int.min_value) ||
458 (*valptr > cptr->info->def.type_int.max_value))) {
459 ret = -EINVAL;
460 }
461 if (maskptr) *maskptr = ~0;
462 } else if (cptr->info->type == pvr2_ctl_enum) {
463 ret = parse_token(
464 ptr,len,valptr,
465 cptr->info->def.type_enum.value_names,
466 cptr->info->def.type_enum.count);
467 if ((ret == 0) &&
468 ((*valptr < 0) ||
469 (*valptr >= cptr->info->def.type_enum.count))) {
470 ret = -EINVAL;
471 }
472 if (maskptr) *maskptr = ~0;
473 } else if (cptr->info->type == pvr2_ctl_bitmask) {
474 ret = parse_tlist(
475 ptr,len,maskptr,valptr,
476 cptr->info->def.type_bitmask.bit_names,
477 cptr->info->def.type_bitmask.valid_bits);
478 }
479 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
480 return ret;
481}
482
483
484/* Convert a given mask/val to a symbolic value */
485int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
486 int mask,int val,
487 char *buf,unsigned int maxlen,
488 unsigned int *len)
489{
490 int ret = -EINVAL;
491
492 *len = 0;
493 if (cptr->info->type == pvr2_ctl_int) {
494 *len = scnprintf(buf,maxlen,"%d",val);
495 ret = 0;
496 } else if (cptr->info->type == pvr2_ctl_enum) {
497 const char **names;
498 names = cptr->info->def.type_enum.value_names;
499 if ((val >= 0) &&
500 (val < cptr->info->def.type_enum.count)) {
501 if (names[val]) {
502 *len = scnprintf(
503 buf,maxlen,"%s",
504 names[val]);
505 } else {
506 *len = 0;
507 }
508 ret = 0;
509 }
510 } else if (cptr->info->type == pvr2_ctl_bitmask) {
511 *len = gen_bitmask_string(
512 val & mask & cptr->info->def.type_bitmask.valid_bits,
513 ~0,!0,
514 cptr->info->def.type_bitmask.bit_names,
515 buf,maxlen);
516 }
517 return ret;
518}
519
520
521/* Convert a given mask/val to a symbolic value */
522int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr,
523 int mask,int val,
524 char *buf,unsigned int maxlen,
525 unsigned int *len)
526{
527 int ret;
528 LOCK_TAKE(cptr->hdw->big_lock); do {
529 ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val,
530 buf,maxlen,len);
531 } while(0); LOCK_GIVE(cptr->hdw->big_lock);
532 return ret;
533}
534
535
536/*
537 Stuff for Emacs to see, in order to encourage consistent editing style:
538 *** Local Variables: ***
539 *** mode: c ***
540 *** fill-column: 75 ***
541 *** tab-width: 8 ***
542 *** c-basic-offset: 8 ***
543 *** End: ***
544 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
new file mode 100644
index 000000000000..9d74151a37da
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
@@ -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#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};
31
32
33/* Set the given control. */
34int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val);
35
36/* Set/clear specific bits of the given control. */
37int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *,int mask,int val);
38
39/* Get the current value of the given control. */
40int pvr2_ctrl_get_value(struct pvr2_ctrl *,int *valptr);
41
42/* Retrieve control's type */
43enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *);
44
45/* Retrieve control's maximum value (int type) */
46int pvr2_ctrl_get_max(struct pvr2_ctrl *);
47
48/* Retrieve control's minimum value (int type) */
49int pvr2_ctrl_get_min(struct pvr2_ctrl *);
50
51/* Retrieve control's default value (any type) */
52int pvr2_ctrl_get_def(struct pvr2_ctrl *);
53
54/* Retrieve control's enumeration count (enum only) */
55int pvr2_ctrl_get_cnt(struct pvr2_ctrl *);
56
57/* Retrieve control's valid mask bits (bit mask only) */
58int pvr2_ctrl_get_mask(struct pvr2_ctrl *);
59
60/* Retrieve the control's name */
61const char *pvr2_ctrl_get_name(struct pvr2_ctrl *);
62
63/* Retrieve the control's desc */
64const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *);
65
66/* Retrieve a control enumeration or bit mask value */
67int pvr2_ctrl_get_valname(struct pvr2_ctrl *,int,char *,unsigned int,
68 unsigned int *);
69
70/* Return true if control is writable */
71int pvr2_ctrl_is_writable(struct pvr2_ctrl *);
72
73/* Return true if control has custom symbolic representation */
74int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *);
75
76/* Convert a given mask/val to a custom symbolic value */
77int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *,
78 int mask,int val,
79 char *buf,unsigned int maxlen,
80 unsigned int *len);
81
82/* Convert a symbolic value to a mask/value pair */
83int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *,
84 const char *buf,unsigned int len,
85 int *maskptr,int *valptr);
86
87/* Convert a given mask/val to a symbolic value */
88int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *,
89 int mask,int val,
90 char *buf,unsigned int maxlen,
91 unsigned int *len);
92
93/* Convert a symbolic value to a mask/value pair */
94int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *,
95 const char *buf,unsigned int len,
96 int *maskptr,int *valptr);
97
98/* Convert a given mask/val to a symbolic value - must already be
99 inside of critical region. */
100int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *,
101 int mask,int val,
102 char *buf,unsigned int maxlen,
103 unsigned int *len);
104
105#endif /* __PVRUSB2_CTRL_H */
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-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
new file mode 100644
index 000000000000..47e7f5dbd516
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -0,0 +1,276 @@
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 PVR2_CVAL_SRATE_48:
108 val = 48000;
109 break;
110 case PVR2_CVAL_SRATE_44_1:
111 val = 44100;
112 break;
113 }
114 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
115}
116
117
118static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
119{
120 struct pvr2_hdw *hdw = ctxt->hdw;
121 return hdw->srate_dirty != 0;
122}
123
124
125struct pvr2_v4l_cx2584x_ops {
126 void (*update)(struct pvr2_v4l_cx2584x *);
127 int (*check)(struct pvr2_v4l_cx2584x *);
128};
129
130
131static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
132 { .update = set_input, .check = check_input},
133 { .update = set_audio, .check = check_audio},
134};
135
136
137static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
138{
139 ctxt->client->handler = 0;
140 ctxt->hdw->decoder_ctrl = 0;
141 kfree(ctxt);
142}
143
144
145static int decoder_check(struct pvr2_v4l_cx2584x *ctxt)
146{
147 unsigned long msk;
148 unsigned int idx;
149
150 for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
151 idx++) {
152 msk = 1 << idx;
153 if (ctxt->stale_mask & msk) continue;
154 if (decoder_ops[idx].check(ctxt)) {
155 ctxt->stale_mask |= msk;
156 }
157 }
158 return ctxt->stale_mask != 0;
159}
160
161
162static void decoder_update(struct pvr2_v4l_cx2584x *ctxt)
163{
164 unsigned long msk;
165 unsigned int idx;
166
167 for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
168 idx++) {
169 msk = 1 << idx;
170 if (!(ctxt->stale_mask & msk)) continue;
171 ctxt->stale_mask &= ~msk;
172 decoder_ops[idx].update(ctxt);
173 }
174}
175
176
177static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
178{
179 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
180 pvr2_v4l2_cmd_stream(ctxt->client,fl);
181}
182
183
184static int decoder_detect(struct pvr2_i2c_client *cp)
185{
186 int ret;
187 /* Attempt to query the decoder - let's see if it will answer */
188 struct v4l2_queryctrl qc;
189
190 memset(&qc,0,sizeof(qc));
191
192 qc.id = V4L2_CID_BRIGHTNESS;
193
194 ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
195 return ret == 0; /* Return true if it answered */
196}
197
198
199static int decoder_is_tuned(struct pvr2_v4l_cx2584x *ctxt)
200{
201 struct v4l2_tuner vt;
202 int ret;
203
204 memset(&vt,0,sizeof(vt));
205 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
206 if (ret < 0) return -EINVAL;
207 return vt.signal ? 1 : 0;
208}
209
210
211static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
212 char *buf,unsigned int cnt)
213{
214 return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
215}
216
217
218static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
219{
220 int ret;
221 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0);
222 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
223}
224
225
226const static struct pvr2_i2c_handler_functions hfuncs = {
227 .detach = (void (*)(void *))decoder_detach,
228 .check = (int (*)(void *))decoder_check,
229 .update = (void (*)(void *))decoder_update,
230 .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
231};
232
233
234int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
235 struct pvr2_i2c_client *cp)
236{
237 struct pvr2_v4l_cx2584x *ctxt;
238
239 if (hdw->decoder_ctrl) return 0;
240 if (cp->handler) return 0;
241 if (!decoder_detect(cp)) return 0;
242
243 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
244 if (!ctxt) return 0;
245 memset(ctxt,0,sizeof(*ctxt));
246
247 ctxt->handler.func_data = ctxt;
248 ctxt->handler.func_table = &hfuncs;
249 ctxt->ctrl.ctxt = ctxt;
250 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
251 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
252 ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned;
253 ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
254 ctxt->client = cp;
255 ctxt->hdw = hdw;
256 ctxt->stale_mask = (1 << (sizeof(decoder_ops)/
257 sizeof(decoder_ops[0]))) - 1;
258 hdw->decoder_ctrl = &ctxt->ctrl;
259 cp->handler = &ctxt->handler;
260 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
261 cp->client->addr);
262 return !0;
263}
264
265
266
267
268/*
269 Stuff for Emacs to see, in order to encourage consistent editing style:
270 *** Local Variables: ***
271 *** mode: c ***
272 *** fill-column: 70 ***
273 *** tab-width: 8 ***
274 *** c-basic-offset: 8 ***
275 *** End: ***
276 */
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..0917fe315f3c
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -0,0 +1,499 @@
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 <linux/videodev2.h>
26#include <media/cx2341x.h>
27#include "pvrusb2-util.h"
28#include "pvrusb2-encoder.h"
29#include "pvrusb2-hdw-internal.h"
30#include "pvrusb2-debug.h"
31
32static u32 pvr_tbl_emphasis [] = {
33 [PVR2_CVAL_AUDIOEMPHASIS_NONE] = 0x0 << 12,
34 [PVR2_CVAL_AUDIOEMPHASIS_50_15] = 0x1 << 12,
35 [PVR2_CVAL_AUDIOEMPHASIS_CCITT] = 0x3 << 12,
36};
37
38static u32 pvr_tbl_srate[] = {
39 [PVR2_CVAL_SRATE_48] = 0x01,
40 [PVR2_CVAL_SRATE_44_1] = 0x00,
41};
42
43static u32 pvr_tbl_audiobitrate[] = {
44 [PVR2_CVAL_AUDIOBITRATE_384] = 0xe << 4,
45 [PVR2_CVAL_AUDIOBITRATE_320] = 0xd << 4,
46 [PVR2_CVAL_AUDIOBITRATE_256] = 0xc << 4,
47 [PVR2_CVAL_AUDIOBITRATE_224] = 0xb << 4,
48 [PVR2_CVAL_AUDIOBITRATE_192] = 0xa << 4,
49 [PVR2_CVAL_AUDIOBITRATE_160] = 0x9 << 4,
50 [PVR2_CVAL_AUDIOBITRATE_128] = 0x8 << 4,
51 [PVR2_CVAL_AUDIOBITRATE_112] = 0x7 << 4,
52 [PVR2_CVAL_AUDIOBITRATE_96] = 0x6 << 4,
53 [PVR2_CVAL_AUDIOBITRATE_80] = 0x5 << 4,
54 [PVR2_CVAL_AUDIOBITRATE_64] = 0x4 << 4,
55 [PVR2_CVAL_AUDIOBITRATE_56] = 0x3 << 4,
56 [PVR2_CVAL_AUDIOBITRATE_48] = 0x2 << 4,
57 [PVR2_CVAL_AUDIOBITRATE_32] = 0x1 << 4,
58 [PVR2_CVAL_AUDIOBITRATE_VBR] = 0x0 << 4,
59};
60
61
62/* Firmware mailbox flags - definitions found from ivtv */
63#define IVTV_MBOX_FIRMWARE_DONE 0x00000004
64#define IVTV_MBOX_DRIVER_DONE 0x00000002
65#define IVTV_MBOX_DRIVER_BUSY 0x00000001
66
67
68static int pvr2_write_encoder_words(struct pvr2_hdw *hdw,
69 const u32 *data, unsigned int dlen)
70{
71 unsigned int idx;
72 int ret;
73 unsigned int offs = 0;
74 unsigned int chunkCnt;
75
76 /*
77
78 Format: First byte must be 0x01. Remaining 32 bit words are
79 spread out into chunks of 7 bytes each, little-endian ordered,
80 offset at zero within each 2 blank bytes following and a
81 single byte that is 0x44 plus the offset of the word. Repeat
82 request for additional words, with offset adjusted
83 accordingly.
84
85 */
86 while (dlen) {
87 chunkCnt = 8;
88 if (chunkCnt > dlen) chunkCnt = dlen;
89 memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
90 hdw->cmd_buffer[0] = 0x01;
91 for (idx = 0; idx < chunkCnt; idx++) {
92 hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs;
93 PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7),
94 data[idx]);
95 }
96 ret = pvr2_send_request(hdw,
97 hdw->cmd_buffer,1+(chunkCnt*7),
98 0,0);
99 if (ret) return ret;
100 data += chunkCnt;
101 dlen -= chunkCnt;
102 offs += chunkCnt;
103 }
104
105 return 0;
106}
107
108
109static int pvr2_read_encoder_words(struct pvr2_hdw *hdw,int statusFl,
110 u32 *data, unsigned int dlen)
111{
112 unsigned int idx;
113 int ret;
114 unsigned int offs = 0;
115 unsigned int chunkCnt;
116
117 /*
118
119 Format: First byte must be 0x02 (status check) or 0x28 (read
120 back block of 32 bit words). Next 6 bytes must be zero,
121 followed by a single byte of 0x44+offset for portion to be
122 read. Returned data is packed set of 32 bits words that were
123 read.
124
125 */
126
127 while (dlen) {
128 chunkCnt = 16;
129 if (chunkCnt > dlen) chunkCnt = dlen;
130 memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
131 hdw->cmd_buffer[0] = statusFl ? 0x02 : 0x28;
132 hdw->cmd_buffer[7] = 0x44 + offs;
133 ret = pvr2_send_request(hdw,
134 hdw->cmd_buffer,8,
135 hdw->cmd_buffer,chunkCnt * 4);
136 if (ret) return ret;
137
138 for (idx = 0; idx < chunkCnt; idx++) {
139 data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4);
140 }
141 data += chunkCnt;
142 dlen -= chunkCnt;
143 offs += chunkCnt;
144 }
145
146 return 0;
147}
148
149
150static int pvr2_write_encoder_vcmd (struct pvr2_hdw *hdw, u8 cmd,
151 int args, ...)
152{
153 unsigned int poll_count;
154 int ret = 0;
155 va_list vl;
156 unsigned int idx;
157 u32 wrData[16];
158 u32 rdData[32];
159
160 /*
161
162 The encoder seems to speak entirely using blocks 32 bit words.
163 In ivtv driver terms, this is a mailbox which we populate with
164 data and watch what the hardware does with it. The first word
165 is a set of flags used to control the transaction, the second
166 word is the command to execute, the third byte is zero (ivtv
167 driver suggests that this is some kind of return value), and
168 the fourth byte is a specified timeout (windows driver always
169 uses 0x00060000 except for one case when it is zero). All
170 successive words are the argument words for the command.
171
172 First, write out the entire set of words, with the first word
173 being zero.
174
175 Next, write out just the first word again, but set it to
176 IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which
177 probably means "go").
178
179 Next, read back 16 words as status. Check the first word,
180 which should have IVTV_MBOX_FIRMWARE_DONE set. If however
181 that bit is not set, then the command isn't done so repeat the
182 read.
183
184 Next, read back 32 words and compare with the original
185 arugments. Hopefully they will match.
186
187 Finally, write out just the first word again, but set it to
188 0x0 this time (which probably means "idle").
189
190 */
191
192
193 LOCK_TAKE(hdw->ctl_lock); do {
194
195 wrData[0] = 0;
196 wrData[1] = cmd;
197 wrData[2] = 0;
198 wrData[3] = 0x00060000;
199 va_start(vl, args);
200 for (idx = 0; idx < args; idx++) {
201 wrData[idx+4] = va_arg(vl, u32);
202 }
203 va_end(vl);
204 args += 4;
205 while (args < sizeof(wrData)/sizeof(wrData[0])) {
206 wrData[args++] = 0;
207 }
208
209 ret = pvr2_write_encoder_words(hdw,wrData,args);
210 if (ret) break;
211 wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY;
212 ret = pvr2_write_encoder_words(hdw,wrData,1);
213 if (ret) break;
214 poll_count = 0;
215 while (1) {
216 if (poll_count < 10000000) poll_count++;
217 ret = pvr2_read_encoder_words(hdw,!0,rdData,1);
218 if (ret) break;
219 if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) {
220 break;
221 }
222 if (poll_count == 100) {
223 pvr2_trace(
224 PVR2_TRACE_ERROR_LEGS,
225 "***WARNING*** device's encoder"
226 " appears to be stuck"
227 " (status=0%08x)",rdData[0]);
228 pvr2_trace(
229 PVR2_TRACE_ERROR_LEGS,
230 "Encoder command: 0x%02x",cmd);
231 for (idx = 4; idx < args; idx++) {
232 pvr2_trace(
233 PVR2_TRACE_ERROR_LEGS,
234 "Encoder arg%d: 0x%08x",
235 idx-3,wrData[idx]);
236 }
237 pvr2_trace(
238 PVR2_TRACE_ERROR_LEGS,
239 "Giving up waiting."
240 " It is likely that"
241 " this is a bad idea...");
242 ret = -EBUSY;
243 break;
244 }
245 }
246 if (ret) break;
247 wrData[0] = 0x7;
248 ret = pvr2_read_encoder_words(hdw,0,rdData,16);
249 if (ret) break;
250 for (idx = 0; idx < args; idx++) {
251 if (rdData[idx] != wrData[idx]) {
252 pvr2_trace(
253 PVR2_TRACE_DEBUG,
254 "pvr2_encoder idx %02x mismatch exp:"
255 " %08x got: %08x",
256 idx,wrData[idx],rdData[idx]);
257 }
258 }
259
260 wrData[0] = 0x0;
261 ret = pvr2_write_encoder_words(hdw,wrData,1);
262 if (ret) break;
263
264 } while(0); LOCK_GIVE(hdw->ctl_lock);
265
266 return ret;
267}
268
269int pvr2_encoder_configure(struct pvr2_hdw *hdw)
270{
271 int ret = 0, audio, i;
272 v4l2_std_id vd_std = hdw->std_mask_cur;
273 int height = hdw->res_ver_val;
274 int width = hdw->res_hor_val;
275 int height_full = !hdw->interlace_val;
276
277 int is_30fps, is_ntsc;
278
279 if (vd_std & V4L2_STD_NTSC) {
280 is_ntsc=1;
281 is_30fps=1;
282 } else if (vd_std & V4L2_STD_PAL_M) {
283 is_ntsc=0;
284 is_30fps=1;
285 } else {
286 is_ntsc=0;
287 is_30fps=0;
288 }
289
290 pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure");
291
292 /* set stream output port. Some notes here: The ivtv-derived
293 encoder documentation says that this command only gets a
294 single argument. However the Windows driver for the model
295 29xxx series hardware has been sending 0x01 as a second
296 argument, while the Windows driver for the model 24xxx
297 series hardware has been sending 0x02 as a second argument.
298 Confusing matters further are the observations that 0x01
299 for that second argument simply won't work on the 24xxx
300 hardware, while 0x02 will work on the 29xxx - except that
301 when we use 0x02 then xawtv breaks due to a loss of
302 synchronization with the mpeg packet headers. While xawtv
303 should be fixed to let it resync better (I did try to
304 contact Gerd about this but he has not answered), it has
305 also been determined that sending 0x00 as this mystery
306 second argument seems to work on both hardware models AND
307 xawtv works again. So we're going to send 0x00. */
308 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_OUTPUT_PORT, 2,
309 0x01, 0x00);
310
311 /* set the Program Index Information. We want I,P,B frames (max 400) */
312 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_PGM_INDEX_INFO, 2,
313 0x07, 0x0190);
314
315 /* NOTE : windows driver sends these */
316 /* Mike Isely <isely@pobox.com> 7-Mar-2006 The windows driver
317 sends the following commands but if we do the same then
318 many apps are no longer able to read the video stream.
319 Leaving these out seems to do no harm at all, so they're
320 commented out for that reason. */
321#ifdef notdef
322 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0);
323 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3,1,0,0);
324 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0);
325 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0);
326 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0);
327 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0);
328#endif
329
330 /* Strange compared to ivtv data. */
331 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
332 0xf0, 0xf0);
333
334 /* setup firmware to notify us about some events (don't know why...) */
335 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4,
336 0, 0, 0x10000000, 0xffffffff);
337
338 /* set fps to 25 or 30 (1 or 0)*/
339 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_FRAME_RATE, 1,
340 is_30fps ? 0 : 1);
341
342 /* set encoding resolution */
343 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_FRAME_SIZE, 2,
344 (height_full ? height : (height / 2)),
345 width);
346 /* set encoding aspect ratio to 4:3 */
347 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_ASPECT_RATIO, 1,
348 0x02);
349
350 /* VBI */
351
352 if (hdw->config == pvr2_config_vbi) {
353 int lines = 2 * (is_30fps ? 12 : 18);
354 int size = (4*((lines*1443+3)/4)) / lines;
355 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_VBI_CONFIG, 7,
356 0xbd05, 1, 4,
357 0x25256262, 0x387f7f7f,
358 lines , size);
359// 0x25256262, 0x13135454, lines , size);
360 /* select vbi lines */
361#define line_used(l) (is_30fps ? (l >= 10 && l <= 21) : (l >= 6 && l <= 23))
362 for (i = 2 ; i <= 24 ; i++){
363 ret |= pvr2_write_encoder_vcmd(
364 hdw,CX2341X_ENC_SET_VBI_LINE, 5,
365 i-1,line_used(i), 0, 0, 0);
366 ret |= pvr2_write_encoder_vcmd(
367 hdw,CX2341X_ENC_SET_VBI_LINE, 5,
368 (i-1) | (1 << 31),
369 line_used(i), 0, 0, 0);
370 }
371 } else {
372 ret |= pvr2_write_encoder_vcmd(
373 hdw,CX2341X_ENC_SET_VBI_LINE, 5,
374 0xffffffff,0,0,0,0);
375 }
376
377 /* set stream type, depending on resolution. */
378 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_STREAM_TYPE, 1,
379 height_full ? 0x0a : 0x0b);
380 /* set video bitrate */
381 ret |= pvr2_write_encoder_vcmd(
382 hdw, CX2341X_ENC_SET_BIT_RATE, 3,
383 (hdw->vbr_val ? 1 : 0),
384 hdw->videobitrate_val,
385 hdw->videopeak_val / 400);
386 /* setup GOP structure (GOP size = 0f or 0c, 3-1 = 2 B-frames) */
387 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
388 is_30fps ? 0x0f : 0x0c, 0x03);
389
390 /* enable 3:2 pulldown */
391 ret |= pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_SET_3_2_PULLDOWN,1,0);
392
393 /* set GOP open/close property (open) */
394 ret |= pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_SET_GOP_CLOSURE,1,0);
395
396 /* set audio stream properties 0x40b9? 0100 0000 1011 1001 */
397 audio = (pvr_tbl_audiobitrate[hdw->audiobitrate_val] |
398 pvr_tbl_srate[hdw->srate_val] |
399 hdw->audiolayer_val << 2 |
400 (hdw->audiocrc_val ? 1 << 14 : 0) |
401 pvr_tbl_emphasis[hdw->audioemphasis_val]);
402
403 ret |= pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_SET_AUDIO_PROPERTIES,1,
404 audio);
405
406 /* set dynamic noise reduction filter to manual, Horiz/Vert */
407 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
408 0, 0x03);
409
410 /* dynamic noise reduction filter param */
411 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2
412 , 0, 0);
413
414 /* dynamic noise reduction median filter */
415 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_CORING_LEVELS, 4,
416 0, 0xff, 0, 0xff);
417
418 /* spacial prefiler parameter */
419 ret |= pvr2_write_encoder_vcmd(hdw,
420 CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
421 0x01, 0x01);
422
423 /* initialize video input */
424 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_INITIALIZE_INPUT, 0);
425
426 if (!ret) {
427 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
428 }
429
430 return ret;
431}
432
433int pvr2_encoder_start(struct pvr2_hdw *hdw)
434{
435 int status;
436
437 /* unmask some interrupts */
438 pvr2_write_register(hdw, 0x0048, 0xbfffffff);
439
440 /* change some GPIO data */
441 pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000481);
442 pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000);
443
444 if (hdw->config == pvr2_config_vbi) {
445 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
446 0x01,0x14);
447 } else if (hdw->config == pvr2_config_mpeg) {
448 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
449 0,0x13);
450 } else {
451 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
452 0,0x13);
453 }
454 if (!status) {
455 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
456 }
457 return status;
458}
459
460int pvr2_encoder_stop(struct pvr2_hdw *hdw)
461{
462 int status;
463
464 /* mask all interrupts */
465 pvr2_write_register(hdw, 0x0048, 0xffffffff);
466
467 if (hdw->config == pvr2_config_vbi) {
468 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
469 0x01,0x01,0x14);
470 } else if (hdw->config == pvr2_config_mpeg) {
471 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
472 0x01,0,0x13);
473 } else {
474 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
475 0x01,0,0x13);
476 }
477
478 /* change some GPIO data */
479 /* Note: Bit d7 of dir appears to control the LED. So we shut it
480 off here. */
481 pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401);
482 pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000);
483
484 if (!status) {
485 hdw->subsys_enabled_mask &= ~(1<<PVR2_SUBSYS_B_ENC_RUN);
486 }
487 return status;
488}
489
490
491/*
492 Stuff for Emacs to see, in order to encourage consistent editing style:
493 *** Local Variables: ***
494 *** mode: c ***
495 *** fill-column: 70 ***
496 *** tab-width: 8 ***
497 *** c-basic-offset: 8 ***
498 *** End: ***
499 */
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..217bbe5d5c80
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -0,0 +1,371 @@
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
43/* Legal values for the SRATE state variable */
44#define PVR2_CVAL_SRATE_48 0
45#define PVR2_CVAL_SRATE_44_1 1
46
47/* Legal values for the AUDIOBITRATE state variable */
48#define PVR2_CVAL_AUDIOBITRATE_384 0
49#define PVR2_CVAL_AUDIOBITRATE_320 1
50#define PVR2_CVAL_AUDIOBITRATE_256 2
51#define PVR2_CVAL_AUDIOBITRATE_224 3
52#define PVR2_CVAL_AUDIOBITRATE_192 4
53#define PVR2_CVAL_AUDIOBITRATE_160 5
54#define PVR2_CVAL_AUDIOBITRATE_128 6
55#define PVR2_CVAL_AUDIOBITRATE_112 7
56#define PVR2_CVAL_AUDIOBITRATE_96 8
57#define PVR2_CVAL_AUDIOBITRATE_80 9
58#define PVR2_CVAL_AUDIOBITRATE_64 10
59#define PVR2_CVAL_AUDIOBITRATE_56 11
60#define PVR2_CVAL_AUDIOBITRATE_48 12
61#define PVR2_CVAL_AUDIOBITRATE_32 13
62#define PVR2_CVAL_AUDIOBITRATE_VBR 14
63
64/* Legal values for the AUDIOEMPHASIS state variable */
65#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0
66#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1
67#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2
68
69/* Legal values for PVR2_CID_HSM */
70#define PVR2_CVAL_HSM_FAIL 0
71#define PVR2_CVAL_HSM_FULL 1
72#define PVR2_CVAL_HSM_HIGH 2
73
74#define PVR2_VID_ENDPOINT 0x84
75#define PVR2_UNK_ENDPOINT 0x86 /* maybe raw yuv ? */
76#define PVR2_VBI_ENDPOINT 0x88
77
78#define PVR2_CTL_BUFFSIZE 64
79
80#define FREQTABLE_SIZE 500
81
82#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0)
83#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0)
84
85struct pvr2_decoder;
86
87typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *);
88typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *);
89typedef int (*pvr2_ctlf_get_value)(struct pvr2_ctrl *,int *);
90typedef int (*pvr2_ctlf_set_value)(struct pvr2_ctrl *,int msk,int val);
91typedef int (*pvr2_ctlf_val_to_sym)(struct pvr2_ctrl *,int msk,int val,
92 char *,unsigned int,unsigned int *);
93typedef int (*pvr2_ctlf_sym_to_val)(struct pvr2_ctrl *,
94 const char *,unsigned int,
95 int *mskp,int *valp);
96
97/* This structure describes a specific control. A table of these is set up
98 in pvrusb2-hdw.c. */
99struct pvr2_ctl_info {
100 /* Control's name suitable for use as an identifier */
101 const char *name;
102
103 /* Short description of control */
104 const char *desc;
105
106 /* Control's implementation */
107 pvr2_ctlf_get_value get_value; /* Get its value */
108 pvr2_ctlf_set_value set_value; /* Set its value */
109 pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */
110 pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */
111 pvr2_ctlf_is_dirty is_dirty; /* Return true if dirty */
112 pvr2_ctlf_clear_dirty clear_dirty; /* Clear dirty state */
113
114 /* Control's type (int, enum, bitmask) */
115 enum pvr2_ctl_type type;
116
117 /* Associated V4L control ID, if any */
118 int v4l_id;
119
120 /* Associated driver internal ID, if any */
121 int internal_id;
122
123 /* Don't implicitly initialize this control's value */
124 int skip_init;
125
126 /* Starting value for this control */
127 int default_value;
128
129 /* Type-specific control information */
130 union {
131 struct { /* Integer control */
132 long min_value; /* lower limit */
133 long max_value; /* upper limit */
134 } type_int;
135 struct { /* enumerated control */
136 unsigned int count; /* enum value count */
137 const char **value_names; /* symbol names */
138 } type_enum;
139 struct { /* bitmask control */
140 unsigned int valid_bits; /* bits in use */
141 const char **bit_names; /* symbol name/bit */
142 } type_bitmask;
143 } def;
144};
145
146
147struct pvr2_ctrl {
148 const struct pvr2_ctl_info *info;
149 struct pvr2_hdw *hdw;
150};
151
152
153struct pvr2_audio_stat {
154 void *ctxt;
155 void (*detach)(void *);
156 int (*status)(void *);
157};
158
159struct pvr2_decoder_ctrl {
160 void *ctxt;
161 void (*detach)(void *);
162 void (*enable)(void *,int);
163 int (*tuned)(void *);
164 void (*force_reset)(void *);
165};
166
167#define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */
168#define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */
169#define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */
170#define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */
171
172#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\
173 PVR2_I2C_PEND_CLIENT |\
174 PVR2_I2C_PEND_REFRESH |\
175 PVR2_I2C_PEND_STALE)
176
177/* Disposition of firmware1 loading situation */
178#define FW1_STATE_UNKNOWN 0
179#define FW1_STATE_MISSING 1
180#define FW1_STATE_FAILED 2
181#define FW1_STATE_RELOAD 3
182#define FW1_STATE_OK 4
183
184/* Known major hardware variants, keyed from device ID */
185#define PVR2_HDW_TYPE_29XXX 0
186#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
187#define PVR2_HDW_TYPE_24XXX 1
188#endif
189
190typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16);
191#define PVR2_I2C_FUNC_CNT 128
192
193/* This structure contains all state data directly needed to
194 manipulate the hardware (as opposed to complying with a kernel
195 interface) */
196struct pvr2_hdw {
197 /* Underlying USB device handle */
198 struct usb_device *usb_dev;
199 struct usb_interface *usb_intf;
200
201 /* Device type, one of PVR2_HDW_TYPE_xxxxx */
202 unsigned int hdw_type;
203
204 /* Video spigot */
205 struct pvr2_stream *vid_stream;
206
207 /* Mutex for all hardware state control */
208 struct mutex big_lock_mutex;
209 int big_lock_held; /* For debugging */
210
211 void (*poll_trigger_func)(void *);
212 void *poll_trigger_data;
213
214 char name[32];
215
216 /* I2C stuff */
217 struct i2c_adapter i2c_adap;
218 struct i2c_algorithm i2c_algo;
219 pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
220 int i2c_cx25840_hack_state;
221 int i2c_linked;
222 unsigned int i2c_pend_types; /* Which types of update are needed */
223 unsigned long i2c_pend_mask; /* Change bits we need to scan */
224 unsigned long i2c_stale_mask; /* Pending broadcast change bits */
225 unsigned long i2c_active_mask; /* All change bits currently in use */
226 struct list_head i2c_clients;
227 struct mutex i2c_list_lock;
228
229 /* Frequency table */
230 unsigned int freqTable[FREQTABLE_SIZE];
231 unsigned int freqProgSlot;
232 unsigned int freqSlot;
233
234 /* Stuff for handling low level control interaction with device */
235 struct mutex ctl_lock_mutex;
236 int ctl_lock_held; /* For debugging */
237 struct urb *ctl_write_urb;
238 struct urb *ctl_read_urb;
239 unsigned char *ctl_write_buffer;
240 unsigned char *ctl_read_buffer;
241 volatile int ctl_write_pend_flag;
242 volatile int ctl_read_pend_flag;
243 volatile int ctl_timeout_flag;
244 struct completion ctl_done;
245 unsigned char cmd_buffer[PVR2_CTL_BUFFSIZE];
246 int cmd_debug_state; // Low level command debugging info
247 unsigned char cmd_debug_code; //
248 unsigned int cmd_debug_write_len; //
249 unsigned int cmd_debug_read_len; //
250
251 int flag_ok; // device in known good state
252 int flag_disconnected; // flag_ok == 0 due to disconnect
253 int flag_init_ok; // true if structure is fully initialized
254 int flag_streaming_enabled; // true if streaming should be on
255 int fw1_state; // current situation with fw1
256
257 int flag_decoder_is_tuned;
258
259 struct pvr2_decoder_ctrl *decoder_ctrl;
260
261 // CPU firmware info (used to help find / save firmware data)
262 char *fw_buffer;
263 unsigned int fw_size;
264
265 // Which subsystem pieces have been enabled / configured
266 unsigned long subsys_enabled_mask;
267
268 // Which subsystems are manipulated to enable streaming
269 unsigned long subsys_stream_mask;
270
271 // True if there is a request to trigger logging of state in each
272 // module.
273 int log_requested;
274
275 /* Tuner / frequency control stuff */
276 unsigned int tuner_type;
277 int tuner_updated;
278 unsigned int freqVal;
279 int freqDirty;
280
281 /* Video standard handling */
282 v4l2_std_id std_mask_eeprom; // Hardware supported selections
283 v4l2_std_id std_mask_avail; // Which standards we may select from
284 v4l2_std_id std_mask_cur; // Currently selected standard(s)
285 unsigned int std_enum_cnt; // # of enumerated standards
286 int std_enum_cur; // selected standard enumeration value
287 int std_dirty; // True if std_mask_cur has changed
288 struct pvr2_ctl_info std_info_enum;
289 struct pvr2_ctl_info std_info_avail;
290 struct pvr2_ctl_info std_info_cur;
291 struct v4l2_standard *std_defs;
292 const char **std_enum_names;
293
294 // Generated string names, one per actual V4L2 standard
295 const char *std_mask_ptrs[32];
296 char std_mask_names[32][10];
297
298 int unit_number; /* ID for driver instance */
299 unsigned long serial_number; /* ID for hardware itself */
300
301 /* Minor number used by v4l logic (yes, this is a hack, as there should
302 be no v4l junk here). Probably a better way to do this. */
303 int v4l_minor_number;
304
305 /* Location of eeprom or a negative number if none */
306 int eeprom_addr;
307
308 enum pvr2_config config;
309
310 /* Information about what audio signal we're hearing */
311 int flag_stereo;
312 int flag_bilingual;
313 struct pvr2_audio_stat *audio_stat;
314
315 /* Control state */
316#define VCREATE_DATA(lab) int lab##_val; int lab##_dirty
317 VCREATE_DATA(brightness);
318 VCREATE_DATA(contrast);
319 VCREATE_DATA(saturation);
320 VCREATE_DATA(hue);
321 VCREATE_DATA(volume);
322 VCREATE_DATA(balance);
323 VCREATE_DATA(bass);
324 VCREATE_DATA(treble);
325 VCREATE_DATA(mute);
326 VCREATE_DATA(srate);
327 VCREATE_DATA(audiobitrate);
328 VCREATE_DATA(audiocrc);
329 VCREATE_DATA(audioemphasis);
330 VCREATE_DATA(vbr);
331 VCREATE_DATA(videobitrate);
332 VCREATE_DATA(videopeak);
333 VCREATE_DATA(input);
334 VCREATE_DATA(audiomode);
335 VCREATE_DATA(res_hor);
336 VCREATE_DATA(res_ver);
337 VCREATE_DATA(interlace);
338 VCREATE_DATA(audiolayer);
339#undef VCREATE_DATA
340
341 struct pvr2_ctrl *controls;
342};
343
344int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
345
346unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *);
347
348void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
349 unsigned long msk,unsigned long val);
350void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
351 unsigned long msk,
352 unsigned long val);
353
354void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
355void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
356
357int pvr2_i2c_basic_op(struct pvr2_hdw *,u8 i2c_addr,
358 u8 *wdata,u16 wlen,
359 u8 *rdata,u16 rlen);
360
361#endif /* __PVRUSB2_HDW_INTERNAL_H */
362
363/*
364 Stuff for Emacs to see, in order to encourage consistent editing style:
365 *** Local Variables: ***
366 *** mode: c ***
367 *** fill-column: 75 ***
368 *** tab-width: 8 ***
369 *** c-basic-offset: 8 ***
370 *** End: ***
371 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
new file mode 100644
index 000000000000..ae2038b939d7
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -0,0 +1,2949 @@
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 <asm/semaphore.h>
27#include <linux/videodev2.h>
28#include <media/cx2341x.h>
29#include "pvrusb2.h"
30#include "pvrusb2-std.h"
31#include "pvrusb2-util.h"
32#include "pvrusb2-hdw.h"
33#include "pvrusb2-i2c-core.h"
34#include "pvrusb2-tuner.h"
35#include "pvrusb2-eeprom.h"
36#include "pvrusb2-hdw-internal.h"
37#include "pvrusb2-encoder.h"
38#include "pvrusb2-debug.h"
39
40struct usb_device_id pvr2_device_table[] = {
41 [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
42#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
43 [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
44#endif
45 { }
46};
47
48MODULE_DEVICE_TABLE(usb, pvr2_device_table);
49
50static const char *pvr2_device_names[] = {
51 [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
52#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
53 [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
54#endif
55};
56
57struct pvr2_string_table {
58 const char **lst;
59 unsigned int cnt;
60};
61
62#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
63// Names of other client modules to request for 24xxx model hardware
64static const char *pvr2_client_24xxx[] = {
65 "cx25840",
66 "tuner",
67 "tda9887",
68 "wm8775",
69};
70#endif
71
72// Names of other client modules to request for 29xxx model hardware
73static const char *pvr2_client_29xxx[] = {
74 "msp3400",
75 "saa7115",
76 "tuner",
77 "tda9887",
78};
79
80static struct pvr2_string_table pvr2_client_lists[] = {
81 [PVR2_HDW_TYPE_29XXX] = {
82 pvr2_client_29xxx,
83 sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]),
84 },
85#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
86 [PVR2_HDW_TYPE_24XXX] = {
87 pvr2_client_24xxx,
88 sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]),
89 },
90#endif
91};
92
93static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0};
94DECLARE_MUTEX(pvr2_unit_sem);
95
96static int ctlchg = 0;
97static int initusbreset = 1;
98static int procreload = 0;
99static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
100static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
101static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
102static int init_pause_msec = 0;
103
104module_param(ctlchg, int, S_IRUGO|S_IWUSR);
105MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
106module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
107MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
108module_param(initusbreset, int, S_IRUGO|S_IWUSR);
109MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
110module_param(procreload, int, S_IRUGO|S_IWUSR);
111MODULE_PARM_DESC(procreload,
112 "Attempt init failure recovery with firmware reload");
113module_param_array(tuner, int, NULL, 0444);
114MODULE_PARM_DESC(tuner,"specify installed tuner type");
115module_param_array(video_std, int, NULL, 0444);
116MODULE_PARM_DESC(video_std,"specify initial video standard");
117module_param_array(tolerance, int, NULL, 0444);
118MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
119
120#define PVR2_CTL_WRITE_ENDPOINT 0x01
121#define PVR2_CTL_READ_ENDPOINT 0x81
122
123#define PVR2_GPIO_IN 0x9008
124#define PVR2_GPIO_OUT 0x900c
125#define PVR2_GPIO_DIR 0x9020
126
127#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
128
129#define PVR2_FIRMWARE_ENDPOINT 0x02
130
131/* size of a firmware chunk */
132#define FIRMWARE_CHUNK_SIZE 0x2000
133
134static const char *control_values_srate[] = {
135 [PVR2_CVAL_SRATE_48] = "48KHz",
136 [PVR2_CVAL_SRATE_44_1] = "44.1KHz",
137};
138
139
140static const char *control_values_audiobitrate[] = {
141 [PVR2_CVAL_AUDIOBITRATE_384] = "384kb/s",
142 [PVR2_CVAL_AUDIOBITRATE_320] = "320kb/s",
143 [PVR2_CVAL_AUDIOBITRATE_256] = "256kb/s",
144 [PVR2_CVAL_AUDIOBITRATE_224] = "224kb/s",
145 [PVR2_CVAL_AUDIOBITRATE_192] = "192kb/s",
146 [PVR2_CVAL_AUDIOBITRATE_160] = "160kb/s",
147 [PVR2_CVAL_AUDIOBITRATE_128] = "128kb/s",
148 [PVR2_CVAL_AUDIOBITRATE_112] = "112kb/s",
149 [PVR2_CVAL_AUDIOBITRATE_96] = "96kb/s",
150 [PVR2_CVAL_AUDIOBITRATE_80] = "80kb/s",
151 [PVR2_CVAL_AUDIOBITRATE_64] = "64kb/s",
152 [PVR2_CVAL_AUDIOBITRATE_56] = "56kb/s",
153 [PVR2_CVAL_AUDIOBITRATE_48] = "48kb/s",
154 [PVR2_CVAL_AUDIOBITRATE_32] = "32kb/s",
155 [PVR2_CVAL_AUDIOBITRATE_VBR] = "VBR",
156};
157
158
159static const char *control_values_audioemphasis[] = {
160 [PVR2_CVAL_AUDIOEMPHASIS_NONE] = "None",
161 [PVR2_CVAL_AUDIOEMPHASIS_50_15] = "50/15us",
162 [PVR2_CVAL_AUDIOEMPHASIS_CCITT] = "CCITT J.17",
163};
164
165
166static const char *control_values_input[] = {
167 [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
168 [PVR2_CVAL_INPUT_RADIO] = "radio",
169 [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
170 [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
171};
172
173
174static const char *control_values_audiomode[] = {
175 [V4L2_TUNER_MODE_MONO] = "Mono",
176 [V4L2_TUNER_MODE_STEREO] = "Stereo",
177 [V4L2_TUNER_MODE_LANG1] = "Lang1",
178 [V4L2_TUNER_MODE_LANG2] = "Lang2",
179 [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
180};
181
182
183static const char *control_values_hsm[] = {
184 [PVR2_CVAL_HSM_FAIL] = "Fail",
185 [PVR2_CVAL_HSM_HIGH] = "High",
186 [PVR2_CVAL_HSM_FULL] = "Full",
187};
188
189
190static const char *control_values_subsystem[] = {
191 [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware",
192 [PVR2_SUBSYS_B_ENC_CFG] = "enc_config",
193 [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run",
194 [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run",
195 [PVR2_SUBSYS_B_ENC_RUN] = "enc_run",
196};
197
198
199static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
200{
201 struct pvr2_hdw *hdw = cptr->hdw;
202 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
203 *vp = hdw->freqTable[hdw->freqProgSlot-1];
204 } else {
205 *vp = 0;
206 }
207 return 0;
208}
209
210static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
211{
212 struct pvr2_hdw *hdw = cptr->hdw;
213 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
214 hdw->freqTable[hdw->freqProgSlot-1] = v;
215 }
216 return 0;
217}
218
219static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
220{
221 *vp = cptr->hdw->freqProgSlot;
222 return 0;
223}
224
225static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
226{
227 struct pvr2_hdw *hdw = cptr->hdw;
228 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
229 hdw->freqProgSlot = v;
230 }
231 return 0;
232}
233
234static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
235{
236 *vp = cptr->hdw->freqSlot;
237 return 0;
238}
239
240static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v)
241{
242 unsigned freq = 0;
243 struct pvr2_hdw *hdw = cptr->hdw;
244 hdw->freqSlot = v;
245 if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) {
246 freq = hdw->freqTable[hdw->freqSlot-1];
247 }
248 if (freq && (freq != hdw->freqVal)) {
249 hdw->freqVal = freq;
250 hdw->freqDirty = !0;
251 }
252 return 0;
253}
254
255static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
256{
257 *vp = cptr->hdw->freqVal;
258 return 0;
259}
260
261static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
262{
263 return cptr->hdw->freqDirty != 0;
264}
265
266static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
267{
268 cptr->hdw->freqDirty = 0;
269}
270
271static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
272{
273 struct pvr2_hdw *hdw = cptr->hdw;
274 hdw->freqVal = v;
275 hdw->freqDirty = !0;
276 hdw->freqSlot = 0;
277 return 0;
278}
279
280static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
281{
282 *vp = cptr->hdw->flag_streaming_enabled;
283 return 0;
284}
285
286static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
287{
288 int result = pvr2_hdw_is_hsm(cptr->hdw);
289 *vp = PVR2_CVAL_HSM_FULL;
290 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
291 if (result) *vp = PVR2_CVAL_HSM_HIGH;
292 return 0;
293}
294
295static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
296{
297 *vp = cptr->hdw->std_mask_avail;
298 return 0;
299}
300
301static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
302{
303 struct pvr2_hdw *hdw = cptr->hdw;
304 v4l2_std_id ns;
305 ns = hdw->std_mask_avail;
306 ns = (ns & ~m) | (v & m);
307 if (ns == hdw->std_mask_avail) return 0;
308 hdw->std_mask_avail = ns;
309 pvr2_hdw_internal_set_std_avail(hdw);
310 pvr2_hdw_internal_find_stdenum(hdw);
311 return 0;
312}
313
314static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
315 char *bufPtr,unsigned int bufSize,
316 unsigned int *len)
317{
318 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
319 return 0;
320}
321
322static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
323 const char *bufPtr,unsigned int bufSize,
324 int *mskp,int *valp)
325{
326 int ret;
327 v4l2_std_id id;
328 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
329 if (ret < 0) return ret;
330 if (mskp) *mskp = id;
331 if (valp) *valp = id;
332 return 0;
333}
334
335static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
336{
337 *vp = cptr->hdw->std_mask_cur;
338 return 0;
339}
340
341static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
342{
343 struct pvr2_hdw *hdw = cptr->hdw;
344 v4l2_std_id ns;
345 ns = hdw->std_mask_cur;
346 ns = (ns & ~m) | (v & m);
347 if (ns == hdw->std_mask_cur) return 0;
348 hdw->std_mask_cur = ns;
349 hdw->std_dirty = !0;
350 pvr2_hdw_internal_find_stdenum(hdw);
351 return 0;
352}
353
354static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
355{
356 return cptr->hdw->std_dirty != 0;
357}
358
359static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
360{
361 cptr->hdw->std_dirty = 0;
362}
363
364static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
365{
366 *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
367 PVR2_SIGNAL_OK) ? 1 : 0);
368 return 0;
369}
370
371static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
372{
373 *vp = cptr->hdw->subsys_enabled_mask;
374 return 0;
375}
376
377static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
378{
379 pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
380 return 0;
381}
382
383static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
384{
385 *vp = cptr->hdw->subsys_stream_mask;
386 return 0;
387}
388
389static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
390{
391 pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
392 return 0;
393}
394
395static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
396{
397 struct pvr2_hdw *hdw = cptr->hdw;
398 if (v < 0) return -EINVAL;
399 if (v > hdw->std_enum_cnt) return -EINVAL;
400 hdw->std_enum_cur = v;
401 if (!v) return 0;
402 v--;
403 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
404 hdw->std_mask_cur = hdw->std_defs[v].id;
405 hdw->std_dirty = !0;
406 return 0;
407}
408
409
410static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
411{
412 *vp = cptr->hdw->std_enum_cur;
413 return 0;
414}
415
416
417static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
418{
419 return cptr->hdw->std_dirty != 0;
420}
421
422
423static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
424{
425 cptr->hdw->std_dirty = 0;
426}
427
428
429#define DEFINT(vmin,vmax) \
430 .type = pvr2_ctl_int, \
431 .def.type_int.min_value = vmin, \
432 .def.type_int.max_value = vmax
433
434#define DEFENUM(tab) \
435 .type = pvr2_ctl_enum, \
436 .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \
437 .def.type_enum.value_names = tab
438
439#define DEFMASK(msk,tab) \
440 .type = pvr2_ctl_bitmask, \
441 .def.type_bitmask.valid_bits = msk, \
442 .def.type_bitmask.bit_names = tab
443
444#define DEFREF(vname) \
445 .set_value = ctrl_set_##vname, \
446 .get_value = ctrl_get_##vname, \
447 .is_dirty = ctrl_isdirty_##vname, \
448 .clear_dirty = ctrl_cleardirty_##vname
449
450
451#define VCREATE_FUNCS(vname) \
452static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
453{*vp = cptr->hdw->vname##_val; return 0;} \
454static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
455{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
456static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
457{return cptr->hdw->vname##_dirty != 0;} \
458static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
459{cptr->hdw->vname##_dirty = 0;}
460
461VCREATE_FUNCS(brightness)
462VCREATE_FUNCS(contrast)
463VCREATE_FUNCS(saturation)
464VCREATE_FUNCS(hue)
465VCREATE_FUNCS(volume)
466VCREATE_FUNCS(balance)
467VCREATE_FUNCS(bass)
468VCREATE_FUNCS(treble)
469VCREATE_FUNCS(mute)
470VCREATE_FUNCS(srate)
471VCREATE_FUNCS(audiobitrate)
472VCREATE_FUNCS(audiocrc)
473VCREATE_FUNCS(audioemphasis)
474VCREATE_FUNCS(vbr)
475VCREATE_FUNCS(videobitrate)
476VCREATE_FUNCS(videopeak)
477VCREATE_FUNCS(input)
478VCREATE_FUNCS(audiomode)
479VCREATE_FUNCS(res_hor)
480VCREATE_FUNCS(res_ver)
481VCREATE_FUNCS(interlace)
482VCREATE_FUNCS(audiolayer)
483
484#define MIN_FREQ 55250000L
485#define MAX_FREQ 850000000L
486
487/* Table definition of all controls which can be manipulated */
488static const struct pvr2_ctl_info control_defs[] = {
489 {
490 .v4l_id = V4L2_CID_BRIGHTNESS,
491 .desc = "Brightness",
492 .name = "brightness",
493 .default_value = 128,
494 DEFREF(brightness),
495 DEFINT(0,255),
496 },{
497 .v4l_id = V4L2_CID_CONTRAST,
498 .desc = "Contrast",
499 .name = "contrast",
500 .default_value = 68,
501 DEFREF(contrast),
502 DEFINT(0,127),
503 },{
504 .v4l_id = V4L2_CID_SATURATION,
505 .desc = "Saturation",
506 .name = "saturation",
507 .default_value = 64,
508 DEFREF(saturation),
509 DEFINT(0,127),
510 },{
511 .v4l_id = V4L2_CID_HUE,
512 .desc = "Hue",
513 .name = "hue",
514 .default_value = 0,
515 DEFREF(hue),
516 DEFINT(-128,127),
517 },{
518 .v4l_id = V4L2_CID_AUDIO_VOLUME,
519 .desc = "Volume",
520 .name = "volume",
521 .default_value = 65535,
522 DEFREF(volume),
523 DEFINT(0,65535),
524 },{
525 .v4l_id = V4L2_CID_AUDIO_BALANCE,
526 .desc = "Balance",
527 .name = "balance",
528 .default_value = 0,
529 DEFREF(balance),
530 DEFINT(-32768,32767),
531 },{
532 .v4l_id = V4L2_CID_AUDIO_BASS,
533 .desc = "Bass",
534 .name = "bass",
535 .default_value = 0,
536 DEFREF(bass),
537 DEFINT(-32768,32767),
538 },{
539 .v4l_id = V4L2_CID_AUDIO_TREBLE,
540 .desc = "Treble",
541 .name = "treble",
542 .default_value = 0,
543 DEFREF(treble),
544 DEFINT(-32768,32767),
545 },{
546 .v4l_id = V4L2_CID_AUDIO_MUTE,
547 .desc = "Mute",
548 .name = "mute",
549 .default_value = 0,
550 DEFREF(mute),
551 DEFINT(0,1),
552 },{
553 .v4l_id = V4L2_CID_PVR_SRATE,
554 .desc = "Sample rate",
555 .name = "srate",
556 .default_value = PVR2_CVAL_SRATE_48,
557 DEFREF(srate),
558 DEFENUM(control_values_srate),
559 },{
560 .v4l_id = V4L2_CID_PVR_AUDIOBITRATE,
561 .desc = "Audio Bitrate",
562 .name = "audio_bitrate",
563 .default_value = PVR2_CVAL_AUDIOBITRATE_224,
564 DEFREF(audiobitrate),
565 DEFENUM(control_values_audiobitrate),
566 },{
567 .v4l_id = V4L2_CID_PVR_AUDIOCRC,
568 .desc = "Audio CRC",
569 .name = "audio_crc",
570 .default_value = 1,
571 DEFREF(audiocrc),
572 DEFINT(0,1),
573 },{
574 .desc = "Audio Layer",
575 .name = "audio_layer",
576 .default_value = 2,
577 DEFREF(audiolayer),
578 DEFINT(0,3),
579 },{
580 .v4l_id = V4L2_CID_PVR_AUDIOEMPHASIS,
581 .desc = "Audio Emphasis",
582 .name = "audio_emphasis",
583 .default_value = PVR2_CVAL_AUDIOEMPHASIS_NONE,
584 DEFREF(audioemphasis),
585 DEFENUM(control_values_audioemphasis),
586 },{
587 .desc = "Interlace mode",
588 .name = "interlace",
589 .internal_id = PVR2_CID_INTERLACE,
590 .default_value = 0,
591 DEFREF(interlace),
592 DEFINT(0,1),
593 },{
594 .v4l_id = V4L2_CID_PVR_VBR,
595 .desc = "Variable video bitrate",
596 .name = "vbr",
597 .default_value = 0,
598 DEFREF(vbr),
599 DEFINT(0,1),
600 },{
601 .v4l_id = V4L2_CID_PVR_VIDEOBITRATE,
602 .desc = "Average video bitrate",
603 .name = "video_average_bitrate",
604 .default_value = 6000000,
605 DEFREF(videobitrate),
606 DEFINT(500000,20000000),
607 },{
608 .v4l_id = V4L2_CID_PVR_VIDEOPEAK,
609 .desc = "Peak video bitrate",
610 .name = "video_peak_bitrate",
611 .default_value = 6000000,
612 DEFREF(videopeak),
613 DEFINT(500000,20000000),
614 },{
615 .desc = "Video Source",
616 .name = "input",
617 .internal_id = PVR2_CID_INPUT,
618 .default_value = PVR2_CVAL_INPUT_TV,
619 DEFREF(input),
620 DEFENUM(control_values_input),
621 },{
622 .desc = "Audio Mode",
623 .name = "audio_mode",
624 .internal_id = PVR2_CID_AUDIOMODE,
625 .default_value = V4L2_TUNER_MODE_STEREO,
626 DEFREF(audiomode),
627 DEFENUM(control_values_audiomode),
628 },{
629 .desc = "Tuner Frequency (Hz)",
630 .name = "frequency",
631 .internal_id = PVR2_CID_FREQUENCY,
632 .default_value = 175250000L,
633 .set_value = ctrl_freq_set,
634 .get_value = ctrl_freq_get,
635 .is_dirty = ctrl_freq_is_dirty,
636 .clear_dirty = ctrl_freq_clear_dirty,
637 DEFINT(MIN_FREQ,MAX_FREQ),
638 },{
639 .desc = "Channel",
640 .name = "channel",
641 .set_value = ctrl_channel_set,
642 .get_value = ctrl_channel_get,
643 DEFINT(0,FREQTABLE_SIZE),
644 },{
645 .desc = "Channel Program Frequency",
646 .name = "freq_table_value",
647 .set_value = ctrl_channelfreq_set,
648 .get_value = ctrl_channelfreq_get,
649 DEFINT(MIN_FREQ,MAX_FREQ),
650 },{
651 .desc = "Channel Program ID",
652 .name = "freq_table_channel",
653 .set_value = ctrl_channelprog_set,
654 .get_value = ctrl_channelprog_get,
655 DEFINT(0,FREQTABLE_SIZE),
656 },{
657 .desc = "Horizontal capture resolution",
658 .name = "resolution_hor",
659 .internal_id = PVR2_CID_HRES,
660 .default_value = 720,
661 DEFREF(res_hor),
662 DEFINT(320,720),
663 },{
664 .desc = "Vertical capture resolution",
665 .name = "resolution_ver",
666 .internal_id = PVR2_CID_VRES,
667 .default_value = 480,
668 DEFREF(res_ver),
669 DEFINT(200,625),
670 },{
671 .desc = "Streaming Enabled",
672 .name = "streaming_enabled",
673 .get_value = ctrl_streamingenabled_get,
674 DEFINT(0,1),
675 },{
676 .desc = "USB Speed",
677 .name = "usb_speed",
678 .get_value = ctrl_hsm_get,
679 DEFENUM(control_values_hsm),
680 },{
681 .desc = "Signal Present",
682 .name = "signal_present",
683 .get_value = ctrl_signal_get,
684 DEFINT(0,1),
685 },{
686 .desc = "Video Standards Available Mask",
687 .name = "video_standard_mask_available",
688 .internal_id = PVR2_CID_STDAVAIL,
689 .skip_init = !0,
690 .get_value = ctrl_stdavail_get,
691 .set_value = ctrl_stdavail_set,
692 .val_to_sym = ctrl_std_val_to_sym,
693 .sym_to_val = ctrl_std_sym_to_val,
694 .type = pvr2_ctl_bitmask,
695 },{
696 .desc = "Video Standards In Use Mask",
697 .name = "video_standard_mask_active",
698 .internal_id = PVR2_CID_STDCUR,
699 .skip_init = !0,
700 .get_value = ctrl_stdcur_get,
701 .set_value = ctrl_stdcur_set,
702 .is_dirty = ctrl_stdcur_is_dirty,
703 .clear_dirty = ctrl_stdcur_clear_dirty,
704 .val_to_sym = ctrl_std_val_to_sym,
705 .sym_to_val = ctrl_std_sym_to_val,
706 .type = pvr2_ctl_bitmask,
707 },{
708 .desc = "Subsystem enabled mask",
709 .name = "debug_subsys_mask",
710 .skip_init = !0,
711 .get_value = ctrl_subsys_get,
712 .set_value = ctrl_subsys_set,
713 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
714 },{
715 .desc = "Subsystem stream mask",
716 .name = "debug_subsys_stream_mask",
717 .skip_init = !0,
718 .get_value = ctrl_subsys_stream_get,
719 .set_value = ctrl_subsys_stream_set,
720 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
721 },{
722 .desc = "Video Standard Name",
723 .name = "video_standard",
724 .internal_id = PVR2_CID_STDENUM,
725 .skip_init = !0,
726 .get_value = ctrl_stdenumcur_get,
727 .set_value = ctrl_stdenumcur_set,
728 .is_dirty = ctrl_stdenumcur_is_dirty,
729 .clear_dirty = ctrl_stdenumcur_clear_dirty,
730 .type = pvr2_ctl_enum,
731 }
732};
733
734#define CTRL_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
735
736
737const char *pvr2_config_get_name(enum pvr2_config cfg)
738{
739 switch (cfg) {
740 case pvr2_config_empty: return "empty";
741 case pvr2_config_mpeg: return "mpeg";
742 case pvr2_config_vbi: return "vbi";
743 case pvr2_config_radio: return "radio";
744 }
745 return "<unknown>";
746}
747
748
749struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
750{
751 return hdw->usb_dev;
752}
753
754
755unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
756{
757 return hdw->serial_number;
758}
759
760
761struct pvr2_hdw *pvr2_hdw_find(int unit_number)
762{
763 if (unit_number < 0) return 0;
764 if (unit_number >= PVR_NUM) return 0;
765 return unit_pointers[unit_number];
766}
767
768
769int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
770{
771 return hdw->unit_number;
772}
773
774
775/* Attempt to locate one of the given set of files. Messages are logged
776 appropriate to what has been found. The return value will be 0 or
777 greater on success (it will be the index of the file name found) and
778 fw_entry will be filled in. Otherwise a negative error is returned on
779 failure. If the return value is -ENOENT then no viable firmware file
780 could be located. */
781static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
782 const struct firmware **fw_entry,
783 const char *fwtypename,
784 unsigned int fwcount,
785 const char *fwnames[])
786{
787 unsigned int idx;
788 int ret = -EINVAL;
789 for (idx = 0; idx < fwcount; idx++) {
790 ret = request_firmware(fw_entry,
791 fwnames[idx],
792 &hdw->usb_dev->dev);
793 if (!ret) {
794 trace_firmware("Located %s firmware: %s;"
795 " uploading...",
796 fwtypename,
797 fwnames[idx]);
798 return idx;
799 }
800 if (ret == -ENOENT) continue;
801 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
802 "request_firmware fatal error with code=%d",ret);
803 return ret;
804 }
805 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
806 "***WARNING***"
807 " Device %s firmware"
808 " seems to be missing.",
809 fwtypename);
810 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
811 "Did you install the pvrusb2 firmware files"
812 " in their proper location?");
813 if (fwcount == 1) {
814 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
815 "request_firmware unable to locate %s file %s",
816 fwtypename,fwnames[0]);
817 } else {
818 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
819 "request_firmware unable to locate"
820 " one of the following %s files:",
821 fwtypename);
822 for (idx = 0; idx < fwcount; idx++) {
823 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
824 "request_firmware: Failed to find %s",
825 fwnames[idx]);
826 }
827 }
828 return ret;
829}
830
831
832/*
833 * pvr2_upload_firmware1().
834 *
835 * Send the 8051 firmware to the device. After the upload, arrange for
836 * device to re-enumerate.
837 *
838 * NOTE : the pointer to the firmware data given by request_firmware()
839 * is not suitable for an usb transaction.
840 *
841 */
842int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
843{
844 const struct firmware *fw_entry = 0;
845 void *fw_ptr;
846 unsigned int pipe;
847 int ret;
848 u16 address;
849 static const char *fw_files_29xxx[] = {
850 "v4l-pvrusb2-29xxx-01.fw",
851 };
852#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
853 static const char *fw_files_24xxx[] = {
854 "v4l-pvrusb2-24xxx-01.fw",
855 };
856#endif
857 static const struct pvr2_string_table fw_file_defs[] = {
858 [PVR2_HDW_TYPE_29XXX] = {
859 fw_files_29xxx,
860 sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
861 },
862#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
863 [PVR2_HDW_TYPE_24XXX] = {
864 fw_files_24xxx,
865 sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]),
866 },
867#endif
868 };
869 hdw->fw1_state = FW1_STATE_FAILED; // default result
870
871 trace_firmware("pvr2_upload_firmware1");
872
873 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
874 fw_file_defs[hdw->hdw_type].cnt,
875 fw_file_defs[hdw->hdw_type].lst);
876 if (ret < 0) {
877 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
878 return ret;
879 }
880
881 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
882 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
883
884 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
885
886 if (fw_entry->size != 0x2000){
887 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
888 release_firmware(fw_entry);
889 return -ENOMEM;
890 }
891
892 fw_ptr = kmalloc(0x800, GFP_KERNEL);
893 if (fw_ptr == NULL){
894 release_firmware(fw_entry);
895 return -ENOMEM;
896 }
897
898 /* We have to hold the CPU during firmware upload. */
899 pvr2_hdw_cpureset_assert(hdw,1);
900
901 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
902 chunk. */
903
904 ret = 0;
905 for(address = 0; address < fw_entry->size; address += 0x800) {
906 memcpy(fw_ptr, fw_entry->data + address, 0x800);
907 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
908 0, fw_ptr, 0x800, HZ);
909 }
910
911 trace_firmware("Upload done, releasing device's CPU");
912
913 /* Now release the CPU. It will disconnect and reconnect later. */
914 pvr2_hdw_cpureset_assert(hdw,0);
915
916 kfree(fw_ptr);
917 release_firmware(fw_entry);
918
919 trace_firmware("Upload done (%d bytes sent)",ret);
920
921 /* We should have written 8192 bytes */
922 if (ret == 8192) {
923 hdw->fw1_state = FW1_STATE_RELOAD;
924 return 0;
925 }
926
927 return -EIO;
928}
929
930
931/*
932 * pvr2_upload_firmware2()
933 *
934 * This uploads encoder firmware on endpoint 2.
935 *
936 */
937
938int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
939{
940 const struct firmware *fw_entry = 0;
941 void *fw_ptr;
942 unsigned int pipe, fw_len, fw_done;
943 int actual_length;
944 int ret = 0;
945 int fwidx;
946 static const char *fw_files[] = {
947 CX2341X_FIRM_ENC_FILENAME,
948 };
949
950 trace_firmware("pvr2_upload_firmware2");
951
952 ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
953 sizeof(fw_files)/sizeof(fw_files[0]),
954 fw_files);
955 if (ret < 0) return ret;
956 fwidx = ret;
957 ret = 0;
958
959 /* First prepare firmware loading */
960 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
961 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
962 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
963 ret |= pvr2_hdw_cmd_deep_reset(hdw);
964 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
965 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
966 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
967 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
968 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
969 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
970 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
971 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
972 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
973 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
974 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
975 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
976 ret |= pvr2_write_u8(hdw, 0x52, 0);
977 ret |= pvr2_write_u16(hdw, 0x0600, 0);
978
979 if (ret) {
980 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
981 "firmware2 upload prep failed, ret=%d",ret);
982 release_firmware(fw_entry);
983 return ret;
984 }
985
986 /* Now send firmware */
987
988 fw_len = fw_entry->size;
989
990 if (fw_len % FIRMWARE_CHUNK_SIZE) {
991 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
992 "size of %s firmware"
993 " must be a multiple of 8192B",
994 fw_files[fwidx]);
995 release_firmware(fw_entry);
996 return -1;
997 }
998
999 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1000 if (fw_ptr == NULL){
1001 release_firmware(fw_entry);
1002 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1003 "failed to allocate memory for firmware2 upload");
1004 return -ENOMEM;
1005 }
1006
1007 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1008
1009 for (fw_done = 0 ; (fw_done < fw_len) && !ret ;
1010 fw_done += FIRMWARE_CHUNK_SIZE ) {
1011 int i;
1012 memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE);
1013 /* Usbsnoop log shows that we must swap bytes... */
1014 for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++)
1015 ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]);
1016
1017 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,
1018 FIRMWARE_CHUNK_SIZE,
1019 &actual_length, HZ);
1020 ret |= (actual_length != FIRMWARE_CHUNK_SIZE);
1021 }
1022
1023 trace_firmware("upload of %s : %i / %i ",
1024 fw_files[fwidx],fw_done,fw_len);
1025
1026 kfree(fw_ptr);
1027 release_firmware(fw_entry);
1028
1029 if (ret) {
1030 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1031 "firmware2 upload transfer failure");
1032 return ret;
1033 }
1034
1035 /* Finish upload */
1036
1037 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1038 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
1039 ret |= pvr2_write_u16(hdw, 0x0600, 0);
1040
1041 if (ret) {
1042 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1043 "firmware2 upload post-proc failure");
1044 } else {
1045 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
1046 }
1047 return ret;
1048}
1049
1050
1051#define FIRMWARE_RECOVERY_BITS \
1052 ((1<<PVR2_SUBSYS_B_ENC_CFG) | \
1053 (1<<PVR2_SUBSYS_B_ENC_RUN) | \
1054 (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \
1055 (1<<PVR2_SUBSYS_B_USBSTREAM_RUN))
1056
1057/*
1058
1059 This single function is key to pretty much everything. The pvrusb2
1060 device can logically be viewed as a series of subsystems which can be
1061 stopped / started or unconfigured / configured. To get things streaming,
1062 one must configure everything and start everything, but there may be
1063 various reasons over time to deconfigure something or stop something.
1064 This function handles all of this activity. Everything EVERYWHERE that
1065 must affect a subsystem eventually comes here to do the work.
1066
1067 The current state of all subsystems is represented by a single bit mask,
1068 known as subsys_enabled_mask. The bit positions are defined by the
1069 PVR2_SUBSYS_xxxx macros, with one subsystem per bit position. At any
1070 time the set of configured or active subsystems can be queried just by
1071 looking at that mask. To change bits in that mask, this function here
1072 must be called. The "msk" argument indicates which bit positions to
1073 change, and the "val" argument defines the new values for the positions
1074 defined by "msk".
1075
1076 There is a priority ordering of starting / stopping things, and for
1077 multiple requested changes, this function implements that ordering.
1078 (Thus we will act on a request to load encoder firmware before we
1079 configure the encoder.) In addition to priority ordering, there is a
1080 recovery strategy implemented here. If a particular step fails and we
1081 detect that failure, this function will clear the affected subsystem bits
1082 and restart. Thus we have a means for recovering from a dead encoder:
1083 Clear all bits that correspond to subsystems that we need to restart /
1084 reconfigure and start over.
1085
1086*/
1087void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
1088 unsigned long msk,unsigned long val)
1089{
1090 unsigned long nmsk;
1091 unsigned long vmsk;
1092 int ret;
1093 unsigned int tryCount = 0;
1094
1095 if (!hdw->flag_ok) return;
1096
1097 msk &= PVR2_SUBSYS_ALL;
1098
1099 for (;;) {
1100 tryCount++;
1101 vmsk = hdw->subsys_enabled_mask & PVR2_SUBSYS_ALL;
1102 nmsk = (vmsk & ~msk) | (val & msk);
1103 if (!(nmsk ^ vmsk)) break;
1104 if (tryCount > 4) {
1105 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1106 "Too many retries when configuring device;"
1107 " giving up");
1108 pvr2_hdw_render_useless(hdw);
1109 break;
1110 }
1111 if (tryCount > 1) {
1112 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1113 "Retrying device reconfiguration");
1114 }
1115 pvr2_trace(PVR2_TRACE_INIT,
1116 "subsys mask changing 0x%lx:0x%lx"
1117 " from 0x%lx to 0x%lx",
1118 msk,val,hdw->subsys_enabled_mask,nmsk);
1119
1120 vmsk = (nmsk ^ hdw->subsys_enabled_mask) &
1121 hdw->subsys_enabled_mask;
1122 if (vmsk) {
1123 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1124 pvr2_trace(PVR2_TRACE_CTL,
1125 "/*---TRACE_CTL----*/"
1126 " pvr2_encoder_stop");
1127 ret = pvr2_encoder_stop(hdw);
1128 if (ret) {
1129 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1130 "Error recovery initiated");
1131 hdw->subsys_enabled_mask &=
1132 ~FIRMWARE_RECOVERY_BITS;
1133 continue;
1134 }
1135 }
1136 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1137 pvr2_trace(PVR2_TRACE_CTL,
1138 "/*---TRACE_CTL----*/"
1139 " pvr2_hdw_cmd_usbstream(0)");
1140 pvr2_hdw_cmd_usbstream(hdw,0);
1141 }
1142 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1143 pvr2_trace(PVR2_TRACE_CTL,
1144 "/*---TRACE_CTL----*/"
1145 " decoder disable");
1146 if (hdw->decoder_ctrl) {
1147 hdw->decoder_ctrl->enable(
1148 hdw->decoder_ctrl->ctxt,0);
1149 } else {
1150 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1151 "WARNING:"
1152 " No decoder present");
1153 }
1154 hdw->subsys_enabled_mask &=
1155 ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1156 }
1157 if (vmsk & PVR2_SUBSYS_CFG_ALL) {
1158 hdw->subsys_enabled_mask &=
1159 ~(vmsk & PVR2_SUBSYS_CFG_ALL);
1160 }
1161 }
1162 vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk;
1163 if (vmsk) {
1164 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) {
1165 pvr2_trace(PVR2_TRACE_CTL,
1166 "/*---TRACE_CTL----*/"
1167 " pvr2_upload_firmware2");
1168 ret = pvr2_upload_firmware2(hdw);
1169 if (ret) {
1170 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1171 "Failure uploading encoder"
1172 " firmware");
1173 pvr2_hdw_render_useless(hdw);
1174 break;
1175 }
1176 }
1177 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) {
1178 pvr2_trace(PVR2_TRACE_CTL,
1179 "/*---TRACE_CTL----*/"
1180 " pvr2_encoder_configure");
1181 ret = pvr2_encoder_configure(hdw);
1182 if (ret) {
1183 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1184 "Error recovery initiated");
1185 hdw->subsys_enabled_mask &=
1186 ~FIRMWARE_RECOVERY_BITS;
1187 continue;
1188 }
1189 }
1190 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1191 pvr2_trace(PVR2_TRACE_CTL,
1192 "/*---TRACE_CTL----*/"
1193 " decoder enable");
1194 if (hdw->decoder_ctrl) {
1195 hdw->decoder_ctrl->enable(
1196 hdw->decoder_ctrl->ctxt,!0);
1197 } else {
1198 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1199 "WARNING:"
1200 " No decoder present");
1201 }
1202 hdw->subsys_enabled_mask |=
1203 (1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1204 }
1205 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1206 pvr2_trace(PVR2_TRACE_CTL,
1207 "/*---TRACE_CTL----*/"
1208 " pvr2_hdw_cmd_usbstream(1)");
1209 pvr2_hdw_cmd_usbstream(hdw,!0);
1210 }
1211 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1212 pvr2_trace(PVR2_TRACE_CTL,
1213 "/*---TRACE_CTL----*/"
1214 " pvr2_encoder_start");
1215 ret = pvr2_encoder_start(hdw);
1216 if (ret) {
1217 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1218 "Error recovery initiated");
1219 hdw->subsys_enabled_mask &=
1220 ~FIRMWARE_RECOVERY_BITS;
1221 continue;
1222 }
1223 }
1224 }
1225 }
1226}
1227
1228
1229void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
1230 unsigned long msk,unsigned long val)
1231{
1232 LOCK_TAKE(hdw->big_lock); do {
1233 pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val);
1234 } while (0); LOCK_GIVE(hdw->big_lock);
1235}
1236
1237
1238void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk)
1239{
1240 pvr2_hdw_subsys_bit_chg(hdw,msk,msk);
1241}
1242
1243
1244void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk)
1245{
1246 pvr2_hdw_subsys_bit_chg(hdw,msk,0);
1247}
1248
1249
1250unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw)
1251{
1252 return hdw->subsys_enabled_mask;
1253}
1254
1255
1256unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw)
1257{
1258 return hdw->subsys_stream_mask;
1259}
1260
1261
1262void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
1263 unsigned long msk,
1264 unsigned long val)
1265{
1266 unsigned long val2;
1267 msk &= PVR2_SUBSYS_ALL;
1268 val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk));
1269 pvr2_trace(PVR2_TRACE_INIT,
1270 "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx",
1271 msk,val,hdw->subsys_stream_mask,val2);
1272 hdw->subsys_stream_mask = val2;
1273}
1274
1275
1276void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
1277 unsigned long msk,
1278 unsigned long val)
1279{
1280 LOCK_TAKE(hdw->big_lock); do {
1281 pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val);
1282 } while (0); LOCK_GIVE(hdw->big_lock);
1283}
1284
1285
1286int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl)
1287{
1288 if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0;
1289 if (enableFl) {
1290 pvr2_trace(PVR2_TRACE_START_STOP,
1291 "/*--TRACE_STREAM--*/ enable");
1292 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0);
1293 } else {
1294 pvr2_trace(PVR2_TRACE_START_STOP,
1295 "/*--TRACE_STREAM--*/ disable");
1296 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1297 }
1298 if (!hdw->flag_ok) return -EIO;
1299 hdw->flag_streaming_enabled = enableFl != 0;
1300 return 0;
1301}
1302
1303
1304int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1305{
1306 return hdw->flag_streaming_enabled != 0;
1307}
1308
1309
1310int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1311{
1312 int ret;
1313 LOCK_TAKE(hdw->big_lock); do {
1314 ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag);
1315 } while (0); LOCK_GIVE(hdw->big_lock);
1316 return ret;
1317}
1318
1319
1320int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw,
1321 enum pvr2_config config)
1322{
1323 unsigned long sm = hdw->subsys_enabled_mask;
1324 if (!hdw->flag_ok) return -EIO;
1325 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1326 hdw->config = config;
1327 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm);
1328 return 0;
1329}
1330
1331
1332int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1333{
1334 int ret;
1335 if (!hdw->flag_ok) return -EIO;
1336 LOCK_TAKE(hdw->big_lock);
1337 ret = pvr2_hdw_set_stream_type_no_lock(hdw,config);
1338 LOCK_GIVE(hdw->big_lock);
1339 return ret;
1340}
1341
1342
1343static int get_default_tuner_type(struct pvr2_hdw *hdw)
1344{
1345 int unit_number = hdw->unit_number;
1346 int tp = -1;
1347 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1348 tp = tuner[unit_number];
1349 }
1350 if (tp < 0) return -EINVAL;
1351 hdw->tuner_type = tp;
1352 return 0;
1353}
1354
1355
1356static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1357{
1358 int unit_number = hdw->unit_number;
1359 int tp = 0;
1360 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1361 tp = video_std[unit_number];
1362 }
1363 return tp;
1364}
1365
1366
1367static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1368{
1369 int unit_number = hdw->unit_number;
1370 int tp = 0;
1371 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1372 tp = tolerance[unit_number];
1373 }
1374 return tp;
1375}
1376
1377
1378static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1379{
1380 /* Try a harmless request to fetch the eeprom's address over
1381 endpoint 1. See what happens. Only the full FX2 image can
1382 respond to this. If this probe fails then likely the FX2
1383 firmware needs be loaded. */
1384 int result;
1385 LOCK_TAKE(hdw->ctl_lock); do {
1386 hdw->cmd_buffer[0] = 0xeb;
1387 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1388 hdw->cmd_buffer,1,
1389 hdw->cmd_buffer,1);
1390 if (result < 0) break;
1391 } while(0); LOCK_GIVE(hdw->ctl_lock);
1392 if (result) {
1393 pvr2_trace(PVR2_TRACE_INIT,
1394 "Probe of device endpoint 1 result status %d",
1395 result);
1396 } else {
1397 pvr2_trace(PVR2_TRACE_INIT,
1398 "Probe of device endpoint 1 succeeded");
1399 }
1400 return result == 0;
1401}
1402
1403static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1404{
1405 char buf[40];
1406 unsigned int bcnt;
1407 v4l2_std_id std1,std2;
1408
1409 std1 = get_default_standard(hdw);
1410
1411 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
1412 pvr2_trace(PVR2_TRACE_INIT,
1413 "Supported video standard(s) reported by eeprom: %.*s",
1414 bcnt,buf);
1415
1416 hdw->std_mask_avail = hdw->std_mask_eeprom;
1417
1418 std2 = std1 & ~hdw->std_mask_avail;
1419 if (std2) {
1420 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
1421 pvr2_trace(PVR2_TRACE_INIT,
1422 "Expanding supported video standards"
1423 " to include: %.*s",
1424 bcnt,buf);
1425 hdw->std_mask_avail |= std2;
1426 }
1427
1428 pvr2_hdw_internal_set_std_avail(hdw);
1429
1430 if (std1) {
1431 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
1432 pvr2_trace(PVR2_TRACE_INIT,
1433 "Initial video standard forced to %.*s",
1434 bcnt,buf);
1435 hdw->std_mask_cur = std1;
1436 hdw->std_dirty = !0;
1437 pvr2_hdw_internal_find_stdenum(hdw);
1438 return;
1439 }
1440
1441 if (hdw->std_enum_cnt > 1) {
1442 // Autoselect the first listed standard
1443 hdw->std_enum_cur = 1;
1444 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1445 hdw->std_dirty = !0;
1446 pvr2_trace(PVR2_TRACE_INIT,
1447 "Initial video standard auto-selected to %s",
1448 hdw->std_defs[hdw->std_enum_cur-1].name);
1449 return;
1450 }
1451
1452 pvr2_trace(PVR2_TRACE_EEPROM,
1453 "Unable to select a viable initial video standard");
1454}
1455
1456
1457static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1458{
1459 int ret;
1460 unsigned int idx;
1461 struct pvr2_ctrl *cptr;
1462 int reloadFl = 0;
1463 if (!reloadFl) {
1464 reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1465 == 0);
1466 if (reloadFl) {
1467 pvr2_trace(PVR2_TRACE_INIT,
1468 "USB endpoint config looks strange"
1469 "; possibly firmware needs to be loaded");
1470 }
1471 }
1472 if (!reloadFl) {
1473 reloadFl = !pvr2_hdw_check_firmware(hdw);
1474 if (reloadFl) {
1475 pvr2_trace(PVR2_TRACE_INIT,
1476 "Check for FX2 firmware failed"
1477 "; possibly firmware needs to be loaded");
1478 }
1479 }
1480 if (reloadFl) {
1481 if (pvr2_upload_firmware1(hdw) != 0) {
1482 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1483 "Failure uploading firmware1");
1484 }
1485 return;
1486 }
1487 hdw->fw1_state = FW1_STATE_OK;
1488
1489 if (initusbreset) {
1490 pvr2_hdw_device_reset(hdw);
1491 }
1492 if (!pvr2_hdw_dev_ok(hdw)) return;
1493
1494 for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) {
1495 request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]);
1496 }
1497
1498 pvr2_hdw_cmd_powerup(hdw);
1499 if (!pvr2_hdw_dev_ok(hdw)) return;
1500
1501 if (pvr2_upload_firmware2(hdw)){
1502 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
1503 pvr2_hdw_render_useless(hdw);
1504 return;
1505 }
1506
1507 // This step MUST happen after the earlier powerup step.
1508 pvr2_i2c_core_init(hdw);
1509 if (!pvr2_hdw_dev_ok(hdw)) return;
1510
1511 for (idx = 0; idx < CTRL_COUNT; idx++) {
1512 cptr = hdw->controls + idx;
1513 if (cptr->info->skip_init) continue;
1514 if (!cptr->info->set_value) continue;
1515 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1516 }
1517
1518 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1519 // thread-safe against the normal pvr2_send_request() mechanism.
1520 // (We should make it thread safe).
1521
1522 ret = pvr2_hdw_get_eeprom_addr(hdw);
1523 if (!pvr2_hdw_dev_ok(hdw)) return;
1524 if (ret < 0) {
1525 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1526 "Unable to determine location of eeprom, skipping");
1527 } else {
1528 hdw->eeprom_addr = ret;
1529 pvr2_eeprom_analyze(hdw);
1530 if (!pvr2_hdw_dev_ok(hdw)) return;
1531 }
1532
1533 pvr2_hdw_setup_std(hdw);
1534
1535 if (!get_default_tuner_type(hdw)) {
1536 pvr2_trace(PVR2_TRACE_INIT,
1537 "pvr2_hdw_setup: Tuner type overridden to %d",
1538 hdw->tuner_type);
1539 }
1540
1541 hdw->tuner_updated = !0;
1542 pvr2_i2c_core_check_stale(hdw);
1543 hdw->tuner_updated = 0;
1544
1545 if (!pvr2_hdw_dev_ok(hdw)) return;
1546
1547 pvr2_hdw_commit_ctl_internal(hdw);
1548 if (!pvr2_hdw_dev_ok(hdw)) return;
1549
1550 hdw->vid_stream = pvr2_stream_create();
1551 if (!pvr2_hdw_dev_ok(hdw)) return;
1552 pvr2_trace(PVR2_TRACE_INIT,
1553 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1554 if (hdw->vid_stream) {
1555 idx = get_default_error_tolerance(hdw);
1556 if (idx) {
1557 pvr2_trace(PVR2_TRACE_INIT,
1558 "pvr2_hdw_setup: video stream %p"
1559 " setting tolerance %u",
1560 hdw->vid_stream,idx);
1561 }
1562 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1563 PVR2_VID_ENDPOINT,idx);
1564 }
1565
1566 if (!pvr2_hdw_dev_ok(hdw)) return;
1567
1568 /* Make sure everything is up to date */
1569 pvr2_i2c_core_sync(hdw);
1570
1571 if (!pvr2_hdw_dev_ok(hdw)) return;
1572
1573 hdw->flag_init_ok = !0;
1574}
1575
1576
1577int pvr2_hdw_setup(struct pvr2_hdw *hdw)
1578{
1579 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
1580 LOCK_TAKE(hdw->big_lock); do {
1581 pvr2_hdw_setup_low(hdw);
1582 pvr2_trace(PVR2_TRACE_INIT,
1583 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
1584 hdw,hdw->flag_ok,hdw->flag_init_ok);
1585 if (pvr2_hdw_dev_ok(hdw)) {
1586 if (pvr2_hdw_init_ok(hdw)) {
1587 pvr2_trace(
1588 PVR2_TRACE_INFO,
1589 "Device initialization"
1590 " completed successfully.");
1591 break;
1592 }
1593 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1594 pvr2_trace(
1595 PVR2_TRACE_INFO,
1596 "Device microcontroller firmware"
1597 " (re)loaded; it should now reset"
1598 " and reconnect.");
1599 break;
1600 }
1601 pvr2_trace(
1602 PVR2_TRACE_ERROR_LEGS,
1603 "Device initialization was not successful.");
1604 if (hdw->fw1_state == FW1_STATE_MISSING) {
1605 pvr2_trace(
1606 PVR2_TRACE_ERROR_LEGS,
1607 "Giving up since device"
1608 " microcontroller firmware"
1609 " appears to be missing.");
1610 break;
1611 }
1612 }
1613 if (procreload) {
1614 pvr2_trace(
1615 PVR2_TRACE_ERROR_LEGS,
1616 "Attempting pvrusb2 recovery by reloading"
1617 " primary firmware.");
1618 pvr2_trace(
1619 PVR2_TRACE_ERROR_LEGS,
1620 "If this works, device should disconnect"
1621 " and reconnect in a sane state.");
1622 hdw->fw1_state = FW1_STATE_UNKNOWN;
1623 pvr2_upload_firmware1(hdw);
1624 } else {
1625 pvr2_trace(
1626 PVR2_TRACE_ERROR_LEGS,
1627 "***WARNING*** pvrusb2 device hardware"
1628 " appears to be jammed"
1629 " and I can't clear it.");
1630 pvr2_trace(
1631 PVR2_TRACE_ERROR_LEGS,
1632 "You might need to power cycle"
1633 " the pvrusb2 device"
1634 " in order to recover.");
1635 }
1636 } while (0); LOCK_GIVE(hdw->big_lock);
1637 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
1638 return hdw->flag_init_ok;
1639}
1640
1641
1642/* Create and return a structure for interacting with the underlying
1643 hardware */
1644struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1645 const struct usb_device_id *devid)
1646{
1647 unsigned int idx,cnt1,cnt2;
1648 struct pvr2_hdw *hdw;
1649 unsigned int hdw_type;
1650 int valid_std_mask;
1651 struct pvr2_ctrl *cptr;
1652 __u8 ifnum;
1653
1654 hdw_type = devid - pvr2_device_table;
1655 if (hdw_type >=
1656 sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) {
1657 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1658 "Bogus device type of %u reported",hdw_type);
1659 return 0;
1660 }
1661
1662 hdw = kmalloc(sizeof(*hdw),GFP_KERNEL);
1663 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
1664 hdw,pvr2_device_names[hdw_type]);
1665 if (!hdw) goto fail;
1666 memset(hdw,0,sizeof(*hdw));
1667
1668 hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * CTRL_COUNT,
1669 GFP_KERNEL);
1670 if (!hdw->controls) goto fail;
1671 memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * CTRL_COUNT);
1672 hdw->hdw_type = hdw_type;
1673
1674 for (idx = 0; idx < 32; idx++) {
1675 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1676 }
1677
1678 for (idx = 0; idx < CTRL_COUNT; idx++) {
1679 cptr = hdw->controls + idx;
1680 cptr->hdw = hdw;
1681 cptr->info = control_defs+idx;
1682 }
1683
1684 // Initialize video standard enum dynamic control
1685 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
1686 if (cptr) {
1687 memcpy(&hdw->std_info_enum,cptr->info,
1688 sizeof(hdw->std_info_enum));
1689 cptr->info = &hdw->std_info_enum;
1690
1691 }
1692 // Initialize control data regarding video standard masks
1693 valid_std_mask = pvr2_std_get_usable();
1694 for (idx = 0; idx < 32; idx++) {
1695 if (!(valid_std_mask & (1 << idx))) continue;
1696 cnt1 = pvr2_std_id_to_str(
1697 hdw->std_mask_names[idx],
1698 sizeof(hdw->std_mask_names[idx])-1,
1699 1 << idx);
1700 hdw->std_mask_names[idx][cnt1] = 0;
1701 }
1702 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
1703 if (cptr) {
1704 memcpy(&hdw->std_info_avail,cptr->info,
1705 sizeof(hdw->std_info_avail));
1706 cptr->info = &hdw->std_info_avail;
1707 hdw->std_info_avail.def.type_bitmask.bit_names =
1708 hdw->std_mask_ptrs;
1709 hdw->std_info_avail.def.type_bitmask.valid_bits =
1710 valid_std_mask;
1711 }
1712 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
1713 if (cptr) {
1714 memcpy(&hdw->std_info_cur,cptr->info,
1715 sizeof(hdw->std_info_cur));
1716 cptr->info = &hdw->std_info_cur;
1717 hdw->std_info_cur.def.type_bitmask.bit_names =
1718 hdw->std_mask_ptrs;
1719 hdw->std_info_avail.def.type_bitmask.valid_bits =
1720 valid_std_mask;
1721 }
1722
1723 hdw->eeprom_addr = -1;
1724 hdw->unit_number = -1;
1725 hdw->v4l_minor_number = -1;
1726 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
1727 if (!hdw->ctl_write_buffer) goto fail;
1728 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
1729 if (!hdw->ctl_read_buffer) goto fail;
1730 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
1731 if (!hdw->ctl_write_urb) goto fail;
1732 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
1733 if (!hdw->ctl_read_urb) goto fail;
1734
1735 down(&pvr2_unit_sem); do {
1736 for (idx = 0; idx < PVR_NUM; idx++) {
1737 if (unit_pointers[idx]) continue;
1738 hdw->unit_number = idx;
1739 unit_pointers[idx] = hdw;
1740 break;
1741 }
1742 } while (0); up(&pvr2_unit_sem);
1743
1744 cnt1 = 0;
1745 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
1746 cnt1 += cnt2;
1747 if (hdw->unit_number >= 0) {
1748 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
1749 ('a' + hdw->unit_number));
1750 cnt1 += cnt2;
1751 }
1752 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
1753 hdw->name[cnt1] = 0;
1754
1755 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
1756 hdw->unit_number,hdw->name);
1757
1758 hdw->tuner_type = -1;
1759 hdw->flag_ok = !0;
1760 /* Initialize the mask of subsystems that we will shut down when we
1761 stop streaming. */
1762 hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
1763 hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
1764
1765 pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
1766 hdw->subsys_stream_mask);
1767
1768 hdw->usb_intf = intf;
1769 hdw->usb_dev = interface_to_usbdev(intf);
1770
1771 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
1772 usb_set_interface(hdw->usb_dev,ifnum,0);
1773
1774 mutex_init(&hdw->ctl_lock_mutex);
1775 mutex_init(&hdw->big_lock_mutex);
1776
1777 return hdw;
1778 fail:
1779 if (hdw) {
1780 if (hdw->ctl_read_urb) usb_free_urb(hdw->ctl_read_urb);
1781 if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb);
1782 if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer);
1783 if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer);
1784 if (hdw->controls) kfree(hdw->controls);
1785 kfree(hdw);
1786 }
1787 return 0;
1788}
1789
1790
1791/* Remove _all_ associations between this driver and the underlying USB
1792 layer. */
1793void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
1794{
1795 if (hdw->flag_disconnected) return;
1796 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
1797 if (hdw->ctl_read_urb) {
1798 usb_kill_urb(hdw->ctl_read_urb);
1799 usb_free_urb(hdw->ctl_read_urb);
1800 hdw->ctl_read_urb = 0;
1801 }
1802 if (hdw->ctl_write_urb) {
1803 usb_kill_urb(hdw->ctl_write_urb);
1804 usb_free_urb(hdw->ctl_write_urb);
1805 hdw->ctl_write_urb = 0;
1806 }
1807 if (hdw->ctl_read_buffer) {
1808 kfree(hdw->ctl_read_buffer);
1809 hdw->ctl_read_buffer = 0;
1810 }
1811 if (hdw->ctl_write_buffer) {
1812 kfree(hdw->ctl_write_buffer);
1813 hdw->ctl_write_buffer = 0;
1814 }
1815 pvr2_hdw_render_useless_unlocked(hdw);
1816 hdw->flag_disconnected = !0;
1817 hdw->usb_dev = 0;
1818 hdw->usb_intf = 0;
1819}
1820
1821
1822/* Destroy hardware interaction structure */
1823void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
1824{
1825 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
1826 if (hdw->fw_buffer) {
1827 kfree(hdw->fw_buffer);
1828 hdw->fw_buffer = 0;
1829 }
1830 if (hdw->vid_stream) {
1831 pvr2_stream_destroy(hdw->vid_stream);
1832 hdw->vid_stream = 0;
1833 }
1834 if (hdw->audio_stat) {
1835 hdw->audio_stat->detach(hdw->audio_stat->ctxt);
1836 }
1837 if (hdw->decoder_ctrl) {
1838 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
1839 }
1840 pvr2_i2c_core_done(hdw);
1841 pvr2_hdw_remove_usb_stuff(hdw);
1842 down(&pvr2_unit_sem); do {
1843 if ((hdw->unit_number >= 0) &&
1844 (hdw->unit_number < PVR_NUM) &&
1845 (unit_pointers[hdw->unit_number] == hdw)) {
1846 unit_pointers[hdw->unit_number] = 0;
1847 }
1848 } while (0); up(&pvr2_unit_sem);
1849 kfree(hdw->controls);
1850 if (hdw->std_defs) kfree(hdw->std_defs);
1851 if (hdw->std_enum_names) kfree(hdw->std_enum_names);
1852 kfree(hdw);
1853}
1854
1855
1856int pvr2_hdw_init_ok(struct pvr2_hdw *hdw)
1857{
1858 return hdw->flag_init_ok;
1859}
1860
1861
1862int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
1863{
1864 return (hdw && hdw->flag_ok);
1865}
1866
1867
1868/* Called when hardware has been unplugged */
1869void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
1870{
1871 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
1872 LOCK_TAKE(hdw->big_lock);
1873 LOCK_TAKE(hdw->ctl_lock);
1874 pvr2_hdw_remove_usb_stuff(hdw);
1875 LOCK_GIVE(hdw->ctl_lock);
1876 LOCK_GIVE(hdw->big_lock);
1877}
1878
1879
1880// Attempt to autoselect an appropriate value for std_enum_cur given
1881// whatever is currently in std_mask_cur
1882void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
1883{
1884 unsigned int idx;
1885 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
1886 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
1887 hdw->std_enum_cur = idx;
1888 return;
1889 }
1890 }
1891 hdw->std_enum_cur = 0;
1892}
1893
1894
1895// Calculate correct set of enumerated standards based on currently known
1896// set of available standards bits.
1897void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
1898{
1899 struct v4l2_standard *newstd;
1900 unsigned int std_cnt;
1901 unsigned int idx;
1902
1903 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
1904
1905 if (hdw->std_defs) {
1906 kfree(hdw->std_defs);
1907 hdw->std_defs = 0;
1908 }
1909 hdw->std_enum_cnt = 0;
1910 if (hdw->std_enum_names) {
1911 kfree(hdw->std_enum_names);
1912 hdw->std_enum_names = 0;
1913 }
1914
1915 if (!std_cnt) {
1916 pvr2_trace(
1917 PVR2_TRACE_ERROR_LEGS,
1918 "WARNING: Failed to identify any viable standards");
1919 }
1920 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
1921 hdw->std_enum_names[0] = "none";
1922 for (idx = 0; idx < std_cnt; idx++) {
1923 hdw->std_enum_names[idx+1] =
1924 newstd[idx].name;
1925 }
1926 // Set up the dynamic control for this standard
1927 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
1928 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
1929 hdw->std_defs = newstd;
1930 hdw->std_enum_cnt = std_cnt+1;
1931 hdw->std_enum_cur = 0;
1932 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
1933}
1934
1935
1936int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
1937 struct v4l2_standard *std,
1938 unsigned int idx)
1939{
1940 int ret = -EINVAL;
1941 if (!idx) return ret;
1942 LOCK_TAKE(hdw->big_lock); do {
1943 if (idx >= hdw->std_enum_cnt) break;
1944 idx--;
1945 memcpy(std,hdw->std_defs+idx,sizeof(*std));
1946 ret = 0;
1947 } while (0); LOCK_GIVE(hdw->big_lock);
1948 return ret;
1949}
1950
1951
1952/* Get the number of defined controls */
1953unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
1954{
1955 return CTRL_COUNT;
1956}
1957
1958
1959/* Retrieve a control handle given its index (0..count-1) */
1960struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
1961 unsigned int idx)
1962{
1963 if (idx >= CTRL_COUNT) return 0;
1964 return hdw->controls + idx;
1965}
1966
1967
1968/* Retrieve a control handle given its index (0..count-1) */
1969struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
1970 unsigned int ctl_id)
1971{
1972 struct pvr2_ctrl *cptr;
1973 unsigned int idx;
1974 int i;
1975
1976 /* This could be made a lot more efficient, but for now... */
1977 for (idx = 0; idx < CTRL_COUNT; idx++) {
1978 cptr = hdw->controls + idx;
1979 i = cptr->info->internal_id;
1980 if (i && (i == ctl_id)) return cptr;
1981 }
1982 return 0;
1983}
1984
1985
1986/* Given an ID, retrieve the control structure associated with it. */
1987struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
1988{
1989 struct pvr2_ctrl *cptr;
1990 unsigned int idx;
1991 int i;
1992
1993 /* This could be made a lot more efficient, but for now... */
1994 for (idx = 0; idx < CTRL_COUNT; idx++) {
1995 cptr = hdw->controls + idx;
1996 i = cptr->info->v4l_id;
1997 if (i && (i == ctl_id)) return cptr;
1998 }
1999 return 0;
2000}
2001
2002
2003static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2004{
2005 switch (tp) {
2006 case pvr2_ctl_int: return "integer";
2007 case pvr2_ctl_enum: return "enum";
2008 case pvr2_ctl_bitmask: return "bitmask";
2009 }
2010 return "";
2011}
2012
2013
2014/* Commit all control changes made up to this point. Subsystems can be
2015 indirectly affected by these changes. For a given set of things being
2016 committed, we'll clear the affected subsystem bits and then once we're
2017 done committing everything we'll make a request to restore the subsystem
2018 state(s) back to their previous value before this function was called.
2019 Thus we can automatically reconfigure affected pieces of the driver as
2020 controls are changed. */
2021int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
2022{
2023 unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
2024 unsigned long stale_subsys_mask = 0;
2025 unsigned int idx;
2026 struct pvr2_ctrl *cptr;
2027 int value;
2028 int commit_flag = 0;
2029 char buf[100];
2030 unsigned int bcnt,ccnt;
2031
2032 for (idx = 0; idx < CTRL_COUNT; idx++) {
2033 cptr = hdw->controls + idx;
2034 if (cptr->info->is_dirty == 0) continue;
2035 if (!cptr->info->is_dirty(cptr)) continue;
2036 if (!commit_flag) {
2037 commit_flag = !0;
2038 }
2039
2040 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2041 cptr->info->name);
2042 value = 0;
2043 cptr->info->get_value(cptr,&value);
2044 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2045 buf+bcnt,
2046 sizeof(buf)-bcnt,&ccnt);
2047 bcnt += ccnt;
2048 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2049 get_ctrl_typename(cptr->info->type));
2050 pvr2_trace(PVR2_TRACE_CTL,
2051 "/*--TRACE_COMMIT--*/ %.*s",
2052 bcnt,buf);
2053 }
2054
2055 if (!commit_flag) {
2056 /* Nothing has changed */
2057 return 0;
2058 }
2059
2060 /* When video standard changes, reset the hres and vres values -
2061 but if the user has pending changes there, then let the changes
2062 take priority. */
2063 if (hdw->std_dirty) {
2064 /* Rewrite the vertical resolution to be appropriate to the
2065 video standard that has been selected. */
2066 int nvres;
2067 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2068 nvres = 480;
2069 } else {
2070 nvres = 576;
2071 }
2072 if (nvres != hdw->res_ver_val) {
2073 hdw->res_ver_val = nvres;
2074 hdw->res_ver_dirty = !0;
2075 }
2076 if (!hdw->interlace_val) {
2077 hdw->interlace_val = 0;
2078 hdw->interlace_dirty = !0;
2079 }
2080 }
2081
2082 if (hdw->std_dirty ||
2083 hdw->res_ver_dirty ||
2084 hdw->res_hor_dirty ||
2085 hdw->interlace_dirty ||
2086 hdw->vbr_dirty ||
2087 hdw->videobitrate_dirty ||
2088 hdw->videopeak_dirty ||
2089 hdw->audiobitrate_dirty ||
2090 hdw->srate_dirty ||
2091 hdw->audiolayer_dirty ||
2092 hdw->audiocrc_dirty ||
2093 hdw->audioemphasis_dirty) {
2094 /* If any of this changes, then the encoder needs to be
2095 reconfigured, and we need to reset the stream. */
2096 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
2097 stale_subsys_mask |= hdw->subsys_stream_mask;
2098 }
2099
2100 /* Scan i2c core at this point - before we clear all the dirty
2101 bits. Various parts of the i2c core will notice dirty bits as
2102 appropriate and arrange to broadcast or directly send updates to
2103 the client drivers in order to keep everything in sync */
2104 pvr2_i2c_core_check_stale(hdw);
2105
2106 for (idx = 0; idx < CTRL_COUNT; idx++) {
2107 cptr = hdw->controls + idx;
2108 if (!cptr->info->clear_dirty) continue;
2109 cptr->info->clear_dirty(cptr);
2110 }
2111
2112 /* Now execute i2c core update */
2113 pvr2_i2c_core_sync(hdw);
2114
2115 pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
2116 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
2117
2118 return 0;
2119}
2120
2121
2122int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2123{
2124 LOCK_TAKE(hdw->big_lock); do {
2125 pvr2_hdw_commit_ctl_internal(hdw);
2126 } while (0); LOCK_GIVE(hdw->big_lock);
2127 return 0;
2128}
2129
2130
2131void pvr2_hdw_poll(struct pvr2_hdw *hdw)
2132{
2133 LOCK_TAKE(hdw->big_lock); do {
2134 pvr2_i2c_core_sync(hdw);
2135 } while (0); LOCK_GIVE(hdw->big_lock);
2136}
2137
2138
2139void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
2140 void (*func)(void *),
2141 void *data)
2142{
2143 LOCK_TAKE(hdw->big_lock); do {
2144 hdw->poll_trigger_func = func;
2145 hdw->poll_trigger_data = data;
2146 } while (0); LOCK_GIVE(hdw->big_lock);
2147}
2148
2149
2150void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
2151{
2152 if (hdw->poll_trigger_func) {
2153 hdw->poll_trigger_func(hdw->poll_trigger_data);
2154 }
2155}
2156
2157
2158void pvr2_hdw_poll_trigger(struct pvr2_hdw *hdw)
2159{
2160 LOCK_TAKE(hdw->big_lock); do {
2161 pvr2_hdw_poll_trigger_unlocked(hdw);
2162 } while (0); LOCK_GIVE(hdw->big_lock);
2163}
2164
2165
2166/* Return name for this driver instance */
2167const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2168{
2169 return hdw->name;
2170}
2171
2172
2173/* Return bit mask indicating signal status */
2174unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
2175{
2176 unsigned int msk = 0;
2177 switch (hdw->input_val) {
2178 case PVR2_CVAL_INPUT_TV:
2179 case PVR2_CVAL_INPUT_RADIO:
2180 if (hdw->decoder_ctrl &&
2181 hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) {
2182 msk |= PVR2_SIGNAL_OK;
2183 if (hdw->audio_stat &&
2184 hdw->audio_stat->status(hdw->audio_stat->ctxt)) {
2185 if (hdw->flag_stereo) {
2186 msk |= PVR2_SIGNAL_STEREO;
2187 }
2188 if (hdw->flag_bilingual) {
2189 msk |= PVR2_SIGNAL_SAP;
2190 }
2191 }
2192 }
2193 break;
2194 default:
2195 msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO;
2196 }
2197 return msk;
2198}
2199
2200
2201int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2202{
2203 int result;
2204 LOCK_TAKE(hdw->ctl_lock); do {
2205 hdw->cmd_buffer[0] = 0x0b;
2206 result = pvr2_send_request(hdw,
2207 hdw->cmd_buffer,1,
2208 hdw->cmd_buffer,1);
2209 if (result < 0) break;
2210 result = (hdw->cmd_buffer[0] != 0);
2211 } while(0); LOCK_GIVE(hdw->ctl_lock);
2212 return result;
2213}
2214
2215
2216/* Return bit mask indicating signal status */
2217unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw)
2218{
2219 unsigned int msk = 0;
2220 LOCK_TAKE(hdw->big_lock); do {
2221 msk = pvr2_hdw_get_signal_status_internal(hdw);
2222 } while (0); LOCK_GIVE(hdw->big_lock);
2223 return msk;
2224}
2225
2226
2227/* Get handle to video output stream */
2228struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2229{
2230 return hp->vid_stream;
2231}
2232
2233
2234void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2235{
2236 LOCK_TAKE(hdw->big_lock); do {
2237 hdw->log_requested = !0;
2238 pvr2_i2c_core_check_stale(hdw);
2239 hdw->log_requested = 0;
2240 pvr2_i2c_core_sync(hdw);
2241 } while (0); LOCK_GIVE(hdw->big_lock);
2242}
2243
2244void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
2245{
2246 int ret;
2247 u16 address;
2248 unsigned int pipe;
2249 LOCK_TAKE(hdw->big_lock); do {
2250 if ((hdw->fw_buffer == 0) == !enable_flag) break;
2251
2252 if (!enable_flag) {
2253 pvr2_trace(PVR2_TRACE_FIRMWARE,
2254 "Cleaning up after CPU firmware fetch");
2255 kfree(hdw->fw_buffer);
2256 hdw->fw_buffer = 0;
2257 hdw->fw_size = 0;
2258 /* Now release the CPU. It will disconnect and
2259 reconnect later. */
2260 pvr2_hdw_cpureset_assert(hdw,0);
2261 break;
2262 }
2263
2264 pvr2_trace(PVR2_TRACE_FIRMWARE,
2265 "Preparing to suck out CPU firmware");
2266 hdw->fw_size = 0x2000;
2267 hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL);
2268 if (!hdw->fw_buffer) {
2269 hdw->fw_size = 0;
2270 break;
2271 }
2272
2273 memset(hdw->fw_buffer,0,hdw->fw_size);
2274
2275 /* We have to hold the CPU during firmware upload. */
2276 pvr2_hdw_cpureset_assert(hdw,1);
2277
2278 /* download the firmware from address 0000-1fff in 2048
2279 (=0x800) bytes chunk. */
2280
2281 pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
2282 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2283 for(address = 0; address < hdw->fw_size; address += 0x800) {
2284 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
2285 address,0,
2286 hdw->fw_buffer+address,0x800,HZ);
2287 if (ret < 0) break;
2288 }
2289
2290 pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
2291
2292 } while (0); LOCK_GIVE(hdw->big_lock);
2293}
2294
2295
2296/* Return true if we're in a mode for retrieval CPU firmware */
2297int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2298{
2299 return hdw->fw_buffer != 0;
2300}
2301
2302
2303int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2304 char *buf,unsigned int cnt)
2305{
2306 int ret = -EINVAL;
2307 LOCK_TAKE(hdw->big_lock); do {
2308 if (!buf) break;
2309 if (!cnt) break;
2310
2311 if (!hdw->fw_buffer) {
2312 ret = -EIO;
2313 break;
2314 }
2315
2316 if (offs >= hdw->fw_size) {
2317 pvr2_trace(PVR2_TRACE_FIRMWARE,
2318 "Read firmware data offs=%d EOF",
2319 offs);
2320 ret = 0;
2321 break;
2322 }
2323
2324 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2325
2326 memcpy(buf,hdw->fw_buffer+offs,cnt);
2327
2328 pvr2_trace(PVR2_TRACE_FIRMWARE,
2329 "Read firmware data offs=%d cnt=%d",
2330 offs,cnt);
2331 ret = cnt;
2332 } while (0); LOCK_GIVE(hdw->big_lock);
2333
2334 return ret;
2335}
2336
2337
2338int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw)
2339{
2340 return hdw->v4l_minor_number;
2341}
2342
2343
2344/* Store the v4l minor device number */
2345void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v)
2346{
2347 hdw->v4l_minor_number = v;
2348}
2349
2350
2351void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw)
2352{
2353 if (!hdw->usb_dev) return;
2354 usb_settoggle(hdw->usb_dev, PVR2_CTL_WRITE_ENDPOINT & 0xf,
2355 !(PVR2_CTL_WRITE_ENDPOINT & USB_DIR_IN), 0);
2356 usb_settoggle(hdw->usb_dev, PVR2_CTL_READ_ENDPOINT & 0xf,
2357 !(PVR2_CTL_READ_ENDPOINT & USB_DIR_IN), 0);
2358 usb_clear_halt(hdw->usb_dev,
2359 usb_rcvbulkpipe(hdw->usb_dev,
2360 PVR2_CTL_READ_ENDPOINT & 0x7f));
2361 usb_clear_halt(hdw->usb_dev,
2362 usb_sndbulkpipe(hdw->usb_dev,
2363 PVR2_CTL_WRITE_ENDPOINT & 0x7f));
2364}
2365
2366
2367static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs)
2368{
2369 struct pvr2_hdw *hdw = urb->context;
2370 hdw->ctl_write_pend_flag = 0;
2371 if (hdw->ctl_read_pend_flag) return;
2372 complete(&hdw->ctl_done);
2373}
2374
2375
2376static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs)
2377{
2378 struct pvr2_hdw *hdw = urb->context;
2379 hdw->ctl_read_pend_flag = 0;
2380 if (hdw->ctl_write_pend_flag) return;
2381 complete(&hdw->ctl_done);
2382}
2383
2384
2385static void pvr2_ctl_timeout(unsigned long data)
2386{
2387 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2388 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2389 hdw->ctl_timeout_flag = !0;
2390 if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) {
2391 usb_unlink_urb(hdw->ctl_write_urb);
2392 }
2393 if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) {
2394 usb_unlink_urb(hdw->ctl_read_urb);
2395 }
2396 }
2397}
2398
2399
2400int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2401 unsigned int timeout,int probe_fl,
2402 void *write_data,unsigned int write_len,
2403 void *read_data,unsigned int read_len)
2404{
2405 unsigned int idx;
2406 int status = 0;
2407 struct timer_list timer;
2408 if (!hdw->ctl_lock_held) {
2409 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2410 "Attempted to execute control transfer"
2411 " without lock!!");
2412 return -EDEADLK;
2413 }
2414 if ((!hdw->flag_ok) && !probe_fl) {
2415 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2416 "Attempted to execute control transfer"
2417 " when device not ok");
2418 return -EIO;
2419 }
2420 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2421 if (!probe_fl) {
2422 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2423 "Attempted to execute control transfer"
2424 " when USB is disconnected");
2425 }
2426 return -ENOTTY;
2427 }
2428
2429 /* Ensure that we have sane parameters */
2430 if (!write_data) write_len = 0;
2431 if (!read_data) read_len = 0;
2432 if (write_len > PVR2_CTL_BUFFSIZE) {
2433 pvr2_trace(
2434 PVR2_TRACE_ERROR_LEGS,
2435 "Attempted to execute %d byte"
2436 " control-write transfer (limit=%d)",
2437 write_len,PVR2_CTL_BUFFSIZE);
2438 return -EINVAL;
2439 }
2440 if (read_len > PVR2_CTL_BUFFSIZE) {
2441 pvr2_trace(
2442 PVR2_TRACE_ERROR_LEGS,
2443 "Attempted to execute %d byte"
2444 " control-read transfer (limit=%d)",
2445 write_len,PVR2_CTL_BUFFSIZE);
2446 return -EINVAL;
2447 }
2448 if ((!write_len) && (!read_len)) {
2449 pvr2_trace(
2450 PVR2_TRACE_ERROR_LEGS,
2451 "Attempted to execute null control transfer?");
2452 return -EINVAL;
2453 }
2454
2455
2456 hdw->cmd_debug_state = 1;
2457 if (write_len) {
2458 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2459 } else {
2460 hdw->cmd_debug_code = 0;
2461 }
2462 hdw->cmd_debug_write_len = write_len;
2463 hdw->cmd_debug_read_len = read_len;
2464
2465 /* Initialize common stuff */
2466 init_completion(&hdw->ctl_done);
2467 hdw->ctl_timeout_flag = 0;
2468 hdw->ctl_write_pend_flag = 0;
2469 hdw->ctl_read_pend_flag = 0;
2470 init_timer(&timer);
2471 timer.expires = jiffies + timeout;
2472 timer.data = (unsigned long)hdw;
2473 timer.function = pvr2_ctl_timeout;
2474
2475 if (write_len) {
2476 hdw->cmd_debug_state = 2;
2477 /* Transfer write data to internal buffer */
2478 for (idx = 0; idx < write_len; idx++) {
2479 hdw->ctl_write_buffer[idx] =
2480 ((unsigned char *)write_data)[idx];
2481 }
2482 /* Initiate a write request */
2483 usb_fill_bulk_urb(hdw->ctl_write_urb,
2484 hdw->usb_dev,
2485 usb_sndbulkpipe(hdw->usb_dev,
2486 PVR2_CTL_WRITE_ENDPOINT),
2487 hdw->ctl_write_buffer,
2488 write_len,
2489 pvr2_ctl_write_complete,
2490 hdw);
2491 hdw->ctl_write_urb->actual_length = 0;
2492 hdw->ctl_write_pend_flag = !0;
2493 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2494 if (status < 0) {
2495 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2496 "Failed to submit write-control"
2497 " URB status=%d",status);
2498 hdw->ctl_write_pend_flag = 0;
2499 goto done;
2500 }
2501 }
2502
2503 if (read_len) {
2504 hdw->cmd_debug_state = 3;
2505 memset(hdw->ctl_read_buffer,0x43,read_len);
2506 /* Initiate a read request */
2507 usb_fill_bulk_urb(hdw->ctl_read_urb,
2508 hdw->usb_dev,
2509 usb_rcvbulkpipe(hdw->usb_dev,
2510 PVR2_CTL_READ_ENDPOINT),
2511 hdw->ctl_read_buffer,
2512 read_len,
2513 pvr2_ctl_read_complete,
2514 hdw);
2515 hdw->ctl_read_urb->actual_length = 0;
2516 hdw->ctl_read_pend_flag = !0;
2517 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
2518 if (status < 0) {
2519 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2520 "Failed to submit read-control"
2521 " URB status=%d",status);
2522 hdw->ctl_read_pend_flag = 0;
2523 goto done;
2524 }
2525 }
2526
2527 /* Start timer */
2528 add_timer(&timer);
2529
2530 /* Now wait for all I/O to complete */
2531 hdw->cmd_debug_state = 4;
2532 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2533 wait_for_completion(&hdw->ctl_done);
2534 }
2535 hdw->cmd_debug_state = 5;
2536
2537 /* Stop timer */
2538 del_timer_sync(&timer);
2539
2540 hdw->cmd_debug_state = 6;
2541 status = 0;
2542
2543 if (hdw->ctl_timeout_flag) {
2544 status = -ETIMEDOUT;
2545 if (!probe_fl) {
2546 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2547 "Timed out control-write");
2548 }
2549 goto done;
2550 }
2551
2552 if (write_len) {
2553 /* Validate results of write request */
2554 if ((hdw->ctl_write_urb->status != 0) &&
2555 (hdw->ctl_write_urb->status != -ENOENT) &&
2556 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
2557 (hdw->ctl_write_urb->status != -ECONNRESET)) {
2558 /* USB subsystem is reporting some kind of failure
2559 on the write */
2560 status = hdw->ctl_write_urb->status;
2561 if (!probe_fl) {
2562 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2563 "control-write URB failure,"
2564 " status=%d",
2565 status);
2566 }
2567 goto done;
2568 }
2569 if (hdw->ctl_write_urb->actual_length < write_len) {
2570 /* Failed to write enough data */
2571 status = -EIO;
2572 if (!probe_fl) {
2573 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2574 "control-write URB short,"
2575 " expected=%d got=%d",
2576 write_len,
2577 hdw->ctl_write_urb->actual_length);
2578 }
2579 goto done;
2580 }
2581 }
2582 if (read_len) {
2583 /* Validate results of read request */
2584 if ((hdw->ctl_read_urb->status != 0) &&
2585 (hdw->ctl_read_urb->status != -ENOENT) &&
2586 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
2587 (hdw->ctl_read_urb->status != -ECONNRESET)) {
2588 /* USB subsystem is reporting some kind of failure
2589 on the read */
2590 status = hdw->ctl_read_urb->status;
2591 if (!probe_fl) {
2592 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2593 "control-read URB failure,"
2594 " status=%d",
2595 status);
2596 }
2597 goto done;
2598 }
2599 if (hdw->ctl_read_urb->actual_length < read_len) {
2600 /* Failed to read enough data */
2601 status = -EIO;
2602 if (!probe_fl) {
2603 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2604 "control-read URB short,"
2605 " expected=%d got=%d",
2606 read_len,
2607 hdw->ctl_read_urb->actual_length);
2608 }
2609 goto done;
2610 }
2611 /* Transfer retrieved data out from internal buffer */
2612 for (idx = 0; idx < read_len; idx++) {
2613 ((unsigned char *)read_data)[idx] =
2614 hdw->ctl_read_buffer[idx];
2615 }
2616 }
2617
2618 done:
2619
2620 hdw->cmd_debug_state = 0;
2621 if ((status < 0) && (!probe_fl)) {
2622 pvr2_hdw_render_useless_unlocked(hdw);
2623 }
2624 return status;
2625}
2626
2627
2628int pvr2_send_request(struct pvr2_hdw *hdw,
2629 void *write_data,unsigned int write_len,
2630 void *read_data,unsigned int read_len)
2631{
2632 return pvr2_send_request_ex(hdw,HZ*4,0,
2633 write_data,write_len,
2634 read_data,read_len);
2635}
2636
2637int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
2638{
2639 int ret;
2640
2641 LOCK_TAKE(hdw->ctl_lock);
2642
2643 hdw->cmd_buffer[0] = 0x04; /* write register prefix */
2644 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
2645 hdw->cmd_buffer[5] = 0;
2646 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2647 hdw->cmd_buffer[7] = reg & 0xff;
2648
2649
2650 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
2651
2652 LOCK_GIVE(hdw->ctl_lock);
2653
2654 return ret;
2655}
2656
2657
2658int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
2659{
2660 int ret = 0;
2661
2662 LOCK_TAKE(hdw->ctl_lock);
2663
2664 hdw->cmd_buffer[0] = 0x05; /* read register prefix */
2665 hdw->cmd_buffer[1] = 0;
2666 hdw->cmd_buffer[2] = 0;
2667 hdw->cmd_buffer[3] = 0;
2668 hdw->cmd_buffer[4] = 0;
2669 hdw->cmd_buffer[5] = 0;
2670 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2671 hdw->cmd_buffer[7] = reg & 0xff;
2672
2673 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
2674 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
2675
2676 LOCK_GIVE(hdw->ctl_lock);
2677
2678 return ret;
2679}
2680
2681
2682int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
2683{
2684 int ret;
2685
2686 LOCK_TAKE(hdw->ctl_lock);
2687
2688 hdw->cmd_buffer[0] = (data >> 8) & 0xff;
2689 hdw->cmd_buffer[1] = data & 0xff;
2690
2691 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
2692
2693 LOCK_GIVE(hdw->ctl_lock);
2694
2695 return ret;
2696}
2697
2698
2699int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
2700{
2701 int ret;
2702
2703 LOCK_TAKE(hdw->ctl_lock);
2704
2705 hdw->cmd_buffer[0] = data;
2706
2707 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
2708
2709 LOCK_GIVE(hdw->ctl_lock);
2710
2711 return ret;
2712}
2713
2714
2715void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
2716{
2717 if (!hdw->flag_ok) return;
2718 pvr2_trace(PVR2_TRACE_INIT,"render_useless");
2719 hdw->flag_ok = 0;
2720 if (hdw->vid_stream) {
2721 pvr2_stream_setup(hdw->vid_stream,0,0,0);
2722 }
2723 hdw->flag_streaming_enabled = 0;
2724 hdw->subsys_enabled_mask = 0;
2725}
2726
2727
2728void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
2729{
2730 LOCK_TAKE(hdw->ctl_lock);
2731 pvr2_hdw_render_useless_unlocked(hdw);
2732 LOCK_GIVE(hdw->ctl_lock);
2733}
2734
2735
2736void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
2737{
2738 int ret;
2739 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
2740 ret = usb_lock_device_for_reset(hdw->usb_dev,0);
2741 if (ret == 1) {
2742 ret = usb_reset_device(hdw->usb_dev);
2743 usb_unlock_device(hdw->usb_dev);
2744 } else {
2745 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2746 "Failed to lock USB device ret=%d",ret);
2747 }
2748 if (init_pause_msec) {
2749 pvr2_trace(PVR2_TRACE_INFO,
2750 "Waiting %u msec for hardware to settle",
2751 init_pause_msec);
2752 msleep(init_pause_msec);
2753 }
2754
2755}
2756
2757
2758void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
2759{
2760 char da[1];
2761 unsigned int pipe;
2762 int ret;
2763
2764 if (!hdw->usb_dev) return;
2765
2766 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
2767
2768 da[0] = val ? 0x01 : 0x00;
2769
2770 /* Write the CPUCS register on the 8051. The lsb of the register
2771 is the reset bit; a 1 asserts reset while a 0 clears it. */
2772 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
2773 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
2774 if (ret < 0) {
2775 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2776 "cpureset_assert(%d) error=%d",val,ret);
2777 pvr2_hdw_render_useless(hdw);
2778 }
2779}
2780
2781
2782int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
2783{
2784 int status;
2785 LOCK_TAKE(hdw->ctl_lock); do {
2786 pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
2787 hdw->flag_ok = !0;
2788 hdw->cmd_buffer[0] = 0xdd;
2789 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
2790 } while (0); LOCK_GIVE(hdw->ctl_lock);
2791 return status;
2792}
2793
2794
2795int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
2796{
2797 int status;
2798 LOCK_TAKE(hdw->ctl_lock); do {
2799 pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
2800 hdw->cmd_buffer[0] = 0xde;
2801 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
2802 } while (0); LOCK_GIVE(hdw->ctl_lock);
2803 return status;
2804}
2805
2806
2807int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
2808{
2809 if (!hdw->decoder_ctrl) {
2810 pvr2_trace(PVR2_TRACE_INIT,
2811 "Unable to reset decoder: nothing attached");
2812 return -ENOTTY;
2813 }
2814
2815 if (!hdw->decoder_ctrl->force_reset) {
2816 pvr2_trace(PVR2_TRACE_INIT,
2817 "Unable to reset decoder: not implemented");
2818 return -ENOTTY;
2819 }
2820
2821 pvr2_trace(PVR2_TRACE_INIT,
2822 "Requesting decoder reset");
2823 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
2824 return 0;
2825}
2826
2827
2828int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
2829{
2830 int status;
2831 LOCK_TAKE(hdw->ctl_lock); do {
2832 hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
2833 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
2834 } while (0); LOCK_GIVE(hdw->ctl_lock);
2835 if (!status) {
2836 hdw->subsys_enabled_mask =
2837 ((hdw->subsys_enabled_mask &
2838 ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
2839 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
2840 }
2841 return status;
2842}
2843
2844
2845void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
2846 struct pvr2_hdw_debug_info *ptr)
2847{
2848 ptr->big_lock_held = hdw->big_lock_held;
2849 ptr->ctl_lock_held = hdw->ctl_lock_held;
2850 ptr->flag_ok = hdw->flag_ok;
2851 ptr->flag_disconnected = hdw->flag_disconnected;
2852 ptr->flag_init_ok = hdw->flag_init_ok;
2853 ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
2854 ptr->subsys_flags = hdw->subsys_enabled_mask;
2855 ptr->cmd_debug_state = hdw->cmd_debug_state;
2856 ptr->cmd_code = hdw->cmd_debug_code;
2857 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
2858 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
2859 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
2860 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
2861 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
2862 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
2863 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
2864}
2865
2866
2867int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
2868{
2869 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
2870}
2871
2872
2873int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
2874{
2875 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
2876}
2877
2878
2879int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
2880{
2881 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
2882}
2883
2884
2885int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
2886{
2887 u32 cval,nval;
2888 int ret;
2889 if (~msk) {
2890 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
2891 if (ret) return ret;
2892 nval = (cval & ~msk) | (val & msk);
2893 pvr2_trace(PVR2_TRACE_GPIO,
2894 "GPIO direction changing 0x%x:0x%x"
2895 " from 0x%x to 0x%x",
2896 msk,val,cval,nval);
2897 } else {
2898 nval = val;
2899 pvr2_trace(PVR2_TRACE_GPIO,
2900 "GPIO direction changing to 0x%x",nval);
2901 }
2902 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
2903}
2904
2905
2906int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
2907{
2908 u32 cval,nval;
2909 int ret;
2910 if (~msk) {
2911 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
2912 if (ret) return ret;
2913 nval = (cval & ~msk) | (val & msk);
2914 pvr2_trace(PVR2_TRACE_GPIO,
2915 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
2916 msk,val,cval,nval);
2917 } else {
2918 nval = val;
2919 pvr2_trace(PVR2_TRACE_GPIO,
2920 "GPIO output changing to 0x%x",nval);
2921 }
2922 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
2923}
2924
2925
2926int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
2927{
2928 int result;
2929 LOCK_TAKE(hdw->ctl_lock); do {
2930 hdw->cmd_buffer[0] = 0xeb;
2931 result = pvr2_send_request(hdw,
2932 hdw->cmd_buffer,1,
2933 hdw->cmd_buffer,1);
2934 if (result < 0) break;
2935 result = hdw->cmd_buffer[0];
2936 } while(0); LOCK_GIVE(hdw->ctl_lock);
2937 return result;
2938}
2939
2940
2941/*
2942 Stuff for Emacs to see, in order to encourage consistent editing style:
2943 *** Local Variables: ***
2944 *** mode: c ***
2945 *** fill-column: 75 ***
2946 *** tab-width: 8 ***
2947 *** c-basic-offset: 8 ***
2948 *** End: ***
2949 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
new file mode 100644
index 000000000000..e9adef93e60a
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -0,0 +1,342 @@
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/* Private V4L2-compatible controls available in this driver, look these up
30 with pvr2_hdw_get_ctrl_v4l(). */
31#define V4L2_CID_PVR_SRATE (V4L2_CID_PRIVATE_BASE)
32#define V4L2_CID_PVR_AUDIOBITRATE (V4L2_CID_PRIVATE_BASE+1)
33#define V4L2_CID_PVR_AUDIOCRC (V4L2_CID_PRIVATE_BASE+2)
34#define V4L2_CID_PVR_AUDIOEMPHASIS (V4L2_CID_PRIVATE_BASE+3)
35#define V4L2_CID_PVR_VBR (V4L2_CID_PRIVATE_BASE+4)
36#define V4L2_CID_PVR_VIDEOBITRATE (V4L2_CID_PRIVATE_BASE+5)
37#define V4L2_CID_PVR_VIDEOPEAK (V4L2_CID_PRIVATE_BASE+6)
38#define V4L2_CID_PVR_VIDEOSTANDARD (V4L2_CID_PRIVATE_BASE+7)
39
40/* Private internal control ids, look these up with
41 pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */
42#define PVR2_CID_STDENUM 1
43#define PVR2_CID_STDCUR 2
44#define PVR2_CID_STDAVAIL 3
45#define PVR2_CID_INPUT 4
46#define PVR2_CID_AUDIOMODE 5
47#define PVR2_CID_FREQUENCY 6
48#define PVR2_CID_HRES 7
49#define PVR2_CID_VRES 8
50#define PVR2_CID_INTERLACE 9
51
52/* Legal values for the INPUT state variable */
53#define PVR2_CVAL_INPUT_TV 0
54#define PVR2_CVAL_INPUT_SVIDEO 1
55#define PVR2_CVAL_INPUT_COMPOSITE 2
56#define PVR2_CVAL_INPUT_RADIO 3
57
58/* Values that pvr2_hdw_get_signal_status() returns */
59#define PVR2_SIGNAL_OK 0x0001
60#define PVR2_SIGNAL_STEREO 0x0002
61#define PVR2_SIGNAL_SAP 0x0004
62
63
64/* Subsystem definitions - these are various pieces that can be
65 independently stopped / started. Usually you don't want to mess with
66 this directly (let the driver handle things itself), but it is useful
67 for debugging. */
68#define PVR2_SUBSYS_B_ENC_FIRMWARE 0
69#define PVR2_SUBSYS_B_ENC_CFG 1
70#define PVR2_SUBSYS_B_DIGITIZER_RUN 2
71#define PVR2_SUBSYS_B_USBSTREAM_RUN 3
72#define PVR2_SUBSYS_B_ENC_RUN 4
73
74#define PVR2_SUBSYS_CFG_ALL ( \
75 (1 << PVR2_SUBSYS_B_ENC_FIRMWARE) | \
76 (1 << PVR2_SUBSYS_B_ENC_CFG) )
77#define PVR2_SUBSYS_RUN_ALL ( \
78 (1 << PVR2_SUBSYS_B_DIGITIZER_RUN) | \
79 (1 << PVR2_SUBSYS_B_USBSTREAM_RUN) | \
80 (1 << PVR2_SUBSYS_B_ENC_RUN) )
81#define PVR2_SUBSYS_ALL ( \
82 PVR2_SUBSYS_CFG_ALL | \
83 PVR2_SUBSYS_RUN_ALL )
84
85enum pvr2_config {
86 pvr2_config_empty,
87 pvr2_config_mpeg,
88 pvr2_config_vbi,
89 pvr2_config_radio,
90};
91
92const char *pvr2_config_get_name(enum pvr2_config);
93
94struct pvr2_hdw;
95
96/* Create and return a structure for interacting with the underlying
97 hardware */
98struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
99 const struct usb_device_id *devid);
100
101/* Poll for background activity (if any) */
102void pvr2_hdw_poll(struct pvr2_hdw *);
103
104/* Trigger a poll to take place later at a convenient time */
105void pvr2_hdw_poll_trigger(struct pvr2_hdw *);
106void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *);
107
108/* Register a callback used to trigger a future poll */
109void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *,
110 void (*func)(void *),
111 void *data);
112
113/* Get pointer to structure given unit number */
114struct pvr2_hdw *pvr2_hdw_find(int unit_number);
115
116/* Destroy hardware interaction structure */
117void pvr2_hdw_destroy(struct pvr2_hdw *);
118
119/* Set up the structure and attempt to put the device into a usable state.
120 This can be a time-consuming operation, which is why it is not done
121 internally as part of the create() step. Return value is exactly the
122 same as pvr2_hdw_init_ok(). */
123int pvr2_hdw_setup(struct pvr2_hdw *);
124
125/* Initialization succeeded */
126int pvr2_hdw_init_ok(struct pvr2_hdw *);
127
128/* Return true if in the ready (normal) state */
129int pvr2_hdw_dev_ok(struct pvr2_hdw *);
130
131/* Return small integer number [1..N] for logical instance number of this
132 device. This is useful for indexing array-valued module parameters. */
133int pvr2_hdw_get_unit_number(struct pvr2_hdw *);
134
135/* Get pointer to underlying USB device */
136struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *);
137
138/* Retrieve serial number of device */
139unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
140
141/* Called when hardware has been unplugged */
142void pvr2_hdw_disconnect(struct pvr2_hdw *);
143
144/* Get the number of defined controls */
145unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *);
146
147/* Retrieve a control handle given its index (0..count-1) */
148struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int);
149
150/* Retrieve a control handle given its internal ID (if any) */
151struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *,unsigned int);
152
153/* Retrieve a control handle given its V4L ID (if any) */
154struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *,unsigned int ctl_id);
155
156/* Commit all control changes made up to this point */
157int pvr2_hdw_commit_ctl(struct pvr2_hdw *);
158
159/* Return name for this driver instance */
160const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *);
161
162/* Return PVR2_SIGNAL_XXXX bit mask indicating signal status */
163unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *);
164
165/* Query device and see if it thinks it is on a high-speed USB link */
166int pvr2_hdw_is_hsm(struct pvr2_hdw *);
167
168/* Turn streaming on/off */
169int pvr2_hdw_set_streaming(struct pvr2_hdw *,int);
170
171/* Find out if streaming is on */
172int pvr2_hdw_get_streaming(struct pvr2_hdw *);
173
174/* Configure the type of stream to generate */
175int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config);
176
177/* Get handle to video output stream */
178struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *);
179
180/* Emit a video standard struct */
181int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std,
182 unsigned int idx);
183
184/* Enable / disable various pieces of hardware. Items to change are
185 identified by bit positions within msk, and new state for each item is
186 identified by corresponding bit positions within val. */
187void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
188 unsigned long msk,unsigned long val);
189
190/* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,msk) */
191void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk);
192
193/* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,0) */
194void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk);
195
196/* Retrieve mask indicating which pieces of hardware are currently enabled
197 / configured. */
198unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *);
199
200/* Adjust mask of what get shut down when streaming is stopped. This is a
201 debugging aid. */
202void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
203 unsigned long msk,unsigned long val);
204
205/* Retrieve mask indicating which pieces of hardware are disabled when
206 streaming is turned off. */
207unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *);
208
209
210/* Enable / disable retrieval of CPU firmware. This must be enabled before
211 pvr2_hdw_cpufw_get() will function. Note that doing this may prevent
212 the device from running (and leaving this mode may imply a device
213 reset). */
214void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, int enable_flag);
215
216/* Return true if we're in a mode for retrieval CPU firmware */
217int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *);
218
219/* Retrieve a piece of the CPU's firmware at the given offset. Return
220 value is the number of bytes retrieved or zero if we're past the end or
221 an error otherwise (e.g. if firmware retrieval is not enabled). */
222int pvr2_hdw_cpufw_get(struct pvr2_hdw *,unsigned int offs,
223 char *buf,unsigned int cnt);
224
225/* Retrieve previously stored v4l minor device number */
226int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *);
227
228/* Store the v4l minor device number */
229void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,int);
230
231
232/* The following entry points are all lower level things you normally don't
233 want to worry about. */
234
235/* Attempt to recover from a USB foul-up (in practice I find that if you
236 have to do this, then it's already too late). */
237void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw);
238
239/* Issue a command and get a response from the device. LOTS of higher
240 level stuff is built on this. */
241int pvr2_send_request(struct pvr2_hdw *,
242 void *write_ptr,unsigned int write_len,
243 void *read_ptr,unsigned int read_len);
244
245/* Issue a command and get a response from the device. This extended
246 version includes a probe flag (which if set means that device errors
247 should not be logged or treated as fatal) and a timeout in jiffies.
248 This can be used to non-lethally probe the health of endpoint 1. */
249int pvr2_send_request_ex(struct pvr2_hdw *,unsigned int timeout,int probe_fl,
250 void *write_ptr,unsigned int write_len,
251 void *read_ptr,unsigned int read_len);
252
253/* Slightly higher level device communication functions. */
254int pvr2_write_register(struct pvr2_hdw *, u16, u32);
255int pvr2_read_register(struct pvr2_hdw *, u16, u32 *);
256int pvr2_write_u16(struct pvr2_hdw *, u16, int);
257int pvr2_write_u8(struct pvr2_hdw *, u8, int);
258
259/* Call if for any reason we can't talk to the hardware anymore - this will
260 cause the driver to stop flailing on the device. */
261void pvr2_hdw_render_useless(struct pvr2_hdw *);
262void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *);
263
264/* Set / clear 8051's reset bit */
265void pvr2_hdw_cpureset_assert(struct pvr2_hdw *,int);
266
267/* Execute a USB-commanded device reset */
268void pvr2_hdw_device_reset(struct pvr2_hdw *);
269
270/* Execute hard reset command (after this point it's likely that the
271 encoder will have to be reconfigured). This also clears the "useless"
272 state. */
273int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *);
274
275/* Execute simple reset command */
276int pvr2_hdw_cmd_powerup(struct pvr2_hdw *);
277
278/* Order decoder to reset */
279int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *);
280
281/* Stop / start video stream transport */
282int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
283
284/* Find I2C address of eeprom */
285int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *);
286
287/* Direct manipulation of GPIO bits */
288int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *);
289int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *);
290int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *);
291int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val);
292int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val);
293
294/* This data structure is specifically for the next function... */
295struct pvr2_hdw_debug_info {
296 int big_lock_held;
297 int ctl_lock_held;
298 int flag_ok;
299 int flag_disconnected;
300 int flag_init_ok;
301 int flag_streaming_enabled;
302 unsigned long subsys_flags;
303 int cmd_debug_state;
304 int cmd_debug_write_len;
305 int cmd_debug_read_len;
306 int cmd_debug_write_pend;
307 int cmd_debug_read_pend;
308 int cmd_debug_timeout;
309 int cmd_debug_rstatus;
310 int cmd_debug_wstatus;
311 unsigned char cmd_code;
312};
313
314/* Non-intrusively retrieve internal state info - this is useful for
315 diagnosing lockups. Note that this operation is completed without any
316 kind of locking and so it is not atomic and may yield inconsistent
317 results. This is *purely* a debugging aid. */
318void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
319 struct pvr2_hdw_debug_info *);
320
321/* Cause modules to log their state once */
322void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw);
323
324/* Cause encoder firmware to be uploaded into the device. This is normally
325 done autonomously, but the interface is exported here because it is also
326 a debugging aid. */
327int pvr2_upload_firmware2(struct pvr2_hdw *hdw);
328
329/* List of device types that we can match */
330extern struct usb_device_id pvr2_device_table[];
331
332#endif /* __PVRUSB2_HDW_H */
333
334/*
335 Stuff for Emacs to see, in order to encourage consistent editing style:
336 *** Local Variables: ***
337 *** mode: c ***
338 *** fill-column: 75 ***
339 *** tab-width: 8 ***
340 *** c-basic-offset: 8 ***
341 *** End: ***
342 */
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..d3c538cd0319
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -0,0 +1,180 @@
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 PVR2_TRACE_FIRMWARE| \
50 PVR2_TRACE_EEPROM | \
51 PVR2_TRACE_INIT | \
52 PVR2_TRACE_I2C | \
53 PVR2_TRACE_CHIPS | \
54 PVR2_TRACE_START_STOP | \
55 PVR2_TRACE_CTL | \
56 PVR2_TRACE_DEBUGIFC | \
57 0)
58
59int pvrusb2_debug = DEFAULT_DEBUG_MASK;
60
61module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR);
62MODULE_PARM_DESC(debug, "Debug trace mask");
63
64#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
65static struct pvr2_sysfs_class *class_ptr = 0;
66#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
67
68static void pvr_setup_attach(struct pvr2_context *pvr)
69{
70 /* Create association with v4l layer */
71 pvr2_v4l2_create(pvr);
72#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
73 pvr2_sysfs_create(pvr,class_ptr);
74#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
75}
76
77static int pvr_probe(struct usb_interface *intf,
78 const struct usb_device_id *devid)
79{
80 struct pvr2_context *pvr;
81
82 /* Create underlying hardware interface */
83 pvr = pvr2_context_create(intf,devid,pvr_setup_attach);
84 if (!pvr) {
85 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
86 "Failed to create hdw handler");
87 return -ENOMEM;
88 }
89
90 pvr2_trace(PVR2_TRACE_INIT,"pvr_probe(pvr=%p)",pvr);
91
92 usb_set_intfdata(intf, pvr);
93
94 return 0;
95}
96
97/*
98 * pvr_disconnect()
99 *
100 */
101static void pvr_disconnect(struct usb_interface *intf)
102{
103 struct pvr2_context *pvr = usb_get_intfdata(intf);
104
105 pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr);
106
107 usb_set_intfdata (intf, NULL);
108 pvr2_context_disconnect(pvr);
109
110 pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) DONE",pvr);
111
112}
113
114static struct usb_driver pvr_driver = {
115 name: "pvrusb2",
116 id_table: pvr2_device_table,
117 probe: pvr_probe,
118 disconnect: pvr_disconnect
119};
120
121/*
122 * pvr_init() / pvr_exit()
123 *
124 * This code is run to initialize/exit the driver.
125 *
126 */
127static int __init pvr_init(void)
128{
129 int ret;
130
131 pvr2_trace(PVR2_TRACE_INIT,"pvr_init");
132
133#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
134 class_ptr = pvr2_sysfs_class_create();
135#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
136
137 ret = usb_register(&pvr_driver);
138
139 if (ret == 0)
140 info(DRIVER_DESC " : " DRIVER_VERSION);
141 if (pvrusb2_debug) info("Debug mask is %d (0x%x)",
142 pvrusb2_debug,pvrusb2_debug);
143
144 return ret;
145}
146
147static void __exit pvr_exit(void)
148{
149
150 pvr2_trace(PVR2_TRACE_INIT,"pvr_exit");
151
152#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS
153 pvr2_sysfs_class_destroy(class_ptr);
154#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */
155
156 usb_deregister(&pvr_driver);
157}
158
159module_init(pvr_init);
160module_exit(pvr_exit);
161
162/* Mike Isely <mcisely@pobox.com> 11-Mar-2006: See pvrusb2-hdw.c for
163 MODULE_DEVICE_TABLE(). We have to declare that attribute there
164 because that's where the device table actually is now and it seems
165 that certain gcc configurations get angry if MODULE_DEVICE_TABLE()
166 is used on what ends up being an external symbol. */
167MODULE_AUTHOR(DRIVER_AUTHOR);
168MODULE_DESCRIPTION(DRIVER_DESC);
169MODULE_LICENSE("GPL");
170
171
172/*
173 Stuff for Emacs to see, in order to encourage consistent editing style:
174 *** Local Variables: ***
175 *** mode: c ***
176 *** fill-column: 70 ***
177 *** tab-width: 8 ***
178 *** c-basic-offset: 8 ***
179 *** End: ***
180 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c
new file mode 100644
index 000000000000..64ba223c2358
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.c
@@ -0,0 +1,406 @@
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
25struct std_name {
26 const char *name;
27 v4l2_std_id id;
28};
29
30
31#define CSTD_PAL \
32 (V4L2_STD_PAL_B| \
33 V4L2_STD_PAL_B1| \
34 V4L2_STD_PAL_G| \
35 V4L2_STD_PAL_H| \
36 V4L2_STD_PAL_I| \
37 V4L2_STD_PAL_D| \
38 V4L2_STD_PAL_D1| \
39 V4L2_STD_PAL_K| \
40 V4L2_STD_PAL_M| \
41 V4L2_STD_PAL_N| \
42 V4L2_STD_PAL_Nc| \
43 V4L2_STD_PAL_60)
44
45#define CSTD_NTSC \
46 (V4L2_STD_NTSC_M| \
47 V4L2_STD_NTSC_M_JP| \
48 V4L2_STD_NTSC_M_KR| \
49 V4L2_STD_NTSC_443)
50
51#define CSTD_SECAM \
52 (V4L2_STD_SECAM_B| \
53 V4L2_STD_SECAM_D| \
54 V4L2_STD_SECAM_G| \
55 V4L2_STD_SECAM_H| \
56 V4L2_STD_SECAM_K| \
57 V4L2_STD_SECAM_K1| \
58 V4L2_STD_SECAM_L| \
59 V4L2_STD_SECAM_LC)
60
61#define TSTD_B (V4L2_STD_PAL_B|V4L2_STD_SECAM_B)
62#define TSTD_B1 (V4L2_STD_PAL_B1)
63#define TSTD_D (V4L2_STD_PAL_D|V4L2_STD_SECAM_D)
64#define TSTD_D1 (V4L2_STD_PAL_D1)
65#define TSTD_G (V4L2_STD_PAL_G|V4L2_STD_SECAM_G)
66#define TSTD_H (V4L2_STD_PAL_H|V4L2_STD_SECAM_H)
67#define TSTD_I (V4L2_STD_PAL_I)
68#define TSTD_K (V4L2_STD_PAL_K|V4L2_STD_SECAM_K)
69#define TSTD_K1 (V4L2_STD_SECAM_K1)
70#define TSTD_L (V4L2_STD_SECAM_L)
71#define TSTD_M (V4L2_STD_PAL_M|V4L2_STD_NTSC_M)
72#define TSTD_N (V4L2_STD_PAL_N)
73#define TSTD_Nc (V4L2_STD_PAL_Nc)
74#define TSTD_60 (V4L2_STD_PAL_60)
75
76#define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_SECAM)
77
78/* Mapping of standard bits to color system */
79const static struct std_name std_groups[] = {
80 {"PAL",CSTD_PAL},
81 {"NTSC",CSTD_NTSC},
82 {"SECAM",CSTD_SECAM},
83};
84
85/* Mapping of standard bits to modulation system */
86const static struct std_name std_items[] = {
87 {"B",TSTD_B},
88 {"B1",TSTD_B1},
89 {"D",TSTD_D},
90 {"D1",TSTD_D1},
91 {"G",TSTD_G},
92 {"H",TSTD_H},
93 {"I",TSTD_I},
94 {"K",TSTD_K},
95 {"K1",TSTD_K1},
96 {"L",TSTD_L},
97 {"LC",V4L2_STD_SECAM_LC},
98 {"M",TSTD_M},
99 {"Mj",V4L2_STD_NTSC_M_JP},
100 {"443",V4L2_STD_NTSC_443},
101 {"Mk",V4L2_STD_NTSC_M_KR},
102 {"N",TSTD_N},
103 {"Nc",TSTD_Nc},
104 {"60",TSTD_60},
105};
106
107
108// Search an array of std_name structures and return a pointer to the
109// element with the matching name.
110static const struct std_name *find_std_name(const struct std_name *arrPtr,
111 unsigned int arrSize,
112 const char *bufPtr,
113 unsigned int bufSize)
114{
115 unsigned int idx;
116 const struct std_name *p;
117 for (idx = 0; idx < arrSize; idx++) {
118 p = arrPtr + idx;
119 if (strlen(p->name) != bufSize) continue;
120 if (!memcmp(bufPtr,p->name,bufSize)) return p;
121 }
122 return 0;
123}
124
125
126int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr,
127 unsigned int bufSize)
128{
129 v4l2_std_id id = 0;
130 v4l2_std_id cmsk = 0;
131 v4l2_std_id t;
132 int mMode = 0;
133 unsigned int cnt;
134 char ch;
135 const struct std_name *sp;
136
137 while (bufSize) {
138 if (!mMode) {
139 cnt = 0;
140 while ((cnt < bufSize) && (bufPtr[cnt] != '-')) cnt++;
141 if (cnt >= bufSize) return 0; // No more characters
142 sp = find_std_name(
143 std_groups,
144 sizeof(std_groups)/sizeof(std_groups[0]),
145 bufPtr,cnt);
146 if (!sp) return 0; // Illegal color system name
147 cnt++;
148 bufPtr += cnt;
149 bufSize -= cnt;
150 mMode = !0;
151 cmsk = sp->id;
152 continue;
153 }
154 cnt = 0;
155 while (cnt < bufSize) {
156 ch = bufPtr[cnt];
157 if (ch == ';') {
158 mMode = 0;
159 break;
160 }
161 if (ch == '/') break;
162 cnt++;
163 }
164 sp = find_std_name(std_items,
165 sizeof(std_items)/sizeof(std_items[0]),
166 bufPtr,cnt);
167 if (!sp) return 0; // Illegal modulation system ID
168 t = sp->id & cmsk;
169 if (!t) return 0; // Specific color + modulation system illegal
170 id |= t;
171 if (cnt < bufSize) cnt++;
172 bufPtr += cnt;
173 bufSize -= cnt;
174 }
175
176 if (idPtr) *idPtr = id;
177 return !0;
178}
179
180
181unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize,
182 v4l2_std_id id)
183{
184 unsigned int idx1,idx2;
185 const struct std_name *ip,*gp;
186 int gfl,cfl;
187 unsigned int c1,c2;
188 cfl = 0;
189 c1 = 0;
190 for (idx1 = 0;
191 idx1 < sizeof(std_groups)/sizeof(std_groups[0]);
192 idx1++) {
193 gp = std_groups + idx1;
194 gfl = 0;
195 for (idx2 = 0;
196 idx2 < sizeof(std_items)/sizeof(std_items[0]);
197 idx2++) {
198 ip = std_items + idx2;
199 if (!(gp->id & ip->id & id)) continue;
200 if (!gfl) {
201 if (cfl) {
202 c2 = scnprintf(bufPtr,bufSize,";");
203 c1 += c2;
204 bufSize -= c2;
205 bufPtr += c2;
206 }
207 cfl = !0;
208 c2 = scnprintf(bufPtr,bufSize,
209 "%s-",gp->name);
210 gfl = !0;
211 } else {
212 c2 = scnprintf(bufPtr,bufSize,"/");
213 }
214 c1 += c2;
215 bufSize -= c2;
216 bufPtr += c2;
217 c2 = scnprintf(bufPtr,bufSize,
218 ip->name);
219 c1 += c2;
220 bufSize -= c2;
221 bufPtr += c2;
222 }
223 }
224 return c1;
225}
226
227
228// Template data for possible enumerated video standards. Here we group
229// standards which share common frame rates and resolution.
230static struct v4l2_standard generic_standards[] = {
231 {
232 .id = (TSTD_B|TSTD_B1|
233 TSTD_D|TSTD_D1|
234 TSTD_G|
235 TSTD_H|
236 TSTD_I|
237 TSTD_K|TSTD_K1|
238 TSTD_L|
239 V4L2_STD_SECAM_LC |
240 TSTD_N|TSTD_Nc),
241 .frameperiod =
242 {
243 .numerator = 1,
244 .denominator= 25
245 },
246 .framelines = 625,
247 .reserved = {0,0,0,0}
248 }, {
249 .id = (TSTD_M|
250 V4L2_STD_NTSC_M_JP|
251 V4L2_STD_NTSC_M_KR),
252 .frameperiod =
253 {
254 .numerator = 1001,
255 .denominator= 30000
256 },
257 .framelines = 525,
258 .reserved = {0,0,0,0}
259 }, { // This is a total wild guess
260 .id = (TSTD_60),
261 .frameperiod =
262 {
263 .numerator = 1001,
264 .denominator= 30000
265 },
266 .framelines = 525,
267 .reserved = {0,0,0,0}
268 }, { // This is total wild guess
269 .id = V4L2_STD_NTSC_443,
270 .frameperiod =
271 {
272 .numerator = 1001,
273 .denominator= 30000
274 },
275 .framelines = 525,
276 .reserved = {0,0,0,0}
277 }
278};
279
280#define generic_standards_cnt (sizeof(generic_standards)/sizeof(generic_standards[0]))
281
282static struct v4l2_standard *match_std(v4l2_std_id id)
283{
284 unsigned int idx;
285 for (idx = 0; idx < generic_standards_cnt; idx++) {
286 if (generic_standards[idx].id & id) {
287 return generic_standards + idx;
288 }
289 }
290 return 0;
291}
292
293static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id)
294{
295 struct v4l2_standard *template;
296 int idx;
297 unsigned int bcnt;
298 template = match_std(id);
299 if (!template) return 0;
300 idx = std->index;
301 memcpy(std,template,sizeof(*template));
302 std->index = idx;
303 std->id = id;
304 bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id);
305 std->name[bcnt] = 0;
306 pvr2_trace(PVR2_TRACE_INIT,"Set up standard idx=%u name=%s",
307 std->index,std->name);
308 return !0;
309}
310
311/* These are special cases of combined standards that we should enumerate
312 separately if the component pieces are present. */
313static v4l2_std_id std_mixes[] = {
314 V4L2_STD_PAL_B | V4L2_STD_PAL_G,
315 V4L2_STD_PAL_D | V4L2_STD_PAL_K,
316 V4L2_STD_SECAM_B | V4L2_STD_SECAM_G,
317 V4L2_STD_SECAM_D | V4L2_STD_SECAM_K,
318};
319
320struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
321 v4l2_std_id id)
322{
323 unsigned int std_cnt = 0;
324 unsigned int idx,bcnt,idx2;
325 v4l2_std_id idmsk,cmsk,fmsk;
326 struct v4l2_standard *stddefs;
327
328 if (pvrusb2_debug & PVR2_TRACE_INIT) {
329 char buf[50];
330 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id);
331 pvr2_trace(
332 PVR2_TRACE_INIT,"Mapping standards mask=0x%x (%.*s)",
333 (int)id,bcnt,buf);
334 }
335
336 *countptr = 0;
337 std_cnt = 0;
338 fmsk = 0;
339 for (idmsk = 1, cmsk = id; cmsk; idmsk <<= 1) {
340 if (!(idmsk & cmsk)) continue;
341 cmsk &= ~idmsk;
342 if (match_std(idmsk)) {
343 std_cnt++;
344 continue;
345 }
346 fmsk |= idmsk;
347 }
348
349 for (idx2 = 0; idx2 < sizeof(std_mixes)/sizeof(std_mixes[0]); idx2++) {
350 if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++;
351 }
352
353 if (fmsk) {
354 char buf[50];
355 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk);
356 pvr2_trace(
357 PVR2_TRACE_ERROR_LEGS,
358 "WARNING:"
359 " Failed to classify the following standard(s): %.*s",
360 bcnt,buf);
361 }
362
363 pvr2_trace(PVR2_TRACE_INIT,"Setting up %u unique standard(s)",
364 std_cnt);
365 if (!std_cnt) return 0; // paranoia
366
367 stddefs = kmalloc(sizeof(struct v4l2_standard) * std_cnt,
368 GFP_KERNEL);
369 memset(stddefs,0,sizeof(struct v4l2_standard) * std_cnt);
370 for (idx = 0; idx < std_cnt; idx++) stddefs[idx].index = idx;
371
372 idx = 0;
373
374 /* Enumerate potential special cases */
375 for (idx2 = 0; ((idx2 < sizeof(std_mixes)/sizeof(std_mixes[0])) &&
376 (idx < std_cnt)); idx2++) {
377 if (!(id & std_mixes[idx2])) continue;
378 if (pvr2_std_fill(stddefs+idx,std_mixes[idx2])) idx++;
379 }
380 /* Now enumerate individual pieces */
381 for (idmsk = 1, cmsk = id; cmsk && (idx < std_cnt); idmsk <<= 1) {
382 if (!(idmsk & cmsk)) continue;
383 cmsk &= ~idmsk;
384 if (!pvr2_std_fill(stddefs+idx,idmsk)) continue;
385 idx++;
386 }
387
388 *countptr = std_cnt;
389 return stddefs;
390}
391
392v4l2_std_id pvr2_std_get_usable(void)
393{
394 return CSTD_ALL;
395}
396
397
398/*
399 Stuff for Emacs to see, in order to encourage consistent editing style:
400 *** Local Variables: ***
401 *** mode: c ***
402 *** fill-column: 75 ***
403 *** tab-width: 8 ***
404 *** c-basic-offset: 8 ***
405 *** End: ***
406 */
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..c756b9845056
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -0,0 +1,775 @@
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_min;
59 struct class_device_attribute attr_max;
60 struct class_device_attribute attr_enum;
61 struct class_device_attribute attr_bits;
62 struct class_device_attribute attr_val;
63 struct class_device_attribute attr_custom;
64 struct pvr2_ctrl *cptr;
65 struct pvr2_sysfs *chptr;
66 struct pvr2_sysfs_ctl_item *item_next;
67 struct attribute *attr_gen[6];
68 struct attribute_group grp;
69 char name[80];
70};
71
72struct pvr2_sysfs_class {
73 struct class class;
74};
75
76static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
77{
78 struct pvr2_ctrl *cptr;
79 struct pvr2_sysfs *sfp;
80 const char *name;
81
82 sfp = (struct pvr2_sysfs *)class_dev->class_data;
83 if (!sfp) return -EINVAL;
84 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
85 if (!cptr) return -EINVAL;
86
87 name = pvr2_ctrl_get_desc(cptr);
88 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name);
89
90 if (!name) return -EINVAL;
91
92 return scnprintf(buf,PAGE_SIZE,"%s\n",name);
93}
94
95static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
96{
97 struct pvr2_ctrl *cptr;
98 struct pvr2_sysfs *sfp;
99 long val;
100
101 sfp = (struct pvr2_sysfs *)class_dev->class_data;
102 if (!sfp) return -EINVAL;
103 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
104 if (!cptr) return -EINVAL;
105 val = pvr2_ctrl_get_min(cptr);
106
107 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val);
108
109 return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
110}
111
112static ssize_t show_max(int id,struct class_device *class_dev,char *buf)
113{
114 struct pvr2_ctrl *cptr;
115 struct pvr2_sysfs *sfp;
116 long val;
117
118 sfp = (struct pvr2_sysfs *)class_dev->class_data;
119 if (!sfp) return -EINVAL;
120 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
121 if (!cptr) return -EINVAL;
122 val = pvr2_ctrl_get_max(cptr);
123
124 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val);
125
126 return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
127}
128
129static ssize_t show_val_norm(int id,struct class_device *class_dev,char *buf)
130{
131 struct pvr2_ctrl *cptr;
132 struct pvr2_sysfs *sfp;
133 int val,ret;
134 unsigned int cnt = 0;
135
136 sfp = (struct pvr2_sysfs *)class_dev->class_data;
137 if (!sfp) return -EINVAL;
138 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
139 if (!cptr) return -EINVAL;
140
141 ret = pvr2_ctrl_get_value(cptr,&val);
142 if (ret < 0) return ret;
143
144 ret = pvr2_ctrl_value_to_sym(cptr,~0,val,
145 buf,PAGE_SIZE-1,&cnt);
146
147 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
148 sfp,id,cnt,buf,val);
149 buf[cnt] = '\n';
150 return cnt+1;
151}
152
153static ssize_t show_val_custom(int id,struct class_device *class_dev,char *buf)
154{
155 struct pvr2_ctrl *cptr;
156 struct pvr2_sysfs *sfp;
157 int val,ret;
158 unsigned int cnt = 0;
159
160 sfp = (struct pvr2_sysfs *)class_dev->class_data;
161 if (!sfp) return -EINVAL;
162 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
163 if (!cptr) return -EINVAL;
164
165 ret = pvr2_ctrl_get_value(cptr,&val);
166 if (ret < 0) return ret;
167
168 ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val,
169 buf,PAGE_SIZE-1,&cnt);
170
171 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
172 sfp,id,cnt,buf,val);
173 buf[cnt] = '\n';
174 return cnt+1;
175}
176
177static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
178{
179 struct pvr2_ctrl *cptr;
180 struct pvr2_sysfs *sfp;
181 long val;
182 unsigned int bcnt,ccnt,ecnt;
183
184 sfp = (struct pvr2_sysfs *)class_dev->class_data;
185 if (!sfp) return -EINVAL;
186 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
187 if (!cptr) return -EINVAL;
188 ecnt = pvr2_ctrl_get_cnt(cptr);
189 bcnt = 0;
190 for (val = 0; val < ecnt; val++) {
191 pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
192 bcnt += ccnt;
193 if (bcnt >= PAGE_SIZE) break;
194 buf[bcnt] = '\n';
195 bcnt++;
196 }
197 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id);
198 return bcnt;
199}
200
201static ssize_t show_bits(int id,struct class_device *class_dev,char *buf)
202{
203 struct pvr2_ctrl *cptr;
204 struct pvr2_sysfs *sfp;
205 int valid_bits,msk;
206 unsigned int bcnt,ccnt;
207
208 sfp = (struct pvr2_sysfs *)class_dev->class_data;
209 if (!sfp) return -EINVAL;
210 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
211 if (!cptr) return -EINVAL;
212 valid_bits = pvr2_ctrl_get_mask(cptr);
213 bcnt = 0;
214 for (msk = 1; valid_bits; msk <<= 1) {
215 if (!(msk & valid_bits)) continue;
216 valid_bits &= ~msk;
217 pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
218 bcnt += ccnt;
219 if (bcnt >= PAGE_SIZE) break;
220 buf[bcnt] = '\n';
221 bcnt++;
222 }
223 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id);
224 return bcnt;
225}
226
227static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp,
228 const char *buf,unsigned int count)
229{
230 struct pvr2_ctrl *cptr;
231 int ret;
232 int mask,val;
233
234 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
235 if (customfl) {
236 ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val);
237 } else {
238 ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val);
239 }
240 if (ret < 0) return ret;
241 ret = pvr2_ctrl_set_mask_value(cptr,mask,val);
242 pvr2_hdw_commit_ctl(sfp->channel.hdw);
243 return ret;
244}
245
246static ssize_t store_val_norm(int id,struct class_device *class_dev,
247 const char *buf,size_t count)
248{
249 struct pvr2_sysfs *sfp;
250 int ret;
251 sfp = (struct pvr2_sysfs *)class_dev->class_data;
252 ret = store_val_any(id,0,sfp,buf,count);
253 if (!ret) ret = count;
254 return ret;
255}
256
257static ssize_t store_val_custom(int id,struct class_device *class_dev,
258 const char *buf,size_t count)
259{
260 struct pvr2_sysfs *sfp;
261 int ret;
262 sfp = (struct pvr2_sysfs *)class_dev->class_data;
263 ret = store_val_any(id,1,sfp,buf,count);
264 if (!ret) ret = count;
265 return ret;
266}
267
268/*
269 Mike Isely <isely@pobox.com> 30-April-2005
270
271 This next batch of horrible preprocessor hackery is needed because the
272 kernel's class_device_attribute mechanism fails to pass the actual
273 attribute through to the show / store functions, which means we have no
274 way to package up any attribute-specific parameters, like for example the
275 control id. So we work around this brain-damage by encoding the control
276 id into the show / store functions themselves and pick the function based
277 on the control id we're setting up. These macros try to ease the pain.
278 Yuck.
279*/
280
281#define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \
282static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,char *buf) \
283{ return sf_name(ctl_id,class_dev,buf); }
284
285#define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
286static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf,size_t count) \
287{ return sf_name(ctl_id,class_dev,buf,count); }
288
289#define CREATE_BATCH(ctl_id) \
290CREATE_SHOW_INSTANCE(show_name,ctl_id) \
291CREATE_SHOW_INSTANCE(show_min,ctl_id) \
292CREATE_SHOW_INSTANCE(show_max,ctl_id) \
293CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
294CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \
295CREATE_SHOW_INSTANCE(show_enum,ctl_id) \
296CREATE_SHOW_INSTANCE(show_bits,ctl_id) \
297CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \
298CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \
299
300CREATE_BATCH(0)
301CREATE_BATCH(1)
302CREATE_BATCH(2)
303CREATE_BATCH(3)
304CREATE_BATCH(4)
305CREATE_BATCH(5)
306CREATE_BATCH(6)
307CREATE_BATCH(7)
308CREATE_BATCH(8)
309CREATE_BATCH(9)
310CREATE_BATCH(10)
311CREATE_BATCH(11)
312CREATE_BATCH(12)
313CREATE_BATCH(13)
314CREATE_BATCH(14)
315CREATE_BATCH(15)
316CREATE_BATCH(16)
317CREATE_BATCH(17)
318CREATE_BATCH(18)
319CREATE_BATCH(19)
320CREATE_BATCH(20)
321CREATE_BATCH(21)
322CREATE_BATCH(22)
323CREATE_BATCH(23)
324CREATE_BATCH(24)
325CREATE_BATCH(25)
326CREATE_BATCH(26)
327CREATE_BATCH(27)
328CREATE_BATCH(28)
329CREATE_BATCH(29)
330CREATE_BATCH(30)
331CREATE_BATCH(31)
332CREATE_BATCH(32)
333CREATE_BATCH(33)
334
335struct pvr2_sysfs_func_set {
336 ssize_t (*show_name)(struct class_device *,char *);
337 ssize_t (*show_min)(struct class_device *,char *);
338 ssize_t (*show_max)(struct class_device *,char *);
339 ssize_t (*show_enum)(struct class_device *,char *);
340 ssize_t (*show_bits)(struct class_device *,char *);
341 ssize_t (*show_val_norm)(struct class_device *,char *);
342 ssize_t (*store_val_norm)(struct class_device *,
343 const char *,size_t);
344 ssize_t (*show_val_custom)(struct class_device *,char *);
345 ssize_t (*store_val_custom)(struct class_device *,
346 const char *,size_t);
347};
348
349#define INIT_BATCH(ctl_id) \
350[ctl_id] = { \
351 .show_name = show_name_##ctl_id, \
352 .show_min = show_min_##ctl_id, \
353 .show_max = show_max_##ctl_id, \
354 .show_enum = show_enum_##ctl_id, \
355 .show_bits = show_bits_##ctl_id, \
356 .show_val_norm = show_val_norm_##ctl_id, \
357 .store_val_norm = store_val_norm_##ctl_id, \
358 .show_val_custom = show_val_custom_##ctl_id, \
359 .store_val_custom = store_val_custom_##ctl_id, \
360} \
361
362static struct pvr2_sysfs_func_set funcs[] = {
363 INIT_BATCH(0),
364 INIT_BATCH(1),
365 INIT_BATCH(2),
366 INIT_BATCH(3),
367 INIT_BATCH(4),
368 INIT_BATCH(5),
369 INIT_BATCH(6),
370 INIT_BATCH(7),
371 INIT_BATCH(8),
372 INIT_BATCH(9),
373 INIT_BATCH(10),
374 INIT_BATCH(11),
375 INIT_BATCH(12),
376 INIT_BATCH(13),
377 INIT_BATCH(14),
378 INIT_BATCH(15),
379 INIT_BATCH(16),
380 INIT_BATCH(17),
381 INIT_BATCH(18),
382 INIT_BATCH(19),
383 INIT_BATCH(20),
384 INIT_BATCH(21),
385 INIT_BATCH(22),
386 INIT_BATCH(23),
387 INIT_BATCH(24),
388 INIT_BATCH(25),
389 INIT_BATCH(26),
390 INIT_BATCH(27),
391 INIT_BATCH(28),
392 INIT_BATCH(29),
393 INIT_BATCH(30),
394 INIT_BATCH(31),
395 INIT_BATCH(32),
396 INIT_BATCH(33),
397};
398
399
400static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
401{
402 struct pvr2_sysfs_ctl_item *cip;
403 struct pvr2_sysfs_func_set *fp;
404 struct pvr2_ctrl *cptr;
405 unsigned int cnt,acnt;
406
407 if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) {
408 return;
409 }
410
411 fp = funcs + ctl_id;
412 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
413 if (!cptr) return;
414
415 cip = kmalloc(sizeof(*cip),GFP_KERNEL);
416 if (!cip) return;
417 memset(cip,0,sizeof(*cip));
418 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
419
420 cip->cptr = cptr;
421
422 cip->chptr = sfp;
423 cip->item_next = 0;
424 if (sfp->item_last) {
425 sfp->item_last->item_next = cip;
426 } else {
427 sfp->item_first = cip;
428 }
429 sfp->item_last = cip;
430
431 cip->attr_name.attr.owner = THIS_MODULE;
432 cip->attr_name.attr.name = "name";
433 cip->attr_name.attr.mode = S_IRUGO;
434 cip->attr_name.show = fp->show_name;
435
436 cip->attr_min.attr.owner = THIS_MODULE;
437 cip->attr_min.attr.name = "min_val";
438 cip->attr_min.attr.mode = S_IRUGO;
439 cip->attr_min.show = fp->show_min;
440
441 cip->attr_max.attr.owner = THIS_MODULE;
442 cip->attr_max.attr.name = "max_val";
443 cip->attr_max.attr.mode = S_IRUGO;
444 cip->attr_max.show = fp->show_max;
445
446 cip->attr_val.attr.owner = THIS_MODULE;
447 cip->attr_val.attr.name = "cur_val";
448 cip->attr_val.attr.mode = S_IRUGO;
449
450 cip->attr_custom.attr.owner = THIS_MODULE;
451 cip->attr_custom.attr.name = "custom_val";
452 cip->attr_custom.attr.mode = S_IRUGO;
453
454 cip->attr_enum.attr.owner = THIS_MODULE;
455 cip->attr_enum.attr.name = "enum_val";
456 cip->attr_enum.attr.mode = S_IRUGO;
457 cip->attr_enum.show = fp->show_enum;
458
459 cip->attr_bits.attr.owner = THIS_MODULE;
460 cip->attr_bits.attr.name = "bit_val";
461 cip->attr_bits.attr.mode = S_IRUGO;
462 cip->attr_bits.show = fp->show_bits;
463
464 if (pvr2_ctrl_is_writable(cptr)) {
465 cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
466 cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP;
467 }
468
469 acnt = 0;
470 cip->attr_gen[acnt++] = &cip->attr_name.attr;
471 cip->attr_gen[acnt++] = &cip->attr_val.attr;
472 cip->attr_val.show = fp->show_val_norm;
473 cip->attr_val.store = fp->store_val_norm;
474 if (pvr2_ctrl_has_custom_symbols(cptr)) {
475 cip->attr_gen[acnt++] = &cip->attr_custom.attr;
476 cip->attr_custom.show = fp->show_val_custom;
477 cip->attr_custom.store = fp->store_val_custom;
478 }
479 switch (pvr2_ctrl_get_type(cptr)) {
480 case pvr2_ctl_enum:
481 // Control is an enumeration
482 cip->attr_gen[acnt++] = &cip->attr_enum.attr;
483 break;
484 case pvr2_ctl_int:
485 // Control is an integer
486 cip->attr_gen[acnt++] = &cip->attr_min.attr;
487 cip->attr_gen[acnt++] = &cip->attr_max.attr;
488 break;
489 case pvr2_ctl_bitmask:
490 // Control is an bitmask
491 cip->attr_gen[acnt++] = &cip->attr_bits.attr;
492 break;
493 default: break;
494 }
495
496 cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
497 pvr2_ctrl_get_name(cptr));
498 cip->name[cnt] = 0;
499 cip->grp.name = cip->name;
500 cip->grp.attrs = cip->attr_gen;
501
502 sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
503}
504
505#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
506static ssize_t debuginfo_show(struct class_device *,char *);
507static ssize_t debugcmd_show(struct class_device *,char *);
508static ssize_t debugcmd_store(struct class_device *,const char *,size_t count);
509
510static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
511{
512 struct pvr2_sysfs_debugifc *dip;
513 dip = kmalloc(sizeof(*dip),GFP_KERNEL);
514 if (!dip) return;
515 memset(dip,0,sizeof(*dip));
516 dip->attr_debugcmd.attr.owner = THIS_MODULE;
517 dip->attr_debugcmd.attr.name = "debugcmd";
518 dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
519 dip->attr_debugcmd.show = debugcmd_show;
520 dip->attr_debugcmd.store = debugcmd_store;
521 dip->attr_debuginfo.attr.owner = THIS_MODULE;
522 dip->attr_debuginfo.attr.name = "debuginfo";
523 dip->attr_debuginfo.attr.mode = S_IRUGO;
524 dip->attr_debuginfo.show = debuginfo_show;
525 sfp->debugifc = dip;
526 class_device_create_file(sfp->class_dev,&dip->attr_debugcmd);
527 class_device_create_file(sfp->class_dev,&dip->attr_debuginfo);
528}
529
530
531static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
532{
533 if (!sfp->debugifc) return;
534 class_device_remove_file(sfp->class_dev,
535 &sfp->debugifc->attr_debuginfo);
536 class_device_remove_file(sfp->class_dev,&sfp->debugifc->attr_debugcmd);
537 kfree(sfp->debugifc);
538 sfp->debugifc = 0;
539}
540#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
541
542
543static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
544{
545 unsigned int idx,cnt;
546 cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw);
547 for (idx = 0; idx < cnt; idx++) {
548 pvr2_sysfs_add_control(sfp,idx);
549 }
550}
551
552
553static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
554{
555 struct pvr2_sysfs_ctl_item *cip1,*cip2;
556 for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
557 cip2 = cip1->item_next;
558 sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
559 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
560 kfree(cip1);
561 }
562}
563
564
565static void pvr2_sysfs_class_release(struct class *class)
566{
567 struct pvr2_sysfs_class *clp;
568 clp = container_of(class,struct pvr2_sysfs_class,class);
569 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp);
570 kfree(clp);
571}
572
573
574static void pvr2_sysfs_release(struct class_device *class_dev)
575{
576 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev);
577 kfree(class_dev);
578}
579
580
581static void class_dev_destroy(struct pvr2_sysfs *sfp)
582{
583 if (!sfp->class_dev) return;
584#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
585 pvr2_sysfs_tear_down_debugifc(sfp);
586#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
587 pvr2_sysfs_tear_down_controls(sfp);
588 class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
589 class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number);
590 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
591 sfp->class_dev->class_data = 0;
592 class_device_unregister(sfp->class_dev);
593 sfp->class_dev = 0;
594}
595
596
597static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf)
598{
599 struct pvr2_sysfs *sfp;
600 sfp = (struct pvr2_sysfs *)class_dev->class_data;
601 if (!sfp) return -EINVAL;
602 return scnprintf(buf,PAGE_SIZE,"%d\n",
603 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw));
604}
605
606
607static ssize_t unit_number_show(struct class_device *class_dev,char *buf)
608{
609 struct pvr2_sysfs *sfp;
610 sfp = (struct pvr2_sysfs *)class_dev->class_data;
611 if (!sfp) return -EINVAL;
612 return scnprintf(buf,PAGE_SIZE,"%d\n",
613 pvr2_hdw_get_unit_number(sfp->channel.hdw));
614}
615
616
617static void class_dev_create(struct pvr2_sysfs *sfp,
618 struct pvr2_sysfs_class *class_ptr)
619{
620 struct usb_device *usb_dev;
621 struct class_device *class_dev;
622 usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw);
623 if (!usb_dev) return;
624 class_dev = kmalloc(sizeof(*class_dev),GFP_KERNEL);
625 if (!class_dev) return;
626 memset(class_dev,0,sizeof(*class_dev));
627
628 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
629
630 class_dev->class = &class_ptr->class;
631 if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
632 snprintf(class_dev->class_id,BUS_ID_SIZE,"sn-%lu",
633 pvr2_hdw_get_sn(sfp->channel.hdw));
634 } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
635 snprintf(class_dev->class_id,BUS_ID_SIZE,"unit-%c",
636 pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
637 } else {
638 kfree(class_dev);
639 return;
640 }
641
642 class_dev->dev = &usb_dev->dev;
643
644 sfp->class_dev = class_dev;
645 class_dev->class_data = sfp;
646 class_device_register(class_dev);
647
648 sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE;
649 sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
650 sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
651 sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
652 sfp->attr_v4l_minor_number.store = 0;
653 class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number);
654 sfp->attr_unit_number.attr.owner = THIS_MODULE;
655 sfp->attr_unit_number.attr.name = "unit_number";
656 sfp->attr_unit_number.attr.mode = S_IRUGO;
657 sfp->attr_unit_number.show = unit_number_show;
658 sfp->attr_unit_number.store = 0;
659 class_device_create_file(sfp->class_dev,&sfp->attr_unit_number);
660
661 pvr2_sysfs_add_controls(sfp);
662#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
663 pvr2_sysfs_add_debugifc(sfp);
664#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
665}
666
667
668static void pvr2_sysfs_internal_check(struct pvr2_channel *chp)
669{
670 struct pvr2_sysfs *sfp;
671 sfp = container_of(chp,struct pvr2_sysfs,channel);
672 if (!sfp->channel.mc_head->disconnect_flag) return;
673 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp);
674 class_dev_destroy(sfp);
675 pvr2_channel_done(&sfp->channel);
676 kfree(sfp);
677}
678
679
680struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
681 struct pvr2_sysfs_class *class_ptr)
682{
683 struct pvr2_sysfs *sfp;
684 sfp = kmalloc(sizeof(*sfp),GFP_KERNEL);
685 if (!sfp) return sfp;
686 memset(sfp,0,sizeof(*sfp));
687 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp);
688 pvr2_channel_init(&sfp->channel,mp);
689 sfp->channel.check_func = pvr2_sysfs_internal_check;
690
691 class_dev_create(sfp,class_ptr);
692 return sfp;
693}
694
695
696static int pvr2_sysfs_hotplug(struct class_device *cd,char **envp,
697 int numenvp,char *buf,int size)
698{
699 /* Even though we don't do anything here, we still need this function
700 because sysfs will still try to call it. */
701 return 0;
702}
703
704struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
705{
706 struct pvr2_sysfs_class *clp;
707 clp = kmalloc(sizeof(*clp),GFP_KERNEL);
708 if (!clp) return clp;
709 memset(clp,0,sizeof(*clp));
710 pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp);
711 clp->class.name = "pvrusb2";
712 clp->class.class_release = pvr2_sysfs_class_release;
713 clp->class.release = pvr2_sysfs_release;
714 clp->class.uevent = pvr2_sysfs_hotplug;
715 if (class_register(&clp->class)) {
716 pvr2_sysfs_trace(
717 "Registration failed for pvr2_sysfs_class id=%p",clp);
718 kfree(clp);
719 clp = 0;
720 }
721 return clp;
722}
723
724
725void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
726{
727 class_unregister(&clp->class);
728}
729
730
731#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
732static ssize_t debuginfo_show(struct class_device *class_dev,char *buf)
733{
734 struct pvr2_sysfs *sfp;
735 sfp = (struct pvr2_sysfs *)class_dev->class_data;
736 if (!sfp) return -EINVAL;
737 pvr2_hdw_trigger_module_log(sfp->channel.hdw);
738 return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
739}
740
741
742static ssize_t debugcmd_show(struct class_device *class_dev,char *buf)
743{
744 struct pvr2_sysfs *sfp;
745 sfp = (struct pvr2_sysfs *)class_dev->class_data;
746 if (!sfp) return -EINVAL;
747 return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
748}
749
750
751static ssize_t debugcmd_store(struct class_device *class_dev,
752 const char *buf,size_t count)
753{
754 struct pvr2_sysfs *sfp;
755 int ret;
756
757 sfp = (struct pvr2_sysfs *)class_dev->class_data;
758 if (!sfp) return -EINVAL;
759
760 ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
761 if (ret < 0) return ret;
762 return count;
763}
764#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
765
766
767/*
768 Stuff for Emacs to see, in order to encourage consistent editing style:
769 *** Local Variables: ***
770 *** mode: c ***
771 *** fill-column: 75 ***
772 *** tab-width: 8 ***
773 *** c-basic-offset: 8 ***
774 *** End: ***
775 */
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..74b681aeda2f
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -0,0 +1,1056 @@
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 "pvrusb2-context.h"
25#include "pvrusb2-hdw.h"
26#include "pvrusb2.h"
27#include "pvrusb2-debug.h"
28#include "pvrusb2-v4l2.h"
29#include "pvrusb2-ioread.h"
30#include <linux/videodev2.h>
31#include <media/v4l2-common.h>
32
33struct pvr2_v4l2_dev;
34struct pvr2_v4l2_fh;
35struct pvr2_v4l2;
36
37/* V4L no longer provide the ability to set / get a private context pointer
38 (i.e. video_get_drvdata / video_set_drvdata), which means we have to
39 concoct our own context locating mechanism. Supposedly this is intended
40 to simplify driver implementation. It's not clear to me how that can
41 possibly be true. Our solution here is to maintain a lookup table of
42 our context instances, indexed by the minor device number of the V4L
43 device. See pvr2_v4l2_open() for some implications of this approach. */
44static struct pvr2_v4l2_dev *devices[256];
45static DEFINE_MUTEX(device_lock);
46
47struct pvr2_v4l2_dev {
48 struct pvr2_v4l2 *v4lp;
49 struct video_device *vdev;
50 struct pvr2_context_stream *stream;
51 int ctxt_idx;
52 enum pvr2_config config;
53};
54
55struct pvr2_v4l2_fh {
56 struct pvr2_channel channel;
57 struct pvr2_v4l2_dev *dev_info;
58 enum v4l2_priority prio;
59 struct pvr2_ioread *rhp;
60 struct file *file;
61 struct pvr2_v4l2 *vhead;
62 struct pvr2_v4l2_fh *vnext;
63 struct pvr2_v4l2_fh *vprev;
64 wait_queue_head_t wait_data;
65 int fw_mode_flag;
66};
67
68struct pvr2_v4l2 {
69 struct pvr2_channel channel;
70 struct pvr2_v4l2_fh *vfirst;
71 struct pvr2_v4l2_fh *vlast;
72
73 struct v4l2_prio_state prio;
74
75 /* streams */
76 struct pvr2_v4l2_dev video_dev;
77};
78
79static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
80module_param_array(video_nr, int, NULL, 0444);
81MODULE_PARM_DESC(video_nr, "Offset for device's minor");
82
83struct v4l2_capability pvr_capability ={
84 .driver = "pvrusb2",
85 .card = "Hauppauge WinTV pvr-usb2",
86 .bus_info = "usb",
87 .version = KERNEL_VERSION(0,8,0),
88 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
89 V4L2_CAP_TUNER | V4L2_CAP_AUDIO |
90 V4L2_CAP_READWRITE),
91 .reserved = {0,0,0,0}
92};
93
94static struct v4l2_tuner pvr_v4l2_tuners[]= {
95 {
96 .index = 0,
97 .name = "TV Tuner",
98 .type = V4L2_TUNER_ANALOG_TV,
99 .capability = (V4L2_TUNER_CAP_NORM |
100 V4L2_TUNER_CAP_STEREO |
101 V4L2_TUNER_CAP_LANG1 |
102 V4L2_TUNER_CAP_LANG2),
103 .rangelow = 0,
104 .rangehigh = 0,
105 .rxsubchans = V4L2_TUNER_SUB_STEREO,
106 .audmode = V4L2_TUNER_MODE_STEREO,
107 .signal = 0,
108 .afc = 0,
109 .reserved = {0,0,0,0}
110 }
111};
112
113struct v4l2_fmtdesc pvr_fmtdesc [] = {
114 {
115 .index = 0,
116 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
117 .flags = V4L2_FMT_FLAG_COMPRESSED,
118 .description = "MPEG1/2",
119 // This should really be V4L2_PIX_FMT_MPEG, but xawtv
120 // breaks when I do that.
121 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
122 .reserved = { 0, 0, 0, 0 }
123 }
124};
125
126#define PVR_FORMAT_PIX 0
127#define PVR_FORMAT_VBI 1
128
129struct v4l2_format pvr_format [] = {
130 [PVR_FORMAT_PIX] = {
131 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
132 .fmt = {
133 .pix = {
134 .width = 720,
135 .height = 576,
136 // This should really be V4L2_PIX_FMT_MPEG,
137 // but xawtv breaks when I do that.
138 .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
139 .field = V4L2_FIELD_INTERLACED,
140 .bytesperline = 0, // doesn't make sense
141 // here
142 //FIXME : Don't know what to put here...
143 .sizeimage = (32*1024),
144 .colorspace = 0, // doesn't make sense here
145 .priv = 0
146 }
147 }
148 },
149 [PVR_FORMAT_VBI] = {
150 .type = V4L2_BUF_TYPE_VBI_CAPTURE,
151 .fmt = {
152 .vbi = {
153 .sampling_rate = 27000000,
154 .offset = 248,
155 .samples_per_line = 1443,
156 .sample_format = V4L2_PIX_FMT_GREY,
157 .start = { 0, 0 },
158 .count = { 0, 0 },
159 .flags = 0,
160 .reserved = { 0, 0 }
161 }
162 }
163 }
164};
165
166/*
167 * pvr_ioctl()
168 *
169 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
170 *
171 */
172static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
173 unsigned int cmd, void *arg)
174{
175 struct pvr2_v4l2_fh *fh = file->private_data;
176 struct pvr2_v4l2 *vp = fh->vhead;
177 struct pvr2_v4l2_dev *dev_info = fh->dev_info;
178 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
179 int ret = -EINVAL;
180
181 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
182 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd);
183 }
184
185 if (!pvr2_hdw_dev_ok(hdw)) {
186 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
187 "ioctl failed - bad or no context");
188 return -EFAULT;
189 }
190
191 /* check priority */
192 switch (cmd) {
193 case VIDIOC_S_CTRL:
194 case VIDIOC_S_STD:
195 case VIDIOC_S_INPUT:
196 case VIDIOC_S_TUNER:
197 case VIDIOC_S_FREQUENCY:
198 ret = v4l2_prio_check(&vp->prio, &fh->prio);
199 if (ret)
200 return ret;
201 }
202
203 switch (cmd) {
204 case VIDIOC_QUERYCAP:
205 {
206 struct v4l2_capability *cap = arg;
207
208 memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
209
210 ret = 0;
211 break;
212 }
213
214 case VIDIOC_G_PRIORITY:
215 {
216 enum v4l2_priority *p = arg;
217
218 *p = v4l2_prio_max(&vp->prio);
219 ret = 0;
220 break;
221 }
222
223 case VIDIOC_S_PRIORITY:
224 {
225 enum v4l2_priority *prio = arg;
226
227 ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio);
228 break;
229 }
230
231 case VIDIOC_ENUMSTD:
232 {
233 struct v4l2_standard *vs = (struct v4l2_standard *)arg;
234 int idx = vs->index;
235 ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1);
236 break;
237 }
238
239 case VIDIOC_G_STD:
240 {
241 int val = 0;
242 ret = pvr2_ctrl_get_value(
243 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val);
244 *(v4l2_std_id *)arg = val;
245 break;
246 }
247
248 case VIDIOC_S_STD:
249 {
250 ret = pvr2_ctrl_set_value(
251 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
252 *(v4l2_std_id *)arg);
253 break;
254 }
255
256 case VIDIOC_ENUMINPUT:
257 {
258 struct pvr2_ctrl *cptr;
259 struct v4l2_input *vi = (struct v4l2_input *)arg;
260 struct v4l2_input tmp;
261 unsigned int cnt;
262
263 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
264
265 memset(&tmp,0,sizeof(tmp));
266 tmp.index = vi->index;
267 ret = 0;
268 switch (vi->index) {
269 case PVR2_CVAL_INPUT_TV:
270 case PVR2_CVAL_INPUT_RADIO:
271 tmp.type = V4L2_INPUT_TYPE_TUNER;
272 break;
273 case PVR2_CVAL_INPUT_SVIDEO:
274 case PVR2_CVAL_INPUT_COMPOSITE:
275 tmp.type = V4L2_INPUT_TYPE_CAMERA;
276 break;
277 default:
278 ret = -EINVAL;
279 break;
280 }
281 if (ret < 0) break;
282
283 cnt = 0;
284 pvr2_ctrl_get_valname(cptr,vi->index,
285 tmp.name,sizeof(tmp.name)-1,&cnt);
286 tmp.name[cnt] = 0;
287
288 /* Don't bother with audioset, since this driver currently
289 always switches the audio whenever the video is
290 switched. */
291
292 /* Handling std is a tougher problem. It doesn't make
293 sense in cases where a device might be multi-standard.
294 We could just copy out the current value for the
295 standard, but it can change over time. For now just
296 leave it zero. */
297
298 memcpy(vi, &tmp, sizeof(tmp));
299
300 ret = 0;
301 break;
302 }
303
304 case VIDIOC_G_INPUT:
305 {
306 struct pvr2_ctrl *cptr;
307 struct v4l2_input *vi = (struct v4l2_input *)arg;
308 int val;
309 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
310 val = 0;
311 ret = pvr2_ctrl_get_value(cptr,&val);
312 vi->index = val;
313 break;
314 }
315
316 case VIDIOC_S_INPUT:
317 {
318 struct v4l2_input *vi = (struct v4l2_input *)arg;
319 ret = pvr2_ctrl_set_value(
320 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
321 vi->index);
322 break;
323 }
324
325 case VIDIOC_ENUMAUDIO:
326 {
327 ret = -EINVAL;
328 break;
329 }
330
331 case VIDIOC_G_AUDIO:
332 {
333 ret = -EINVAL;
334 break;
335 }
336
337 case VIDIOC_S_AUDIO:
338 {
339 ret = -EINVAL;
340 break;
341 }
342 case VIDIOC_G_TUNER:
343 {
344 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
345 unsigned int status_mask;
346 int val;
347 if (vt->index !=0) break;
348
349 status_mask = pvr2_hdw_get_signal_status(hdw);
350
351 memcpy(vt, &pvr_v4l2_tuners[vt->index],
352 sizeof(struct v4l2_tuner));
353
354 vt->signal = 0;
355 if (status_mask & PVR2_SIGNAL_OK) {
356 if (status_mask & PVR2_SIGNAL_STEREO) {
357 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
358 } else {
359 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
360 }
361 if (status_mask & PVR2_SIGNAL_SAP) {
362 vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 |
363 V4L2_TUNER_SUB_LANG2);
364 }
365 vt->signal = 65535;
366 }
367
368 val = 0;
369 ret = pvr2_ctrl_get_value(
370 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
371 &val);
372 vt->audmode = val;
373 break;
374 }
375
376 case VIDIOC_S_TUNER:
377 {
378 struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
379
380 if (vt->index != 0)
381 break;
382
383 ret = pvr2_ctrl_set_value(
384 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
385 vt->audmode);
386 }
387
388 case VIDIOC_S_FREQUENCY:
389 {
390 const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
391 ret = pvr2_ctrl_set_value(
392 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
393 vf->frequency * 62500);
394 break;
395 }
396
397 case VIDIOC_G_FREQUENCY:
398 {
399 struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
400 int val = 0;
401 ret = pvr2_ctrl_get_value(
402 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
403 &val);
404 val /= 62500;
405 vf->frequency = val;
406 break;
407 }
408
409 case VIDIOC_ENUM_FMT:
410 {
411 struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg;
412
413 /* Only one format is supported : mpeg.*/
414 if (fd->index != 0)
415 break;
416
417 memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
418 ret = 0;
419 break;
420 }
421
422 case VIDIOC_G_FMT:
423 {
424 struct v4l2_format *vf = (struct v4l2_format *)arg;
425 int val;
426 switch(vf->type) {
427 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
428 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
429 sizeof(struct v4l2_format));
430 val = 0;
431 pvr2_ctrl_get_value(
432 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES),
433 &val);
434 vf->fmt.pix.width = val;
435 val = 0;
436 pvr2_ctrl_get_value(
437 pvr2_hdw_get_ctrl_by_id(hdw,
438 PVR2_CID_INTERLACE),
439 &val);
440 if (val) vf->fmt.pix.width /= 2;
441 val = 0;
442 pvr2_ctrl_get_value(
443 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES),
444 &val);
445 vf->fmt.pix.height = val;
446 ret = 0;
447 break;
448 case V4L2_BUF_TYPE_VBI_CAPTURE:
449 // ????? Still need to figure out to do VBI correctly
450 ret = -EINVAL;
451 break;
452 default:
453 ret = -EINVAL;
454 break;
455 }
456 break;
457 }
458
459 case VIDIOC_TRY_FMT:
460 case VIDIOC_S_FMT:
461 {
462 struct v4l2_format *vf = (struct v4l2_format *)arg;
463
464 ret = 0;
465 switch(vf->type) {
466 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
467 int h = vf->fmt.pix.height;
468 int w = vf->fmt.pix.width;
469 int vd_std, hf, hh;
470
471 vd_std = 0;
472 pvr2_ctrl_get_value(
473 pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
474 &vd_std);
475 if (vd_std & V4L2_STD_525_60) {
476 hf=480;
477 } else {
478 hf=576;
479 }
480 hh = (int) (hf / 2);
481
482 memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
483 sizeof(struct v4l2_format));
484 if (w > 720)
485 vf->fmt.pix.width = 720;
486 vf->fmt.pix.width &= 0xff0;
487 vf->fmt.pix.height = (h > hh) ? hf : hh;
488
489 if (cmd == VIDIOC_S_FMT) {
490 pvr2_ctrl_set_value(
491 pvr2_hdw_get_ctrl_by_id(hdw,
492 PVR2_CID_HRES),
493 vf->fmt.pix.width);
494 pvr2_ctrl_set_value(
495 pvr2_hdw_get_ctrl_by_id(hdw,
496 PVR2_CID_VRES),
497 vf->fmt.pix.height);
498 pvr2_ctrl_set_value(
499 pvr2_hdw_get_ctrl_by_id(
500 hdw,PVR2_CID_INTERLACE),
501 vf->fmt.pix.height != hf);
502 }
503 } break;
504 case V4L2_BUF_TYPE_VBI_CAPTURE:
505 // ????? Still need to figure out to do VBI correctly
506 ret = -EINVAL;
507 break;
508 default:
509 ret = -EINVAL;
510 break;
511 }
512 break;
513 }
514
515 case VIDIOC_STREAMON:
516 {
517 ret = pvr2_hdw_set_stream_type(hdw,dev_info->config);
518 if (ret < 0) return ret;
519 ret = pvr2_hdw_set_streaming(hdw,!0);
520 break;
521 }
522
523 case VIDIOC_STREAMOFF:
524 {
525 ret = pvr2_hdw_set_streaming(hdw,0);
526 break;
527 }
528
529 case VIDIOC_QUERYCTRL:
530 {
531 struct pvr2_ctrl *cptr;
532 struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg;
533 ret = 0;
534 cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id);
535 if (!cptr) {
536 ret = -EINVAL;
537 break;
538 }
539
540 strlcpy(vc->name,pvr2_ctrl_get_name(cptr),sizeof(vc->name));
541 vc->default_value = pvr2_ctrl_get_def(cptr);
542 switch (pvr2_ctrl_get_type(cptr)) {
543 case pvr2_ctl_enum:
544 vc->type = V4L2_CTRL_TYPE_MENU;
545 vc->minimum = 0;
546 vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
547 vc->step = 1;
548 break;
549 case pvr2_ctl_int:
550 vc->type = V4L2_CTRL_TYPE_INTEGER;
551 vc->minimum = pvr2_ctrl_get_min(cptr);
552 vc->maximum = pvr2_ctrl_get_max(cptr);
553 vc->step = 1;
554 break;
555 default:
556 ret = -EINVAL;
557 break;
558 }
559 break;
560 }
561
562 case VIDIOC_QUERYMENU:
563 {
564 struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg;
565 unsigned int cnt = 0;
566 ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id),
567 vm->index,
568 vm->name,sizeof(vm->name)-1,
569 &cnt);
570 vm->name[cnt] = 0;
571 break;
572 }
573
574 case VIDIOC_G_CTRL:
575 {
576 struct v4l2_control *vc = (struct v4l2_control *)arg;
577 int val = 0;
578 ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
579 &val);
580 vc->value = val;
581 break;
582 }
583
584 case VIDIOC_S_CTRL:
585 {
586 struct v4l2_control *vc = (struct v4l2_control *)arg;
587 ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
588 vc->value);
589 break;
590 }
591
592 case VIDIOC_LOG_STATUS:
593 {
594 int nr = pvr2_hdw_get_unit_number(hdw);
595
596 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
597 pvr2_hdw_trigger_module_log(hdw);
598 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
599 ret = 0;
600 break;
601 }
602
603 default :
604 ret = v4l_compat_translate_ioctl(inode,file,cmd,
605 arg,pvr2_v4l2_do_ioctl);
606 }
607
608 pvr2_hdw_commit_ctl(hdw);
609
610 if (ret < 0) {
611 if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
612 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
613 "pvr2_v4l2_do_ioctl failure, ret=%d",ret);
614 } else {
615 if (pvrusb2_debug & PVR2_TRACE_ERROR_LEGS) {
616 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
617 "pvr2_v4l2_do_ioctl failure, ret=%d"
618 " command was:",ret);
619 v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
620 cmd);
621 }
622 }
623 } else {
624 pvr2_trace(PVR2_TRACE_V4LIOCTL,
625 "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)",
626 ret,ret);
627 }
628 return ret;
629}
630
631
632static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
633{
634 pvr2_trace(PVR2_TRACE_INIT,
635 "unregistering device video%d [%s]",
636 dip->vdev->minor,pvr2_config_get_name(dip->config));
637 if (dip->ctxt_idx >= 0) {
638 mutex_lock(&device_lock);
639 devices[dip->ctxt_idx] = NULL;
640 dip->ctxt_idx = -1;
641 mutex_unlock(&device_lock);
642 }
643 video_unregister_device(dip->vdev);
644}
645
646
647static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
648{
649 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1);
650 pvr2_v4l2_dev_destroy(&vp->video_dev);
651
652 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
653 pvr2_channel_done(&vp->channel);
654 kfree(vp);
655}
656
657
658void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
659{
660 struct pvr2_v4l2 *vp;
661 vp = container_of(chp,struct pvr2_v4l2,channel);
662 if (!vp->channel.mc_head->disconnect_flag) return;
663 if (vp->vfirst) return;
664 pvr2_v4l2_destroy_no_lock(vp);
665}
666
667
668int pvr2_v4l2_ioctl(struct inode *inode, struct file *file,
669 unsigned int cmd, unsigned long arg)
670{
671
672/* Temporary hack : use ivtv api until a v4l2 one is available. */
673#define IVTV_IOC_G_CODEC 0xFFEE7703
674#define IVTV_IOC_S_CODEC 0xFFEE7704
675 if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
676 return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl);
677}
678
679
680int pvr2_v4l2_release(struct inode *inode, struct file *file)
681{
682 struct pvr2_v4l2_fh *fhp = file->private_data;
683 struct pvr2_v4l2 *vp = fhp->vhead;
684 struct pvr2_context *mp = fhp->vhead->channel.mc_head;
685
686 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
687
688 if (fhp->rhp) {
689 struct pvr2_stream *sp;
690 struct pvr2_hdw *hdw;
691 hdw = fhp->channel.mc_head->hdw;
692 pvr2_hdw_set_streaming(hdw,0);
693 sp = pvr2_ioread_get_stream(fhp->rhp);
694 if (sp) pvr2_stream_set_callback(sp,0,0);
695 pvr2_ioread_destroy(fhp->rhp);
696 fhp->rhp = 0;
697 }
698 v4l2_prio_close(&vp->prio, &fhp->prio);
699 file->private_data = NULL;
700
701 pvr2_context_enter(mp); do {
702 if (fhp->vnext) {
703 fhp->vnext->vprev = fhp->vprev;
704 } else {
705 vp->vlast = fhp->vprev;
706 }
707 if (fhp->vprev) {
708 fhp->vprev->vnext = fhp->vnext;
709 } else {
710 vp->vfirst = fhp->vnext;
711 }
712 fhp->vnext = 0;
713 fhp->vprev = 0;
714 fhp->vhead = 0;
715 pvr2_channel_done(&fhp->channel);
716 pvr2_trace(PVR2_TRACE_STRUCT,
717 "Destroying pvr_v4l2_fh id=%p",fhp);
718 kfree(fhp);
719 if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
720 pvr2_v4l2_destroy_no_lock(vp);
721 }
722 } while (0); pvr2_context_exit(mp);
723 return 0;
724}
725
726
727int pvr2_v4l2_open(struct inode *inode, struct file *file)
728{
729 struct pvr2_v4l2_dev *dip = 0; /* Our own context pointer */
730 struct pvr2_v4l2_fh *fhp;
731 struct pvr2_v4l2 *vp;
732 struct pvr2_hdw *hdw;
733
734 mutex_lock(&device_lock);
735 /* MCI 7-Jun-2006 Even though we're just doing what amounts to an
736 atomic read of the device mapping array here, we still need the
737 mutex. The problem is that there is a tiny race possible when
738 we register the device. We can't update the device mapping
739 array until after the device has been registered, owing to the
740 fact that we can't know the minor device number until after the
741 registration succeeds. And if another thread tries to open the
742 device in the window of time after registration but before the
743 map is updated, then it will get back an erroneous null pointer
744 and the open will result in a spurious failure. The only way to
745 prevent that is to (a) be inside the mutex here before we access
746 the array, and (b) cover the entire registration process later
747 on with this same mutex. Thus if we get inside the mutex here,
748 then we can be assured that the registration process actually
749 completed correctly. This is an unhappy complication from the
750 use of global data in a driver that lives in a preemptible
751 environment. It sure would be nice if the video device itself
752 had a means for storing and retrieving a local context pointer.
753 Oh wait. It did. But now it's gone. Silly me. */
754 {
755 unsigned int midx = iminor(file->f_dentry->d_inode);
756 if (midx < sizeof(devices)/sizeof(devices[0])) {
757 dip = devices[midx];
758 }
759 }
760 mutex_unlock(&device_lock);
761
762 if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
763
764 vp = dip->v4lp;
765 hdw = vp->channel.hdw;
766
767 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
768
769 if (!pvr2_hdw_dev_ok(hdw)) {
770 pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
771 "pvr2_v4l2_open: hardware not ready");
772 return -EIO;
773 }
774
775 fhp = kmalloc(sizeof(*fhp),GFP_KERNEL);
776 if (!fhp) {
777 return -ENOMEM;
778 }
779 memset(fhp,0,sizeof(*fhp));
780
781 init_waitqueue_head(&fhp->wait_data);
782 fhp->dev_info = dip;
783
784 pvr2_context_enter(vp->channel.mc_head); do {
785 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
786 pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
787 fhp->vnext = 0;
788 fhp->vprev = vp->vlast;
789 if (vp->vlast) {
790 vp->vlast->vnext = fhp;
791 } else {
792 vp->vfirst = fhp;
793 }
794 vp->vlast = fhp;
795 fhp->vhead = vp;
796 } while (0); pvr2_context_exit(vp->channel.mc_head);
797
798 fhp->file = file;
799 file->private_data = fhp;
800 v4l2_prio_open(&vp->prio,&fhp->prio);
801
802 fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
803
804 return 0;
805}
806
807
808static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
809{
810 wake_up(&fhp->wait_data);
811}
812
813static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
814{
815 int ret;
816 struct pvr2_stream *sp;
817 struct pvr2_hdw *hdw;
818 if (fh->rhp) return 0;
819
820 /* First read() attempt. Try to claim the stream and start
821 it... */
822 if ((ret = pvr2_channel_claim_stream(&fh->channel,
823 fh->dev_info->stream)) != 0) {
824 /* Someone else must already have it */
825 return ret;
826 }
827
828 fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream);
829 if (!fh->rhp) {
830 pvr2_channel_claim_stream(&fh->channel,0);
831 return -ENOMEM;
832 }
833
834 hdw = fh->channel.mc_head->hdw;
835 sp = fh->dev_info->stream->stream;
836 pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
837 pvr2_hdw_set_stream_type(hdw,fh->dev_info->config);
838 pvr2_hdw_set_streaming(hdw,!0);
839 ret = pvr2_ioread_set_enabled(fh->rhp,!0);
840
841 return ret;
842}
843
844
845static ssize_t pvr2_v4l2_read(struct file *file,
846 char __user *buff, size_t count, loff_t *ppos)
847{
848 struct pvr2_v4l2_fh *fh = file->private_data;
849 int ret;
850
851 if (fh->fw_mode_flag) {
852 struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
853 char *tbuf;
854 int c1,c2;
855 int tcnt = 0;
856 unsigned int offs = *ppos;
857
858 tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
859 if (!tbuf) return -ENOMEM;
860
861 while (count) {
862 c1 = count;
863 if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
864 c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
865 if (c2 < 0) {
866 tcnt = c2;
867 break;
868 }
869 if (!c2) break;
870 if (copy_to_user(buff,tbuf,c2)) {
871 tcnt = -EFAULT;
872 break;
873 }
874 offs += c2;
875 tcnt += c2;
876 buff += c2;
877 count -= c2;
878 *ppos += c2;
879 }
880 kfree(tbuf);
881 return tcnt;
882 }
883
884 if (!fh->rhp) {
885 ret = pvr2_v4l2_iosetup(fh);
886 if (ret) {
887 return ret;
888 }
889 }
890
891 for (;;) {
892 ret = pvr2_ioread_read(fh->rhp,buff,count);
893 if (ret >= 0) break;
894 if (ret != -EAGAIN) break;
895 if (file->f_flags & O_NONBLOCK) break;
896 /* Doing blocking I/O. Wait here. */
897 ret = wait_event_interruptible(
898 fh->wait_data,
899 pvr2_ioread_avail(fh->rhp) >= 0);
900 if (ret < 0) break;
901 }
902
903 return ret;
904}
905
906
907static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
908{
909 unsigned int mask = 0;
910 struct pvr2_v4l2_fh *fh = file->private_data;
911 int ret;
912
913 if (fh->fw_mode_flag) {
914 mask |= POLLIN | POLLRDNORM;
915 return mask;
916 }
917
918 if (!fh->rhp) {
919 ret = pvr2_v4l2_iosetup(fh);
920 if (ret) return POLLERR;
921 }
922
923 poll_wait(file,&fh->wait_data,wait);
924
925 if (pvr2_ioread_avail(fh->rhp) >= 0) {
926 mask |= POLLIN | POLLRDNORM;
927 }
928
929 return mask;
930}
931
932
933static struct file_operations vdev_fops = {
934 .owner = THIS_MODULE,
935 .open = pvr2_v4l2_open,
936 .release = pvr2_v4l2_release,
937 .read = pvr2_v4l2_read,
938 .ioctl = pvr2_v4l2_ioctl,
939 .llseek = no_llseek,
940 .poll = pvr2_v4l2_poll,
941};
942
943
944#define VID_HARDWARE_PVRUSB2 38 /* FIXME : need a good value */
945
946static struct video_device vdev_template = {
947 .owner = THIS_MODULE,
948 .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
949 .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
950 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO
951 | V4L2_CAP_READWRITE),
952 .hardware = VID_HARDWARE_PVRUSB2,
953 .fops = &vdev_fops,
954};
955
956
957static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
958 struct pvr2_v4l2 *vp,
959 enum pvr2_config cfg)
960{
961 int mindevnum;
962 int unit_number;
963 int v4l_type;
964 dip->v4lp = vp;
965 dip->config = cfg;
966
967
968 switch (cfg) {
969 case pvr2_config_mpeg:
970 v4l_type = VFL_TYPE_GRABBER;
971 dip->stream = &vp->channel.mc_head->video_stream;
972 break;
973 case pvr2_config_vbi:
974 v4l_type = VFL_TYPE_VBI;
975 break;
976 case pvr2_config_radio:
977 v4l_type = VFL_TYPE_RADIO;
978 break;
979 default:
980 /* Bail out (this should be impossible) */
981 err("Failed to set up pvrusb2 v4l dev"
982 " due to unrecognized config");
983 return;
984 }
985
986 if (!dip->stream) {
987 err("Failed to set up pvrusb2 v4l dev"
988 " due to missing stream instance");
989 return;
990 }
991
992 dip->vdev = video_device_alloc();
993 if (!dip->vdev) {
994 err("Alloc of pvrusb2 v4l video device failed");
995 return;
996 }
997
998 memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
999 dip->vdev->release = video_device_release;
1000 mutex_lock(&device_lock);
1001
1002 mindevnum = -1;
1003 unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
1004 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1005 mindevnum = video_nr[unit_number];
1006 }
1007 if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) &&
1008 (video_register_device(dip->vdev, v4l_type, -1) < 0)) {
1009 err("Failed to register pvrusb2 v4l video device");
1010 } else {
1011 pvr2_trace(PVR2_TRACE_INIT,
1012 "registered device video%d [%s]",
1013 dip->vdev->minor,pvr2_config_get_name(dip->config));
1014 }
1015
1016 if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) &&
1017 (devices[dip->vdev->minor] == NULL)) {
1018 dip->ctxt_idx = dip->vdev->minor;
1019 devices[dip->ctxt_idx] = dip;
1020 }
1021 mutex_unlock(&device_lock);
1022
1023 pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
1024 dip->vdev->minor);
1025}
1026
1027
1028struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1029{
1030 struct pvr2_v4l2 *vp;
1031
1032 vp = kmalloc(sizeof(*vp),GFP_KERNEL);
1033 if (!vp) return vp;
1034 memset(vp,0,sizeof(*vp));
1035 vp->video_dev.ctxt_idx = -1;
1036 pvr2_channel_init(&vp->channel,mnp);
1037 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1038
1039 vp->channel.check_func = pvr2_v4l2_internal_check;
1040
1041 /* register streams */
1042 pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg);
1043
1044
1045 return vp;
1046}
1047
1048/*
1049 Stuff for Emacs to see, in order to encourage consistent editing style:
1050 *** Local Variables: ***
1051 *** mode: c ***
1052 *** fill-column: 75 ***
1053 *** tab-width: 8 ***
1054 *** c-basic-offset: 8 ***
1055 *** End: ***
1056 */
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..4127c82f7bf6
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -0,0 +1,250 @@
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 PVR2_CVAL_SRATE_48:
95 val = 48000;
96 break;
97 case PVR2_CVAL_SRATE_44_1:
98 val = 44100;
99 break;
100 }
101 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
102}
103
104
105static int check_audio(struct pvr2_v4l_decoder *ctxt)
106{
107 struct pvr2_hdw *hdw = ctxt->hdw;
108 return hdw->srate_dirty != 0;
109}
110
111
112struct pvr2_v4l_decoder_ops {
113 void (*update)(struct pvr2_v4l_decoder *);
114 int (*check)(struct pvr2_v4l_decoder *);
115};
116
117
118static const struct pvr2_v4l_decoder_ops decoder_ops[] = {
119 { .update = set_input, .check = check_input},
120 { .update = set_audio, .check = check_audio},
121};
122
123
124static void decoder_detach(struct pvr2_v4l_decoder *ctxt)
125{
126 ctxt->client->handler = 0;
127 ctxt->hdw->decoder_ctrl = 0;
128 kfree(ctxt);
129}
130
131
132static int decoder_check(struct pvr2_v4l_decoder *ctxt)
133{
134 unsigned long msk;
135 unsigned int idx;
136
137 for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
138 idx++) {
139 msk = 1 << idx;
140 if (ctxt->stale_mask & msk) continue;
141 if (decoder_ops[idx].check(ctxt)) {
142 ctxt->stale_mask |= msk;
143 }
144 }
145 return ctxt->stale_mask != 0;
146}
147
148
149static void decoder_update(struct pvr2_v4l_decoder *ctxt)
150{
151 unsigned long msk;
152 unsigned int idx;
153
154 for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]);
155 idx++) {
156 msk = 1 << idx;
157 if (!(ctxt->stale_mask & msk)) continue;
158 ctxt->stale_mask &= ~msk;
159 decoder_ops[idx].update(ctxt);
160 }
161}
162
163
164static int decoder_detect(struct pvr2_i2c_client *cp)
165{
166 /* Attempt to query the decoder - let's see if it will answer */
167 struct v4l2_tuner vt;
168 int ret;
169
170 memset(&vt,0,sizeof(vt));
171 ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt);
172 return ret == 0; /* Return true if it answered */
173}
174
175
176static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl)
177{
178 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl);
179 pvr2_v4l2_cmd_stream(ctxt->client,fl);
180}
181
182
183static int decoder_is_tuned(struct pvr2_v4l_decoder *ctxt)
184{
185 struct v4l2_tuner vt;
186 int ret;
187
188 memset(&vt,0,sizeof(vt));
189 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt);
190 if (ret < 0) return -EINVAL;
191 return vt.signal ? 1 : 0;
192}
193
194
195static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt)
196{
197 return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l");
198}
199
200
201const static struct pvr2_i2c_handler_functions hfuncs = {
202 .detach = (void (*)(void *))decoder_detach,
203 .check = (int (*)(void *))decoder_check,
204 .update = (void (*)(void *))decoder_update,
205 .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
206};
207
208
209int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
210 struct pvr2_i2c_client *cp)
211{
212 struct pvr2_v4l_decoder *ctxt;
213
214 if (hdw->decoder_ctrl) return 0;
215 if (cp->handler) return 0;
216 if (!decoder_detect(cp)) return 0;
217
218 ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
219 if (!ctxt) return 0;
220 memset(ctxt,0,sizeof(*ctxt));
221
222 ctxt->handler.func_data = ctxt;
223 ctxt->handler.func_table = &hfuncs;
224 ctxt->ctrl.ctxt = ctxt;
225 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
226 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
227 ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned;
228 ctxt->client = cp;
229 ctxt->hdw = hdw;
230 ctxt->stale_mask = (1 << (sizeof(decoder_ops)/
231 sizeof(decoder_ops[0]))) - 1;
232 hdw->decoder_ctrl = &ctxt->ctrl;
233 cp->handler = &ctxt->handler;
234 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up",
235 cp->client->addr);
236 return !0;
237}
238
239
240
241
242/*
243 Stuff for Emacs to see, in order to encourage consistent editing style:
244 *** Local Variables: ***
245 *** mode: c ***
246 *** fill-column: 70 ***
247 *** tab-width: 8 ***
248 *** c-basic-offset: 8 ***
249 *** End: ***
250 */
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 */