aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pvrusb2')
-rw-r--r--drivers/media/video/pvrusb2/Kconfig8
-rw-r--r--drivers/media/video/pvrusb2/Makefile7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c142
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.h6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c95
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h (renamed from drivers/media/video/pvrusb2/pvrusb2-tuner.h)21
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c245
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c5
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.h12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c102
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h34
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h50
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c648
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c113
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c322
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h50
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c417
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.h57
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-tuner.c120
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c18
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c214
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.h7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.c134
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.h4
30 files changed, 904 insertions, 1957 deletions
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 854c2a885358..f9b6001e1dd7 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -40,10 +40,10 @@ config VIDEO_PVRUSB2_DVB
40 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 40 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
41 select DVB_S5H1409 if !DVB_FE_CUSTOMISE 41 select DVB_S5H1409 if !DVB_FE_CUSTOMISE
42 select DVB_S5H1411 if !DVB_FE_CUSTOMISE 42 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
43 select DVB_TDA10048 if !DVB_FE_CUSTOMIZE 43 select DVB_TDA10048 if !DVB_FE_CUSTOMISE
44 select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE 44 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
45 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE 45 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
46 select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE 46 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
47 ---help--- 47 ---help---
48 48
49 This option enables a DVB interface for the pvrusb2 driver. 49 This option enables a DVB interface for the pvrusb2 driver.
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
index 4fda2de69ab7..de2fc14f043b 100644
--- a/drivers/media/video/pvrusb2/Makefile
+++ b/drivers/media/video/pvrusb2/Makefile
@@ -2,14 +2,15 @@ obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
2obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o 2obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
3obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o 3obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o
4 4
5pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ 5pvrusb2-objs := pvrusb2-i2c-core.o \
6 pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \ 6 pvrusb2-audio.o \
7 pvrusb2-encoder.o pvrusb2-video-v4l.o \ 7 pvrusb2-encoder.o pvrusb2-video-v4l.o \
8 pvrusb2-eeprom.o pvrusb2-tuner.o \ 8 pvrusb2-eeprom.o \
9 pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \ 9 pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
10 pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \ 10 pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \
11 pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ 11 pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
12 pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \ 12 pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
13 pvrusb2-cs53l32a.o \
13 $(obj-pvrusb2-dvb-y) \ 14 $(obj-pvrusb2-dvb-y) \
14 $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) 15 $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
15 16
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index cdedaa55f152..ccf2a3c7ad06 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -26,14 +26,6 @@
26#include <media/msp3400.h> 26#include <media/msp3400.h>
27#include <media/v4l2-common.h> 27#include <media/v4l2-common.h>
28 28
29struct pvr2_msp3400_handler {
30 struct pvr2_hdw *hdw;
31 struct pvr2_i2c_client *client;
32 struct pvr2_i2c_handler i2c_handler;
33 unsigned long stale_mask;
34};
35
36
37 29
38struct routing_scheme { 30struct routing_scheme {
39 const int *def; 31 const int *def;
@@ -63,123 +55,33 @@ static const struct routing_scheme routing_schemes[] = {
63 }, 55 },
64}; 56};
65 57
66/* This function selects the correct audio input source */ 58void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
67static void set_stereo(struct pvr2_msp3400_handler *ctxt)
68{
69 struct pvr2_hdw *hdw = ctxt->hdw;
70 struct v4l2_routing route;
71 const struct routing_scheme *sp;
72 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
73
74 pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo");
75
76 if ((sid < ARRAY_SIZE(routing_schemes)) &&
77 ((sp = routing_schemes + sid) != NULL) &&
78 (hdw->input_val >= 0) &&
79 (hdw->input_val < sp->cnt)) {
80 route.input = sp->def[hdw->input_val];
81 } else {
82 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
83 "*** WARNING *** i2c msp3400 v4l2 set_stereo:"
84 " Invalid routing scheme (%u) and/or input (%d)",
85 sid,hdw->input_val);
86 return;
87 }
88 route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
89 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
90}
91
92
93static int check_stereo(struct pvr2_msp3400_handler *ctxt)
94{ 59{
95 struct pvr2_hdw *hdw = ctxt->hdw; 60 if (hdw->input_dirty || hdw->force_dirty) {
96 return hdw->input_dirty; 61 struct v4l2_routing route;
97} 62 const struct routing_scheme *sp;
98 63 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
99 64
100struct pvr2_msp3400_ops { 65 pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
101 void (*update)(struct pvr2_msp3400_handler *); 66
102 int (*check)(struct pvr2_msp3400_handler *); 67 if ((sid < ARRAY_SIZE(routing_schemes)) &&
103}; 68 ((sp = routing_schemes + sid) != NULL) &&
104 69 (hdw->input_val >= 0) &&
105 70 (hdw->input_val < sp->cnt)) {
106static const struct pvr2_msp3400_ops msp3400_ops[] = { 71 route.input = sp->def[hdw->input_val];
107 { .update = set_stereo, .check = check_stereo}, 72 } else {
108}; 73 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
109 74 "*** WARNING *** subdev msp3400 set_input:"
110 75 " Invalid routing scheme (%u)"
111static int msp3400_check(struct pvr2_msp3400_handler *ctxt) 76 " and/or input (%d)",
112{ 77 sid, hdw->input_val);
113 unsigned long msk; 78 return;
114 unsigned int idx;
115
116 for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
117 msk = 1 << idx;
118 if (ctxt->stale_mask & msk) continue;
119 if (msp3400_ops[idx].check(ctxt)) {
120 ctxt->stale_mask |= msk;
121 } 79 }
80 route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
81 sd->ops->audio->s_routing(sd, &route);
122 } 82 }
123 return ctxt->stale_mask != 0;
124} 83}
125 84
126
127static void msp3400_update(struct pvr2_msp3400_handler *ctxt)
128{
129 unsigned long msk;
130 unsigned int idx;
131
132 for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
133 msk = 1 << idx;
134 if (!(ctxt->stale_mask & msk)) continue;
135 ctxt->stale_mask &= ~msk;
136 msp3400_ops[idx].update(ctxt);
137 }
138}
139
140
141static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt)
142{
143 ctxt->client->handler = NULL;
144 kfree(ctxt);
145}
146
147
148static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt,
149 char *buf,unsigned int cnt)
150{
151 return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2");
152}
153
154
155static const struct pvr2_i2c_handler_functions msp3400_funcs = {
156 .detach = (void (*)(void *))pvr2_msp3400_detach,
157 .check = (int (*)(void *))msp3400_check,
158 .update = (void (*)(void *))msp3400_update,
159 .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe,
160};
161
162
163int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
164{
165 struct pvr2_msp3400_handler *ctxt;
166 if (cp->handler) return 0;
167
168 ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
169 if (!ctxt) return 0;
170
171 ctxt->i2c_handler.func_data = ctxt;
172 ctxt->i2c_handler.func_table = &msp3400_funcs;
173 ctxt->client = cp;
174 ctxt->hdw = hdw;
175 ctxt->stale_mask = (1 << ARRAY_SIZE(msp3400_ops)) - 1;
176 cp->handler = &ctxt->i2c_handler;
177 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up",
178 cp->client->addr);
179 return !0;
180}
181
182
183/* 85/*
184 Stuff for Emacs to see, in order to encourage consistent editing style: 86 Stuff for Emacs to see, in order to encourage consistent editing style:
185 *** Local Variables: *** 87 *** Local Variables: ***
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h
index ac54eed3721b..e3e63d750891 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.h
@@ -22,10 +22,8 @@
22#ifndef __PVRUSB2_AUDIO_H 22#ifndef __PVRUSB2_AUDIO_H
23#define __PVRUSB2_AUDIO_H 23#define __PVRUSB2_AUDIO_H
24 24
25#include "pvrusb2-i2c-core.h" 25#include "pvrusb2-hdw-internal.h"
26 26void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
27int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
28
29#endif /* __PVRUSB2_AUDIO_H */ 27#endif /* __PVRUSB2_AUDIO_H */
30 28
31/* 29/*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
new file mode 100644
index 000000000000..b5c3428ebb9f
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
@@ -0,0 +1,95 @@
1/*
2 *
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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/*
23
24 This source file is specifically designed to interface with the
25 v4l-dvb cs53l32a module.
26
27*/
28
29#include "pvrusb2-cs53l32a.h"
30
31
32#include "pvrusb2-hdw-internal.h"
33#include "pvrusb2-debug.h"
34#include <linux/videodev2.h>
35#include <media/v4l2-common.h>
36#include <linux/errno.h>
37#include <linux/slab.h>
38
39struct routing_scheme {
40 const int *def;
41 unsigned int cnt;
42};
43
44
45static const int routing_scheme1[] = {
46 [PVR2_CVAL_INPUT_TV] = 2, /* 1 or 2 seems to work here */
47 [PVR2_CVAL_INPUT_RADIO] = 2,
48 [PVR2_CVAL_INPUT_COMPOSITE] = 0,
49 [PVR2_CVAL_INPUT_SVIDEO] = 0,
50};
51
52static const struct routing_scheme routing_schemes[] = {
53 [PVR2_ROUTING_SCHEME_ONAIR] = {
54 .def = routing_scheme1,
55 .cnt = ARRAY_SIZE(routing_scheme1),
56 },
57};
58
59
60void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
61{
62 if (hdw->input_dirty || hdw->force_dirty) {
63 struct v4l2_routing route;
64 const struct routing_scheme *sp;
65 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
66 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
67 hdw->input_val);
68 if ((sid < ARRAY_SIZE(routing_schemes)) &&
69 ((sp = routing_schemes + sid) != NULL) &&
70 (hdw->input_val >= 0) &&
71 (hdw->input_val < sp->cnt)) {
72 route.input = sp->def[hdw->input_val];
73 } else {
74 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
75 "*** WARNING *** subdev v4l2 set_input:"
76 " Invalid routing scheme (%u)"
77 " and/or input (%d)",
78 sid, hdw->input_val);
79 return;
80 }
81 route.output = 0;
82 sd->ops->audio->s_routing(sd, &route);
83 }
84}
85
86
87/*
88 Stuff for Emacs to see, in order to encourage consistent editing style:
89 *** Local Variables: ***
90 *** mode: c ***
91 *** fill-column: 70 ***
92 *** tab-width: 8 ***
93 *** c-basic-offset: 8 ***
94 *** End: ***
95 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
index ef4afaf37b0a..53ba548b72a7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
@@ -2,6 +2,7 @@
2 * 2 *
3 * 3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com> 4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * 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 * it under the terms of the GNU General Public License as published by
@@ -17,14 +18,24 @@
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * 19 *
19 */ 20 */
20#ifndef __PVRUSB2_TUNER_H
21#define __PVRUSB2_TUNER_H
22 21
23#include "pvrusb2-i2c-core.h" 22#ifndef __PVRUSB2_CS53L32A_H
23#define __PVRUSB2_CS53L32A_H
24 24
25int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); 25/*
26
27 This module connects the pvrusb2 driver to the I2C chip level
28 driver which handles device video processing. This interface is
29 used internally by the driver; higher level code should only
30 interact through the interface provided by pvrusb2-hdw.h.
31
32*/
33
34
35#include "pvrusb2-hdw-internal.h"
36void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
26 37
27#endif /* __PVRUSB2_TUNER_H */ 38#endif /* __PVRUSB2_AUDIO_CS53L32A_H */
28 39
29/* 40/*
30 Stuff for Emacs to see, in order to encourage consistent editing style: 41 Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 895859ec495a..4e017ff26c36 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -28,7 +28,6 @@
28 28
29#include "pvrusb2-cx2584x-v4l.h" 29#include "pvrusb2-cx2584x-v4l.h"
30#include "pvrusb2-video-v4l.h" 30#include "pvrusb2-video-v4l.h"
31#include "pvrusb2-i2c-cmd-v4l2.h"
32 31
33 32
34#include "pvrusb2-hdw-internal.h" 33#include "pvrusb2-hdw-internal.h"
@@ -39,14 +38,6 @@
39#include <linux/errno.h> 38#include <linux/errno.h>
40#include <linux/slab.h> 39#include <linux/slab.h>
41 40
42struct pvr2_v4l_cx2584x {
43 struct pvr2_i2c_handler handler;
44 struct pvr2_decoder_ctrl ctrl;
45 struct pvr2_i2c_client *client;
46 struct pvr2_hdw *hdw;
47 unsigned long stale_mask;
48};
49
50 41
51struct routing_scheme_item { 42struct routing_scheme_item {
52 int vid; 43 int vid;
@@ -110,218 +101,44 @@ static const struct routing_scheme routing_schemes[] = {
110 }, 101 },
111}; 102};
112 103
113static void set_input(struct pvr2_v4l_cx2584x *ctxt) 104void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
114{
115 struct pvr2_hdw *hdw = ctxt->hdw;
116 struct v4l2_routing route;
117 enum cx25840_video_input vid_input;
118 enum cx25840_audio_input aud_input;
119 const struct routing_scheme *sp;
120 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
121
122 memset(&route,0,sizeof(route));
123
124 if ((sid < ARRAY_SIZE(routing_schemes)) &&
125 ((sp = routing_schemes + sid) != NULL) &&
126 (hdw->input_val >= 0) &&
127 (hdw->input_val < sp->cnt)) {
128 vid_input = sp->def[hdw->input_val].vid;
129 aud_input = sp->def[hdw->input_val].aud;
130 } else {
131 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
132 "*** WARNING *** i2c cx2584x set_input:"
133 " Invalid routing scheme (%u) and/or input (%d)",
134 sid,hdw->input_val);
135 return;
136 }
137
138 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
139 vid_input,aud_input);
140 route.input = (u32)vid_input;
141 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
142 route.input = (u32)aud_input;
143 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
144}
145
146
147static int check_input(struct pvr2_v4l_cx2584x *ctxt)
148{
149 struct pvr2_hdw *hdw = ctxt->hdw;
150 return hdw->input_dirty != 0;
151}
152
153
154static void set_audio(struct pvr2_v4l_cx2584x *ctxt)
155{
156 u32 val;
157 struct pvr2_hdw *hdw = ctxt->hdw;
158
159 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d",
160 hdw->srate_val);
161 switch (hdw->srate_val) {
162 default:
163 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
164 val = 48000;
165 break;
166 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
167 val = 44100;
168 break;
169 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
170 val = 32000;
171 break;
172 }
173 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
174}
175
176
177static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
178{
179 struct pvr2_hdw *hdw = ctxt->hdw;
180 return hdw->srate_dirty != 0;
181}
182
183
184struct pvr2_v4l_cx2584x_ops {
185 void (*update)(struct pvr2_v4l_cx2584x *);
186 int (*check)(struct pvr2_v4l_cx2584x *);
187};
188
189
190static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
191 { .update = set_input, .check = check_input},
192 { .update = set_audio, .check = check_audio},
193};
194
195
196static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
197{ 105{
198 ctxt->client->handler = NULL; 106 pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
199 pvr2_hdw_set_decoder(ctxt->hdw,NULL); 107 if (hdw->input_dirty || hdw->force_dirty) {
200 kfree(ctxt); 108 struct v4l2_routing route;
201} 109 enum cx25840_video_input vid_input;
202 110 enum cx25840_audio_input aud_input;
203 111 const struct routing_scheme *sp;
204static int decoder_check(struct pvr2_v4l_cx2584x *ctxt) 112 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
205{ 113
206 unsigned long msk; 114 memset(&route, 0, sizeof(route));
207 unsigned int idx; 115
208 116 if ((sid < ARRAY_SIZE(routing_schemes)) &&
209 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) { 117 ((sp = routing_schemes + sid) != NULL) &&
210 msk = 1 << idx; 118 (hdw->input_val >= 0) &&
211 if (ctxt->stale_mask & msk) continue; 119 (hdw->input_val < sp->cnt)) {
212 if (decoder_ops[idx].check(ctxt)) { 120 vid_input = sp->def[hdw->input_val].vid;
213 ctxt->stale_mask |= msk; 121 aud_input = sp->def[hdw->input_val].aud;
122 } else {
123 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
124 "*** WARNING *** subdev cx2584x set_input:"
125 " Invalid routing scheme (%u)"
126 " and/or input (%d)",
127 sid, hdw->input_val);
128 return;
214 } 129 }
215 }
216 return ctxt->stale_mask != 0;
217}
218
219 130
220static void decoder_update(struct pvr2_v4l_cx2584x *ctxt) 131 pvr2_trace(PVR2_TRACE_CHIPS,
221{ 132 "subdev cx2584x set_input vid=0x%x aud=0x%x",
222 unsigned long msk; 133 vid_input, aud_input);
223 unsigned int idx; 134 route.input = (u32)vid_input;
224 135 sd->ops->video->s_routing(sd, &route);
225 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) { 136 route.input = (u32)aud_input;
226 msk = 1 << idx; 137 sd->ops->audio->s_routing(sd, &route);
227 if (!(ctxt->stale_mask & msk)) continue;
228 ctxt->stale_mask &= ~msk;
229 decoder_ops[idx].update(ctxt);
230 } 138 }
231} 139}
232 140
233 141
234static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
235{
236 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
237 pvr2_v4l2_cmd_stream(ctxt->client,fl);
238}
239
240
241static int decoder_detect(struct pvr2_i2c_client *cp)
242{
243 int ret;
244 /* Attempt to query the decoder - let's see if it will answer */
245 struct v4l2_queryctrl qc;
246
247 memset(&qc,0,sizeof(qc));
248
249 qc.id = V4L2_CID_BRIGHTNESS;
250
251 ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
252 return ret == 0; /* Return true if it answered */
253}
254
255
256static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
257 char *buf,unsigned int cnt)
258{
259 return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
260}
261
262
263static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
264{
265 int ret;
266 ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
267 pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
268}
269
270
271static const struct pvr2_i2c_handler_functions hfuncs = {
272 .detach = (void (*)(void *))decoder_detach,
273 .check = (int (*)(void *))decoder_check,
274 .update = (void (*)(void *))decoder_update,
275 .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
276};
277
278
279int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
280 struct pvr2_i2c_client *cp)
281{
282 struct pvr2_v4l_cx2584x *ctxt;
283
284 if (hdw->decoder_ctrl) return 0;
285 if (cp->handler) return 0;
286 if (!decoder_detect(cp)) return 0;
287
288 ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
289 if (!ctxt) return 0;
290
291 ctxt->handler.func_data = ctxt;
292 ctxt->handler.func_table = &hfuncs;
293 ctxt->ctrl.ctxt = ctxt;
294 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
295 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
296 ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
297 ctxt->client = cp;
298 ctxt->hdw = hdw;
299 ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
300 pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
301 cp->handler = &ctxt->handler;
302 {
303 /*
304 Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit
305 of nuttiness for cx25840 causes that module to
306 correctly set up its video scaling. This is really
307 a problem in the cx25840 module itself, but we work
308 around it here. The problem has not been seen in
309 ivtv because there VBI is supported and set up. We
310 don't do VBI here (at least not yet) and thus we
311 never attempted to even set it up.
312 */
313 struct v4l2_format fmt;
314 memset(&fmt,0,sizeof(fmt));
315 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
316 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_FMT,&fmt);
317 }
318 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
319 cp->client->addr);
320 return !0;
321}
322
323
324
325 142
326/* 143/*
327 Stuff for Emacs to see, in order to encourage consistent editing style: 144 Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
index 66abf77f51fd..e35c2322a08c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
@@ -34,9 +34,9 @@
34 34
35 35
36 36
37#include "pvrusb2-i2c-core.h" 37#include "pvrusb2-hdw-internal.h"
38 38
39int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); 39void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
40 40
41 41
42#endif /* __PVRUSB2_CX2584X_V4L_H */ 42#endif /* __PVRUSB2_CX2584X_V4L_H */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
index ca892fb78a5b..fbe3856bdca6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -23,7 +23,6 @@
23#include "pvrusb2-debugifc.h" 23#include "pvrusb2-debugifc.h"
24#include "pvrusb2-hdw.h" 24#include "pvrusb2-hdw.h"
25#include "pvrusb2-debug.h" 25#include "pvrusb2-debug.h"
26#include "pvrusb2-i2c-core.h"
27 26
28struct debugifc_mask_item { 27struct debugifc_mask_item {
29 const char *name; 28 const char *name;
@@ -147,10 +146,6 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
147 bcnt += ccnt; acnt -= ccnt; buf += ccnt; 146 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
148 ccnt = pvr2_hdw_state_report(hdw,buf,acnt); 147 ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
149 bcnt += ccnt; acnt -= ccnt; buf += ccnt; 148 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
150 ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n");
151 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
152 ccnt = pvr2_i2c_report(hdw,buf,acnt);
153 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
154 149
155 return bcnt; 150 return bcnt;
156} 151}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
index e24ff59f8605..2f8d46761cd0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
@@ -22,16 +22,16 @@
22 22
23struct pvr2_hdw; 23struct pvr2_hdw;
24 24
25/* Non-intrusively print some useful debugging info from inside the
26 driver. This should work even if the driver appears to be
27 wedged. */
28int pvr2_debugifc_print_info(struct pvr2_hdw *,
29 char *buf_ptr,unsigned int buf_size);
30
31/* Print general status of driver. This will also trigger a probe of 25/* Print general status of driver. This will also trigger a probe of
32 the USB link. Unlike print_info(), this one synchronizes with the 26 the USB link. Unlike print_info(), this one synchronizes with the
33 driver so the information should be self-consistent (but it will 27 driver so the information should be self-consistent (but it will
34 hang if the driver is wedged). */ 28 hang if the driver is wedged). */
29int pvr2_debugifc_print_info(struct pvr2_hdw *,
30 char *buf_ptr, unsigned int buf_size);
31
32/* Non-intrusively print some useful debugging info from inside the
33 driver. This should work even if the driver appears to be
34 wedged. */
35int pvr2_debugifc_print_status(struct pvr2_hdw *, 35int pvr2_debugifc_print_status(struct pvr2_hdw *,
36 char *buf_ptr,unsigned int buf_size); 36 char *buf_ptr,unsigned int buf_size);
37 37
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index cbe2a3417851..1cb6a260e8b0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -46,10 +46,11 @@ pvr2_device_desc structures.
46/*------------------------------------------------------------------------*/ 46/*------------------------------------------------------------------------*/
47/* Hauppauge PVR-USB2 Model 29xxx */ 47/* Hauppauge PVR-USB2 Model 29xxx */
48 48
49static const char *pvr2_client_29xxx[] = { 49static const struct pvr2_device_client_desc pvr2_cli_29xxx[] = {
50 "msp3400", 50 { .module_id = PVR2_CLIENT_ID_SAA7115 },
51 "saa7115", 51 { .module_id = PVR2_CLIENT_ID_MSP3400 },
52 "tuner", 52 { .module_id = PVR2_CLIENT_ID_TUNER },
53 { .module_id = PVR2_CLIENT_ID_DEMOD },
53}; 54};
54 55
55static const char *pvr2_fw1_names_29xxx[] = { 56static const char *pvr2_fw1_names_29xxx[] = {
@@ -59,8 +60,8 @@ static const char *pvr2_fw1_names_29xxx[] = {
59static const struct pvr2_device_desc pvr2_device_29xxx = { 60static const struct pvr2_device_desc pvr2_device_29xxx = {
60 .description = "WinTV PVR USB2 Model Category 29xxx", 61 .description = "WinTV PVR USB2 Model Category 29xxx",
61 .shortname = "29xxx", 62 .shortname = "29xxx",
62 .client_modules.lst = pvr2_client_29xxx, 63 .client_table.lst = pvr2_cli_29xxx,
63 .client_modules.cnt = ARRAY_SIZE(pvr2_client_29xxx), 64 .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx),
64 .fx2_firmware.lst = pvr2_fw1_names_29xxx, 65 .fx2_firmware.lst = pvr2_fw1_names_29xxx,
65 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx), 66 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx),
66 .flag_has_hauppauge_rom = !0, 67 .flag_has_hauppauge_rom = !0,
@@ -77,10 +78,11 @@ static const struct pvr2_device_desc pvr2_device_29xxx = {
77/*------------------------------------------------------------------------*/ 78/*------------------------------------------------------------------------*/
78/* Hauppauge PVR-USB2 Model 24xxx */ 79/* Hauppauge PVR-USB2 Model 24xxx */
79 80
80static const char *pvr2_client_24xxx[] = { 81static const struct pvr2_device_client_desc pvr2_cli_24xxx[] = {
81 "cx25840", 82 { .module_id = PVR2_CLIENT_ID_CX25840 },
82 "tuner", 83 { .module_id = PVR2_CLIENT_ID_TUNER },
83 "wm8775", 84 { .module_id = PVR2_CLIENT_ID_WM8775 },
85 { .module_id = PVR2_CLIENT_ID_DEMOD },
84}; 86};
85 87
86static const char *pvr2_fw1_names_24xxx[] = { 88static const char *pvr2_fw1_names_24xxx[] = {
@@ -90,8 +92,8 @@ static const char *pvr2_fw1_names_24xxx[] = {
90static const struct pvr2_device_desc pvr2_device_24xxx = { 92static const struct pvr2_device_desc pvr2_device_24xxx = {
91 .description = "WinTV PVR USB2 Model Category 24xxx", 93 .description = "WinTV PVR USB2 Model Category 24xxx",
92 .shortname = "24xxx", 94 .shortname = "24xxx",
93 .client_modules.lst = pvr2_client_24xxx, 95 .client_table.lst = pvr2_cli_24xxx,
94 .client_modules.cnt = ARRAY_SIZE(pvr2_client_24xxx), 96 .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx),
95 .fx2_firmware.lst = pvr2_fw1_names_24xxx, 97 .fx2_firmware.lst = pvr2_fw1_names_24xxx,
96 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_24xxx), 98 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_24xxx),
97 .flag_has_cx25840 = !0, 99 .flag_has_cx25840 = !0,
@@ -111,16 +113,16 @@ static const struct pvr2_device_desc pvr2_device_24xxx = {
111/*------------------------------------------------------------------------*/ 113/*------------------------------------------------------------------------*/
112/* GOTVIEW USB2.0 DVD2 */ 114/* GOTVIEW USB2.0 DVD2 */
113 115
114static const char *pvr2_client_gotview_2[] = { 116static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = {
115 "cx25840", 117 { .module_id = PVR2_CLIENT_ID_CX25840 },
116 "tuner", 118 { .module_id = PVR2_CLIENT_ID_TUNER },
117}; 119};
118 120
119static const struct pvr2_device_desc pvr2_device_gotview_2 = { 121static const struct pvr2_device_desc pvr2_device_gotview_2 = {
120 .description = "Gotview USB 2.0 DVD 2", 122 .description = "Gotview USB 2.0 DVD 2",
121 .shortname = "gv2", 123 .shortname = "gv2",
122 .client_modules.lst = pvr2_client_gotview_2, 124 .client_table.lst = pvr2_cli_gotview_2,
123 .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2), 125 .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
124 .flag_has_cx25840 = !0, 126 .flag_has_cx25840 = !0,
125 .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 127 .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
126 .flag_has_analogtuner = !0, 128 .flag_has_analogtuner = !0,
@@ -140,8 +142,8 @@ static const struct pvr2_device_desc pvr2_device_gotview_2 = {
140static const struct pvr2_device_desc pvr2_device_gotview_2d = { 142static const struct pvr2_device_desc pvr2_device_gotview_2d = {
141 .description = "Gotview USB 2.0 DVD Deluxe", 143 .description = "Gotview USB 2.0 DVD Deluxe",
142 .shortname = "gv2d", 144 .shortname = "gv2d",
143 .client_modules.lst = pvr2_client_gotview_2, 145 .client_table.lst = pvr2_cli_gotview_2,
144 .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2), 146 .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
145 .flag_has_cx25840 = !0, 147 .flag_has_cx25840 = !0,
146 .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 148 .default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
147 .flag_has_analogtuner = !0, 149 .flag_has_analogtuner = !0,
@@ -181,29 +183,29 @@ static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
181 return 0; 183 return 0;
182} 184}
183 185
184static struct pvr2_dvb_props pvr2_onair_creator_fe_props = { 186static const struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
185 .frontend_attach = pvr2_lgdt3303_attach, 187 .frontend_attach = pvr2_lgdt3303_attach,
186 .tuner_attach = pvr2_lgh06xf_attach, 188 .tuner_attach = pvr2_lgh06xf_attach,
187}; 189};
188#endif 190#endif
189 191
190static const char *pvr2_client_onair_creator[] = { 192static const struct pvr2_device_client_desc pvr2_cli_onair_creator[] = {
191 "saa7115", 193 { .module_id = PVR2_CLIENT_ID_SAA7115 },
192 "tuner", 194 { .module_id = PVR2_CLIENT_ID_CS53L32A },
193 "cs53l32a", 195 { .module_id = PVR2_CLIENT_ID_TUNER },
194}; 196};
195 197
196static const struct pvr2_device_desc pvr2_device_onair_creator = { 198static const struct pvr2_device_desc pvr2_device_onair_creator = {
197 .description = "OnAir Creator Hybrid USB tuner", 199 .description = "OnAir Creator Hybrid USB tuner",
198 .shortname = "oac", 200 .shortname = "oac",
199 .client_modules.lst = pvr2_client_onair_creator, 201 .client_table.lst = pvr2_cli_onair_creator,
200 .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_creator), 202 .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_creator),
201 .default_tuner_type = TUNER_LG_TDVS_H06XF, 203 .default_tuner_type = TUNER_LG_TDVS_H06XF,
202 .flag_has_analogtuner = !0, 204 .flag_has_analogtuner = !0,
203 .flag_has_composite = !0, 205 .flag_has_composite = !0,
204 .flag_has_svideo = !0, 206 .flag_has_svideo = !0,
205 .flag_digital_requires_cx23416 = !0, 207 .flag_digital_requires_cx23416 = !0,
206 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, 208 .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
207 .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR, 209 .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
208 .default_std_mask = V4L2_STD_NTSC_M, 210 .default_std_mask = V4L2_STD_NTSC_M,
209#ifdef CONFIG_VIDEO_PVRUSB2_DVB 211#ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -241,29 +243,29 @@ static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
241 return 0; 243 return 0;
242} 244}
243 245
244static struct pvr2_dvb_props pvr2_onair_usb2_fe_props = { 246static const struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
245 .frontend_attach = pvr2_lgdt3302_attach, 247 .frontend_attach = pvr2_lgdt3302_attach,
246 .tuner_attach = pvr2_fcv1236d_attach, 248 .tuner_attach = pvr2_fcv1236d_attach,
247}; 249};
248#endif 250#endif
249 251
250static const char *pvr2_client_onair_usb2[] = { 252static const struct pvr2_device_client_desc pvr2_cli_onair_usb2[] = {
251 "saa7115", 253 { .module_id = PVR2_CLIENT_ID_SAA7115 },
252 "tuner", 254 { .module_id = PVR2_CLIENT_ID_CS53L32A },
253 "cs53l32a", 255 { .module_id = PVR2_CLIENT_ID_TUNER },
254}; 256};
255 257
256static const struct pvr2_device_desc pvr2_device_onair_usb2 = { 258static const struct pvr2_device_desc pvr2_device_onair_usb2 = {
257 .description = "OnAir USB2 Hybrid USB tuner", 259 .description = "OnAir USB2 Hybrid USB tuner",
258 .shortname = "oa2", 260 .shortname = "oa2",
259 .client_modules.lst = pvr2_client_onair_usb2, 261 .client_table.lst = pvr2_cli_onair_usb2,
260 .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_usb2), 262 .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_usb2),
261 .default_tuner_type = TUNER_PHILIPS_FCV1236D, 263 .default_tuner_type = TUNER_PHILIPS_FCV1236D,
262 .flag_has_analogtuner = !0, 264 .flag_has_analogtuner = !0,
263 .flag_has_composite = !0, 265 .flag_has_composite = !0,
264 .flag_has_svideo = !0, 266 .flag_has_svideo = !0,
265 .flag_digital_requires_cx23416 = !0, 267 .flag_digital_requires_cx23416 = !0,
266 .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, 268 .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
267 .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR, 269 .digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
268 .default_std_mask = V4L2_STD_NTSC_M, 270 .default_std_mask = V4L2_STD_NTSC_M,
269#ifdef CONFIG_VIDEO_PVRUSB2_DVB 271#ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -314,15 +316,16 @@ static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
314 return 0; 316 return 0;
315} 317}
316 318
317static struct pvr2_dvb_props pvr2_73xxx_dvb_props = { 319static const struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
318 .frontend_attach = pvr2_tda10048_attach, 320 .frontend_attach = pvr2_tda10048_attach,
319 .tuner_attach = pvr2_73xxx_tda18271_8295_attach, 321 .tuner_attach = pvr2_73xxx_tda18271_8295_attach,
320}; 322};
321#endif 323#endif
322 324
323static const char *pvr2_client_73xxx[] = { 325static const struct pvr2_device_client_desc pvr2_cli_73xxx[] = {
324 "cx25840", 326 { .module_id = PVR2_CLIENT_ID_CX25840 },
325 "tuner", 327 { .module_id = PVR2_CLIENT_ID_TUNER,
328 .i2c_address_list = "\x42"},
326}; 329};
327 330
328static const char *pvr2_fw1_names_73xxx[] = { 331static const char *pvr2_fw1_names_73xxx[] = {
@@ -332,8 +335,8 @@ static const char *pvr2_fw1_names_73xxx[] = {
332static const struct pvr2_device_desc pvr2_device_73xxx = { 335static const struct pvr2_device_desc pvr2_device_73xxx = {
333 .description = "WinTV HVR-1900 Model Category 73xxx", 336 .description = "WinTV HVR-1900 Model Category 73xxx",
334 .shortname = "73xxx", 337 .shortname = "73xxx",
335 .client_modules.lst = pvr2_client_73xxx, 338 .client_table.lst = pvr2_cli_73xxx,
336 .client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx), 339 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
337 .fx2_firmware.lst = pvr2_fw1_names_73xxx, 340 .fx2_firmware.lst = pvr2_fw1_names_73xxx,
338 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx), 341 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx),
339 .flag_has_cx25840 = !0, 342 .flag_has_cx25840 = !0,
@@ -418,22 +421,17 @@ static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
418 return 0; 421 return 0;
419} 422}
420 423
421static struct pvr2_dvb_props pvr2_750xx_dvb_props = { 424static const struct pvr2_dvb_props pvr2_750xx_dvb_props = {
422 .frontend_attach = pvr2_s5h1409_attach, 425 .frontend_attach = pvr2_s5h1409_attach,
423 .tuner_attach = pvr2_tda18271_8295_attach, 426 .tuner_attach = pvr2_tda18271_8295_attach,
424}; 427};
425 428
426static struct pvr2_dvb_props pvr2_751xx_dvb_props = { 429static const struct pvr2_dvb_props pvr2_751xx_dvb_props = {
427 .frontend_attach = pvr2_s5h1411_attach, 430 .frontend_attach = pvr2_s5h1411_attach,
428 .tuner_attach = pvr2_tda18271_8295_attach, 431 .tuner_attach = pvr2_tda18271_8295_attach,
429}; 432};
430#endif 433#endif
431 434
432static const char *pvr2_client_75xxx[] = {
433 "cx25840",
434 "tuner",
435};
436
437static const char *pvr2_fw1_names_75xxx[] = { 435static const char *pvr2_fw1_names_75xxx[] = {
438 "v4l-pvrusb2-73xxx-01.fw", 436 "v4l-pvrusb2-73xxx-01.fw",
439}; 437};
@@ -441,8 +439,8 @@ static const char *pvr2_fw1_names_75xxx[] = {
441static const struct pvr2_device_desc pvr2_device_750xx = { 439static const struct pvr2_device_desc pvr2_device_750xx = {
442 .description = "WinTV HVR-1950 Model Category 750xx", 440 .description = "WinTV HVR-1950 Model Category 750xx",
443 .shortname = "750xx", 441 .shortname = "750xx",
444 .client_modules.lst = pvr2_client_75xxx, 442 .client_table.lst = pvr2_cli_73xxx,
445 .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), 443 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
446 .fx2_firmware.lst = pvr2_fw1_names_75xxx, 444 .fx2_firmware.lst = pvr2_fw1_names_75xxx,
447 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx), 445 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
448 .flag_has_cx25840 = !0, 446 .flag_has_cx25840 = !0,
@@ -463,8 +461,8 @@ static const struct pvr2_device_desc pvr2_device_750xx = {
463static const struct pvr2_device_desc pvr2_device_751xx = { 461static const struct pvr2_device_desc pvr2_device_751xx = {
464 .description = "WinTV HVR-1950 Model Category 751xx", 462 .description = "WinTV HVR-1950 Model Category 751xx",
465 .shortname = "751xx", 463 .shortname = "751xx",
466 .client_modules.lst = pvr2_client_75xxx, 464 .client_table.lst = pvr2_cli_73xxx,
467 .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), 465 .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
468 .fx2_firmware.lst = pvr2_fw1_names_75xxx, 466 .fx2_firmware.lst = pvr2_fw1_names_75xxx,
469 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx), 467 .fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
470 .flag_has_cx25840 = !0, 468 .flag_has_cx25840 = !0,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index cb3a33eb0276..3e553389cbc3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -33,6 +33,34 @@
33*/ 33*/
34 34
35 35
36#define PVR2_CLIENT_ID_NULL 0
37#define PVR2_CLIENT_ID_MSP3400 1
38#define PVR2_CLIENT_ID_CX25840 2
39#define PVR2_CLIENT_ID_SAA7115 3
40#define PVR2_CLIENT_ID_TUNER 4
41#define PVR2_CLIENT_ID_CS53L32A 5
42#define PVR2_CLIENT_ID_WM8775 6
43#define PVR2_CLIENT_ID_DEMOD 7
44
45struct pvr2_device_client_desc {
46 /* One ovr PVR2_CLIENT_ID_xxxx */
47 unsigned char module_id;
48
49 /* Null-terminated array of I2C addresses to try in order
50 initialize the module. It's safe to make this null terminated
51 since we're never going to encounter an i2c device with an
52 address of zero. If this is a null pointer or zero-length,
53 then no I2C addresses have been specified, in which case we'll
54 try some compiled in defaults for now. */
55 unsigned char *i2c_address_list;
56};
57
58struct pvr2_device_client_table {
59 const struct pvr2_device_client_desc *lst;
60 unsigned char cnt;
61};
62
63
36struct pvr2_string_table { 64struct pvr2_string_table {
37 const char **lst; 65 const char **lst;
38 unsigned int cnt; 66 unsigned int cnt;
@@ -40,6 +68,7 @@ struct pvr2_string_table {
40 68
41#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0 69#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0
42#define PVR2_ROUTING_SCHEME_GOTVIEW 1 70#define PVR2_ROUTING_SCHEME_GOTVIEW 1
71#define PVR2_ROUTING_SCHEME_ONAIR 2
43 72
44#define PVR2_DIGITAL_SCHEME_NONE 0 73#define PVR2_DIGITAL_SCHEME_NONE 0
45#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 74#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
@@ -66,6 +95,9 @@ struct pvr2_device_desc {
66 /* List of additional client modules we need to load */ 95 /* List of additional client modules we need to load */
67 struct pvr2_string_table client_modules; 96 struct pvr2_string_table client_modules;
68 97
98 /* List of defined client modules we need to load */
99 struct pvr2_device_client_table client_table;
100
69 /* List of FX2 firmware file names we should search; if empty then 101 /* List of FX2 firmware file names we should search; if empty then
70 FX2 firmware check / load is skipped and we assume the device 102 FX2 firmware check / load is skipped and we assume the device
71 was initialized from internal ROM. */ 103 was initialized from internal ROM. */
@@ -73,7 +105,7 @@ struct pvr2_device_desc {
73 105
74#ifdef CONFIG_VIDEO_PVRUSB2_DVB 106#ifdef CONFIG_VIDEO_PVRUSB2_DVB
75 /* callback functions to handle attachment of digital tuner & demod */ 107 /* callback functions to handle attachment of digital tuner & demod */
76 struct pvr2_dvb_props *dvb_props; 108 const struct pvr2_dvb_props *dvb_props;
77 109
78#endif 110#endif
79 /* Initial standard bits to use for this device, if not zero. 111 /* Initial standard bits to use for this device, if not zero.
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
index 77b3c3385066..b7f5c49b1dbc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
@@ -321,7 +321,7 @@ static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap)
321static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap) 321static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
322{ 322{
323 struct pvr2_hdw *hdw = adap->channel.hdw; 323 struct pvr2_hdw *hdw = adap->channel.hdw;
324 struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props; 324 const struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
325 int ret = 0; 325 int ret = 0;
326 326
327 if (dvb_props == NULL) { 327 if (dvb_props == NULL) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 273d2a1aa220..54ac5349dee2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -347,7 +347,7 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
347 int encMisc3Arg = 0; 347 int encMisc3Arg = 0;
348 348
349#if 0 349#if 0
350 /* This inexplicable bit happens in the Hauppage windows 350 /* This inexplicable bit happens in the Hauppauge windows
351 driver (for both 24xxx and 29xxx devices). However I 351 driver (for both 24xxx and 29xxx devices). However I
352 currently see no difference in behavior with or without 352 currently see no difference in behavior with or without
353 this stuff. Leave this here as a note of its existence, 353 this stuff. Leave this here as a note of its existence,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index de7ee7264be6..5d75eb5211b1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -38,6 +38,7 @@
38#include <linux/mutex.h> 38#include <linux/mutex.h>
39#include "pvrusb2-hdw.h" 39#include "pvrusb2-hdw.h"
40#include "pvrusb2-io.h" 40#include "pvrusb2-io.h"
41#include <media/v4l2-device.h>
41#include <media/cx2341x.h> 42#include <media/cx2341x.h>
42#include "pvrusb2-devattr.h" 43#include "pvrusb2-devattr.h"
43 44
@@ -57,8 +58,6 @@
57#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0) 58#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0)
58#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0) 59#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0)
59 60
60struct pvr2_decoder;
61
62typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *); 61typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *);
63typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *); 62typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *);
64typedef int (*pvr2_ctlf_check_value)(struct pvr2_ctrl *,int); 63typedef int (*pvr2_ctlf_check_value)(struct pvr2_ctrl *,int);
@@ -139,22 +138,6 @@ struct pvr2_ctrl {
139}; 138};
140 139
141 140
142struct pvr2_decoder_ctrl {
143 void *ctxt;
144 void (*detach)(void *);
145 void (*enable)(void *,int);
146 void (*force_reset)(void *);
147};
148
149#define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */
150#define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */
151#define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */
152#define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */
153
154#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\
155 PVR2_I2C_PEND_CLIENT |\
156 PVR2_I2C_PEND_REFRESH |\
157 PVR2_I2C_PEND_STALE)
158 141
159/* Disposition of firmware1 loading situation */ 142/* Disposition of firmware1 loading situation */
160#define FW1_STATE_UNKNOWN 0 143#define FW1_STATE_UNKNOWN 0
@@ -179,6 +162,8 @@ struct pvr2_hdw {
179 struct usb_device *usb_dev; 162 struct usb_device *usb_dev;
180 struct usb_interface *usb_intf; 163 struct usb_interface *usb_intf;
181 164
165 /* Our handle into the v4l2 sub-device architecture */
166 struct v4l2_device v4l2_dev;
182 /* Device description, anything that must adjust behavior based on 167 /* Device description, anything that must adjust behavior based on
183 device specific info will use information held here. */ 168 device specific info will use information held here. */
184 const struct pvr2_device_desc *hdw_desc; 169 const struct pvr2_device_desc *hdw_desc;
@@ -186,7 +171,6 @@ struct pvr2_hdw {
186 /* Kernel worker thread handling */ 171 /* Kernel worker thread handling */
187 struct workqueue_struct *workqueue; 172 struct workqueue_struct *workqueue;
188 struct work_struct workpoll; /* Update driver state */ 173 struct work_struct workpoll; /* Update driver state */
189 struct work_struct worki2csync; /* Update i2c clients */
190 174
191 /* Video spigot */ 175 /* Video spigot */
192 struct pvr2_stream *vid_stream; 176 struct pvr2_stream *vid_stream;
@@ -195,20 +179,26 @@ struct pvr2_hdw {
195 struct mutex big_lock_mutex; 179 struct mutex big_lock_mutex;
196 int big_lock_held; /* For debugging */ 180 int big_lock_held; /* For debugging */
197 181
182 /* This is a simple string which identifies the instance of this
183 driver. It is unique within the set of existing devices, but
184 there is no attempt to keep the name consistent with the same
185 physical device each time. */
198 char name[32]; 186 char name[32];
199 187
188 /* This is a simple string which identifies the physical device
189 instance itself - if possible. (If not possible, then it is
190 based on the specific driver instance, similar to name above.)
191 The idea here is that userspace might hopefully be able to use
192 this recognize specific tuners. It will encode a serial number,
193 if available. */
194 char identifier[32];
195
200 /* I2C stuff */ 196 /* I2C stuff */
201 struct i2c_adapter i2c_adap; 197 struct i2c_adapter i2c_adap;
202 struct i2c_algorithm i2c_algo; 198 struct i2c_algorithm i2c_algo;
203 pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT]; 199 pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
204 int i2c_cx25840_hack_state; 200 int i2c_cx25840_hack_state;
205 int i2c_linked; 201 int i2c_linked;
206 unsigned int i2c_pend_types; /* Which types of update are needed */
207 unsigned long i2c_pend_mask; /* Change bits we need to scan */
208 unsigned long i2c_stale_mask; /* Pending broadcast change bits */
209 unsigned long i2c_active_mask; /* All change bits currently in use */
210 struct list_head i2c_clients;
211 struct mutex i2c_list_lock;
212 202
213 /* Frequency table */ 203 /* Frequency table */
214 unsigned int freqTable[FREQTABLE_SIZE]; 204 unsigned int freqTable[FREQTABLE_SIZE];
@@ -275,6 +265,7 @@ struct pvr2_hdw {
275 wait_queue_head_t state_wait_data; 265 wait_queue_head_t state_wait_data;
276 266
277 267
268 int force_dirty; /* consider all controls dirty if true */
278 int flag_ok; /* device in known good state */ 269 int flag_ok; /* device in known good state */
279 int flag_disconnected; /* flag_ok == 0 due to disconnect */ 270 int flag_disconnected; /* flag_ok == 0 due to disconnect */
280 int flag_init_ok; /* true if structure is fully initialized */ 271 int flag_init_ok; /* true if structure is fully initialized */
@@ -283,17 +274,13 @@ struct pvr2_hdw {
283 int flag_decoder_missed;/* We've noticed missing decoder */ 274 int flag_decoder_missed;/* We've noticed missing decoder */
284 int flag_tripped; /* Indicates overall failure to start */ 275 int flag_tripped; /* Indicates overall failure to start */
285 276
286 struct pvr2_decoder_ctrl *decoder_ctrl; 277 unsigned int decoder_client_id;
287 278
288 // CPU firmware info (used to help find / save firmware data) 279 // CPU firmware info (used to help find / save firmware data)
289 char *fw_buffer; 280 char *fw_buffer;
290 unsigned int fw_size; 281 unsigned int fw_size;
291 int fw_cpu_flag; /* True if we are dealing with the CPU */ 282 int fw_cpu_flag; /* True if we are dealing with the CPU */
292 283
293 // True if there is a request to trigger logging of state in each
294 // module.
295 int log_requested;
296
297 /* Tuner / frequency control stuff */ 284 /* Tuner / frequency control stuff */
298 unsigned int tuner_type; 285 unsigned int tuner_type;
299 int tuner_updated; 286 int tuner_updated;
@@ -391,7 +378,8 @@ struct pvr2_hdw {
391 378
392/* This function gets the current frequency */ 379/* This function gets the current frequency */
393unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *); 380unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *);
394void pvr2_hdw_set_decoder(struct pvr2_hdw *,struct pvr2_decoder_ctrl *); 381
382void pvr2_hdw_status_poll(struct pvr2_hdw *);
395 383
396#endif /* __PVRUSB2_HDW_INTERNAL_H */ 384#endif /* __PVRUSB2_HDW_INTERNAL_H */
397 385
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index fa304e5f252a..7a65b42a4f53 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -24,17 +24,22 @@
24#include <linux/firmware.h> 24#include <linux/firmware.h>
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <media/v4l2-common.h> 26#include <media/v4l2-common.h>
27#include <media/tuner.h>
27#include "pvrusb2.h" 28#include "pvrusb2.h"
28#include "pvrusb2-std.h" 29#include "pvrusb2-std.h"
29#include "pvrusb2-util.h" 30#include "pvrusb2-util.h"
30#include "pvrusb2-hdw.h" 31#include "pvrusb2-hdw.h"
31#include "pvrusb2-i2c-core.h" 32#include "pvrusb2-i2c-core.h"
32#include "pvrusb2-tuner.h"
33#include "pvrusb2-eeprom.h" 33#include "pvrusb2-eeprom.h"
34#include "pvrusb2-hdw-internal.h" 34#include "pvrusb2-hdw-internal.h"
35#include "pvrusb2-encoder.h" 35#include "pvrusb2-encoder.h"
36#include "pvrusb2-debug.h" 36#include "pvrusb2-debug.h"
37#include "pvrusb2-fx2-cmd.h" 37#include "pvrusb2-fx2-cmd.h"
38#include "pvrusb2-wm8775.h"
39#include "pvrusb2-video-v4l.h"
40#include "pvrusb2-cx2584x-v4l.h"
41#include "pvrusb2-cs53l32a.h"
42#include "pvrusb2-audio.h"
38 43
39#define TV_MIN_FREQ 55250000L 44#define TV_MIN_FREQ 55250000L
40#define TV_MAX_FREQ 850000000L 45#define TV_MAX_FREQ 850000000L
@@ -104,6 +109,39 @@ MODULE_PARM_DESC(radio_freq, "specify initial radio frequency");
104/* size of a firmware chunk */ 109/* size of a firmware chunk */
105#define FIRMWARE_CHUNK_SIZE 0x2000 110#define FIRMWARE_CHUNK_SIZE 0x2000
106 111
112typedef void (*pvr2_subdev_update_func)(struct pvr2_hdw *,
113 struct v4l2_subdev *);
114
115static const pvr2_subdev_update_func pvr2_module_update_functions[] = {
116 [PVR2_CLIENT_ID_WM8775] = pvr2_wm8775_subdev_update,
117 [PVR2_CLIENT_ID_SAA7115] = pvr2_saa7115_subdev_update,
118 [PVR2_CLIENT_ID_MSP3400] = pvr2_msp3400_subdev_update,
119 [PVR2_CLIENT_ID_CX25840] = pvr2_cx25840_subdev_update,
120 [PVR2_CLIENT_ID_CS53L32A] = pvr2_cs53l32a_subdev_update,
121};
122
123static const char *module_names[] = {
124 [PVR2_CLIENT_ID_MSP3400] = "msp3400",
125 [PVR2_CLIENT_ID_CX25840] = "cx25840",
126 [PVR2_CLIENT_ID_SAA7115] = "saa7115",
127 [PVR2_CLIENT_ID_TUNER] = "tuner",
128 [PVR2_CLIENT_ID_DEMOD] = "tuner",
129 [PVR2_CLIENT_ID_CS53L32A] = "cs53l32a",
130 [PVR2_CLIENT_ID_WM8775] = "wm8775",
131};
132
133
134static const unsigned char *module_i2c_addresses[] = {
135 [PVR2_CLIENT_ID_TUNER] = "\x60\x61\x62\x63",
136 [PVR2_CLIENT_ID_DEMOD] = "\x43",
137 [PVR2_CLIENT_ID_MSP3400] = "\x40",
138 [PVR2_CLIENT_ID_SAA7115] = "\x21",
139 [PVR2_CLIENT_ID_WM8775] = "\x1b",
140 [PVR2_CLIENT_ID_CX25840] = "\x44",
141 [PVR2_CLIENT_ID_CS53L32A] = "\x11",
142};
143
144
107/* Define the list of additional controls we'll dynamically construct based 145/* Define the list of additional controls we'll dynamically construct based
108 on query of the cx2341x module. */ 146 on query of the cx2341x module. */
109struct pvr2_mpeg_ids { 147struct pvr2_mpeg_ids {
@@ -277,7 +315,6 @@ static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v);
277static void pvr2_hdw_state_sched(struct pvr2_hdw *); 315static void pvr2_hdw_state_sched(struct pvr2_hdw *);
278static int pvr2_hdw_state_eval(struct pvr2_hdw *); 316static int pvr2_hdw_state_eval(struct pvr2_hdw *);
279static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); 317static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
280static void pvr2_hdw_worker_i2c(struct work_struct *work);
281static void pvr2_hdw_worker_poll(struct work_struct *work); 318static void pvr2_hdw_worker_poll(struct work_struct *work);
282static int pvr2_hdw_wait(struct pvr2_hdw *,int state); 319static int pvr2_hdw_wait(struct pvr2_hdw *,int state);
283static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *); 320static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *);
@@ -642,7 +679,7 @@ static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
642 unsigned long fv; 679 unsigned long fv;
643 struct pvr2_hdw *hdw = cptr->hdw; 680 struct pvr2_hdw *hdw = cptr->hdw;
644 if (hdw->tuner_signal_stale) { 681 if (hdw->tuner_signal_stale) {
645 pvr2_i2c_core_status_poll(hdw); 682 pvr2_hdw_status_poll(hdw);
646 } 683 }
647 fv = hdw->tuner_signal_info.rangehigh; 684 fv = hdw->tuner_signal_info.rangehigh;
648 if (!fv) { 685 if (!fv) {
@@ -664,7 +701,7 @@ static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
664 unsigned long fv; 701 unsigned long fv;
665 struct pvr2_hdw *hdw = cptr->hdw; 702 struct pvr2_hdw *hdw = cptr->hdw;
666 if (hdw->tuner_signal_stale) { 703 if (hdw->tuner_signal_stale) {
667 pvr2_i2c_core_status_poll(hdw); 704 pvr2_hdw_status_poll(hdw);
668 } 705 }
669 fv = hdw->tuner_signal_info.rangelow; 706 fv = hdw->tuner_signal_info.rangelow;
670 if (!fv) { 707 if (!fv) {
@@ -858,7 +895,7 @@ static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
858static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) 895static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
859{ 896{
860 struct pvr2_hdw *hdw = cptr->hdw; 897 struct pvr2_hdw *hdw = cptr->hdw;
861 pvr2_i2c_core_status_poll(hdw); 898 pvr2_hdw_status_poll(hdw);
862 *vp = hdw->tuner_signal_info.signal; 899 *vp = hdw->tuner_signal_info.signal;
863 return 0; 900 return 0;
864} 901}
@@ -868,7 +905,7 @@ static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
868 int val = 0; 905 int val = 0;
869 unsigned int subchan; 906 unsigned int subchan;
870 struct pvr2_hdw *hdw = cptr->hdw; 907 struct pvr2_hdw *hdw = cptr->hdw;
871 pvr2_i2c_core_status_poll(hdw); 908 pvr2_hdw_status_poll(hdw);
872 subchan = hdw->tuner_signal_info.rxsubchans; 909 subchan = hdw->tuner_signal_info.rxsubchans;
873 if (subchan & V4L2_TUNER_SUB_MONO) { 910 if (subchan & V4L2_TUNER_SUB_MONO) {
874 val |= (1 << V4L2_TUNER_MODE_MONO); 911 val |= (1 << V4L2_TUNER_MODE_MONO);
@@ -1283,6 +1320,12 @@ const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
1283} 1320}
1284 1321
1285 1322
1323const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *hdw)
1324{
1325 return hdw->identifier;
1326}
1327
1328
1286unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw) 1329unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
1287{ 1330{
1288 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio; 1331 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
@@ -1634,33 +1677,27 @@ static const char *pvr2_get_state_name(unsigned int st)
1634 1677
1635static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl) 1678static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
1636{ 1679{
1637 if (!hdw->decoder_ctrl) { 1680 /* Even though we really only care about the video decoder chip at
1638 if (!hdw->flag_decoder_missed) { 1681 this point, we'll broadcast stream on/off to all sub-devices
1639 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 1682 anyway, just in case somebody else wants to hear the
1640 "WARNING: No decoder present"); 1683 command... */
1641 hdw->flag_decoder_missed = !0; 1684 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s",
1642 trace_stbit("flag_decoder_missed", 1685 (enablefl ? "on" : "off"));
1643 hdw->flag_decoder_missed); 1686 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl);
1644 } 1687 if (hdw->decoder_client_id) {
1645 return -EIO; 1688 /* We get here if the encoder has been noticed. Otherwise
1689 we'll issue a warning to the user (which should
1690 normally never happen). */
1691 return 0;
1646 } 1692 }
1647 hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt,enablefl); 1693 if (!hdw->flag_decoder_missed) {
1648 return 0; 1694 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1649} 1695 "WARNING: No decoder present");
1650 1696 hdw->flag_decoder_missed = !0;
1651
1652void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr)
1653{
1654 if (hdw->decoder_ctrl == ptr) return;
1655 hdw->decoder_ctrl = ptr;
1656 if (hdw->decoder_ctrl && hdw->flag_decoder_missed) {
1657 hdw->flag_decoder_missed = 0;
1658 trace_stbit("flag_decoder_missed", 1697 trace_stbit("flag_decoder_missed",
1659 hdw->flag_decoder_missed); 1698 hdw->flag_decoder_missed);
1660 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1661 "Decoder has appeared");
1662 pvr2_hdw_state_sched(hdw);
1663 } 1699 }
1700 return -EIO;
1664} 1701}
1665 1702
1666 1703
@@ -1927,6 +1964,166 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1927} 1964}
1928 1965
1929 1966
1967static unsigned int pvr2_copy_i2c_addr_list(
1968 unsigned short *dst, const unsigned char *src,
1969 unsigned int dst_max)
1970{
1971 unsigned int cnt = 0;
1972 if (!src) return 0;
1973 while (src[cnt] && (cnt + 1) < dst_max) {
1974 dst[cnt] = src[cnt];
1975 cnt++;
1976 }
1977 dst[cnt] = I2C_CLIENT_END;
1978 return cnt;
1979}
1980
1981
1982static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
1983 const struct pvr2_device_client_desc *cd)
1984{
1985 const char *fname;
1986 unsigned char mid;
1987 struct v4l2_subdev *sd;
1988 unsigned int i2ccnt;
1989 const unsigned char *p;
1990 /* Arbitrary count - max # i2c addresses we will probe */
1991 unsigned short i2caddr[25];
1992
1993 mid = cd->module_id;
1994 fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
1995 if (!fname) {
1996 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1997 "Module ID %u for device %s has no name",
1998 mid,
1999 hdw->hdw_desc->description);
2000 return -EINVAL;
2001 }
2002 pvr2_trace(PVR2_TRACE_INIT,
2003 "Module ID %u (%s) for device %s being loaded...",
2004 mid, fname,
2005 hdw->hdw_desc->description);
2006
2007 i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list,
2008 ARRAY_SIZE(i2caddr));
2009 if (!i2ccnt && ((p = (mid < ARRAY_SIZE(module_i2c_addresses)) ?
2010 module_i2c_addresses[mid] : NULL) != NULL)) {
2011 /* Second chance: Try default i2c address list */
2012 i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, p,
2013 ARRAY_SIZE(i2caddr));
2014 if (i2ccnt) {
2015 pvr2_trace(PVR2_TRACE_INIT,
2016 "Module ID %u:"
2017 " Using default i2c address list",
2018 mid);
2019 }
2020 }
2021
2022 if (!i2ccnt) {
2023 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2024 "Module ID %u (%s) for device %s:"
2025 " No i2c addresses",
2026 mid, fname, hdw->hdw_desc->description);
2027 return -EINVAL;
2028 }
2029
2030 /* Note how the 2nd and 3rd arguments are the same for both
2031 * v4l2_i2c_new_subdev() and v4l2_i2c_new_probed_subdev(). Why?
2032 * Well the 2nd argument is the module name to load, while the 3rd
2033 * argument is documented in the framework as being the "chipid" -
2034 * and every other place where I can find examples of this, the
2035 * "chipid" appears to just be the module name again. So here we
2036 * just do the same thing. */
2037 if (i2ccnt == 1) {
2038 pvr2_trace(PVR2_TRACE_INIT,
2039 "Module ID %u:"
2040 " Setting up with specified i2c address 0x%x",
2041 mid, i2caddr[0]);
2042 sd = v4l2_i2c_new_subdev(&hdw->i2c_adap,
2043 fname, fname,
2044 i2caddr[0]);
2045 } else {
2046 pvr2_trace(PVR2_TRACE_INIT,
2047 "Module ID %u:"
2048 " Setting up with address probe list",
2049 mid);
2050 sd = v4l2_i2c_new_probed_subdev(&hdw->i2c_adap,
2051 fname, fname,
2052 i2caddr);
2053 }
2054
2055 if (!sd) {
2056 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2057 "Module ID %u (%s) for device %s failed to load",
2058 mid, fname, hdw->hdw_desc->description);
2059 return -EIO;
2060 }
2061
2062 /* Tag this sub-device instance with the module ID we know about.
2063 In other places we'll use that tag to determine if the instance
2064 requires special handling. */
2065 sd->grp_id = mid;
2066
2067 pvr2_trace(PVR2_TRACE_INFO, "Attached sub-driver %s", fname);
2068
2069
2070 /* client-specific setup... */
2071 switch (mid) {
2072 case PVR2_CLIENT_ID_CX25840:
2073 hdw->decoder_client_id = mid;
2074 {
2075 /*
2076 Mike Isely <isely@pobox.com> 19-Nov-2006 - This
2077 bit of nuttiness for cx25840 causes that module
2078 to correctly set up its video scaling. This is
2079 really a problem in the cx25840 module itself,
2080 but we work around it here. The problem has not
2081 been seen in ivtv because there VBI is supported
2082 and set up. We don't do VBI here (at least not
2083 yet) and thus we never attempted to even set it
2084 up.
2085 */
2086 struct v4l2_format fmt;
2087 pvr2_trace(PVR2_TRACE_INIT,
2088 "Module ID %u:"
2089 " Executing cx25840 VBI hack",
2090 mid);
2091 memset(&fmt, 0, sizeof(fmt));
2092 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
2093 v4l2_device_call_all(&hdw->v4l2_dev, mid,
2094 video, s_fmt, &fmt);
2095 }
2096 break;
2097 case PVR2_CLIENT_ID_SAA7115:
2098 hdw->decoder_client_id = mid;
2099 break;
2100 default: break;
2101 }
2102
2103 return 0;
2104}
2105
2106
2107static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw)
2108{
2109 unsigned int idx;
2110 const struct pvr2_string_table *cm;
2111 const struct pvr2_device_client_table *ct;
2112 int okFl = !0;
2113
2114 cm = &hdw->hdw_desc->client_modules;
2115 for (idx = 0; idx < cm->cnt; idx++) {
2116 request_module(cm->lst[idx]);
2117 }
2118
2119 ct = &hdw->hdw_desc->client_table;
2120 for (idx = 0; idx < ct->cnt; idx++) {
2121 if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0;
2122 }
2123 if (!okFl) pvr2_hdw_render_useless(hdw);
2124}
2125
2126
1930static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) 2127static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1931{ 2128{
1932 int ret; 2129 int ret;
@@ -1966,9 +2163,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1966 2163
1967 if (!pvr2_hdw_dev_ok(hdw)) return; 2164 if (!pvr2_hdw_dev_ok(hdw)) return;
1968 2165
1969 for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) { 2166 hdw->force_dirty = !0;
1970 request_module(hdw->hdw_desc->client_modules.lst[idx]);
1971 }
1972 2167
1973 if (!hdw->hdw_desc->flag_no_powerup) { 2168 if (!hdw->hdw_desc->flag_no_powerup) {
1974 pvr2_hdw_cmd_powerup(hdw); 2169 pvr2_hdw_cmd_powerup(hdw);
@@ -1987,6 +2182,11 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1987 pvr2_i2c_core_init(hdw); 2182 pvr2_i2c_core_init(hdw);
1988 if (!pvr2_hdw_dev_ok(hdw)) return; 2183 if (!pvr2_hdw_dev_ok(hdw)) return;
1989 2184
2185 pvr2_hdw_load_modules(hdw);
2186 if (!pvr2_hdw_dev_ok(hdw)) return;
2187
2188 v4l2_device_call_all(&hdw->v4l2_dev, 0, core, init, 0);
2189
1990 for (idx = 0; idx < CTRLDEF_COUNT; idx++) { 2190 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
1991 cptr = hdw->controls + idx; 2191 cptr = hdw->controls + idx;
1992 if (cptr->info->skip_init) continue; 2192 if (cptr->info->skip_init) continue;
@@ -2024,6 +2224,19 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
2024 hdw->std_mask_eeprom = V4L2_STD_ALL; 2224 hdw->std_mask_eeprom = V4L2_STD_ALL;
2025 } 2225 }
2026 2226
2227 if (hdw->serial_number) {
2228 idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
2229 "sn-%lu", hdw->serial_number);
2230 } else if (hdw->unit_number >= 0) {
2231 idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
2232 "unit-%c",
2233 hdw->unit_number + 'a');
2234 } else {
2235 idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
2236 "unit-??");
2237 }
2238 hdw->identifier[idx] = 0;
2239
2027 pvr2_hdw_setup_std(hdw); 2240 pvr2_hdw_setup_std(hdw);
2028 2241
2029 if (!get_default_tuner_type(hdw)) { 2242 if (!get_default_tuner_type(hdw)) {
@@ -2032,8 +2245,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
2032 hdw->tuner_type); 2245 hdw->tuner_type);
2033 } 2246 }
2034 2247
2035 pvr2_i2c_core_check_stale(hdw);
2036 hdw->tuner_updated = 0;
2037 2248
2038 if (!pvr2_hdw_dev_ok(hdw)) return; 2249 if (!pvr2_hdw_dev_ok(hdw)) return;
2039 2250
@@ -2171,11 +2382,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2171 struct pvr2_hdw *hdw = NULL; 2382 struct pvr2_hdw *hdw = NULL;
2172 int valid_std_mask; 2383 int valid_std_mask;
2173 struct pvr2_ctrl *cptr; 2384 struct pvr2_ctrl *cptr;
2385 struct usb_device *usb_dev;
2174 const struct pvr2_device_desc *hdw_desc; 2386 const struct pvr2_device_desc *hdw_desc;
2175 __u8 ifnum; 2387 __u8 ifnum;
2176 struct v4l2_queryctrl qctrl; 2388 struct v4l2_queryctrl qctrl;
2177 struct pvr2_ctl_info *ciptr; 2389 struct pvr2_ctl_info *ciptr;
2178 2390
2391 usb_dev = interface_to_usbdev(intf);
2392
2179 hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info); 2393 hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info);
2180 2394
2181 if (hdw_desc == NULL) { 2395 if (hdw_desc == NULL) {
@@ -2360,6 +2574,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2360 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL); 2574 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
2361 if (!hdw->ctl_read_urb) goto fail; 2575 if (!hdw->ctl_read_urb) goto fail;
2362 2576
2577 if (v4l2_device_register(&usb_dev->dev, &hdw->v4l2_dev) != 0) {
2578 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2579 "Error registering with v4l core, giving up");
2580 goto fail;
2581 }
2363 mutex_lock(&pvr2_unit_mtx); do { 2582 mutex_lock(&pvr2_unit_mtx); do {
2364 for (idx = 0; idx < PVR_NUM; idx++) { 2583 for (idx = 0; idx < PVR_NUM; idx++) {
2365 if (unit_pointers[idx]) continue; 2584 if (unit_pointers[idx]) continue;
@@ -2382,7 +2601,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2382 2601
2383 hdw->workqueue = create_singlethread_workqueue(hdw->name); 2602 hdw->workqueue = create_singlethread_workqueue(hdw->name);
2384 INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); 2603 INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll);
2385 INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c);
2386 2604
2387 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", 2605 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
2388 hdw->unit_number,hdw->name); 2606 hdw->unit_number,hdw->name);
@@ -2391,12 +2609,9 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
2391 hdw->flag_ok = !0; 2609 hdw->flag_ok = !0;
2392 2610
2393 hdw->usb_intf = intf; 2611 hdw->usb_intf = intf;
2394 hdw->usb_dev = interface_to_usbdev(intf); 2612 hdw->usb_dev = usb_dev;
2395 2613
2396 scnprintf(hdw->bus_info,sizeof(hdw->bus_info), 2614 usb_make_path(hdw->usb_dev, hdw->bus_info, sizeof(hdw->bus_info));
2397 "usb %s address %d",
2398 dev_name(&hdw->usb_dev->dev),
2399 hdw->usb_dev->devnum);
2400 2615
2401 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber; 2616 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2402 usb_set_interface(hdw->usb_dev,ifnum,0); 2617 usb_set_interface(hdw->usb_dev,ifnum,0);
@@ -2454,6 +2669,10 @@ static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
2454 hdw->ctl_write_buffer = NULL; 2669 hdw->ctl_write_buffer = NULL;
2455 } 2670 }
2456 hdw->flag_disconnected = !0; 2671 hdw->flag_disconnected = !0;
2672 /* If we don't do this, then there will be a dangling struct device
2673 reference to our disappearing device persisting inside the V4L
2674 core... */
2675 v4l2_device_disconnect(&hdw->v4l2_dev);
2457 hdw->usb_dev = NULL; 2676 hdw->usb_dev = NULL;
2458 hdw->usb_intf = NULL; 2677 hdw->usb_intf = NULL;
2459 pvr2_hdw_render_useless(hdw); 2678 pvr2_hdw_render_useless(hdw);
@@ -2481,10 +2700,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2481 pvr2_stream_destroy(hdw->vid_stream); 2700 pvr2_stream_destroy(hdw->vid_stream);
2482 hdw->vid_stream = NULL; 2701 hdw->vid_stream = NULL;
2483 } 2702 }
2484 if (hdw->decoder_ctrl) {
2485 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2486 }
2487 pvr2_i2c_core_done(hdw); 2703 pvr2_i2c_core_done(hdw);
2704 v4l2_device_unregister(&hdw->v4l2_dev);
2488 pvr2_hdw_remove_usb_stuff(hdw); 2705 pvr2_hdw_remove_usb_stuff(hdw);
2489 mutex_lock(&pvr2_unit_mtx); do { 2706 mutex_lock(&pvr2_unit_mtx); do {
2490 if ((hdw->unit_number >= 0) && 2707 if ((hdw->unit_number >= 0) &&
@@ -2678,6 +2895,150 @@ static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2678} 2895}
2679 2896
2680 2897
2898static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id,
2899 const char *name, int val)
2900{
2901 struct v4l2_control ctrl;
2902 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 %s=%d", name, val);
2903 memset(&ctrl, 0, sizeof(ctrl));
2904 ctrl.id = id;
2905 ctrl.value = val;
2906 v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_ctrl, &ctrl);
2907}
2908
2909#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \
2910 if ((hdw)->lab##_dirty || (hdw)->force_dirty) { \
2911 pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \
2912 }
2913
2914/* Execute whatever commands are required to update the state of all the
2915 sub-devices so that they match our current control values. */
2916static void pvr2_subdev_update(struct pvr2_hdw *hdw)
2917{
2918 struct v4l2_subdev *sd;
2919 unsigned int id;
2920 pvr2_subdev_update_func fp;
2921
2922 pvr2_trace(PVR2_TRACE_CHIPS, "subdev update...");
2923
2924 if (hdw->tuner_updated || hdw->force_dirty) {
2925 struct tuner_setup setup;
2926 pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)",
2927 hdw->tuner_type);
2928 if (((int)(hdw->tuner_type)) >= 0) {
2929 setup.addr = ADDR_UNSET;
2930 setup.type = hdw->tuner_type;
2931 setup.mode_mask = T_RADIO | T_ANALOG_TV;
2932 v4l2_device_call_all(&hdw->v4l2_dev, 0,
2933 tuner, s_type_addr, &setup);
2934 }
2935 }
2936
2937 if (hdw->input_dirty || hdw->std_dirty || hdw->force_dirty) {
2938 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_standard");
2939 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
2940 v4l2_device_call_all(&hdw->v4l2_dev, 0,
2941 tuner, s_radio);
2942 } else {
2943 v4l2_std_id vs;
2944 vs = hdw->std_mask_cur;
2945 v4l2_device_call_all(&hdw->v4l2_dev, 0,
2946 tuner, s_std, vs);
2947 }
2948 hdw->tuner_signal_stale = !0;
2949 hdw->cropcap_stale = !0;
2950 }
2951
2952 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_BRIGHTNESS, brightness);
2953 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_CONTRAST, contrast);
2954 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_SATURATION, saturation);
2955 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_HUE, hue);
2956 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_MUTE, mute);
2957 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_VOLUME, volume);
2958 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BALANCE, balance);
2959 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BASS, bass);
2960 PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_TREBLE, treble);
2961
2962 if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
2963 struct v4l2_tuner vt;
2964 memset(&vt, 0, sizeof(vt));
2965 vt.audmode = hdw->audiomode_val;
2966 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
2967 }
2968
2969 if (hdw->freqDirty || hdw->force_dirty) {
2970 unsigned long fv;
2971 struct v4l2_frequency freq;
2972 fv = pvr2_hdw_get_cur_freq(hdw);
2973 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_freq(%lu)", fv);
2974 if (hdw->tuner_signal_stale) pvr2_hdw_status_poll(hdw);
2975 memset(&freq, 0, sizeof(freq));
2976 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
2977 /* ((fv * 1000) / 62500) */
2978 freq.frequency = (fv * 2) / 125;
2979 } else {
2980 freq.frequency = fv / 62500;
2981 }
2982 /* tuner-core currently doesn't seem to care about this, but
2983 let's set it anyway for completeness. */
2984 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
2985 freq.type = V4L2_TUNER_RADIO;
2986 } else {
2987 freq.type = V4L2_TUNER_ANALOG_TV;
2988 }
2989 freq.tuner = 0;
2990 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner,
2991 s_frequency, &freq);
2992 }
2993
2994 if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) {
2995 struct v4l2_format fmt;
2996 memset(&fmt, 0, sizeof(fmt));
2997 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2998 fmt.fmt.pix.width = hdw->res_hor_val;
2999 fmt.fmt.pix.height = hdw->res_ver_val;
3000 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)",
3001 fmt.fmt.pix.width, fmt.fmt.pix.height);
3002 v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt);
3003 }
3004
3005 if (hdw->srate_dirty || hdw->force_dirty) {
3006 u32 val;
3007 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d",
3008 hdw->srate_val);
3009 switch (hdw->srate_val) {
3010 default:
3011 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
3012 val = 48000;
3013 break;
3014 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
3015 val = 44100;
3016 break;
3017 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
3018 val = 32000;
3019 break;
3020 }
3021 v4l2_device_call_all(&hdw->v4l2_dev, 0,
3022 audio, s_clock_freq, val);
3023 }
3024
3025 /* Unable to set crop parameters; there is apparently no equivalent
3026 for VIDIOC_S_CROP */
3027
3028 v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
3029 id = sd->grp_id;
3030 if (id >= ARRAY_SIZE(pvr2_module_update_functions)) continue;
3031 fp = pvr2_module_update_functions[id];
3032 if (!fp) continue;
3033 (*fp)(hdw, sd);
3034 }
3035
3036 if (hdw->tuner_signal_stale || hdw->cropcap_stale) {
3037 pvr2_hdw_status_poll(hdw);
3038 }
3039}
3040
3041
2681/* Figure out if we need to commit control changes. If so, mark internal 3042/* Figure out if we need to commit control changes. If so, mark internal
2682 state flags to indicate this fact and return true. Otherwise do nothing 3043 state flags to indicate this fact and return true. Otherwise do nothing
2683 else and return false. */ 3044 else and return false. */
@@ -2686,7 +3047,7 @@ static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
2686 unsigned int idx; 3047 unsigned int idx;
2687 struct pvr2_ctrl *cptr; 3048 struct pvr2_ctrl *cptr;
2688 int value; 3049 int value;
2689 int commit_flag = 0; 3050 int commit_flag = hdw->force_dirty;
2690 char buf[100]; 3051 char buf[100];
2691 unsigned int bcnt,ccnt; 3052 unsigned int bcnt,ccnt;
2692 3053
@@ -2842,18 +3203,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
2842 cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS); 3203 cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
2843 } 3204 }
2844 3205
2845 /* Scan i2c core at this point - before we clear all the dirty
2846 bits. Various parts of the i2c core will notice dirty bits as
2847 appropriate and arrange to broadcast or directly send updates to
2848 the client drivers in order to keep everything in sync */
2849 pvr2_i2c_core_check_stale(hdw);
2850
2851 for (idx = 0; idx < hdw->control_cnt; idx++) {
2852 cptr = hdw->controls + idx;
2853 if (!cptr->info->clear_dirty) continue;
2854 cptr->info->clear_dirty(cptr);
2855 }
2856
2857 if (hdw->active_stream_type != hdw->desired_stream_type) { 3206 if (hdw->active_stream_type != hdw->desired_stream_type) {
2858 /* Handle any side effects of stream config here */ 3207 /* Handle any side effects of stream config here */
2859 hdw->active_stream_type = hdw->desired_stream_type; 3208 hdw->active_stream_type = hdw->desired_stream_type;
@@ -2873,8 +3222,16 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
2873 } 3222 }
2874 } 3223 }
2875 3224
2876 /* Now execute i2c core update */ 3225 /* Check and update state for all sub-devices. */
2877 pvr2_i2c_core_sync(hdw); 3226 pvr2_subdev_update(hdw);
3227
3228 hdw->tuner_updated = 0;
3229 hdw->force_dirty = 0;
3230 for (idx = 0; idx < hdw->control_cnt; idx++) {
3231 cptr = hdw->controls + idx;
3232 if (!cptr->info->clear_dirty) continue;
3233 cptr->info->clear_dirty(cptr);
3234 }
2878 3235
2879 if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) && 3236 if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
2880 hdw->state_encoder_run) { 3237 hdw->state_encoder_run) {
@@ -2904,15 +3261,6 @@ int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2904} 3261}
2905 3262
2906 3263
2907static void pvr2_hdw_worker_i2c(struct work_struct *work)
2908{
2909 struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync);
2910 LOCK_TAKE(hdw->big_lock); do {
2911 pvr2_i2c_core_sync(hdw);
2912 } while (0); LOCK_GIVE(hdw->big_lock);
2913}
2914
2915
2916static void pvr2_hdw_worker_poll(struct work_struct *work) 3264static void pvr2_hdw_worker_poll(struct work_struct *work)
2917{ 3265{
2918 int fl = 0; 3266 int fl = 0;
@@ -2973,7 +3321,7 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2973void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw) 3321void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
2974{ 3322{
2975 LOCK_TAKE(hdw->big_lock); do { 3323 LOCK_TAKE(hdw->big_lock); do {
2976 pvr2_i2c_core_status_poll(hdw); 3324 pvr2_hdw_status_poll(hdw);
2977 } while (0); LOCK_GIVE(hdw->big_lock); 3325 } while (0); LOCK_GIVE(hdw->big_lock);
2978} 3326}
2979 3327
@@ -2983,7 +3331,7 @@ static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw)
2983 if (!hdw->cropcap_stale) { 3331 if (!hdw->cropcap_stale) {
2984 return 0; 3332 return 0;
2985 } 3333 }
2986 pvr2_i2c_core_status_poll(hdw); 3334 pvr2_hdw_status_poll(hdw);
2987 if (hdw->cropcap_stale) { 3335 if (hdw->cropcap_stale) {
2988 return -EIO; 3336 return -EIO;
2989 } 3337 }
@@ -3010,7 +3358,7 @@ int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
3010{ 3358{
3011 LOCK_TAKE(hdw->big_lock); do { 3359 LOCK_TAKE(hdw->big_lock); do {
3012 if (hdw->tuner_signal_stale) { 3360 if (hdw->tuner_signal_stale) {
3013 pvr2_i2c_core_status_poll(hdw); 3361 pvr2_hdw_status_poll(hdw);
3014 } 3362 }
3015 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner)); 3363 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
3016 } while (0); LOCK_GIVE(hdw->big_lock); 3364 } while (0); LOCK_GIVE(hdw->big_lock);
@@ -3029,11 +3377,8 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
3029{ 3377{
3030 int nr = pvr2_hdw_get_unit_number(hdw); 3378 int nr = pvr2_hdw_get_unit_number(hdw);
3031 LOCK_TAKE(hdw->big_lock); do { 3379 LOCK_TAKE(hdw->big_lock); do {
3032 hdw->log_requested = !0;
3033 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); 3380 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
3034 pvr2_i2c_core_check_stale(hdw); 3381 v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status);
3035 hdw->log_requested = 0;
3036 pvr2_i2c_core_sync(hdw);
3037 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); 3382 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
3038 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); 3383 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
3039 pvr2_hdw_state_log_state(hdw); 3384 pvr2_hdw_state_log_state(hdw);
@@ -3716,22 +4061,16 @@ int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw)
3716 4061
3717int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) 4062int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
3718{ 4063{
3719 if (!hdw->decoder_ctrl) {
3720 pvr2_trace(PVR2_TRACE_INIT,
3721 "Unable to reset decoder: nothing attached");
3722 return -ENOTTY;
3723 }
3724
3725 if (!hdw->decoder_ctrl->force_reset) {
3726 pvr2_trace(PVR2_TRACE_INIT,
3727 "Unable to reset decoder: not implemented");
3728 return -ENOTTY;
3729 }
3730
3731 pvr2_trace(PVR2_TRACE_INIT, 4064 pvr2_trace(PVR2_TRACE_INIT,
3732 "Requesting decoder reset"); 4065 "Requesting decoder reset");
3733 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt); 4066 if (hdw->decoder_client_id) {
3734 return 0; 4067 v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
4068 core, reset, 0);
4069 return 0;
4070 }
4071 pvr2_trace(PVR2_TRACE_INIT,
4072 "Unable to reset decoder: nothing attached");
4073 return -ENOTTY;
3735} 4074}
3736 4075
3737 4076
@@ -4476,6 +4815,79 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
4476} 4815}
4477 4816
4478 4817
4818/* Generate report containing info about attached sub-devices and attached
4819 i2c clients, including an indication of which attached i2c clients are
4820 actually sub-devices. */
4821static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
4822 char *buf, unsigned int acnt)
4823{
4824 struct v4l2_subdev *sd;
4825 unsigned int tcnt = 0;
4826 unsigned int ccnt;
4827 struct i2c_client *client;
4828 struct list_head *item;
4829 void *cd;
4830 const char *p;
4831 unsigned int id;
4832
4833 ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:");
4834 tcnt += ccnt;
4835 v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
4836 id = sd->grp_id;
4837 p = NULL;
4838 if (id < ARRAY_SIZE(module_names)) p = module_names[id];
4839 if (p) {
4840 ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p);
4841 tcnt += ccnt;
4842 } else {
4843 ccnt = scnprintf(buf + tcnt, acnt - tcnt,
4844 " (unknown id=%u)", id);
4845 tcnt += ccnt;
4846 }
4847 }
4848 ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
4849 tcnt += ccnt;
4850
4851 ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n");
4852 tcnt += ccnt;
4853
4854 mutex_lock(&hdw->i2c_adap.clist_lock);
4855 list_for_each(item, &hdw->i2c_adap.clients) {
4856 client = list_entry(item, struct i2c_client, list);
4857 ccnt = scnprintf(buf + tcnt, acnt - tcnt,
4858 " %s: i2c=%02x", client->name, client->addr);
4859 tcnt += ccnt;
4860 cd = i2c_get_clientdata(client);
4861 v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
4862 if (cd == sd) {
4863 id = sd->grp_id;
4864 p = NULL;
4865 if (id < ARRAY_SIZE(module_names)) {
4866 p = module_names[id];
4867 }
4868 if (p) {
4869 ccnt = scnprintf(buf + tcnt,
4870 acnt - tcnt,
4871 " subdev=%s", p);
4872 tcnt += ccnt;
4873 } else {
4874 ccnt = scnprintf(buf + tcnt,
4875 acnt - tcnt,
4876 " subdev= id %u)",
4877 id);
4878 tcnt += ccnt;
4879 }
4880 break;
4881 }
4882 }
4883 ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
4884 tcnt += ccnt;
4885 }
4886 mutex_unlock(&hdw->i2c_adap.clist_lock);
4887 return tcnt;
4888}
4889
4890
4479unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw, 4891unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
4480 char *buf,unsigned int acnt) 4892 char *buf,unsigned int acnt)
4481{ 4893{
@@ -4490,6 +4902,8 @@ unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
4490 buf[0] = '\n'; ccnt = 1; 4902 buf[0] = '\n'; ccnt = 1;
4491 bcnt += ccnt; acnt -= ccnt; buf += ccnt; 4903 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
4492 } 4904 }
4905 ccnt = pvr2_hdw_report_clients(hdw, buf, acnt);
4906 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
4493 LOCK_GIVE(hdw->big_lock); 4907 LOCK_GIVE(hdw->big_lock);
4494 return bcnt; 4908 return bcnt;
4495} 4909}
@@ -4497,14 +4911,25 @@ unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
4497 4911
4498static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw) 4912static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
4499{ 4913{
4500 char buf[128]; 4914 char buf[256];
4501 unsigned int idx,ccnt; 4915 unsigned int idx, ccnt;
4916 unsigned int lcnt, ucnt;
4502 4917
4503 for (idx = 0; ; idx++) { 4918 for (idx = 0; ; idx++) {
4504 ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf)); 4919 ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
4505 if (!ccnt) break; 4920 if (!ccnt) break;
4506 printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf); 4921 printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
4507 } 4922 }
4923 ccnt = pvr2_hdw_report_clients(hdw, buf, sizeof(buf));
4924 ucnt = 0;
4925 while (ucnt < ccnt) {
4926 lcnt = 0;
4927 while ((lcnt + ucnt < ccnt) && (buf[lcnt + ucnt] != '\n')) {
4928 lcnt++;
4929 }
4930 printk(KERN_INFO "%s %.*s\n", hdw->name, lcnt, buf + ucnt);
4931 ucnt += lcnt + 1;
4932 }
4508} 4933}
4509 4934
4510 4935
@@ -4641,6 +5066,30 @@ int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
4641} 5066}
4642 5067
4643 5068
5069void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
5070{
5071 struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
5072 memset(vtp, 0, sizeof(*vtp));
5073 hdw->tuner_signal_stale = 0;
5074 /* Note: There apparently is no replacement for VIDIOC_CROPCAP
5075 using v4l2-subdev - therefore we can't support that AT ALL right
5076 now. (Of course, no sub-drivers seem to implement it either.
5077 But now it's a a chicken and egg problem...) */
5078 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner,
5079 &hdw->tuner_signal_info);
5080 pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll"
5081 " type=%u strength=%u audio=0x%x cap=0x%x"
5082 " low=%u hi=%u",
5083 vtp->type,
5084 vtp->signal, vtp->rxsubchans, vtp->capability,
5085 vtp->rangelow, vtp->rangehigh);
5086
5087 /* We have to do this to avoid getting into constant polling if
5088 there's nobody to answer a poll of cropcap info. */
5089 hdw->cropcap_stale = 0;
5090}
5091
5092
4644unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw) 5093unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
4645{ 5094{
4646 return hdw->input_avail_mask; 5095 return hdw->input_avail_mask;
@@ -4736,7 +5185,6 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
4736 int setFl, u64 *val_ptr) 5185 int setFl, u64 *val_ptr)
4737{ 5186{
4738#ifdef CONFIG_VIDEO_ADV_DEBUG 5187#ifdef CONFIG_VIDEO_ADV_DEBUG
4739 struct pvr2_i2c_client *cp;
4740 struct v4l2_dbg_register req; 5188 struct v4l2_dbg_register req;
4741 int stat = 0; 5189 int stat = 0;
4742 int okFl = 0; 5190 int okFl = 0;
@@ -4746,21 +5194,9 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
4746 req.match = *match; 5194 req.match = *match;
4747 req.reg = reg_id; 5195 req.reg = reg_id;
4748 if (setFl) req.val = *val_ptr; 5196 if (setFl) req.val = *val_ptr;
4749 mutex_lock(&hdw->i2c_list_lock); do { 5197 /* It would be nice to know if a sub-device answered the request */
4750 list_for_each_entry(cp, &hdw->i2c_clients, list) { 5198 v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req);
4751 if (!v4l2_chip_match_i2c_client( 5199 if (!setFl) *val_ptr = req.val;
4752 cp->client,
4753 &req.match)) {
4754 continue;
4755 }
4756 stat = pvr2_i2c_client_cmd(
4757 cp,(setFl ? VIDIOC_DBG_S_REGISTER :
4758 VIDIOC_DBG_G_REGISTER),&req);
4759 if (!setFl) *val_ptr = req.val;
4760 okFl = !0;
4761 break;
4762 }
4763 } while (0); mutex_unlock(&hdw->i2c_list_lock);
4764 if (okFl) { 5200 if (okFl) {
4765 return stat; 5201 return stat;
4766 } 5202 }
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 1b4fec337c6b..7b6940554e9a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -132,6 +132,9 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
132/* Retrieve bus location info of device */ 132/* Retrieve bus location info of device */
133const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *); 133const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *);
134 134
135/* Retrieve per-instance string identifier for this specific device */
136const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *);
137
135/* Called when hardware has been unplugged */ 138/* Called when hardware has been unplugged */
136void pvr2_hdw_disconnect(struct pvr2_hdw *); 139void pvr2_hdw_disconnect(struct pvr2_hdw *);
137 140
@@ -236,8 +239,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
236 enum pvr2_v4l_type index,int); 239 enum pvr2_v4l_type index,int);
237 240
238/* Direct read/write access to chip's registers: 241/* Direct read/write access to chip's registers:
239 match_type - how to interpret match_chip (e.g. driver ID, i2c address) 242 match - specify criteria to identify target chip (this is a v4l dbg struct)
240 match_chip - chip match value (e.g. I2C_DRIVERD_xxxx)
241 reg_id - register number to access 243 reg_id - register number to access
242 setFl - true to set the register, false to read it 244 setFl - true to set the register, false to read it
243 val_ptr - storage location for source / result. */ 245 val_ptr - storage location for source / result. */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
deleted file mode 100644
index 94a47718e88e..000000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2 *
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 <linux/kernel.h>
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-video-v4l.h"
29#include "pvrusb2-cx2584x-v4l.h"
30#include "pvrusb2-wm8775.h"
31
32#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
33
34#define OP_STANDARD 0
35#define OP_AUDIOMODE 1
36#define OP_BCSH 2
37#define OP_VOLUME 3
38#define OP_FREQ 4
39#define OP_AUDIORATE 5
40#define OP_CROP 6
41#define OP_SIZE 7
42#define OP_LOG 8
43
44static const struct pvr2_i2c_op * const ops[] = {
45 [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard,
46 [OP_AUDIOMODE] = &pvr2_i2c_op_v4l2_audiomode,
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_CROP] = &pvr2_i2c_op_v4l2_crop,
51 [OP_SIZE] = &pvr2_i2c_op_v4l2_size,
52 [OP_LOG] = &pvr2_i2c_op_v4l2_log,
53};
54
55void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
56{
57 int id;
58 id = cp->client->driver->id;
59 cp->ctl_mask = ((1 << OP_STANDARD) |
60 (1 << OP_AUDIOMODE) |
61 (1 << OP_BCSH) |
62 (1 << OP_VOLUME) |
63 (1 << OP_FREQ) |
64 (1 << OP_CROP) |
65 (1 << OP_SIZE) |
66 (1 << OP_LOG));
67 cp->status_poll = pvr2_v4l2_cmd_status_poll;
68
69 if (id == I2C_DRIVERID_MSP3400) {
70 if (pvr2_i2c_msp3400_setup(hdw,cp)) {
71 return;
72 }
73 }
74 if (id == I2C_DRIVERID_TUNER) {
75 if (pvr2_i2c_tuner_setup(hdw,cp)) {
76 return;
77 }
78 }
79 if (id == I2C_DRIVERID_CX25840) {
80 if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
81 return;
82 }
83 }
84 if (id == I2C_DRIVERID_WM8775) {
85 if (pvr2_i2c_wm8775_setup(hdw,cp)) {
86 return;
87 }
88 }
89 if (id == I2C_DRIVERID_SAA711X) {
90 if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
91 return;
92 }
93 }
94}
95
96
97const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
98{
99 if (idx >= ARRAY_SIZE(ops))
100 return NULL;
101 return ops[idx];
102}
103
104
105/*
106 Stuff for Emacs to see, in order to encourage consistent editing style:
107 *** Local Variables: ***
108 *** mode: c ***
109 *** fill-column: 75 ***
110 *** tab-width: 8 ***
111 *** c-basic-offset: 8 ***
112 *** End: ***
113 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
deleted file mode 100644
index 16bb11902a52..000000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
+++ /dev/null
@@ -1,322 +0,0 @@
1/*
2 *
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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-cmd-v4l2.h"
23#include "pvrusb2-hdw-internal.h"
24#include "pvrusb2-debug.h"
25#include <linux/videodev2.h>
26#include <media/v4l2-common.h>
27
28static void set_standard(struct pvr2_hdw *hdw)
29{
30 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_standard");
31
32 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
33 pvr2_i2c_core_cmd(hdw,AUDC_SET_RADIO,NULL);
34 } else {
35 v4l2_std_id vs;
36 vs = hdw->std_mask_cur;
37 pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
38 }
39 hdw->tuner_signal_stale = !0;
40 hdw->cropcap_stale = !0;
41}
42
43
44static int check_standard(struct pvr2_hdw *hdw)
45{
46 return (hdw->input_dirty != 0) || (hdw->std_dirty != 0);
47}
48
49
50const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = {
51 .check = check_standard,
52 .update = set_standard,
53 .name = "v4l2_standard",
54};
55
56
57static void set_bcsh(struct pvr2_hdw *hdw)
58{
59 struct v4l2_control ctrl;
60 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh"
61 " b=%d c=%d s=%d h=%d",
62 hdw->brightness_val,hdw->contrast_val,
63 hdw->saturation_val,hdw->hue_val);
64 memset(&ctrl,0,sizeof(ctrl));
65 ctrl.id = V4L2_CID_BRIGHTNESS;
66 ctrl.value = hdw->brightness_val;
67 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
68 ctrl.id = V4L2_CID_CONTRAST;
69 ctrl.value = hdw->contrast_val;
70 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
71 ctrl.id = V4L2_CID_SATURATION;
72 ctrl.value = hdw->saturation_val;
73 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
74 ctrl.id = V4L2_CID_HUE;
75 ctrl.value = hdw->hue_val;
76 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
77}
78
79
80static int check_bcsh(struct pvr2_hdw *hdw)
81{
82 return (hdw->brightness_dirty ||
83 hdw->contrast_dirty ||
84 hdw->saturation_dirty ||
85 hdw->hue_dirty);
86}
87
88
89const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = {
90 .check = check_bcsh,
91 .update = set_bcsh,
92 .name = "v4l2_bcsh",
93};
94
95
96static void set_volume(struct pvr2_hdw *hdw)
97{
98 struct v4l2_control ctrl;
99 pvr2_trace(PVR2_TRACE_CHIPS,
100 "i2c v4l2 set_volume"
101 "(vol=%d bal=%d bas=%d treb=%d mute=%d)",
102 hdw->volume_val,
103 hdw->balance_val,
104 hdw->bass_val,
105 hdw->treble_val,
106 hdw->mute_val);
107 memset(&ctrl,0,sizeof(ctrl));
108 ctrl.id = V4L2_CID_AUDIO_MUTE;
109 ctrl.value = hdw->mute_val ? 1 : 0;
110 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
111 ctrl.id = V4L2_CID_AUDIO_VOLUME;
112 ctrl.value = hdw->volume_val;
113 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
114 ctrl.id = V4L2_CID_AUDIO_BALANCE;
115 ctrl.value = hdw->balance_val;
116 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
117 ctrl.id = V4L2_CID_AUDIO_BASS;
118 ctrl.value = hdw->bass_val;
119 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
120 ctrl.id = V4L2_CID_AUDIO_TREBLE;
121 ctrl.value = hdw->treble_val;
122 pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
123}
124
125
126static int check_volume(struct pvr2_hdw *hdw)
127{
128 return (hdw->volume_dirty ||
129 hdw->balance_dirty ||
130 hdw->bass_dirty ||
131 hdw->treble_dirty ||
132 hdw->mute_dirty);
133}
134
135
136const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = {
137 .check = check_volume,
138 .update = set_volume,
139 .name = "v4l2_volume",
140};
141
142
143static void set_audiomode(struct pvr2_hdw *hdw)
144{
145 struct v4l2_tuner vt;
146 memset(&vt,0,sizeof(vt));
147 vt.audmode = hdw->audiomode_val;
148 pvr2_i2c_core_cmd(hdw,VIDIOC_S_TUNER,&vt);
149}
150
151
152static int check_audiomode(struct pvr2_hdw *hdw)
153{
154 return (hdw->input_dirty ||
155 hdw->audiomode_dirty);
156}
157
158
159const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode = {
160 .check = check_audiomode,
161 .update = set_audiomode,
162 .name = "v4l2_audiomode",
163};
164
165
166static void set_frequency(struct pvr2_hdw *hdw)
167{
168 unsigned long fv;
169 struct v4l2_frequency freq;
170 fv = pvr2_hdw_get_cur_freq(hdw);
171 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv);
172 if (hdw->tuner_signal_stale) {
173 pvr2_i2c_core_status_poll(hdw);
174 }
175 memset(&freq,0,sizeof(freq));
176 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
177 // ((fv * 1000) / 62500)
178 freq.frequency = (fv * 2) / 125;
179 } else {
180 freq.frequency = fv / 62500;
181 }
182 /* tuner-core currently doesn't seem to care about this, but
183 let's set it anyway for completeness. */
184 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
185 freq.type = V4L2_TUNER_RADIO;
186 } else {
187 freq.type = V4L2_TUNER_ANALOG_TV;
188 }
189 freq.tuner = 0;
190 pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq);
191}
192
193
194static int check_frequency(struct pvr2_hdw *hdw)
195{
196 return hdw->freqDirty != 0;
197}
198
199
200const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = {
201 .check = check_frequency,
202 .update = set_frequency,
203 .name = "v4l2_freq",
204};
205
206
207static void set_size(struct pvr2_hdw *hdw)
208{
209 struct v4l2_format fmt;
210
211 memset(&fmt,0,sizeof(fmt));
212
213 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
214 fmt.fmt.pix.width = hdw->res_hor_val;
215 fmt.fmt.pix.height = hdw->res_ver_val;
216
217 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)",
218 fmt.fmt.pix.width,fmt.fmt.pix.height);
219
220 pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt);
221}
222
223
224static int check_size(struct pvr2_hdw *hdw)
225{
226 return (hdw->res_hor_dirty || hdw->res_ver_dirty);
227}
228
229
230const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = {
231 .check = check_size,
232 .update = set_size,
233 .name = "v4l2_size",
234};
235
236
237static void set_crop(struct pvr2_hdw *hdw)
238{
239 struct v4l2_crop crop;
240
241 memset(&crop, 0, sizeof crop);
242 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
243 crop.c.left = hdw->cropl_val;
244 crop.c.top = hdw->cropt_val;
245 crop.c.height = hdw->croph_val;
246 crop.c.width = hdw->cropw_val;
247
248 pvr2_trace(PVR2_TRACE_CHIPS,
249 "i2c v4l2 set_crop crop=%d:%d:%d:%d",
250 crop.c.width, crop.c.height, crop.c.left, crop.c.top);
251
252 pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop);
253}
254
255static int check_crop(struct pvr2_hdw *hdw)
256{
257 return (hdw->cropl_dirty || hdw->cropt_dirty ||
258 hdw->cropw_dirty || hdw->croph_dirty);
259}
260
261const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop = {
262 .check = check_crop,
263 .update = set_crop,
264 .name = "v4l2_crop",
265};
266
267
268static void do_log(struct pvr2_hdw *hdw)
269{
270 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()");
271 pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,NULL);
272
273}
274
275
276static int check_log(struct pvr2_hdw *hdw)
277{
278 return hdw->log_requested != 0;
279}
280
281
282const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = {
283 .check = check_log,
284 .update = do_log,
285 .name = "v4l2_log",
286};
287
288
289void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl)
290{
291 pvr2_i2c_client_cmd(cp,
292 (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),NULL);
293}
294
295
296void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp)
297{
298 int stat;
299 struct pvr2_hdw *hdw = cp->hdw;
300 if (hdw->cropcap_stale) {
301 hdw->cropcap_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
302 stat = pvr2_i2c_client_cmd(cp, VIDIOC_CROPCAP,
303 &hdw->cropcap_info);
304 if (stat == 0) {
305 /* Check was successful, so the data is no
306 longer considered stale. */
307 hdw->cropcap_stale = 0;
308 }
309 }
310 pvr2_i2c_client_cmd(cp, VIDIOC_G_TUNER, &hdw->tuner_signal_info);
311}
312
313
314/*
315 Stuff for Emacs to see, in order to encourage consistent editing style:
316 *** Local Variables: ***
317 *** mode: c ***
318 *** fill-column: 70 ***
319 *** tab-width: 8 ***
320 *** c-basic-offset: 8 ***
321 *** End: ***
322 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
deleted file mode 100644
index eb744a20610d..000000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 *
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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#ifndef __PVRUSB2_CMD_V4L2_H
23#define __PVRUSB2_CMD_V4L2_H
24
25#include "pvrusb2-i2c-core.h"
26
27extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard;
28extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_radio;
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_crop;
33extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size;
34extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode;
35extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log;
36
37void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int);
38void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *);
39
40#endif /* __PVRUSB2_CMD_V4L2_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: 70 ***
47 *** tab-width: 8 ***
48 *** c-basic-offset: 8 ***
49 *** End: ***
50 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index d6a35401fefb..9464862745fa 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -18,6 +18,7 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/i2c.h>
21#include "pvrusb2-i2c-core.h" 22#include "pvrusb2-i2c-core.h"
22#include "pvrusb2-hdw-internal.h" 23#include "pvrusb2-hdw-internal.h"
23#include "pvrusb2-debug.h" 24#include "pvrusb2-debug.h"
@@ -29,8 +30,7 @@
29/* 30/*
30 31
31 This module attempts to implement a compliant I2C adapter for the pvrusb2 32 This module attempts to implement a compliant I2C adapter for the pvrusb2
32 device. By doing this we can then make use of existing functionality in 33 device.
33 V4L (e.g. tuner.c) rather than rolling our own.
34 34
35*/ 35*/
36 36
@@ -42,10 +42,6 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
42module_param_array(ir_mode, int, NULL, 0444); 42module_param_array(ir_mode, int, NULL, 0444);
43MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR"); 43MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
44 44
45static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
46 unsigned int detail,
47 char *buf,unsigned int maxlen);
48
49static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ 45static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
50 u8 i2c_addr, /* I2C address we're talking to */ 46 u8 i2c_addr, /* I2C address we're talking to */
51 u8 *data, /* Data to write */ 47 u8 *data, /* Data to write */
@@ -524,414 +520,13 @@ static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
524 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; 520 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
525} 521}
526 522
527static int pvr2_i2c_core_singleton(struct i2c_client *cp,
528 unsigned int cmd,void *arg)
529{
530 int stat;
531 if (!cp) return -EINVAL;
532 if (!(cp->driver)) return -EINVAL;
533 if (!(cp->driver->command)) return -EINVAL;
534 if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN;
535 stat = cp->driver->command(cp,cmd,arg);
536 module_put(cp->driver->driver.owner);
537 return stat;
538}
539
540int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg)
541{
542 int stat;
543 if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
544 char buf[100];
545 unsigned int cnt;
546 cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
547 buf,sizeof(buf));
548 pvr2_trace(PVR2_TRACE_I2C_CMD,
549 "i2c COMMAND (code=%u 0x%x) to %.*s",
550 cmd,cmd,cnt,buf);
551 }
552 stat = pvr2_i2c_core_singleton(cp->client,cmd,arg);
553 if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
554 char buf[100];
555 unsigned int cnt;
556 cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
557 buf,sizeof(buf));
558 pvr2_trace(PVR2_TRACE_I2C_CMD,
559 "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat);
560 }
561 return stat;
562}
563
564int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg)
565{
566 struct pvr2_i2c_client *cp, *ncp;
567 int stat = -EINVAL;
568
569 if (!hdw) return stat;
570
571 mutex_lock(&hdw->i2c_list_lock);
572 list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
573 if (!cp->recv_enable) continue;
574 mutex_unlock(&hdw->i2c_list_lock);
575 stat = pvr2_i2c_client_cmd(cp,cmd,arg);
576 mutex_lock(&hdw->i2c_list_lock);
577 }
578 mutex_unlock(&hdw->i2c_list_lock);
579 return stat;
580}
581
582
583static int handler_check(struct pvr2_i2c_client *cp)
584{
585 struct pvr2_i2c_handler *hp = cp->handler;
586 if (!hp) return 0;
587 if (!hp->func_table->check) return 0;
588 return hp->func_table->check(hp->func_data) != 0;
589}
590
591#define BUFSIZE 500
592
593
594void pvr2_i2c_core_status_poll(struct pvr2_hdw *hdw)
595{
596 struct pvr2_i2c_client *cp;
597 mutex_lock(&hdw->i2c_list_lock); do {
598 struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
599 memset(vtp,0,sizeof(*vtp));
600 list_for_each_entry(cp, &hdw->i2c_clients, list) {
601 if (!cp->detected_flag) continue;
602 if (!cp->status_poll) continue;
603 cp->status_poll(cp);
604 }
605 hdw->tuner_signal_stale = 0;
606 pvr2_trace(PVR2_TRACE_CHIPS,"i2c status poll"
607 " type=%u strength=%u audio=0x%x cap=0x%x"
608 " low=%u hi=%u",
609 vtp->type,
610 vtp->signal,vtp->rxsubchans,vtp->capability,
611 vtp->rangelow,vtp->rangehigh);
612 } while (0); mutex_unlock(&hdw->i2c_list_lock);
613}
614
615
616/* Issue various I2C operations to bring chip-level drivers into sync with
617 state stored in this driver. */
618void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
619{
620 unsigned long msk;
621 unsigned int idx;
622 struct pvr2_i2c_client *cp, *ncp;
623
624 if (!hdw->i2c_linked) return;
625 if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) {
626 return;
627 }
628 mutex_lock(&hdw->i2c_list_lock); do {
629 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN");
630 if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) {
631 /* One or more I2C clients have attached since we
632 last synced. So scan the list and identify the
633 new clients. */
634 char *buf;
635 unsigned int cnt;
636 unsigned long amask = 0;
637 buf = kmalloc(BUFSIZE,GFP_KERNEL);
638 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT");
639 hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT;
640 list_for_each_entry(cp, &hdw->i2c_clients, list) {
641 if (!cp->detected_flag) {
642 cp->ctl_mask = 0;
643 pvr2_i2c_probe(hdw,cp);
644 cp->detected_flag = !0;
645 msk = cp->ctl_mask;
646 cnt = 0;
647 if (buf) {
648 cnt = pvr2_i2c_client_describe(
649 cp,
650 PVR2_I2C_DETAIL_ALL,
651 buf,BUFSIZE);
652 }
653 trace_i2c("Probed: %.*s",cnt,buf);
654 if (handler_check(cp)) {
655 hdw->i2c_pend_types |=
656 PVR2_I2C_PEND_CLIENT;
657 }
658 cp->pend_mask = msk;
659 hdw->i2c_pend_mask |= msk;
660 hdw->i2c_pend_types |=
661 PVR2_I2C_PEND_REFRESH;
662 }
663 amask |= cp->ctl_mask;
664 }
665 hdw->i2c_active_mask = amask;
666 if (buf) kfree(buf);
667 }
668 if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) {
669 /* Need to do one or more global updates. Arrange
670 for this to happen. */
671 unsigned long m2;
672 pvr2_trace(PVR2_TRACE_I2C_CORE,
673 "i2c: PEND_STALE (0x%lx)",
674 hdw->i2c_stale_mask);
675 hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE;
676 list_for_each_entry(cp, &hdw->i2c_clients, list) {
677 m2 = hdw->i2c_stale_mask;
678 m2 &= cp->ctl_mask;
679 m2 &= ~cp->pend_mask;
680 if (m2) {
681 pvr2_trace(PVR2_TRACE_I2C_CORE,
682 "i2c: cp=%p setting 0x%lx",
683 cp,m2);
684 cp->pend_mask |= m2;
685 }
686 }
687 hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
688 hdw->i2c_stale_mask = 0;
689 hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH;
690 }
691 if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) {
692 /* One or more client handlers are asking for an
693 update. Run through the list of known clients
694 and update each one. */
695 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT");
696 hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT;
697 list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients,
698 list) {
699 if (!cp->handler) continue;
700 if (!cp->handler->func_table->update) continue;
701 pvr2_trace(PVR2_TRACE_I2C_CORE,
702 "i2c: cp=%p update",cp);
703 mutex_unlock(&hdw->i2c_list_lock);
704 cp->handler->func_table->update(
705 cp->handler->func_data);
706 mutex_lock(&hdw->i2c_list_lock);
707 /* If client's update function set some
708 additional pending bits, account for that
709 here. */
710 if (cp->pend_mask & ~hdw->i2c_pend_mask) {
711 hdw->i2c_pend_mask |= cp->pend_mask;
712 hdw->i2c_pend_types |=
713 PVR2_I2C_PEND_REFRESH;
714 }
715 }
716 }
717 if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) {
718 const struct pvr2_i2c_op *opf;
719 unsigned long pm;
720 /* Some actual updates are pending. Walk through
721 each update type and perform it. */
722 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH"
723 " (0x%lx)",hdw->i2c_pend_mask);
724 hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH;
725 pm = hdw->i2c_pend_mask;
726 hdw->i2c_pend_mask = 0;
727 for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
728 if (!(pm & msk)) continue;
729 pm &= ~msk;
730 list_for_each_entry(cp, &hdw->i2c_clients,
731 list) {
732 if (cp->pend_mask & msk) {
733 cp->pend_mask &= ~msk;
734 cp->recv_enable = !0;
735 } else {
736 cp->recv_enable = 0;
737 }
738 }
739 opf = pvr2_i2c_get_op(idx);
740 if (!opf) continue;
741 mutex_unlock(&hdw->i2c_list_lock);
742 opf->update(hdw);
743 mutex_lock(&hdw->i2c_list_lock);
744 }
745 }
746 pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END");
747 } while (0); mutex_unlock(&hdw->i2c_list_lock);
748}
749
750int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
751{
752 unsigned long msk,sm,pm;
753 unsigned int idx;
754 const struct pvr2_i2c_op *opf;
755 struct pvr2_i2c_client *cp;
756 unsigned int pt = 0;
757
758 pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN");
759
760 pm = hdw->i2c_active_mask;
761 sm = 0;
762 for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
763 if (!(msk & pm)) continue;
764 pm &= ~msk;
765 opf = pvr2_i2c_get_op(idx);
766 if (!opf) continue;
767 if (opf->check(hdw)) {
768 sm |= msk;
769 }
770 }
771 if (sm) pt |= PVR2_I2C_PEND_STALE;
772
773 list_for_each_entry(cp, &hdw->i2c_clients, list)
774 if (handler_check(cp))
775 pt |= PVR2_I2C_PEND_CLIENT;
776
777 if (pt) {
778 mutex_lock(&hdw->i2c_list_lock); do {
779 hdw->i2c_pend_types |= pt;
780 hdw->i2c_stale_mask |= sm;
781 hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
782 } while (0); mutex_unlock(&hdw->i2c_list_lock);
783 }
784
785 pvr2_trace(PVR2_TRACE_I2C_CORE,
786 "i2c: types=0x%x stale=0x%lx pend=0x%lx",
787 hdw->i2c_pend_types,
788 hdw->i2c_stale_mask,
789 hdw->i2c_pend_mask);
790 pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END");
791
792 return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0;
793}
794
795static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
796 unsigned int detail,
797 char *buf,unsigned int maxlen)
798{
799 unsigned int ccnt,bcnt;
800 int spcfl = 0;
801 const struct pvr2_i2c_op *opf;
802
803 ccnt = 0;
804 if (detail & PVR2_I2C_DETAIL_DEBUG) {
805 bcnt = scnprintf(buf,maxlen,
806 "ctxt=%p ctl_mask=0x%lx",
807 cp,cp->ctl_mask);
808 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
809 spcfl = !0;
810 }
811 bcnt = scnprintf(buf,maxlen,
812 "%s%s @ 0x%x",
813 (spcfl ? " " : ""),
814 cp->client->name,
815 cp->client->addr);
816 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
817 if ((detail & PVR2_I2C_DETAIL_HANDLER) &&
818 cp->handler && cp->handler->func_table->describe) {
819 bcnt = scnprintf(buf,maxlen," (");
820 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
821 bcnt = cp->handler->func_table->describe(
822 cp->handler->func_data,buf,maxlen);
823 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
824 bcnt = scnprintf(buf,maxlen,")");
825 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
826 }
827 if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) {
828 unsigned int idx;
829 unsigned long msk,sm;
830
831 bcnt = scnprintf(buf,maxlen," [");
832 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
833 sm = 0;
834 spcfl = 0;
835 for (idx = 0, msk = 1; msk; idx++, msk <<= 1) {
836 if (!(cp->ctl_mask & msk)) continue;
837 opf = pvr2_i2c_get_op(idx);
838 if (opf) {
839 bcnt = scnprintf(buf,maxlen,"%s%s",
840 spcfl ? " " : "",
841 opf->name);
842 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
843 spcfl = !0;
844 } else {
845 sm |= msk;
846 }
847 }
848 if (sm) {
849 bcnt = scnprintf(buf,maxlen,"%s%lx",
850 idx != 0 ? " " : "",sm);
851 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
852 }
853 bcnt = scnprintf(buf,maxlen,"]");
854 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
855 }
856 return ccnt;
857}
858
859unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw,
860 char *buf,unsigned int maxlen)
861{
862 unsigned int ccnt,bcnt;
863 struct pvr2_i2c_client *cp;
864 ccnt = 0;
865 mutex_lock(&hdw->i2c_list_lock); do {
866 list_for_each_entry(cp, &hdw->i2c_clients, list) {
867 bcnt = pvr2_i2c_client_describe(
868 cp,
869 (PVR2_I2C_DETAIL_HANDLER|
870 PVR2_I2C_DETAIL_CTLMASK),
871 buf,maxlen);
872 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
873 bcnt = scnprintf(buf,maxlen,"\n");
874 ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
875 }
876 } while (0); mutex_unlock(&hdw->i2c_list_lock);
877 return ccnt;
878}
879
880static int pvr2_i2c_attach_inform(struct i2c_client *client) 523static int pvr2_i2c_attach_inform(struct i2c_client *client)
881{ 524{
882 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
883 struct pvr2_i2c_client *cp;
884 int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL);
885 cp = kzalloc(sizeof(*cp),GFP_KERNEL);
886 trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]",
887 client->name,
888 client->addr,cp);
889 if (!cp) return -ENOMEM;
890 cp->hdw = hdw;
891 INIT_LIST_HEAD(&cp->list);
892 cp->client = client;
893 mutex_lock(&hdw->i2c_list_lock); do {
894 hdw->cropcap_stale = !0;
895 list_add_tail(&cp->list,&hdw->i2c_clients);
896 hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT;
897 } while (0); mutex_unlock(&hdw->i2c_list_lock);
898 if (fl) queue_work(hdw->workqueue,&hdw->worki2csync);
899 return 0; 525 return 0;
900} 526}
901 527
902static int pvr2_i2c_detach_inform(struct i2c_client *client) 528static int pvr2_i2c_detach_inform(struct i2c_client *client)
903{ 529{
904 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
905 struct pvr2_i2c_client *cp, *ncp;
906 unsigned long amask = 0;
907 int foundfl = 0;
908 mutex_lock(&hdw->i2c_list_lock); do {
909 hdw->cropcap_stale = !0;
910 list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
911 if (cp->client == client) {
912 trace_i2c("pvr2_i2c_detach"
913 " [client=%s @ 0x%x ctxt=%p]",
914 client->name,
915 client->addr,cp);
916 if (cp->handler &&
917 cp->handler->func_table->detach) {
918 cp->handler->func_table->detach(
919 cp->handler->func_data);
920 }
921 list_del(&cp->list);
922 kfree(cp);
923 foundfl = !0;
924 continue;
925 }
926 amask |= cp->ctl_mask;
927 }
928 hdw->i2c_active_mask = amask;
929 } while (0); mutex_unlock(&hdw->i2c_list_lock);
930 if (!foundfl) {
931 trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]",
932 client->name,
933 client->addr);
934 }
935 return 0; 530 return 0;
936} 531}
937 532
@@ -942,7 +537,7 @@ static struct i2c_algorithm pvr2_i2c_algo_template = {
942 537
943static struct i2c_adapter pvr2_i2c_adap_template = { 538static struct i2c_adapter pvr2_i2c_adap_template = {
944 .owner = THIS_MODULE, 539 .owner = THIS_MODULE,
945 .class = I2C_CLASS_TV_ANALOG, 540 .class = 0,
946 .id = I2C_HW_B_BT848, 541 .id = I2C_HW_B_BT848,
947 .client_register = pvr2_i2c_attach_inform, 542 .client_register = pvr2_i2c_attach_inform,
948 .client_unregister = pvr2_i2c_detach_inform, 543 .client_unregister = pvr2_i2c_detach_inform,
@@ -1009,12 +604,8 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
1009 hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev; 604 hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
1010 hdw->i2c_adap.algo = &hdw->i2c_algo; 605 hdw->i2c_adap.algo = &hdw->i2c_algo;
1011 hdw->i2c_adap.algo_data = hdw; 606 hdw->i2c_adap.algo_data = hdw;
1012 hdw->i2c_pend_mask = 0;
1013 hdw->i2c_stale_mask = 0;
1014 hdw->i2c_active_mask = 0;
1015 INIT_LIST_HEAD(&hdw->i2c_clients);
1016 mutex_init(&hdw->i2c_list_lock);
1017 hdw->i2c_linked = !0; 607 hdw->i2c_linked = !0;
608 i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
1018 i2c_add_adapter(&hdw->i2c_adap); 609 i2c_add_adapter(&hdw->i2c_adap);
1019 if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { 610 if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
1020 /* Probe for a different type of IR receiver on this 611 /* Probe for a different type of IR receiver on this
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
index 6ef7a1c0e935..6a75769200bd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
@@ -20,68 +20,13 @@
20#ifndef __PVRUSB2_I2C_CORE_H 20#ifndef __PVRUSB2_I2C_CORE_H
21#define __PVRUSB2_I2C_CORE_H 21#define __PVRUSB2_I2C_CORE_H
22 22
23#include <linux/list.h>
24#include <linux/i2c.h>
25
26struct pvr2_hdw; 23struct pvr2_hdw;
27struct pvr2_i2c_client;
28struct pvr2_i2c_handler;
29struct pvr2_i2c_handler_functions;
30struct pvr2_i2c_op;
31struct pvr2_i2c_op_functions;
32
33struct pvr2_i2c_client {
34 struct i2c_client *client;
35 struct pvr2_i2c_handler *handler;
36 struct list_head list;
37 struct pvr2_hdw *hdw;
38 int detected_flag;
39 int recv_enable;
40 unsigned long pend_mask;
41 unsigned long ctl_mask;
42 void (*status_poll)(struct pvr2_i2c_client *);
43};
44
45struct pvr2_i2c_handler {
46 void *func_data;
47 const struct pvr2_i2c_handler_functions *func_table;
48};
49
50struct pvr2_i2c_handler_functions {
51 void (*detach)(void *);
52 int (*check)(void *);
53 void (*update)(void *);
54 unsigned int (*describe)(void *,char *,unsigned int);
55};
56
57struct pvr2_i2c_op {
58 int (*check)(struct pvr2_hdw *);
59 void (*update)(struct pvr2_hdw *);
60 const char *name;
61};
62 24
63void pvr2_i2c_core_init(struct pvr2_hdw *); 25void pvr2_i2c_core_init(struct pvr2_hdw *);
64void pvr2_i2c_core_done(struct pvr2_hdw *); 26void pvr2_i2c_core_done(struct pvr2_hdw *);
65 27
66int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg);
67int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg);
68
69int pvr2_i2c_core_check_stale(struct pvr2_hdw *);
70void pvr2_i2c_core_sync(struct pvr2_hdw *);
71void pvr2_i2c_core_status_poll(struct pvr2_hdw *);
72unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen);
73#define PVR2_I2C_DETAIL_DEBUG 0x0001
74#define PVR2_I2C_DETAIL_HANDLER 0x0002
75#define PVR2_I2C_DETAIL_CTLMASK 0x0004
76#define PVR2_I2C_DETAIL_ALL (\
77 PVR2_I2C_DETAIL_DEBUG |\
78 PVR2_I2C_DETAIL_HANDLER |\
79 PVR2_I2C_DETAIL_CTLMASK)
80
81void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *);
82const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx);
83 28
84#endif /* __PVRUSB2_I2C_CORE_H */ 29#endif /* __PVRUSB2_I2C_ADAPTER_H */
85 30
86 31
87/* 32/*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index 9b3c874d96d6..8689ddb54420 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -137,10 +137,10 @@ static int __init pvr_init(void)
137 ret = usb_register(&pvr_driver); 137 ret = usb_register(&pvr_driver);
138 138
139 if (ret == 0) 139 if (ret == 0)
140 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" 140 printk(KERN_INFO "pvrusb2: " DRIVER_VERSION ":"
141 DRIVER_DESC "\n"); 141 DRIVER_DESC "\n");
142 if (pvrusb2_debug) 142 if (pvrusb2_debug)
143 printk(KERN_INFO KBUILD_MODNAME ": Debug mask is %d (0x%x)\n", 143 printk(KERN_INFO "pvrusb2: Debug mask is %d (0x%x)\n",
144 pvrusb2_debug,pvrusb2_debug); 144 pvrusb2_debug,pvrusb2_debug);
145 145
146 pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete"); 146 pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index e641cd971453..e20ba1e6e0ea 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -627,16 +627,8 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
627 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); 627 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
628 628
629 class_dev->class = &class_ptr->class; 629 class_dev->class = &class_ptr->class;
630 if (pvr2_hdw_get_sn(sfp->channel.hdw)) { 630 dev_set_name(class_dev, "%s",
631 dev_set_name(class_dev, "sn-%lu", 631 pvr2_hdw_get_device_identifier(sfp->channel.hdw));
632 pvr2_hdw_get_sn(sfp->channel.hdw));
633 } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
634 dev_set_name(class_dev, "unit-%c",
635 pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
636 } else {
637 kfree(class_dev);
638 return;
639 }
640 632
641 class_dev->parent = &usb_dev->dev; 633 class_dev->parent = &usb_dev->dev;
642 634
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
deleted file mode 100644
index 07775d1aad4e..000000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.c
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 *
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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.h"
23#include "pvrusb2-util.h"
24#include "pvrusb2-tuner.h"
25#include "pvrusb2-hdw-internal.h"
26#include "pvrusb2-debug.h"
27#include <linux/videodev2.h>
28#include <media/tuner.h>
29#include <media/v4l2-common.h>
30
31struct pvr2_tuner_handler {
32 struct pvr2_hdw *hdw;
33 struct pvr2_i2c_client *client;
34 struct pvr2_i2c_handler i2c_handler;
35 int type_update_fl;
36};
37
38
39static void set_type(struct pvr2_tuner_handler *ctxt)
40{
41 struct pvr2_hdw *hdw = ctxt->hdw;
42 struct tuner_setup setup;
43 pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type);
44 if (((int)(hdw->tuner_type)) < 0) return;
45
46 setup.addr = ADDR_UNSET;
47 setup.type = hdw->tuner_type;
48 setup.mode_mask = T_RADIO | T_ANALOG_TV;
49 /* We may really want mode_mask to be T_ANALOG_TV for now */
50 pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup);
51 ctxt->type_update_fl = 0;
52}
53
54
55static int tuner_check(struct pvr2_tuner_handler *ctxt)
56{
57 struct pvr2_hdw *hdw = ctxt->hdw;
58 if (hdw->tuner_updated) ctxt->type_update_fl = !0;
59 return ctxt->type_update_fl != 0;
60}
61
62
63static void tuner_update(struct pvr2_tuner_handler *ctxt)
64{
65 if (ctxt->type_update_fl) set_type(ctxt);
66}
67
68
69static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt)
70{
71 ctxt->client->handler = NULL;
72 kfree(ctxt);
73}
74
75
76static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt)
77{
78 return scnprintf(buf,cnt,"handler: pvrusb2-tuner");
79}
80
81
82static const struct pvr2_i2c_handler_functions tuner_funcs = {
83 .detach = (void (*)(void *))pvr2_tuner_detach,
84 .check = (int (*)(void *))tuner_check,
85 .update = (void (*)(void *))tuner_update,
86 .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe,
87};
88
89
90int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
91{
92 struct pvr2_tuner_handler *ctxt;
93 if (cp->handler) return 0;
94
95 ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
96 if (!ctxt) return 0;
97
98 ctxt->i2c_handler.func_data = ctxt;
99 ctxt->i2c_handler.func_table = &tuner_funcs;
100 ctxt->type_update_fl = !0;
101 ctxt->client = cp;
102 ctxt->hdw = hdw;
103 cp->handler = &ctxt->i2c_handler;
104 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up",
105 cp->client->addr);
106 return !0;
107}
108
109
110
111
112/*
113 Stuff for Emacs to see, in order to encourage consistent editing style:
114 *** Local Variables: ***
115 *** mode: c ***
116 *** fill-column: 70 ***
117 *** tab-width: 8 ***
118 *** c-basic-offset: 8 ***
119 *** End: ***
120 */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 878fd52a73b3..9e0f2b07b93b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -91,7 +91,7 @@ static struct v4l2_capability pvr_capability ={
91 .card = "Hauppauge WinTV pvr-usb2", 91 .card = "Hauppauge WinTV pvr-usb2",
92 .bus_info = "usb", 92 .bus_info = "usb",
93 .version = KERNEL_VERSION(0,8,0), 93 .version = KERNEL_VERSION(0,8,0),
94 .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | 94 .capabilities = (V4L2_CAP_VIDEO_CAPTURE |
95 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | 95 V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
96 V4L2_CAP_READWRITE), 96 V4L2_CAP_READWRITE),
97 .reserved = {0,0,0,0} 97 .reserved = {0,0,0,0}
@@ -952,10 +952,6 @@ static long pvr2_v4l2_ioctl(struct file *file,
952 unsigned int cmd, unsigned long arg) 952 unsigned int cmd, unsigned long arg)
953{ 953{
954 954
955/* Temporary hack : use ivtv api until a v4l2 one is available. */
956#define IVTV_IOC_G_CODEC 0xFFEE7703
957#define IVTV_IOC_S_CODEC 0xFFEE7704
958 if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
959 return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl); 955 return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl);
960} 956}
961 957
@@ -1268,8 +1264,9 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1268 dip->minor_type = pvr2_v4l_type_video; 1264 dip->minor_type = pvr2_v4l_type_video;
1269 nr_ptr = video_nr; 1265 nr_ptr = video_nr;
1270 if (!dip->stream) { 1266 if (!dip->stream) {
1271 err("Failed to set up pvrusb2 v4l video dev" 1267 pr_err(KBUILD_MODNAME
1272 " due to missing stream instance"); 1268 ": Failed to set up pvrusb2 v4l video dev"
1269 " due to missing stream instance\n");
1273 return; 1270 return;
1274 } 1271 }
1275 break; 1272 break;
@@ -1286,8 +1283,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1286 break; 1283 break;
1287 default: 1284 default:
1288 /* Bail out (this should be impossible) */ 1285 /* Bail out (this should be impossible) */
1289 err("Failed to set up pvrusb2 v4l dev" 1286 pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
1290 " due to unrecognized config"); 1287 " due to unrecognized config\n");
1291 return; 1288 return;
1292 } 1289 }
1293 1290
@@ -1303,7 +1300,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1303 dip->v4l_type, mindevnum) < 0) && 1300 dip->v4l_type, mindevnum) < 0) &&
1304 (video_register_device(&dip->devbase, 1301 (video_register_device(&dip->devbase,
1305 dip->v4l_type, -1) < 0)) { 1302 dip->v4l_type, -1) < 0)) {
1306 err("Failed to register pvrusb2 v4l device"); 1303 pr_err(KBUILD_MODNAME
1304 ": Failed to register pvrusb2 v4l device\n");
1307 } 1305 }
1308 1306
1309 printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n", 1307 printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 4059648c7056..b3862f5554bd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -28,7 +28,7 @@
28*/ 28*/
29 29
30#include "pvrusb2-video-v4l.h" 30#include "pvrusb2-video-v4l.h"
31#include "pvrusb2-i2c-cmd-v4l2.h" 31
32 32
33 33
34#include "pvrusb2-hdw-internal.h" 34#include "pvrusb2-hdw-internal.h"
@@ -39,15 +39,6 @@
39#include <linux/errno.h> 39#include <linux/errno.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41 41
42struct pvr2_v4l_decoder {
43 struct pvr2_i2c_handler handler;
44 struct pvr2_decoder_ctrl ctrl;
45 struct pvr2_i2c_client *client;
46 struct pvr2_hdw *hdw;
47 unsigned long stale_mask;
48};
49
50
51struct routing_scheme { 42struct routing_scheme {
52 const int *def; 43 const int *def;
53 unsigned int cnt; 44 unsigned int cnt;
@@ -63,190 +54,51 @@ static const int routing_scheme0[] = {
63 [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, 54 [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2,
64}; 55};
65 56
57static const int routing_scheme1[] = {
58 [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
59 [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
60 [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE3,
61 [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */
62};
63
66static const struct routing_scheme routing_schemes[] = { 64static const struct routing_scheme routing_schemes[] = {
67 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = { 65 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
68 .def = routing_scheme0, 66 .def = routing_scheme0,
69 .cnt = ARRAY_SIZE(routing_scheme0), 67 .cnt = ARRAY_SIZE(routing_scheme0),
70 }, 68 },
69 [PVR2_ROUTING_SCHEME_ONAIR] = {
70 .def = routing_scheme1,
71 .cnt = ARRAY_SIZE(routing_scheme1),
72 },
71}; 73};
72 74
73static void set_input(struct pvr2_v4l_decoder *ctxt) 75void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
74{
75 struct pvr2_hdw *hdw = ctxt->hdw;
76 struct v4l2_routing route;
77 const struct routing_scheme *sp;
78 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
79
80 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val);
81
82 if ((sid < ARRAY_SIZE(routing_schemes)) &&
83 ((sp = routing_schemes + sid) != NULL) &&
84 (hdw->input_val >= 0) &&
85 (hdw->input_val < sp->cnt)) {
86 route.input = sp->def[hdw->input_val];
87 } else {
88 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
89 "*** WARNING *** i2c v4l2 set_input:"
90 " Invalid routing scheme (%u) and/or input (%d)",
91 sid,hdw->input_val);
92 return;
93 }
94
95 route.output = 0;
96 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
97}
98
99
100static int check_input(struct pvr2_v4l_decoder *ctxt)
101{
102 struct pvr2_hdw *hdw = ctxt->hdw;
103 return hdw->input_dirty != 0;
104}
105
106
107static void set_audio(struct pvr2_v4l_decoder *ctxt)
108{
109 u32 val;
110 struct pvr2_hdw *hdw = ctxt->hdw;
111
112 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d",
113 hdw->srate_val);
114 switch (hdw->srate_val) {
115 default:
116 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
117 val = 48000;
118 break;
119 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
120 val = 44100;
121 break;
122 case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
123 val = 32000;
124 break;
125 }
126 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
127}
128
129
130static int check_audio(struct pvr2_v4l_decoder *ctxt)
131{
132 struct pvr2_hdw *hdw = ctxt->hdw;
133 return hdw->srate_dirty != 0;
134}
135
136
137struct pvr2_v4l_decoder_ops {
138 void (*update)(struct pvr2_v4l_decoder *);
139 int (*check)(struct pvr2_v4l_decoder *);
140};
141
142
143static const struct pvr2_v4l_decoder_ops decoder_ops[] = {
144 { .update = set_input, .check = check_input},
145 { .update = set_audio, .check = check_audio},
146};
147
148
149static void decoder_detach(struct pvr2_v4l_decoder *ctxt)
150{ 76{
151 ctxt->client->handler = NULL; 77 if (hdw->input_dirty || hdw->force_dirty) {
152 pvr2_hdw_set_decoder(ctxt->hdw,NULL); 78 struct v4l2_routing route;
153 kfree(ctxt); 79 const struct routing_scheme *sp;
154} 80 unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
155 81 pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
156 82 hdw->input_val);
157static int decoder_check(struct pvr2_v4l_decoder *ctxt) 83 if ((sid < ARRAY_SIZE(routing_schemes)) &&
158{ 84 ((sp = routing_schemes + sid) != NULL) &&
159 unsigned long msk; 85 (hdw->input_val >= 0) &&
160 unsigned int idx; 86 (hdw->input_val < sp->cnt)) {
161 87 route.input = sp->def[hdw->input_val];
162 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) { 88 } else {
163 msk = 1 << idx; 89 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
164 if (ctxt->stale_mask & msk) continue; 90 "*** WARNING *** subdev v4l2 set_input:"
165 if (decoder_ops[idx].check(ctxt)) { 91 " Invalid routing scheme (%u)"
166 ctxt->stale_mask |= msk; 92 " and/or input (%d)",
93 sid, hdw->input_val);
94 return;
167 } 95 }
96 route.output = 0;
97 sd->ops->video->s_routing(sd, &route);
168 } 98 }
169 return ctxt->stale_mask != 0;
170}
171
172
173static void decoder_update(struct pvr2_v4l_decoder *ctxt)
174{
175 unsigned long msk;
176 unsigned int idx;
177
178 for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
179 msk = 1 << idx;
180 if (!(ctxt->stale_mask & msk)) continue;
181 ctxt->stale_mask &= ~msk;
182 decoder_ops[idx].update(ctxt);
183 }
184}
185
186
187static int decoder_detect(struct pvr2_i2c_client *cp)
188{
189 /* Attempt to query the decoder - let's see if it will answer */
190 struct v4l2_tuner vt;
191 int ret;
192
193 memset(&vt,0,sizeof(vt));
194 ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt);
195 return ret == 0; /* Return true if it answered */
196}
197
198
199static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl)
200{
201 pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl);
202 pvr2_v4l2_cmd_stream(ctxt->client,fl);
203}
204
205
206static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt)
207{
208 return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l");
209}
210
211
212static const struct pvr2_i2c_handler_functions hfuncs = {
213 .detach = (void (*)(void *))decoder_detach,
214 .check = (int (*)(void *))decoder_check,
215 .update = (void (*)(void *))decoder_update,
216 .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
217};
218
219
220int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
221 struct pvr2_i2c_client *cp)
222{
223 struct pvr2_v4l_decoder *ctxt;
224
225 if (hdw->decoder_ctrl) return 0;
226 if (cp->handler) return 0;
227 if (!decoder_detect(cp)) return 0;
228
229 ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
230 if (!ctxt) return 0;
231
232 ctxt->handler.func_data = ctxt;
233 ctxt->handler.func_table = &hfuncs;
234 ctxt->ctrl.ctxt = ctxt;
235 ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
236 ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
237 ctxt->client = cp;
238 ctxt->hdw = hdw;
239 ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
240 pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
241 cp->handler = &ctxt->handler;
242 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up",
243 cp->client->addr);
244 return !0;
245} 99}
246 100
247 101
248
249
250/* 102/*
251 Stuff for Emacs to see, in order to encourage consistent editing style: 103 Stuff for Emacs to see, in order to encourage consistent editing style:
252 *** Local Variables: *** 104 *** Local Variables: ***
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
index 4ff5b892b303..3b0bd5db602b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
@@ -32,11 +32,8 @@
32*/ 32*/
33 33
34 34
35 35#include "pvrusb2-hdw-internal.h"
36#include "pvrusb2-i2c-core.h" 36void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
37
38int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
39
40 37
41#endif /* __PVRUSB2_VIDEO_V4L_H */ 38#endif /* __PVRUSB2_VIDEO_V4L_H */
42 39
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index f6fcf0ac6118..1670aa4051ce 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -27,7 +27,6 @@
27*/ 27*/
28 28
29#include "pvrusb2-wm8775.h" 29#include "pvrusb2-wm8775.h"
30#include "pvrusb2-i2c-cmd-v4l2.h"
31 30
32 31
33#include "pvrusb2-hdw-internal.h" 32#include "pvrusb2-hdw-internal.h"
@@ -37,128 +36,31 @@
37#include <linux/errno.h> 36#include <linux/errno.h>
38#include <linux/slab.h> 37#include <linux/slab.h>
39 38
40struct pvr2_v4l_wm8775 { 39void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
41 struct pvr2_i2c_handler handler;
42 struct pvr2_i2c_client *client;
43 struct pvr2_hdw *hdw;
44 unsigned long stale_mask;
45};
46
47
48static void set_input(struct pvr2_v4l_wm8775 *ctxt)
49{
50 struct v4l2_routing route;
51 struct pvr2_hdw *hdw = ctxt->hdw;
52
53 memset(&route,0,sizeof(route));
54
55 switch(hdw->input_val) {
56 case PVR2_CVAL_INPUT_RADIO:
57 route.input = 1;
58 break;
59 default:
60 /* All other cases just use the second input */
61 route.input = 2;
62 break;
63 }
64 pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d route=0x%x)",
65 hdw->input_val,route.input);
66
67 pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
68}
69
70static int check_input(struct pvr2_v4l_wm8775 *ctxt)
71{
72 struct pvr2_hdw *hdw = ctxt->hdw;
73 return hdw->input_dirty != 0;
74}
75
76
77struct pvr2_v4l_wm8775_ops {
78 void (*update)(struct pvr2_v4l_wm8775 *);
79 int (*check)(struct pvr2_v4l_wm8775 *);
80};
81
82
83static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = {
84 { .update = set_input, .check = check_input},
85};
86
87
88static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt,
89 char *buf,unsigned int cnt)
90{
91 return scnprintf(buf,cnt,"handler: pvrusb2-wm8775");
92}
93
94
95static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt)
96{ 40{
97 ctxt->client->handler = NULL; 41 if (hdw->input_dirty || hdw->force_dirty) {
98 kfree(ctxt); 42 struct v4l2_routing route;
99} 43
100 44 memset(&route, 0, sizeof(route));
101 45
102static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt) 46 switch (hdw->input_val) {
103{ 47 case PVR2_CVAL_INPUT_RADIO:
104 unsigned long msk; 48 route.input = 1;
105 unsigned int idx; 49 break;
106 50 default:
107 for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) { 51 /* All other cases just use the second input */
108 msk = 1 << idx; 52 route.input = 2;
109 if (ctxt->stale_mask & msk) continue; 53 break;
110 if (wm8775_ops[idx].check(ctxt)) {
111 ctxt->stale_mask |= msk;
112 } 54 }
113 } 55 pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775"
114 return ctxt->stale_mask != 0; 56 " set_input(val=%d route=0x%x)",
115} 57 hdw->input_val, route.input);
116
117
118static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt)
119{
120 unsigned long msk;
121 unsigned int idx;
122 58
123 for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) { 59 sd->ops->audio->s_routing(sd, &route);
124 msk = 1 << idx;
125 if (!(ctxt->stale_mask & msk)) continue;
126 ctxt->stale_mask &= ~msk;
127 wm8775_ops[idx].update(ctxt);
128 } 60 }
129} 61}
130 62
131 63
132static const struct pvr2_i2c_handler_functions hfuncs = {
133 .detach = (void (*)(void *))wm8775_detach,
134 .check = (int (*)(void *))wm8775_check,
135 .update = (void (*)(void *))wm8775_update,
136 .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe,
137};
138
139
140int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
141{
142 struct pvr2_v4l_wm8775 *ctxt;
143
144 if (cp->handler) return 0;
145
146 ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
147 if (!ctxt) return 0;
148
149 ctxt->handler.func_data = ctxt;
150 ctxt->handler.func_table = &hfuncs;
151 ctxt->client = cp;
152 ctxt->hdw = hdw;
153 ctxt->stale_mask = (1 << ARRAY_SIZE(wm8775_ops)) - 1;
154 cp->handler = &ctxt->handler;
155 pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up",
156 cp->client->addr);
157 return !0;
158}
159
160
161
162 64
163/* 65/*
164 Stuff for Emacs to see, in order to encourage consistent editing style: 66 Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
index 807090961255..0577bc7246fb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
@@ -34,9 +34,9 @@
34 34
35 35
36 36
37#include "pvrusb2-i2c-core.h" 37#include "pvrusb2-hdw-internal.h"
38 38
39int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); 39void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
40 40
41 41
42#endif /* __PVRUSB2_WM8775_H */ 42#endif /* __PVRUSB2_WM8775_H */