blob: c8ee379159e289b051f1a7946bff2e450933f0b8 [file] [log] [blame]
Mike Iselyd8554972006-06-26 20:58:46 -03001/*
2 *
3 * $Id$
4 *
5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/errno.h>
23#include <linux/string.h>
24#include <linux/slab.h>
25#include <linux/firmware.h>
Mike Iselyd8554972006-06-26 20:58:46 -030026#include <linux/videodev2.h>
Mike Isely32ffa9a2006-09-23 22:26:52 -030027#include <media/v4l2-common.h>
Mike Iselyb2bbaa92006-06-25 20:03:59 -030028#include <asm/semaphore.h>
Mike Iselyd8554972006-06-26 20:58:46 -030029#include "pvrusb2.h"
30#include "pvrusb2-std.h"
31#include "pvrusb2-util.h"
32#include "pvrusb2-hdw.h"
33#include "pvrusb2-i2c-core.h"
34#include "pvrusb2-tuner.h"
35#include "pvrusb2-eeprom.h"
36#include "pvrusb2-hdw-internal.h"
37#include "pvrusb2-encoder.h"
38#include "pvrusb2-debug.h"
Michael Krufky8d364362007-01-22 02:17:55 -030039#include "pvrusb2-fx2-cmd.h"
Mike Iselyd8554972006-06-26 20:58:46 -030040
Mike Isely1bde0282006-12-27 23:30:13 -030041#define TV_MIN_FREQ 55250000L
42#define TV_MAX_FREQ 850000000L
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -030043
Mike Iselyd8554972006-06-26 20:58:46 -030044struct usb_device_id pvr2_device_table[] = {
45 [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
Mike Iselyd8554972006-06-26 20:58:46 -030046 [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
Mike Iselyd8554972006-06-26 20:58:46 -030047 { }
48};
49
50MODULE_DEVICE_TABLE(usb, pvr2_device_table);
51
52static const char *pvr2_device_names[] = {
53 [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
Mike Iselyd8554972006-06-26 20:58:46 -030054 [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
Mike Iselyd8554972006-06-26 20:58:46 -030055};
56
57struct pvr2_string_table {
58 const char **lst;
59 unsigned int cnt;
60};
61
Mike Iselyd8554972006-06-26 20:58:46 -030062// Names of other client modules to request for 24xxx model hardware
63static const char *pvr2_client_24xxx[] = {
64 "cx25840",
65 "tuner",
Mike Iselyd8554972006-06-26 20:58:46 -030066 "wm8775",
67};
Mike Iselyd8554972006-06-26 20:58:46 -030068
69// Names of other client modules to request for 29xxx model hardware
70static const char *pvr2_client_29xxx[] = {
71 "msp3400",
72 "saa7115",
73 "tuner",
Mike Iselyd8554972006-06-26 20:58:46 -030074};
75
76static struct pvr2_string_table pvr2_client_lists[] = {
77 [PVR2_HDW_TYPE_29XXX] = {
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -030078 pvr2_client_29xxx, ARRAY_SIZE(pvr2_client_29xxx)
Mike Iselyd8554972006-06-26 20:58:46 -030079 },
Mike Iselyd8554972006-06-26 20:58:46 -030080 [PVR2_HDW_TYPE_24XXX] = {
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -030081 pvr2_client_24xxx, ARRAY_SIZE(pvr2_client_24xxx)
Mike Iselyd8554972006-06-26 20:58:46 -030082 },
Mike Iselyd8554972006-06-26 20:58:46 -030083};
84
Mike Iselya0fd1cb2006-06-30 11:35:28 -030085static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -030086static DEFINE_MUTEX(pvr2_unit_mtx);
Mike Iselyd8554972006-06-26 20:58:46 -030087
88static int ctlchg = 0;
89static int initusbreset = 1;
90static int procreload = 0;
91static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
92static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
93static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
94static int init_pause_msec = 0;
95
96module_param(ctlchg, int, S_IRUGO|S_IWUSR);
97MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
98module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
99MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
100module_param(initusbreset, int, S_IRUGO|S_IWUSR);
101MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
102module_param(procreload, int, S_IRUGO|S_IWUSR);
103MODULE_PARM_DESC(procreload,
104 "Attempt init failure recovery with firmware reload");
105module_param_array(tuner, int, NULL, 0444);
106MODULE_PARM_DESC(tuner,"specify installed tuner type");
107module_param_array(video_std, int, NULL, 0444);
108MODULE_PARM_DESC(video_std,"specify initial video standard");
109module_param_array(tolerance, int, NULL, 0444);
110MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
111
112#define PVR2_CTL_WRITE_ENDPOINT 0x01
113#define PVR2_CTL_READ_ENDPOINT 0x81
114
115#define PVR2_GPIO_IN 0x9008
116#define PVR2_GPIO_OUT 0x900c
117#define PVR2_GPIO_DIR 0x9020
118
119#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
120
121#define PVR2_FIRMWARE_ENDPOINT 0x02
122
123/* size of a firmware chunk */
124#define FIRMWARE_CHUNK_SIZE 0x2000
125
Mike Iselyb30d2442006-06-25 20:05:01 -0300126/* Define the list of additional controls we'll dynamically construct based
127 on query of the cx2341x module. */
128struct pvr2_mpeg_ids {
129 const char *strid;
130 int id;
131};
132static const struct pvr2_mpeg_ids mpeg_ids[] = {
133 {
134 .strid = "audio_layer",
135 .id = V4L2_CID_MPEG_AUDIO_ENCODING,
136 },{
137 .strid = "audio_bitrate",
138 .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE,
139 },{
140 /* Already using audio_mode elsewhere :-( */
141 .strid = "mpeg_audio_mode",
142 .id = V4L2_CID_MPEG_AUDIO_MODE,
143 },{
144 .strid = "mpeg_audio_mode_extension",
145 .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
146 },{
147 .strid = "audio_emphasis",
148 .id = V4L2_CID_MPEG_AUDIO_EMPHASIS,
149 },{
150 .strid = "audio_crc",
151 .id = V4L2_CID_MPEG_AUDIO_CRC,
152 },{
153 .strid = "video_aspect",
154 .id = V4L2_CID_MPEG_VIDEO_ASPECT,
155 },{
156 .strid = "video_b_frames",
157 .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
158 },{
159 .strid = "video_gop_size",
160 .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
161 },{
162 .strid = "video_gop_closure",
163 .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
164 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300165 .strid = "video_bitrate_mode",
166 .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
167 },{
168 .strid = "video_bitrate",
169 .id = V4L2_CID_MPEG_VIDEO_BITRATE,
170 },{
171 .strid = "video_bitrate_peak",
172 .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
173 },{
174 .strid = "video_temporal_decimation",
175 .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
176 },{
177 .strid = "stream_type",
178 .id = V4L2_CID_MPEG_STREAM_TYPE,
179 },{
180 .strid = "video_spatial_filter_mode",
181 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
182 },{
183 .strid = "video_spatial_filter",
184 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
185 },{
186 .strid = "video_luma_spatial_filter_type",
187 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
188 },{
189 .strid = "video_chroma_spatial_filter_type",
190 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
191 },{
192 .strid = "video_temporal_filter_mode",
193 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
194 },{
195 .strid = "video_temporal_filter",
196 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
197 },{
198 .strid = "video_median_filter_type",
199 .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
200 },{
201 .strid = "video_luma_median_filter_top",
202 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
203 },{
204 .strid = "video_luma_median_filter_bottom",
205 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
206 },{
207 .strid = "video_chroma_median_filter_top",
208 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
209 },{
210 .strid = "video_chroma_median_filter_bottom",
211 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
212 }
213};
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -0300214#define MPEGDEF_COUNT ARRAY_SIZE(mpeg_ids)
Mike Iselyc05c0462006-06-25 20:04:25 -0300215
Mike Iselyd8554972006-06-26 20:58:46 -0300216
Mike Isely434449f2006-08-08 09:10:06 -0300217static const char *control_values_srate[] = {
218 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100] = "44.1 kHz",
219 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000] = "48 kHz",
220 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000] = "32 kHz",
221};
Mike Iselyd8554972006-06-26 20:58:46 -0300222
Mike Iselyd8554972006-06-26 20:58:46 -0300223
224
225static const char *control_values_input[] = {
226 [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
227 [PVR2_CVAL_INPUT_RADIO] = "radio",
228 [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
229 [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
230};
231
232
233static const char *control_values_audiomode[] = {
234 [V4L2_TUNER_MODE_MONO] = "Mono",
235 [V4L2_TUNER_MODE_STEREO] = "Stereo",
236 [V4L2_TUNER_MODE_LANG1] = "Lang1",
237 [V4L2_TUNER_MODE_LANG2] = "Lang2",
238 [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
239};
240
241
242static const char *control_values_hsm[] = {
243 [PVR2_CVAL_HSM_FAIL] = "Fail",
244 [PVR2_CVAL_HSM_HIGH] = "High",
245 [PVR2_CVAL_HSM_FULL] = "Full",
246};
247
248
249static const char *control_values_subsystem[] = {
250 [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware",
251 [PVR2_SUBSYS_B_ENC_CFG] = "enc_config",
252 [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run",
253 [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run",
254 [PVR2_SUBSYS_B_ENC_RUN] = "enc_run",
255};
256
Mike Isely1bde0282006-12-27 23:30:13 -0300257static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300258static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
259static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
260static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300261static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
262static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
263static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw);
264static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
265 unsigned long msk,
266 unsigned long val);
267static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
268 unsigned long msk,
269 unsigned long val);
270static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
271 unsigned int timeout,int probe_fl,
272 void *write_data,unsigned int write_len,
273 void *read_data,unsigned int read_len);
Mike Iselyd8554972006-06-26 20:58:46 -0300274
275static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
276{
277 struct pvr2_hdw *hdw = cptr->hdw;
278 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
279 *vp = hdw->freqTable[hdw->freqProgSlot-1];
280 } else {
281 *vp = 0;
282 }
283 return 0;
284}
285
286static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
287{
288 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300289 unsigned int slotId = hdw->freqProgSlot;
290 if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) {
291 hdw->freqTable[slotId-1] = v;
292 /* Handle side effects correctly - if we're tuned to this
293 slot, then forgot the slot id relation since the stored
294 frequency has been changed. */
295 if (hdw->freqSelector) {
296 if (hdw->freqSlotRadio == slotId) {
297 hdw->freqSlotRadio = 0;
298 }
299 } else {
300 if (hdw->freqSlotTelevision == slotId) {
301 hdw->freqSlotTelevision = 0;
302 }
303 }
Mike Iselyd8554972006-06-26 20:58:46 -0300304 }
305 return 0;
306}
307
308static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
309{
310 *vp = cptr->hdw->freqProgSlot;
311 return 0;
312}
313
314static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
315{
316 struct pvr2_hdw *hdw = cptr->hdw;
317 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
318 hdw->freqProgSlot = v;
319 }
320 return 0;
321}
322
323static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
324{
Mike Isely1bde0282006-12-27 23:30:13 -0300325 struct pvr2_hdw *hdw = cptr->hdw;
326 *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision;
Mike Iselyd8554972006-06-26 20:58:46 -0300327 return 0;
328}
329
Mike Isely1bde0282006-12-27 23:30:13 -0300330static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId)
Mike Iselyd8554972006-06-26 20:58:46 -0300331{
332 unsigned freq = 0;
333 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300334 if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0;
335 if (slotId > 0) {
336 freq = hdw->freqTable[slotId-1];
337 if (!freq) return 0;
338 pvr2_hdw_set_cur_freq(hdw,freq);
Mike Iselyd8554972006-06-26 20:58:46 -0300339 }
Mike Isely1bde0282006-12-27 23:30:13 -0300340 if (hdw->freqSelector) {
341 hdw->freqSlotRadio = slotId;
342 } else {
343 hdw->freqSlotTelevision = slotId;
Mike Iselyd8554972006-06-26 20:58:46 -0300344 }
345 return 0;
346}
347
348static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
349{
Mike Isely1bde0282006-12-27 23:30:13 -0300350 *vp = pvr2_hdw_get_cur_freq(cptr->hdw);
Mike Iselyd8554972006-06-26 20:58:46 -0300351 return 0;
352}
353
354static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
355{
356 return cptr->hdw->freqDirty != 0;
357}
358
359static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
360{
361 cptr->hdw->freqDirty = 0;
362}
363
364static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
365{
Mike Isely1bde0282006-12-27 23:30:13 -0300366 pvr2_hdw_set_cur_freq(cptr->hdw,v);
Mike Iselyd8554972006-06-26 20:58:46 -0300367 return 0;
368}
369
Mike Isely3ad9fc32006-09-02 22:37:52 -0300370static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
371{
372 /* Actual maximum depends on the video standard in effect. */
373 if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
374 *vp = 480;
375 } else {
376 *vp = 576;
377 }
378 return 0;
379}
380
381static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
382{
383 /* Actual minimum depends on device type. */
384 if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
385 *vp = 75;
386 } else {
387 *vp = 17;
388 }
389 return 0;
390}
391
Mike Isely1bde0282006-12-27 23:30:13 -0300392static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
393{
394 *vp = cptr->hdw->input_val;
395 return 0;
396}
397
398static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
399{
400 struct pvr2_hdw *hdw = cptr->hdw;
401
402 if (hdw->input_val != v) {
403 hdw->input_val = v;
404 hdw->input_dirty = !0;
405 }
406
407 /* Handle side effects - if we switch to a mode that needs the RF
408 tuner, then select the right frequency choice as well and mark
409 it dirty. */
410 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
411 hdw->freqSelector = 0;
412 hdw->freqDirty = !0;
413 } else if (hdw->input_val == PVR2_CVAL_INPUT_TV) {
414 hdw->freqSelector = 1;
415 hdw->freqDirty = !0;
416 }
417 return 0;
418}
419
420static int ctrl_isdirty_input(struct pvr2_ctrl *cptr)
421{
422 return cptr->hdw->input_dirty != 0;
423}
424
425static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr)
426{
427 cptr->hdw->input_dirty = 0;
428}
429
Mike Isely5549f542006-12-27 23:28:54 -0300430
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300431static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
432{
Mike Isely644afdb2007-01-20 00:19:23 -0300433 unsigned long fv;
434 struct pvr2_hdw *hdw = cptr->hdw;
435 if (hdw->tuner_signal_stale) {
436 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300437 }
Mike Isely644afdb2007-01-20 00:19:23 -0300438 fv = hdw->tuner_signal_info.rangehigh;
439 if (!fv) {
440 /* Safety fallback */
441 *vp = TV_MAX_FREQ;
442 return 0;
443 }
444 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
445 fv = (fv * 125) / 2;
446 } else {
447 fv = fv * 62500;
448 }
449 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300450 return 0;
451}
452
453static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
454{
Mike Isely644afdb2007-01-20 00:19:23 -0300455 unsigned long fv;
456 struct pvr2_hdw *hdw = cptr->hdw;
457 if (hdw->tuner_signal_stale) {
458 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300459 }
Mike Isely644afdb2007-01-20 00:19:23 -0300460 fv = hdw->tuner_signal_info.rangelow;
461 if (!fv) {
462 /* Safety fallback */
463 *vp = TV_MIN_FREQ;
464 return 0;
465 }
466 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
467 fv = (fv * 125) / 2;
468 } else {
469 fv = fv * 62500;
470 }
471 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300472 return 0;
473}
474
Mike Iselyb30d2442006-06-25 20:05:01 -0300475static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
476{
477 return cptr->hdw->enc_stale != 0;
478}
479
480static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
481{
482 cptr->hdw->enc_stale = 0;
483}
484
485static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
486{
487 int ret;
488 struct v4l2_ext_controls cs;
489 struct v4l2_ext_control c1;
490 memset(&cs,0,sizeof(cs));
491 memset(&c1,0,sizeof(c1));
492 cs.controls = &c1;
493 cs.count = 1;
494 c1.id = cptr->info->v4l_id;
Hans Verkuil01f1e442007-08-21 18:32:42 -0300495 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs,
Mike Iselyb30d2442006-06-25 20:05:01 -0300496 VIDIOC_G_EXT_CTRLS);
497 if (ret) return ret;
498 *vp = c1.value;
499 return 0;
500}
501
502static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
503{
504 int ret;
505 struct v4l2_ext_controls cs;
506 struct v4l2_ext_control c1;
507 memset(&cs,0,sizeof(cs));
508 memset(&c1,0,sizeof(c1));
509 cs.controls = &c1;
510 cs.count = 1;
511 c1.id = cptr->info->v4l_id;
512 c1.value = v;
Hans Verkuil01f1e442007-08-21 18:32:42 -0300513 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs,
Mike Iselyb30d2442006-06-25 20:05:01 -0300514 VIDIOC_S_EXT_CTRLS);
515 if (ret) return ret;
516 cptr->hdw->enc_stale = !0;
517 return 0;
518}
519
520static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
521{
522 struct v4l2_queryctrl qctrl;
523 struct pvr2_ctl_info *info;
524 qctrl.id = cptr->info->v4l_id;
525 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
526 /* Strip out the const so we can adjust a function pointer. It's
527 OK to do this here because we know this is a dynamically created
528 control, so the underlying storage for the info pointer is (a)
529 private to us, and (b) not in read-only storage. Either we do
530 this or we significantly complicate the underlying control
531 implementation. */
532 info = (struct pvr2_ctl_info *)(cptr->info);
533 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
534 if (info->set_value) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300535 info->set_value = NULL;
Mike Iselyb30d2442006-06-25 20:05:01 -0300536 }
537 } else {
538 if (!(info->set_value)) {
539 info->set_value = ctrl_cx2341x_set;
540 }
541 }
542 return qctrl.flags;
543}
544
Mike Iselyd8554972006-06-26 20:58:46 -0300545static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
546{
547 *vp = cptr->hdw->flag_streaming_enabled;
548 return 0;
549}
550
551static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
552{
553 int result = pvr2_hdw_is_hsm(cptr->hdw);
554 *vp = PVR2_CVAL_HSM_FULL;
555 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
556 if (result) *vp = PVR2_CVAL_HSM_HIGH;
557 return 0;
558}
559
560static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
561{
562 *vp = cptr->hdw->std_mask_avail;
563 return 0;
564}
565
566static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
567{
568 struct pvr2_hdw *hdw = cptr->hdw;
569 v4l2_std_id ns;
570 ns = hdw->std_mask_avail;
571 ns = (ns & ~m) | (v & m);
572 if (ns == hdw->std_mask_avail) return 0;
573 hdw->std_mask_avail = ns;
574 pvr2_hdw_internal_set_std_avail(hdw);
575 pvr2_hdw_internal_find_stdenum(hdw);
576 return 0;
577}
578
579static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
580 char *bufPtr,unsigned int bufSize,
581 unsigned int *len)
582{
583 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
584 return 0;
585}
586
587static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
588 const char *bufPtr,unsigned int bufSize,
589 int *mskp,int *valp)
590{
591 int ret;
592 v4l2_std_id id;
593 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
594 if (ret < 0) return ret;
595 if (mskp) *mskp = id;
596 if (valp) *valp = id;
597 return 0;
598}
599
600static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
601{
602 *vp = cptr->hdw->std_mask_cur;
603 return 0;
604}
605
606static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
607{
608 struct pvr2_hdw *hdw = cptr->hdw;
609 v4l2_std_id ns;
610 ns = hdw->std_mask_cur;
611 ns = (ns & ~m) | (v & m);
612 if (ns == hdw->std_mask_cur) return 0;
613 hdw->std_mask_cur = ns;
614 hdw->std_dirty = !0;
615 pvr2_hdw_internal_find_stdenum(hdw);
616 return 0;
617}
618
619static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
620{
621 return cptr->hdw->std_dirty != 0;
622}
623
624static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
625{
626 cptr->hdw->std_dirty = 0;
627}
628
629static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
630{
Mike Isely18103c572007-01-20 00:09:47 -0300631 struct pvr2_hdw *hdw = cptr->hdw;
632 pvr2_i2c_core_status_poll(hdw);
633 *vp = hdw->tuner_signal_info.signal;
634 return 0;
635}
636
637static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
638{
639 int val = 0;
640 unsigned int subchan;
641 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely644afdb2007-01-20 00:19:23 -0300642 pvr2_i2c_core_status_poll(hdw);
Mike Isely18103c572007-01-20 00:09:47 -0300643 subchan = hdw->tuner_signal_info.rxsubchans;
644 if (subchan & V4L2_TUNER_SUB_MONO) {
645 val |= (1 << V4L2_TUNER_MODE_MONO);
646 }
647 if (subchan & V4L2_TUNER_SUB_STEREO) {
648 val |= (1 << V4L2_TUNER_MODE_STEREO);
649 }
650 if (subchan & V4L2_TUNER_SUB_LANG1) {
651 val |= (1 << V4L2_TUNER_MODE_LANG1);
652 }
653 if (subchan & V4L2_TUNER_SUB_LANG2) {
654 val |= (1 << V4L2_TUNER_MODE_LANG2);
655 }
656 *vp = val;
Mike Iselyd8554972006-06-26 20:58:46 -0300657 return 0;
658}
659
660static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
661{
662 *vp = cptr->hdw->subsys_enabled_mask;
663 return 0;
664}
665
666static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
667{
668 pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
669 return 0;
670}
671
672static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
673{
674 *vp = cptr->hdw->subsys_stream_mask;
675 return 0;
676}
677
678static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
679{
680 pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
681 return 0;
682}
683
684static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
685{
686 struct pvr2_hdw *hdw = cptr->hdw;
687 if (v < 0) return -EINVAL;
688 if (v > hdw->std_enum_cnt) return -EINVAL;
689 hdw->std_enum_cur = v;
690 if (!v) return 0;
691 v--;
692 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
693 hdw->std_mask_cur = hdw->std_defs[v].id;
694 hdw->std_dirty = !0;
695 return 0;
696}
697
698
699static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
700{
701 *vp = cptr->hdw->std_enum_cur;
702 return 0;
703}
704
705
706static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
707{
708 return cptr->hdw->std_dirty != 0;
709}
710
711
712static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
713{
714 cptr->hdw->std_dirty = 0;
715}
716
717
718#define DEFINT(vmin,vmax) \
719 .type = pvr2_ctl_int, \
720 .def.type_int.min_value = vmin, \
721 .def.type_int.max_value = vmax
722
723#define DEFENUM(tab) \
724 .type = pvr2_ctl_enum, \
Mike Isely27c7b712007-01-20 00:39:17 -0300725 .def.type_enum.count = ARRAY_SIZE(tab), \
Mike Iselyd8554972006-06-26 20:58:46 -0300726 .def.type_enum.value_names = tab
727
Mike Isely33213962006-06-25 20:04:40 -0300728#define DEFBOOL \
729 .type = pvr2_ctl_bool
730
Mike Iselyd8554972006-06-26 20:58:46 -0300731#define DEFMASK(msk,tab) \
732 .type = pvr2_ctl_bitmask, \
733 .def.type_bitmask.valid_bits = msk, \
734 .def.type_bitmask.bit_names = tab
735
736#define DEFREF(vname) \
737 .set_value = ctrl_set_##vname, \
738 .get_value = ctrl_get_##vname, \
739 .is_dirty = ctrl_isdirty_##vname, \
740 .clear_dirty = ctrl_cleardirty_##vname
741
742
743#define VCREATE_FUNCS(vname) \
744static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
745{*vp = cptr->hdw->vname##_val; return 0;} \
746static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
747{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
748static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
749{return cptr->hdw->vname##_dirty != 0;} \
750static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
751{cptr->hdw->vname##_dirty = 0;}
752
753VCREATE_FUNCS(brightness)
754VCREATE_FUNCS(contrast)
755VCREATE_FUNCS(saturation)
756VCREATE_FUNCS(hue)
757VCREATE_FUNCS(volume)
758VCREATE_FUNCS(balance)
759VCREATE_FUNCS(bass)
760VCREATE_FUNCS(treble)
761VCREATE_FUNCS(mute)
Mike Iselyc05c0462006-06-25 20:04:25 -0300762VCREATE_FUNCS(audiomode)
763VCREATE_FUNCS(res_hor)
764VCREATE_FUNCS(res_ver)
Mike Iselyd8554972006-06-26 20:58:46 -0300765VCREATE_FUNCS(srate)
Mike Iselyd8554972006-06-26 20:58:46 -0300766
Mike Iselyd8554972006-06-26 20:58:46 -0300767/* Table definition of all controls which can be manipulated */
768static const struct pvr2_ctl_info control_defs[] = {
769 {
770 .v4l_id = V4L2_CID_BRIGHTNESS,
771 .desc = "Brightness",
772 .name = "brightness",
773 .default_value = 128,
774 DEFREF(brightness),
775 DEFINT(0,255),
776 },{
777 .v4l_id = V4L2_CID_CONTRAST,
778 .desc = "Contrast",
779 .name = "contrast",
780 .default_value = 68,
781 DEFREF(contrast),
782 DEFINT(0,127),
783 },{
784 .v4l_id = V4L2_CID_SATURATION,
785 .desc = "Saturation",
786 .name = "saturation",
787 .default_value = 64,
788 DEFREF(saturation),
789 DEFINT(0,127),
790 },{
791 .v4l_id = V4L2_CID_HUE,
792 .desc = "Hue",
793 .name = "hue",
794 .default_value = 0,
795 DEFREF(hue),
796 DEFINT(-128,127),
797 },{
798 .v4l_id = V4L2_CID_AUDIO_VOLUME,
799 .desc = "Volume",
800 .name = "volume",
Mike Isely139eecf2006-12-27 23:36:33 -0300801 .default_value = 62000,
Mike Iselyd8554972006-06-26 20:58:46 -0300802 DEFREF(volume),
803 DEFINT(0,65535),
804 },{
805 .v4l_id = V4L2_CID_AUDIO_BALANCE,
806 .desc = "Balance",
807 .name = "balance",
808 .default_value = 0,
809 DEFREF(balance),
810 DEFINT(-32768,32767),
811 },{
812 .v4l_id = V4L2_CID_AUDIO_BASS,
813 .desc = "Bass",
814 .name = "bass",
815 .default_value = 0,
816 DEFREF(bass),
817 DEFINT(-32768,32767),
818 },{
819 .v4l_id = V4L2_CID_AUDIO_TREBLE,
820 .desc = "Treble",
821 .name = "treble",
822 .default_value = 0,
823 DEFREF(treble),
824 DEFINT(-32768,32767),
825 },{
826 .v4l_id = V4L2_CID_AUDIO_MUTE,
827 .desc = "Mute",
828 .name = "mute",
829 .default_value = 0,
830 DEFREF(mute),
Mike Isely33213962006-06-25 20:04:40 -0300831 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300832 },{
Mike Iselyc05c0462006-06-25 20:04:25 -0300833 .desc = "Video Source",
834 .name = "input",
835 .internal_id = PVR2_CID_INPUT,
836 .default_value = PVR2_CVAL_INPUT_TV,
837 DEFREF(input),
838 DEFENUM(control_values_input),
839 },{
840 .desc = "Audio Mode",
841 .name = "audio_mode",
842 .internal_id = PVR2_CID_AUDIOMODE,
843 .default_value = V4L2_TUNER_MODE_STEREO,
844 DEFREF(audiomode),
845 DEFENUM(control_values_audiomode),
846 },{
847 .desc = "Horizontal capture resolution",
848 .name = "resolution_hor",
849 .internal_id = PVR2_CID_HRES,
850 .default_value = 720,
851 DEFREF(res_hor),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300852 DEFINT(19,720),
Mike Iselyc05c0462006-06-25 20:04:25 -0300853 },{
854 .desc = "Vertical capture resolution",
855 .name = "resolution_ver",
856 .internal_id = PVR2_CID_VRES,
857 .default_value = 480,
858 DEFREF(res_ver),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300859 DEFINT(17,576),
860 /* Hook in check for video standard and adjust maximum
861 depending on the standard. */
862 .get_max_value = ctrl_vres_max_get,
863 .get_min_value = ctrl_vres_min_get,
Mike Iselyc05c0462006-06-25 20:04:25 -0300864 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300865 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
Mike Isely434449f2006-08-08 09:10:06 -0300866 .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
867 .desc = "Audio Sampling Frequency",
Mike Iselyd8554972006-06-26 20:58:46 -0300868 .name = "srate",
Mike Iselyd8554972006-06-26 20:58:46 -0300869 DEFREF(srate),
870 DEFENUM(control_values_srate),
871 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300872 .desc = "Tuner Frequency (Hz)",
873 .name = "frequency",
874 .internal_id = PVR2_CID_FREQUENCY,
Mike Isely1bde0282006-12-27 23:30:13 -0300875 .default_value = 0,
Mike Iselyd8554972006-06-26 20:58:46 -0300876 .set_value = ctrl_freq_set,
877 .get_value = ctrl_freq_get,
878 .is_dirty = ctrl_freq_is_dirty,
879 .clear_dirty = ctrl_freq_clear_dirty,
Mike Isely644afdb2007-01-20 00:19:23 -0300880 DEFINT(0,0),
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300881 /* Hook in check for input value (tv/radio) and adjust
882 max/min values accordingly */
883 .get_max_value = ctrl_freq_max_get,
884 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300885 },{
886 .desc = "Channel",
887 .name = "channel",
888 .set_value = ctrl_channel_set,
889 .get_value = ctrl_channel_get,
890 DEFINT(0,FREQTABLE_SIZE),
891 },{
892 .desc = "Channel Program Frequency",
893 .name = "freq_table_value",
894 .set_value = ctrl_channelfreq_set,
895 .get_value = ctrl_channelfreq_get,
Mike Isely644afdb2007-01-20 00:19:23 -0300896 DEFINT(0,0),
Mike Isely1bde0282006-12-27 23:30:13 -0300897 /* Hook in check for input value (tv/radio) and adjust
898 max/min values accordingly */
Mike Isely1bde0282006-12-27 23:30:13 -0300899 .get_max_value = ctrl_freq_max_get,
900 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300901 },{
902 .desc = "Channel Program ID",
903 .name = "freq_table_channel",
904 .set_value = ctrl_channelprog_set,
905 .get_value = ctrl_channelprog_get,
906 DEFINT(0,FREQTABLE_SIZE),
907 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300908 .desc = "Streaming Enabled",
909 .name = "streaming_enabled",
910 .get_value = ctrl_streamingenabled_get,
Mike Isely33213962006-06-25 20:04:40 -0300911 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300912 },{
913 .desc = "USB Speed",
914 .name = "usb_speed",
915 .get_value = ctrl_hsm_get,
916 DEFENUM(control_values_hsm),
917 },{
918 .desc = "Signal Present",
919 .name = "signal_present",
920 .get_value = ctrl_signal_get,
Mike Isely18103c572007-01-20 00:09:47 -0300921 DEFINT(0,65535),
922 },{
923 .desc = "Audio Modes Present",
924 .name = "audio_modes_present",
925 .get_value = ctrl_audio_modes_present_get,
926 /* For this type we "borrow" the V4L2_TUNER_MODE enum from
927 v4l. Nothing outside of this module cares about this,
928 but I reuse it in order to also reuse the
929 control_values_audiomode string table. */
930 DEFMASK(((1 << V4L2_TUNER_MODE_MONO)|
931 (1 << V4L2_TUNER_MODE_STEREO)|
932 (1 << V4L2_TUNER_MODE_LANG1)|
933 (1 << V4L2_TUNER_MODE_LANG2)),
934 control_values_audiomode),
Mike Iselyd8554972006-06-26 20:58:46 -0300935 },{
936 .desc = "Video Standards Available Mask",
937 .name = "video_standard_mask_available",
938 .internal_id = PVR2_CID_STDAVAIL,
939 .skip_init = !0,
940 .get_value = ctrl_stdavail_get,
941 .set_value = ctrl_stdavail_set,
942 .val_to_sym = ctrl_std_val_to_sym,
943 .sym_to_val = ctrl_std_sym_to_val,
944 .type = pvr2_ctl_bitmask,
945 },{
946 .desc = "Video Standards In Use Mask",
947 .name = "video_standard_mask_active",
948 .internal_id = PVR2_CID_STDCUR,
949 .skip_init = !0,
950 .get_value = ctrl_stdcur_get,
951 .set_value = ctrl_stdcur_set,
952 .is_dirty = ctrl_stdcur_is_dirty,
953 .clear_dirty = ctrl_stdcur_clear_dirty,
954 .val_to_sym = ctrl_std_val_to_sym,
955 .sym_to_val = ctrl_std_sym_to_val,
956 .type = pvr2_ctl_bitmask,
957 },{
958 .desc = "Subsystem enabled mask",
959 .name = "debug_subsys_mask",
960 .skip_init = !0,
961 .get_value = ctrl_subsys_get,
962 .set_value = ctrl_subsys_set,
963 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
964 },{
965 .desc = "Subsystem stream mask",
966 .name = "debug_subsys_stream_mask",
967 .skip_init = !0,
968 .get_value = ctrl_subsys_stream_get,
969 .set_value = ctrl_subsys_stream_set,
970 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
971 },{
972 .desc = "Video Standard Name",
973 .name = "video_standard",
974 .internal_id = PVR2_CID_STDENUM,
975 .skip_init = !0,
976 .get_value = ctrl_stdenumcur_get,
977 .set_value = ctrl_stdenumcur_set,
978 .is_dirty = ctrl_stdenumcur_is_dirty,
979 .clear_dirty = ctrl_stdenumcur_clear_dirty,
980 .type = pvr2_ctl_enum,
981 }
982};
983
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -0300984#define CTRLDEF_COUNT ARRAY_SIZE(control_defs)
Mike Iselyd8554972006-06-26 20:58:46 -0300985
986
987const char *pvr2_config_get_name(enum pvr2_config cfg)
988{
989 switch (cfg) {
990 case pvr2_config_empty: return "empty";
991 case pvr2_config_mpeg: return "mpeg";
992 case pvr2_config_vbi: return "vbi";
Mike Isely16eb40d2006-12-30 18:27:32 -0300993 case pvr2_config_pcm: return "pcm";
994 case pvr2_config_rawvideo: return "raw video";
Mike Iselyd8554972006-06-26 20:58:46 -0300995 }
996 return "<unknown>";
997}
998
999
1000struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
1001{
1002 return hdw->usb_dev;
1003}
1004
1005
1006unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
1007{
1008 return hdw->serial_number;
1009}
1010
Mike Isely31a18542007-04-08 01:11:47 -03001011
1012const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
1013{
1014 return hdw->bus_info;
1015}
1016
1017
Mike Isely1bde0282006-12-27 23:30:13 -03001018unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
1019{
1020 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
1021}
1022
1023/* Set the currently tuned frequency and account for all possible
1024 driver-core side effects of this action. */
1025void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val)
1026{
Mike Isely7c74e572007-01-20 00:15:41 -03001027 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
Mike Isely1bde0282006-12-27 23:30:13 -03001028 if (hdw->freqSelector) {
1029 /* Swing over to radio frequency selection */
1030 hdw->freqSelector = 0;
1031 hdw->freqDirty = !0;
1032 }
Mike Isely1bde0282006-12-27 23:30:13 -03001033 if (hdw->freqValRadio != val) {
1034 hdw->freqValRadio = val;
1035 hdw->freqSlotRadio = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001036 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001037 }
Mike Isely7c74e572007-01-20 00:15:41 -03001038 } else {
Mike Isely1bde0282006-12-27 23:30:13 -03001039 if (!(hdw->freqSelector)) {
1040 /* Swing over to television frequency selection */
1041 hdw->freqSelector = 1;
1042 hdw->freqDirty = !0;
1043 }
Mike Isely1bde0282006-12-27 23:30:13 -03001044 if (hdw->freqValTelevision != val) {
1045 hdw->freqValTelevision = val;
1046 hdw->freqSlotTelevision = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001047 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001048 }
Mike Isely1bde0282006-12-27 23:30:13 -03001049 }
1050}
1051
Mike Iselyd8554972006-06-26 20:58:46 -03001052int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
1053{
1054 return hdw->unit_number;
1055}
1056
1057
1058/* Attempt to locate one of the given set of files. Messages are logged
1059 appropriate to what has been found. The return value will be 0 or
1060 greater on success (it will be the index of the file name found) and
1061 fw_entry will be filled in. Otherwise a negative error is returned on
1062 failure. If the return value is -ENOENT then no viable firmware file
1063 could be located. */
1064static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
1065 const struct firmware **fw_entry,
1066 const char *fwtypename,
1067 unsigned int fwcount,
1068 const char *fwnames[])
1069{
1070 unsigned int idx;
1071 int ret = -EINVAL;
1072 for (idx = 0; idx < fwcount; idx++) {
1073 ret = request_firmware(fw_entry,
1074 fwnames[idx],
1075 &hdw->usb_dev->dev);
1076 if (!ret) {
1077 trace_firmware("Located %s firmware: %s;"
1078 " uploading...",
1079 fwtypename,
1080 fwnames[idx]);
1081 return idx;
1082 }
1083 if (ret == -ENOENT) continue;
1084 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1085 "request_firmware fatal error with code=%d",ret);
1086 return ret;
1087 }
1088 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1089 "***WARNING***"
1090 " Device %s firmware"
1091 " seems to be missing.",
1092 fwtypename);
1093 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1094 "Did you install the pvrusb2 firmware files"
1095 " in their proper location?");
1096 if (fwcount == 1) {
1097 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1098 "request_firmware unable to locate %s file %s",
1099 fwtypename,fwnames[0]);
1100 } else {
1101 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1102 "request_firmware unable to locate"
1103 " one of the following %s files:",
1104 fwtypename);
1105 for (idx = 0; idx < fwcount; idx++) {
1106 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1107 "request_firmware: Failed to find %s",
1108 fwnames[idx]);
1109 }
1110 }
1111 return ret;
1112}
1113
1114
1115/*
1116 * pvr2_upload_firmware1().
1117 *
1118 * Send the 8051 firmware to the device. After the upload, arrange for
1119 * device to re-enumerate.
1120 *
1121 * NOTE : the pointer to the firmware data given by request_firmware()
1122 * is not suitable for an usb transaction.
1123 *
1124 */
Adrian Bunk07e337e2006-06-30 11:30:20 -03001125static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001126{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001127 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001128 void *fw_ptr;
1129 unsigned int pipe;
1130 int ret;
1131 u16 address;
1132 static const char *fw_files_29xxx[] = {
1133 "v4l-pvrusb2-29xxx-01.fw",
1134 };
Mike Iselyd8554972006-06-26 20:58:46 -03001135 static const char *fw_files_24xxx[] = {
1136 "v4l-pvrusb2-24xxx-01.fw",
1137 };
Mike Iselyd8554972006-06-26 20:58:46 -03001138 static const struct pvr2_string_table fw_file_defs[] = {
1139 [PVR2_HDW_TYPE_29XXX] = {
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001140 fw_files_29xxx, ARRAY_SIZE(fw_files_29xxx)
Mike Iselyd8554972006-06-26 20:58:46 -03001141 },
Mike Iselyd8554972006-06-26 20:58:46 -03001142 [PVR2_HDW_TYPE_24XXX] = {
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001143 fw_files_24xxx, ARRAY_SIZE(fw_files_24xxx)
Mike Iselyd8554972006-06-26 20:58:46 -03001144 },
Mike Iselyd8554972006-06-26 20:58:46 -03001145 };
Mike Isely1d643a32007-09-08 22:18:50 -03001146
1147 if ((hdw->hdw_type >= ARRAY_SIZE(fw_file_defs)) ||
1148 (!fw_file_defs[hdw->hdw_type].lst)) {
1149 hdw->fw1_state = FW1_STATE_OK;
1150 return 0;
1151 }
1152
Mike Iselyd8554972006-06-26 20:58:46 -03001153 hdw->fw1_state = FW1_STATE_FAILED; // default result
1154
1155 trace_firmware("pvr2_upload_firmware1");
1156
1157 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
1158 fw_file_defs[hdw->hdw_type].cnt,
1159 fw_file_defs[hdw->hdw_type].lst);
1160 if (ret < 0) {
1161 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
1162 return ret;
1163 }
1164
1165 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
1166 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
1167
1168 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
1169
1170 if (fw_entry->size != 0x2000){
1171 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
1172 release_firmware(fw_entry);
1173 return -ENOMEM;
1174 }
1175
1176 fw_ptr = kmalloc(0x800, GFP_KERNEL);
1177 if (fw_ptr == NULL){
1178 release_firmware(fw_entry);
1179 return -ENOMEM;
1180 }
1181
1182 /* We have to hold the CPU during firmware upload. */
1183 pvr2_hdw_cpureset_assert(hdw,1);
1184
1185 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
1186 chunk. */
1187
1188 ret = 0;
1189 for(address = 0; address < fw_entry->size; address += 0x800) {
1190 memcpy(fw_ptr, fw_entry->data + address, 0x800);
1191 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
1192 0, fw_ptr, 0x800, HZ);
1193 }
1194
1195 trace_firmware("Upload done, releasing device's CPU");
1196
1197 /* Now release the CPU. It will disconnect and reconnect later. */
1198 pvr2_hdw_cpureset_assert(hdw,0);
1199
1200 kfree(fw_ptr);
1201 release_firmware(fw_entry);
1202
1203 trace_firmware("Upload done (%d bytes sent)",ret);
1204
1205 /* We should have written 8192 bytes */
1206 if (ret == 8192) {
1207 hdw->fw1_state = FW1_STATE_RELOAD;
1208 return 0;
1209 }
1210
1211 return -EIO;
1212}
1213
1214
1215/*
1216 * pvr2_upload_firmware2()
1217 *
1218 * This uploads encoder firmware on endpoint 2.
1219 *
1220 */
1221
1222int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
1223{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001224 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001225 void *fw_ptr;
Mike Isely90060d32007-02-08 02:02:53 -03001226 unsigned int pipe, fw_len, fw_done, bcnt, icnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001227 int actual_length;
1228 int ret = 0;
1229 int fwidx;
1230 static const char *fw_files[] = {
1231 CX2341X_FIRM_ENC_FILENAME,
1232 };
1233
Mike Isely1d643a32007-09-08 22:18:50 -03001234 if ((hdw->hdw_type != PVR2_HDW_TYPE_29XXX) &&
1235 (hdw->hdw_type != PVR2_HDW_TYPE_24XXX)) {
1236 return 0;
1237 }
1238
Mike Iselyd8554972006-06-26 20:58:46 -03001239 trace_firmware("pvr2_upload_firmware2");
1240
1241 ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001242 ARRAY_SIZE(fw_files), fw_files);
Mike Iselyd8554972006-06-26 20:58:46 -03001243 if (ret < 0) return ret;
1244 fwidx = ret;
1245 ret = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001246 /* Since we're about to completely reinitialize the encoder,
1247 invalidate our cached copy of its configuration state. Next
1248 time we configure the encoder, then we'll fully configure it. */
1249 hdw->enc_cur_valid = 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001250
1251 /* First prepare firmware loading */
1252 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
1253 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
1254 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1255 ret |= pvr2_hdw_cmd_deep_reset(hdw);
1256 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
1257 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
1258 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1259 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
1260 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
1261 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
1262 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
1263 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
1264 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
1265 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
1266 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
1267 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
Mike Isely567d7112007-01-28 15:38:55 -03001268 LOCK_TAKE(hdw->ctl_lock); do {
1269 hdw->cmd_buffer[0] = FX2CMD_FWPOST1;
Al Viro89952d12007-03-14 09:17:59 +00001270 ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Isely567d7112007-01-28 15:38:55 -03001271 hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
1272 hdw->cmd_buffer[1] = 0;
Al Viro89952d12007-03-14 09:17:59 +00001273 ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
Mike Isely567d7112007-01-28 15:38:55 -03001274 } while (0); LOCK_GIVE(hdw->ctl_lock);
Mike Iselyd8554972006-06-26 20:58:46 -03001275
1276 if (ret) {
1277 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1278 "firmware2 upload prep failed, ret=%d",ret);
1279 release_firmware(fw_entry);
1280 return ret;
1281 }
1282
1283 /* Now send firmware */
1284
1285 fw_len = fw_entry->size;
1286
Mike Isely90060d32007-02-08 02:02:53 -03001287 if (fw_len % sizeof(u32)) {
Mike Iselyd8554972006-06-26 20:58:46 -03001288 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1289 "size of %s firmware"
Mike Isely48dc30a2007-03-03 10:13:05 -02001290 " must be a multiple of %zu bytes",
Mike Isely90060d32007-02-08 02:02:53 -03001291 fw_files[fwidx],sizeof(u32));
Mike Iselyd8554972006-06-26 20:58:46 -03001292 release_firmware(fw_entry);
1293 return -1;
1294 }
1295
1296 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1297 if (fw_ptr == NULL){
1298 release_firmware(fw_entry);
1299 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1300 "failed to allocate memory for firmware2 upload");
1301 return -ENOMEM;
1302 }
1303
1304 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1305
Mike Isely90060d32007-02-08 02:02:53 -03001306 fw_done = 0;
1307 for (fw_done = 0; fw_done < fw_len;) {
1308 bcnt = fw_len - fw_done;
1309 if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE;
1310 memcpy(fw_ptr, fw_entry->data + fw_done, bcnt);
1311 /* Usbsnoop log shows that we must swap bytes... */
1312 for (icnt = 0; icnt < bcnt/4 ; icnt++)
1313 ((u32 *)fw_ptr)[icnt] =
1314 ___swab32(((u32 *)fw_ptr)[icnt]);
Mike Iselyd8554972006-06-26 20:58:46 -03001315
Mike Isely90060d32007-02-08 02:02:53 -03001316 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001317 &actual_length, HZ);
Mike Isely90060d32007-02-08 02:02:53 -03001318 ret |= (actual_length != bcnt);
1319 if (ret) break;
1320 fw_done += bcnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001321 }
1322
1323 trace_firmware("upload of %s : %i / %i ",
1324 fw_files[fwidx],fw_done,fw_len);
1325
1326 kfree(fw_ptr);
1327 release_firmware(fw_entry);
1328
1329 if (ret) {
1330 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1331 "firmware2 upload transfer failure");
1332 return ret;
1333 }
1334
1335 /* Finish upload */
1336
1337 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1338 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
Mike Isely567d7112007-01-28 15:38:55 -03001339 LOCK_TAKE(hdw->ctl_lock); do {
1340 hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
1341 hdw->cmd_buffer[1] = 0;
Al Viro89952d12007-03-14 09:17:59 +00001342 ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
Mike Isely567d7112007-01-28 15:38:55 -03001343 } while (0); LOCK_GIVE(hdw->ctl_lock);
Mike Iselyd8554972006-06-26 20:58:46 -03001344
1345 if (ret) {
1346 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1347 "firmware2 upload post-proc failure");
1348 } else {
1349 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
1350 }
1351 return ret;
1352}
1353
1354
1355#define FIRMWARE_RECOVERY_BITS \
1356 ((1<<PVR2_SUBSYS_B_ENC_CFG) | \
1357 (1<<PVR2_SUBSYS_B_ENC_RUN) | \
1358 (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \
1359 (1<<PVR2_SUBSYS_B_USBSTREAM_RUN))
1360
1361/*
1362
1363 This single function is key to pretty much everything. The pvrusb2
1364 device can logically be viewed as a series of subsystems which can be
1365 stopped / started or unconfigured / configured. To get things streaming,
1366 one must configure everything and start everything, but there may be
1367 various reasons over time to deconfigure something or stop something.
1368 This function handles all of this activity. Everything EVERYWHERE that
1369 must affect a subsystem eventually comes here to do the work.
1370
1371 The current state of all subsystems is represented by a single bit mask,
1372 known as subsys_enabled_mask. The bit positions are defined by the
1373 PVR2_SUBSYS_xxxx macros, with one subsystem per bit position. At any
1374 time the set of configured or active subsystems can be queried just by
1375 looking at that mask. To change bits in that mask, this function here
1376 must be called. The "msk" argument indicates which bit positions to
1377 change, and the "val" argument defines the new values for the positions
1378 defined by "msk".
1379
1380 There is a priority ordering of starting / stopping things, and for
1381 multiple requested changes, this function implements that ordering.
1382 (Thus we will act on a request to load encoder firmware before we
1383 configure the encoder.) In addition to priority ordering, there is a
1384 recovery strategy implemented here. If a particular step fails and we
1385 detect that failure, this function will clear the affected subsystem bits
1386 and restart. Thus we have a means for recovering from a dead encoder:
1387 Clear all bits that correspond to subsystems that we need to restart /
1388 reconfigure and start over.
1389
1390*/
Adrian Bunk07e337e2006-06-30 11:30:20 -03001391static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
1392 unsigned long msk,
1393 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001394{
1395 unsigned long nmsk;
1396 unsigned long vmsk;
1397 int ret;
1398 unsigned int tryCount = 0;
1399
1400 if (!hdw->flag_ok) return;
1401
1402 msk &= PVR2_SUBSYS_ALL;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001403 nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk);
1404 nmsk &= PVR2_SUBSYS_ALL;
Mike Iselyd8554972006-06-26 20:58:46 -03001405
1406 for (;;) {
1407 tryCount++;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001408 if (!((nmsk ^ hdw->subsys_enabled_mask) &
1409 PVR2_SUBSYS_ALL)) break;
Mike Iselyd8554972006-06-26 20:58:46 -03001410 if (tryCount > 4) {
1411 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1412 "Too many retries when configuring device;"
1413 " giving up");
1414 pvr2_hdw_render_useless(hdw);
1415 break;
1416 }
1417 if (tryCount > 1) {
1418 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1419 "Retrying device reconfiguration");
1420 }
1421 pvr2_trace(PVR2_TRACE_INIT,
1422 "subsys mask changing 0x%lx:0x%lx"
1423 " from 0x%lx to 0x%lx",
1424 msk,val,hdw->subsys_enabled_mask,nmsk);
1425
1426 vmsk = (nmsk ^ hdw->subsys_enabled_mask) &
1427 hdw->subsys_enabled_mask;
1428 if (vmsk) {
1429 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1430 pvr2_trace(PVR2_TRACE_CTL,
1431 "/*---TRACE_CTL----*/"
1432 " pvr2_encoder_stop");
1433 ret = pvr2_encoder_stop(hdw);
1434 if (ret) {
1435 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1436 "Error recovery initiated");
1437 hdw->subsys_enabled_mask &=
1438 ~FIRMWARE_RECOVERY_BITS;
1439 continue;
1440 }
1441 }
1442 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1443 pvr2_trace(PVR2_TRACE_CTL,
1444 "/*---TRACE_CTL----*/"
1445 " pvr2_hdw_cmd_usbstream(0)");
1446 pvr2_hdw_cmd_usbstream(hdw,0);
1447 }
1448 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1449 pvr2_trace(PVR2_TRACE_CTL,
1450 "/*---TRACE_CTL----*/"
1451 " decoder disable");
1452 if (hdw->decoder_ctrl) {
1453 hdw->decoder_ctrl->enable(
1454 hdw->decoder_ctrl->ctxt,0);
1455 } else {
1456 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1457 "WARNING:"
1458 " No decoder present");
1459 }
1460 hdw->subsys_enabled_mask &=
1461 ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1462 }
1463 if (vmsk & PVR2_SUBSYS_CFG_ALL) {
1464 hdw->subsys_enabled_mask &=
1465 ~(vmsk & PVR2_SUBSYS_CFG_ALL);
1466 }
1467 }
1468 vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk;
1469 if (vmsk) {
1470 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) {
1471 pvr2_trace(PVR2_TRACE_CTL,
1472 "/*---TRACE_CTL----*/"
1473 " pvr2_upload_firmware2");
1474 ret = pvr2_upload_firmware2(hdw);
1475 if (ret) {
1476 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1477 "Failure uploading encoder"
1478 " firmware");
1479 pvr2_hdw_render_useless(hdw);
1480 break;
1481 }
1482 }
1483 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) {
1484 pvr2_trace(PVR2_TRACE_CTL,
1485 "/*---TRACE_CTL----*/"
1486 " pvr2_encoder_configure");
1487 ret = pvr2_encoder_configure(hdw);
1488 if (ret) {
1489 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1490 "Error recovery initiated");
1491 hdw->subsys_enabled_mask &=
1492 ~FIRMWARE_RECOVERY_BITS;
1493 continue;
1494 }
1495 }
1496 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1497 pvr2_trace(PVR2_TRACE_CTL,
1498 "/*---TRACE_CTL----*/"
1499 " decoder enable");
1500 if (hdw->decoder_ctrl) {
1501 hdw->decoder_ctrl->enable(
1502 hdw->decoder_ctrl->ctxt,!0);
1503 } else {
1504 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1505 "WARNING:"
1506 " No decoder present");
1507 }
1508 hdw->subsys_enabled_mask |=
1509 (1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1510 }
1511 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1512 pvr2_trace(PVR2_TRACE_CTL,
1513 "/*---TRACE_CTL----*/"
1514 " pvr2_hdw_cmd_usbstream(1)");
1515 pvr2_hdw_cmd_usbstream(hdw,!0);
1516 }
1517 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1518 pvr2_trace(PVR2_TRACE_CTL,
1519 "/*---TRACE_CTL----*/"
1520 " pvr2_encoder_start");
1521 ret = pvr2_encoder_start(hdw);
1522 if (ret) {
1523 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1524 "Error recovery initiated");
1525 hdw->subsys_enabled_mask &=
1526 ~FIRMWARE_RECOVERY_BITS;
1527 continue;
1528 }
1529 }
1530 }
1531 }
1532}
1533
1534
1535void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
1536 unsigned long msk,unsigned long val)
1537{
1538 LOCK_TAKE(hdw->big_lock); do {
1539 pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val);
1540 } while (0); LOCK_GIVE(hdw->big_lock);
1541}
1542
1543
Mike Iselyd8554972006-06-26 20:58:46 -03001544unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw)
1545{
1546 return hdw->subsys_enabled_mask;
1547}
1548
1549
1550unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw)
1551{
1552 return hdw->subsys_stream_mask;
1553}
1554
1555
Adrian Bunk07e337e2006-06-30 11:30:20 -03001556static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
1557 unsigned long msk,
1558 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001559{
1560 unsigned long val2;
1561 msk &= PVR2_SUBSYS_ALL;
1562 val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk));
1563 pvr2_trace(PVR2_TRACE_INIT,
1564 "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx",
1565 msk,val,hdw->subsys_stream_mask,val2);
1566 hdw->subsys_stream_mask = val2;
1567}
1568
1569
1570void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
1571 unsigned long msk,
1572 unsigned long val)
1573{
1574 LOCK_TAKE(hdw->big_lock); do {
1575 pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val);
1576 } while (0); LOCK_GIVE(hdw->big_lock);
1577}
1578
1579
Adrian Bunk07e337e2006-06-30 11:30:20 -03001580static int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl)
Mike Iselyd8554972006-06-26 20:58:46 -03001581{
1582 if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0;
1583 if (enableFl) {
1584 pvr2_trace(PVR2_TRACE_START_STOP,
1585 "/*--TRACE_STREAM--*/ enable");
1586 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0);
1587 } else {
1588 pvr2_trace(PVR2_TRACE_START_STOP,
1589 "/*--TRACE_STREAM--*/ disable");
1590 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1591 }
1592 if (!hdw->flag_ok) return -EIO;
1593 hdw->flag_streaming_enabled = enableFl != 0;
1594 return 0;
1595}
1596
1597
1598int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1599{
1600 return hdw->flag_streaming_enabled != 0;
1601}
1602
1603
1604int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1605{
1606 int ret;
1607 LOCK_TAKE(hdw->big_lock); do {
1608 ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag);
1609 } while (0); LOCK_GIVE(hdw->big_lock);
1610 return ret;
1611}
1612
1613
Adrian Bunk07e337e2006-06-30 11:30:20 -03001614static int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw,
1615 enum pvr2_config config)
Mike Iselyd8554972006-06-26 20:58:46 -03001616{
1617 unsigned long sm = hdw->subsys_enabled_mask;
1618 if (!hdw->flag_ok) return -EIO;
1619 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1620 hdw->config = config;
1621 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm);
1622 return 0;
1623}
1624
1625
1626int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1627{
1628 int ret;
1629 if (!hdw->flag_ok) return -EIO;
1630 LOCK_TAKE(hdw->big_lock);
1631 ret = pvr2_hdw_set_stream_type_no_lock(hdw,config);
1632 LOCK_GIVE(hdw->big_lock);
1633 return ret;
1634}
1635
1636
1637static int get_default_tuner_type(struct pvr2_hdw *hdw)
1638{
1639 int unit_number = hdw->unit_number;
1640 int tp = -1;
1641 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1642 tp = tuner[unit_number];
1643 }
1644 if (tp < 0) return -EINVAL;
1645 hdw->tuner_type = tp;
1646 return 0;
1647}
1648
1649
1650static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1651{
1652 int unit_number = hdw->unit_number;
1653 int tp = 0;
1654 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1655 tp = video_std[unit_number];
1656 }
1657 return tp;
1658}
1659
1660
1661static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1662{
1663 int unit_number = hdw->unit_number;
1664 int tp = 0;
1665 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1666 tp = tolerance[unit_number];
1667 }
1668 return tp;
1669}
1670
1671
1672static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1673{
1674 /* Try a harmless request to fetch the eeprom's address over
1675 endpoint 1. See what happens. Only the full FX2 image can
1676 respond to this. If this probe fails then likely the FX2
1677 firmware needs be loaded. */
1678 int result;
1679 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03001680 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03001681 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1682 hdw->cmd_buffer,1,
1683 hdw->cmd_buffer,1);
1684 if (result < 0) break;
1685 } while(0); LOCK_GIVE(hdw->ctl_lock);
1686 if (result) {
1687 pvr2_trace(PVR2_TRACE_INIT,
1688 "Probe of device endpoint 1 result status %d",
1689 result);
1690 } else {
1691 pvr2_trace(PVR2_TRACE_INIT,
1692 "Probe of device endpoint 1 succeeded");
1693 }
1694 return result == 0;
1695}
1696
1697static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1698{
1699 char buf[40];
1700 unsigned int bcnt;
1701 v4l2_std_id std1,std2;
1702
1703 std1 = get_default_standard(hdw);
1704
1705 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
1706 pvr2_trace(PVR2_TRACE_INIT,
1707 "Supported video standard(s) reported by eeprom: %.*s",
1708 bcnt,buf);
1709
1710 hdw->std_mask_avail = hdw->std_mask_eeprom;
1711
1712 std2 = std1 & ~hdw->std_mask_avail;
1713 if (std2) {
1714 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
1715 pvr2_trace(PVR2_TRACE_INIT,
1716 "Expanding supported video standards"
1717 " to include: %.*s",
1718 bcnt,buf);
1719 hdw->std_mask_avail |= std2;
1720 }
1721
1722 pvr2_hdw_internal_set_std_avail(hdw);
1723
1724 if (std1) {
1725 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
1726 pvr2_trace(PVR2_TRACE_INIT,
1727 "Initial video standard forced to %.*s",
1728 bcnt,buf);
1729 hdw->std_mask_cur = std1;
1730 hdw->std_dirty = !0;
1731 pvr2_hdw_internal_find_stdenum(hdw);
1732 return;
1733 }
1734
1735 if (hdw->std_enum_cnt > 1) {
1736 // Autoselect the first listed standard
1737 hdw->std_enum_cur = 1;
1738 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1739 hdw->std_dirty = !0;
1740 pvr2_trace(PVR2_TRACE_INIT,
1741 "Initial video standard auto-selected to %s",
1742 hdw->std_defs[hdw->std_enum_cur-1].name);
1743 return;
1744 }
1745
Mike Isely0885ba12006-06-25 21:30:47 -03001746 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
Mike Iselyd8554972006-06-26 20:58:46 -03001747 "Unable to select a viable initial video standard");
1748}
1749
1750
1751static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1752{
1753 int ret;
1754 unsigned int idx;
1755 struct pvr2_ctrl *cptr;
1756 int reloadFl = 0;
Mike Isely1d643a32007-09-08 22:18:50 -03001757 if ((hdw->hdw_type == PVR2_HDW_TYPE_29XXX) ||
1758 (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) {
1759 if (!reloadFl) {
1760 reloadFl =
1761 (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1762 == 0);
1763 if (reloadFl) {
1764 pvr2_trace(PVR2_TRACE_INIT,
1765 "USB endpoint config looks strange"
1766 "; possibly firmware needs to be"
1767 " loaded");
1768 }
1769 }
1770 if (!reloadFl) {
1771 reloadFl = !pvr2_hdw_check_firmware(hdw);
1772 if (reloadFl) {
1773 pvr2_trace(PVR2_TRACE_INIT,
1774 "Check for FX2 firmware failed"
1775 "; possibly firmware needs to be"
1776 " loaded");
1777 }
1778 }
Mike Iselyd8554972006-06-26 20:58:46 -03001779 if (reloadFl) {
Mike Isely1d643a32007-09-08 22:18:50 -03001780 if (pvr2_upload_firmware1(hdw) != 0) {
1781 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1782 "Failure uploading firmware1");
1783 }
1784 return;
Mike Iselyd8554972006-06-26 20:58:46 -03001785 }
1786 }
Mike Iselyd8554972006-06-26 20:58:46 -03001787 hdw->fw1_state = FW1_STATE_OK;
1788
1789 if (initusbreset) {
1790 pvr2_hdw_device_reset(hdw);
1791 }
1792 if (!pvr2_hdw_dev_ok(hdw)) return;
1793
Mike Isely1d643a32007-09-08 22:18:50 -03001794 if (hdw->hdw_type < ARRAY_SIZE(pvr2_client_lists)) {
1795 for (idx = 0;
1796 idx < pvr2_client_lists[hdw->hdw_type].cnt;
1797 idx++) {
1798 request_module(
1799 pvr2_client_lists[hdw->hdw_type].lst[idx]);
1800 }
Mike Iselyd8554972006-06-26 20:58:46 -03001801 }
1802
Mike Isely1d643a32007-09-08 22:18:50 -03001803 if ((hdw->hdw_type == PVR2_HDW_TYPE_29XXX) ||
1804 (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) {
1805 pvr2_hdw_cmd_powerup(hdw);
1806 if (!pvr2_hdw_dev_ok(hdw)) return;
Mike Iselyd8554972006-06-26 20:58:46 -03001807
Mike Isely1d643a32007-09-08 22:18:50 -03001808 if (pvr2_upload_firmware2(hdw)){
1809 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
1810 pvr2_hdw_render_useless(hdw);
1811 return;
1812 }
Mike Iselyd8554972006-06-26 20:58:46 -03001813 }
1814
1815 // This step MUST happen after the earlier powerup step.
1816 pvr2_i2c_core_init(hdw);
1817 if (!pvr2_hdw_dev_ok(hdw)) return;
1818
Mike Iselyc05c0462006-06-25 20:04:25 -03001819 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001820 cptr = hdw->controls + idx;
1821 if (cptr->info->skip_init) continue;
1822 if (!cptr->info->set_value) continue;
1823 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1824 }
1825
Mike Isely1bde0282006-12-27 23:30:13 -03001826 /* Set up special default values for the television and radio
1827 frequencies here. It's not really important what these defaults
1828 are, but I set them to something usable in the Chicago area just
1829 to make driver testing a little easier. */
1830
1831 /* US Broadcast channel 7 (175.25 MHz) */
1832 hdw->freqValTelevision = 175250000L;
1833 /* 104.3 MHz, a usable FM station for my area */
1834 hdw->freqValRadio = 104300000L;
1835
Mike Iselyd8554972006-06-26 20:58:46 -03001836 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1837 // thread-safe against the normal pvr2_send_request() mechanism.
1838 // (We should make it thread safe).
1839
1840 ret = pvr2_hdw_get_eeprom_addr(hdw);
1841 if (!pvr2_hdw_dev_ok(hdw)) return;
1842 if (ret < 0) {
1843 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1844 "Unable to determine location of eeprom, skipping");
1845 } else {
1846 hdw->eeprom_addr = ret;
1847 pvr2_eeprom_analyze(hdw);
1848 if (!pvr2_hdw_dev_ok(hdw)) return;
1849 }
1850
1851 pvr2_hdw_setup_std(hdw);
1852
1853 if (!get_default_tuner_type(hdw)) {
1854 pvr2_trace(PVR2_TRACE_INIT,
1855 "pvr2_hdw_setup: Tuner type overridden to %d",
1856 hdw->tuner_type);
1857 }
1858
1859 hdw->tuner_updated = !0;
1860 pvr2_i2c_core_check_stale(hdw);
1861 hdw->tuner_updated = 0;
1862
1863 if (!pvr2_hdw_dev_ok(hdw)) return;
1864
1865 pvr2_hdw_commit_ctl_internal(hdw);
1866 if (!pvr2_hdw_dev_ok(hdw)) return;
1867
1868 hdw->vid_stream = pvr2_stream_create();
1869 if (!pvr2_hdw_dev_ok(hdw)) return;
1870 pvr2_trace(PVR2_TRACE_INIT,
1871 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1872 if (hdw->vid_stream) {
1873 idx = get_default_error_tolerance(hdw);
1874 if (idx) {
1875 pvr2_trace(PVR2_TRACE_INIT,
1876 "pvr2_hdw_setup: video stream %p"
1877 " setting tolerance %u",
1878 hdw->vid_stream,idx);
1879 }
1880 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1881 PVR2_VID_ENDPOINT,idx);
1882 }
1883
1884 if (!pvr2_hdw_dev_ok(hdw)) return;
1885
1886 /* Make sure everything is up to date */
1887 pvr2_i2c_core_sync(hdw);
1888
1889 if (!pvr2_hdw_dev_ok(hdw)) return;
1890
1891 hdw->flag_init_ok = !0;
1892}
1893
1894
1895int pvr2_hdw_setup(struct pvr2_hdw *hdw)
1896{
1897 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
1898 LOCK_TAKE(hdw->big_lock); do {
1899 pvr2_hdw_setup_low(hdw);
1900 pvr2_trace(PVR2_TRACE_INIT,
1901 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
1902 hdw,hdw->flag_ok,hdw->flag_init_ok);
1903 if (pvr2_hdw_dev_ok(hdw)) {
1904 if (pvr2_hdw_init_ok(hdw)) {
1905 pvr2_trace(
1906 PVR2_TRACE_INFO,
1907 "Device initialization"
1908 " completed successfully.");
1909 break;
1910 }
1911 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1912 pvr2_trace(
1913 PVR2_TRACE_INFO,
1914 "Device microcontroller firmware"
1915 " (re)loaded; it should now reset"
1916 " and reconnect.");
1917 break;
1918 }
1919 pvr2_trace(
1920 PVR2_TRACE_ERROR_LEGS,
1921 "Device initialization was not successful.");
1922 if (hdw->fw1_state == FW1_STATE_MISSING) {
1923 pvr2_trace(
1924 PVR2_TRACE_ERROR_LEGS,
1925 "Giving up since device"
1926 " microcontroller firmware"
1927 " appears to be missing.");
1928 break;
1929 }
1930 }
1931 if (procreload) {
1932 pvr2_trace(
1933 PVR2_TRACE_ERROR_LEGS,
1934 "Attempting pvrusb2 recovery by reloading"
1935 " primary firmware.");
1936 pvr2_trace(
1937 PVR2_TRACE_ERROR_LEGS,
1938 "If this works, device should disconnect"
1939 " and reconnect in a sane state.");
1940 hdw->fw1_state = FW1_STATE_UNKNOWN;
1941 pvr2_upload_firmware1(hdw);
1942 } else {
1943 pvr2_trace(
1944 PVR2_TRACE_ERROR_LEGS,
1945 "***WARNING*** pvrusb2 device hardware"
1946 " appears to be jammed"
1947 " and I can't clear it.");
1948 pvr2_trace(
1949 PVR2_TRACE_ERROR_LEGS,
1950 "You might need to power cycle"
1951 " the pvrusb2 device"
1952 " in order to recover.");
1953 }
1954 } while (0); LOCK_GIVE(hdw->big_lock);
1955 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
1956 return hdw->flag_init_ok;
1957}
1958
1959
1960/* Create and return a structure for interacting with the underlying
1961 hardware */
1962struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1963 const struct usb_device_id *devid)
1964{
1965 unsigned int idx,cnt1,cnt2;
1966 struct pvr2_hdw *hdw;
1967 unsigned int hdw_type;
1968 int valid_std_mask;
1969 struct pvr2_ctrl *cptr;
1970 __u8 ifnum;
Mike Iselyb30d2442006-06-25 20:05:01 -03001971 struct v4l2_queryctrl qctrl;
1972 struct pvr2_ctl_info *ciptr;
Mike Iselyd8554972006-06-26 20:58:46 -03001973
1974 hdw_type = devid - pvr2_device_table;
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001975 if (hdw_type >= ARRAY_SIZE(pvr2_device_names)) {
Mike Iselyd8554972006-06-26 20:58:46 -03001976 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1977 "Bogus device type of %u reported",hdw_type);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001978 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001979 }
1980
Mike Iselyca545f72007-01-20 00:37:11 -03001981 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -03001982 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
1983 hdw,pvr2_device_names[hdw_type]);
1984 if (!hdw) goto fail;
Mike Isely18103c572007-01-20 00:09:47 -03001985 hdw->tuner_signal_stale = !0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001986 cx2341x_fill_defaults(&hdw->enc_ctl_state);
Mike Iselyd8554972006-06-26 20:58:46 -03001987
Mike Iselyc05c0462006-06-25 20:04:25 -03001988 hdw->control_cnt = CTRLDEF_COUNT;
Mike Iselyb30d2442006-06-25 20:05:01 -03001989 hdw->control_cnt += MPEGDEF_COUNT;
Mike Iselyca545f72007-01-20 00:37:11 -03001990 hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001991 GFP_KERNEL);
1992 if (!hdw->controls) goto fail;
Mike Iselyd8554972006-06-26 20:58:46 -03001993 hdw->hdw_type = hdw_type;
Mike Iselyc05c0462006-06-25 20:04:25 -03001994 for (idx = 0; idx < hdw->control_cnt; idx++) {
1995 cptr = hdw->controls + idx;
1996 cptr->hdw = hdw;
1997 }
Mike Iselyd8554972006-06-26 20:58:46 -03001998 for (idx = 0; idx < 32; idx++) {
1999 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
2000 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002001 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002002 cptr = hdw->controls + idx;
Mike Iselyd8554972006-06-26 20:58:46 -03002003 cptr->info = control_defs+idx;
2004 }
Mike Iselyb30d2442006-06-25 20:05:01 -03002005 /* Define and configure additional controls from cx2341x module. */
Mike Iselyca545f72007-01-20 00:37:11 -03002006 hdw->mpeg_ctrl_info = kzalloc(
Mike Iselyb30d2442006-06-25 20:05:01 -03002007 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
2008 if (!hdw->mpeg_ctrl_info) goto fail;
Mike Iselyb30d2442006-06-25 20:05:01 -03002009 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
2010 cptr = hdw->controls + idx + CTRLDEF_COUNT;
2011 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
2012 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
2013 ciptr->name = mpeg_ids[idx].strid;
2014 ciptr->v4l_id = mpeg_ids[idx].id;
2015 ciptr->skip_init = !0;
2016 ciptr->get_value = ctrl_cx2341x_get;
2017 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
2018 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
2019 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
2020 qctrl.id = ciptr->v4l_id;
2021 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
2022 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
2023 ciptr->set_value = ctrl_cx2341x_set;
2024 }
2025 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
2026 PVR2_CTLD_INFO_DESC_SIZE);
2027 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
2028 ciptr->default_value = qctrl.default_value;
2029 switch (qctrl.type) {
2030 default:
2031 case V4L2_CTRL_TYPE_INTEGER:
2032 ciptr->type = pvr2_ctl_int;
2033 ciptr->def.type_int.min_value = qctrl.minimum;
2034 ciptr->def.type_int.max_value = qctrl.maximum;
2035 break;
2036 case V4L2_CTRL_TYPE_BOOLEAN:
2037 ciptr->type = pvr2_ctl_bool;
2038 break;
2039 case V4L2_CTRL_TYPE_MENU:
2040 ciptr->type = pvr2_ctl_enum;
2041 ciptr->def.type_enum.value_names =
2042 cx2341x_ctrl_get_menu(ciptr->v4l_id);
2043 for (cnt1 = 0;
2044 ciptr->def.type_enum.value_names[cnt1] != NULL;
2045 cnt1++) { }
2046 ciptr->def.type_enum.count = cnt1;
2047 break;
2048 }
2049 cptr->info = ciptr;
2050 }
Mike Iselyd8554972006-06-26 20:58:46 -03002051
2052 // Initialize video standard enum dynamic control
2053 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
2054 if (cptr) {
2055 memcpy(&hdw->std_info_enum,cptr->info,
2056 sizeof(hdw->std_info_enum));
2057 cptr->info = &hdw->std_info_enum;
2058
2059 }
2060 // Initialize control data regarding video standard masks
2061 valid_std_mask = pvr2_std_get_usable();
2062 for (idx = 0; idx < 32; idx++) {
2063 if (!(valid_std_mask & (1 << idx))) continue;
2064 cnt1 = pvr2_std_id_to_str(
2065 hdw->std_mask_names[idx],
2066 sizeof(hdw->std_mask_names[idx])-1,
2067 1 << idx);
2068 hdw->std_mask_names[idx][cnt1] = 0;
2069 }
2070 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
2071 if (cptr) {
2072 memcpy(&hdw->std_info_avail,cptr->info,
2073 sizeof(hdw->std_info_avail));
2074 cptr->info = &hdw->std_info_avail;
2075 hdw->std_info_avail.def.type_bitmask.bit_names =
2076 hdw->std_mask_ptrs;
2077 hdw->std_info_avail.def.type_bitmask.valid_bits =
2078 valid_std_mask;
2079 }
2080 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
2081 if (cptr) {
2082 memcpy(&hdw->std_info_cur,cptr->info,
2083 sizeof(hdw->std_info_cur));
2084 cptr->info = &hdw->std_info_cur;
2085 hdw->std_info_cur.def.type_bitmask.bit_names =
2086 hdw->std_mask_ptrs;
2087 hdw->std_info_avail.def.type_bitmask.valid_bits =
2088 valid_std_mask;
2089 }
2090
2091 hdw->eeprom_addr = -1;
2092 hdw->unit_number = -1;
Mike Isely80793842006-12-27 23:12:28 -03002093 hdw->v4l_minor_number_video = -1;
2094 hdw->v4l_minor_number_vbi = -1;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002095 hdw->v4l_minor_number_radio = -1;
Mike Iselyd8554972006-06-26 20:58:46 -03002096 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2097 if (!hdw->ctl_write_buffer) goto fail;
2098 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2099 if (!hdw->ctl_read_buffer) goto fail;
2100 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
2101 if (!hdw->ctl_write_urb) goto fail;
2102 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
2103 if (!hdw->ctl_read_urb) goto fail;
2104
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002105 mutex_lock(&pvr2_unit_mtx); do {
Mike Iselyd8554972006-06-26 20:58:46 -03002106 for (idx = 0; idx < PVR_NUM; idx++) {
2107 if (unit_pointers[idx]) continue;
2108 hdw->unit_number = idx;
2109 unit_pointers[idx] = hdw;
2110 break;
2111 }
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002112 } while (0); mutex_unlock(&pvr2_unit_mtx);
Mike Iselyd8554972006-06-26 20:58:46 -03002113
2114 cnt1 = 0;
2115 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
2116 cnt1 += cnt2;
2117 if (hdw->unit_number >= 0) {
2118 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
2119 ('a' + hdw->unit_number));
2120 cnt1 += cnt2;
2121 }
2122 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
2123 hdw->name[cnt1] = 0;
2124
2125 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
2126 hdw->unit_number,hdw->name);
2127
2128 hdw->tuner_type = -1;
2129 hdw->flag_ok = !0;
2130 /* Initialize the mask of subsystems that we will shut down when we
2131 stop streaming. */
2132 hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
2133 hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
2134
2135 pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
2136 hdw->subsys_stream_mask);
2137
2138 hdw->usb_intf = intf;
2139 hdw->usb_dev = interface_to_usbdev(intf);
2140
Mike Isely31a18542007-04-08 01:11:47 -03002141 scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
2142 "usb %s address %d",
2143 hdw->usb_dev->dev.bus_id,
2144 hdw->usb_dev->devnum);
2145
Mike Iselyd8554972006-06-26 20:58:46 -03002146 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2147 usb_set_interface(hdw->usb_dev,ifnum,0);
2148
2149 mutex_init(&hdw->ctl_lock_mutex);
2150 mutex_init(&hdw->big_lock_mutex);
2151
2152 return hdw;
2153 fail:
2154 if (hdw) {
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002155 usb_free_urb(hdw->ctl_read_urb);
2156 usb_free_urb(hdw->ctl_write_urb);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002157 kfree(hdw->ctl_read_buffer);
2158 kfree(hdw->ctl_write_buffer);
2159 kfree(hdw->controls);
2160 kfree(hdw->mpeg_ctrl_info);
Mike Iselyd8554972006-06-26 20:58:46 -03002161 kfree(hdw);
2162 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002163 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002164}
2165
2166
2167/* Remove _all_ associations between this driver and the underlying USB
2168 layer. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002169static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002170{
2171 if (hdw->flag_disconnected) return;
2172 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
2173 if (hdw->ctl_read_urb) {
2174 usb_kill_urb(hdw->ctl_read_urb);
2175 usb_free_urb(hdw->ctl_read_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002176 hdw->ctl_read_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002177 }
2178 if (hdw->ctl_write_urb) {
2179 usb_kill_urb(hdw->ctl_write_urb);
2180 usb_free_urb(hdw->ctl_write_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002181 hdw->ctl_write_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002182 }
2183 if (hdw->ctl_read_buffer) {
2184 kfree(hdw->ctl_read_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002185 hdw->ctl_read_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002186 }
2187 if (hdw->ctl_write_buffer) {
2188 kfree(hdw->ctl_write_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002189 hdw->ctl_write_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002190 }
2191 pvr2_hdw_render_useless_unlocked(hdw);
2192 hdw->flag_disconnected = !0;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002193 hdw->usb_dev = NULL;
2194 hdw->usb_intf = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002195}
2196
2197
2198/* Destroy hardware interaction structure */
2199void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2200{
Mike Isely401c27c2007-09-08 22:11:46 -03002201 if (!hdw) return;
Mike Iselyd8554972006-06-26 20:58:46 -03002202 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
2203 if (hdw->fw_buffer) {
2204 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002205 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002206 }
2207 if (hdw->vid_stream) {
2208 pvr2_stream_destroy(hdw->vid_stream);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002209 hdw->vid_stream = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002210 }
Mike Iselyd8554972006-06-26 20:58:46 -03002211 if (hdw->decoder_ctrl) {
2212 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2213 }
2214 pvr2_i2c_core_done(hdw);
2215 pvr2_hdw_remove_usb_stuff(hdw);
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002216 mutex_lock(&pvr2_unit_mtx); do {
Mike Iselyd8554972006-06-26 20:58:46 -03002217 if ((hdw->unit_number >= 0) &&
2218 (hdw->unit_number < PVR_NUM) &&
2219 (unit_pointers[hdw->unit_number] == hdw)) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002220 unit_pointers[hdw->unit_number] = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002221 }
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002222 } while (0); mutex_unlock(&pvr2_unit_mtx);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002223 kfree(hdw->controls);
2224 kfree(hdw->mpeg_ctrl_info);
2225 kfree(hdw->std_defs);
2226 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002227 kfree(hdw);
2228}
2229
2230
2231int pvr2_hdw_init_ok(struct pvr2_hdw *hdw)
2232{
2233 return hdw->flag_init_ok;
2234}
2235
2236
2237int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2238{
2239 return (hdw && hdw->flag_ok);
2240}
2241
2242
2243/* Called when hardware has been unplugged */
2244void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2245{
2246 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2247 LOCK_TAKE(hdw->big_lock);
2248 LOCK_TAKE(hdw->ctl_lock);
2249 pvr2_hdw_remove_usb_stuff(hdw);
2250 LOCK_GIVE(hdw->ctl_lock);
2251 LOCK_GIVE(hdw->big_lock);
2252}
2253
2254
2255// Attempt to autoselect an appropriate value for std_enum_cur given
2256// whatever is currently in std_mask_cur
Adrian Bunk07e337e2006-06-30 11:30:20 -03002257static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002258{
2259 unsigned int idx;
2260 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2261 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2262 hdw->std_enum_cur = idx;
2263 return;
2264 }
2265 }
2266 hdw->std_enum_cur = 0;
2267}
2268
2269
2270// Calculate correct set of enumerated standards based on currently known
2271// set of available standards bits.
Adrian Bunk07e337e2006-06-30 11:30:20 -03002272static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002273{
2274 struct v4l2_standard *newstd;
2275 unsigned int std_cnt;
2276 unsigned int idx;
2277
2278 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2279
2280 if (hdw->std_defs) {
2281 kfree(hdw->std_defs);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002282 hdw->std_defs = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002283 }
2284 hdw->std_enum_cnt = 0;
2285 if (hdw->std_enum_names) {
2286 kfree(hdw->std_enum_names);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002287 hdw->std_enum_names = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002288 }
2289
2290 if (!std_cnt) {
2291 pvr2_trace(
2292 PVR2_TRACE_ERROR_LEGS,
2293 "WARNING: Failed to identify any viable standards");
2294 }
2295 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2296 hdw->std_enum_names[0] = "none";
2297 for (idx = 0; idx < std_cnt; idx++) {
2298 hdw->std_enum_names[idx+1] =
2299 newstd[idx].name;
2300 }
2301 // Set up the dynamic control for this standard
2302 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2303 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2304 hdw->std_defs = newstd;
2305 hdw->std_enum_cnt = std_cnt+1;
2306 hdw->std_enum_cur = 0;
2307 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2308}
2309
2310
2311int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2312 struct v4l2_standard *std,
2313 unsigned int idx)
2314{
2315 int ret = -EINVAL;
2316 if (!idx) return ret;
2317 LOCK_TAKE(hdw->big_lock); do {
2318 if (idx >= hdw->std_enum_cnt) break;
2319 idx--;
2320 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2321 ret = 0;
2322 } while (0); LOCK_GIVE(hdw->big_lock);
2323 return ret;
2324}
2325
2326
2327/* Get the number of defined controls */
2328unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2329{
Mike Iselyc05c0462006-06-25 20:04:25 -03002330 return hdw->control_cnt;
Mike Iselyd8554972006-06-26 20:58:46 -03002331}
2332
2333
2334/* Retrieve a control handle given its index (0..count-1) */
2335struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2336 unsigned int idx)
2337{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002338 if (idx >= hdw->control_cnt) return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002339 return hdw->controls + idx;
2340}
2341
2342
2343/* Retrieve a control handle given its index (0..count-1) */
2344struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2345 unsigned int ctl_id)
2346{
2347 struct pvr2_ctrl *cptr;
2348 unsigned int idx;
2349 int i;
2350
2351 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002352 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002353 cptr = hdw->controls + idx;
2354 i = cptr->info->internal_id;
2355 if (i && (i == ctl_id)) return cptr;
2356 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002357 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002358}
2359
2360
Mike Iselya761f432006-06-25 20:04:44 -03002361/* Given a V4L ID, retrieve the control structure associated with it. */
Mike Iselyd8554972006-06-26 20:58:46 -03002362struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2363{
2364 struct pvr2_ctrl *cptr;
2365 unsigned int idx;
2366 int i;
2367
2368 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002369 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002370 cptr = hdw->controls + idx;
2371 i = cptr->info->v4l_id;
2372 if (i && (i == ctl_id)) return cptr;
2373 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002374 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002375}
2376
2377
Mike Iselya761f432006-06-25 20:04:44 -03002378/* Given a V4L ID for its immediate predecessor, retrieve the control
2379 structure associated with it. */
2380struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2381 unsigned int ctl_id)
2382{
2383 struct pvr2_ctrl *cptr,*cp2;
2384 unsigned int idx;
2385 int i;
2386
2387 /* This could be made a lot more efficient, but for now... */
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002388 cp2 = NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002389 for (idx = 0; idx < hdw->control_cnt; idx++) {
2390 cptr = hdw->controls + idx;
2391 i = cptr->info->v4l_id;
2392 if (!i) continue;
2393 if (i <= ctl_id) continue;
2394 if (cp2 && (cp2->info->v4l_id < i)) continue;
2395 cp2 = cptr;
2396 }
2397 return cp2;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002398 return NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002399}
2400
2401
Mike Iselyd8554972006-06-26 20:58:46 -03002402static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2403{
2404 switch (tp) {
2405 case pvr2_ctl_int: return "integer";
2406 case pvr2_ctl_enum: return "enum";
Mike Isely33213962006-06-25 20:04:40 -03002407 case pvr2_ctl_bool: return "boolean";
Mike Iselyd8554972006-06-26 20:58:46 -03002408 case pvr2_ctl_bitmask: return "bitmask";
2409 }
2410 return "";
2411}
2412
2413
2414/* Commit all control changes made up to this point. Subsystems can be
2415 indirectly affected by these changes. For a given set of things being
2416 committed, we'll clear the affected subsystem bits and then once we're
2417 done committing everything we'll make a request to restore the subsystem
2418 state(s) back to their previous value before this function was called.
2419 Thus we can automatically reconfigure affected pieces of the driver as
2420 controls are changed. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002421static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002422{
2423 unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
2424 unsigned long stale_subsys_mask = 0;
2425 unsigned int idx;
2426 struct pvr2_ctrl *cptr;
2427 int value;
2428 int commit_flag = 0;
2429 char buf[100];
2430 unsigned int bcnt,ccnt;
2431
Mike Iselyc05c0462006-06-25 20:04:25 -03002432 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002433 cptr = hdw->controls + idx;
2434 if (cptr->info->is_dirty == 0) continue;
2435 if (!cptr->info->is_dirty(cptr)) continue;
Mike Iselyfe23a282007-01-20 00:10:55 -03002436 commit_flag = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002437
Mike Iselyfe23a282007-01-20 00:10:55 -03002438 if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002439 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2440 cptr->info->name);
2441 value = 0;
2442 cptr->info->get_value(cptr,&value);
2443 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2444 buf+bcnt,
2445 sizeof(buf)-bcnt,&ccnt);
2446 bcnt += ccnt;
2447 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2448 get_ctrl_typename(cptr->info->type));
2449 pvr2_trace(PVR2_TRACE_CTL,
2450 "/*--TRACE_COMMIT--*/ %.*s",
2451 bcnt,buf);
2452 }
2453
2454 if (!commit_flag) {
2455 /* Nothing has changed */
2456 return 0;
2457 }
2458
2459 /* When video standard changes, reset the hres and vres values -
2460 but if the user has pending changes there, then let the changes
2461 take priority. */
2462 if (hdw->std_dirty) {
2463 /* Rewrite the vertical resolution to be appropriate to the
2464 video standard that has been selected. */
2465 int nvres;
2466 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2467 nvres = 480;
2468 } else {
2469 nvres = 576;
2470 }
2471 if (nvres != hdw->res_ver_val) {
2472 hdw->res_ver_val = nvres;
2473 hdw->res_ver_dirty = !0;
2474 }
Mike Iselyd8554972006-06-26 20:58:46 -03002475 }
2476
2477 if (hdw->std_dirty ||
Mike Isely434449f2006-08-08 09:10:06 -03002478 hdw->enc_stale ||
2479 hdw->srate_dirty ||
2480 hdw->res_ver_dirty ||
2481 hdw->res_hor_dirty ||
Mike Iselyb46cfa82006-06-25 20:04:53 -03002482 0) {
Mike Iselyd8554972006-06-26 20:58:46 -03002483 /* If any of this changes, then the encoder needs to be
2484 reconfigured, and we need to reset the stream. */
2485 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
Mike Iselyd8554972006-06-26 20:58:46 -03002486 }
2487
Pantelis Koukousoulas275b2e22006-12-27 23:05:19 -03002488 if (hdw->input_dirty) {
2489 /* pk: If input changes to or from radio, then the encoder
2490 needs to be restarted (for ENC_MUTE_VIDEO to work) */
2491 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
2492 }
2493
2494
Mike Iselyb30d2442006-06-25 20:05:01 -03002495 if (hdw->srate_dirty) {
2496 /* Write new sample rate into control structure since
2497 * the master copy is stale. We must track srate
2498 * separate from the mpeg control structure because
2499 * other logic also uses this value. */
2500 struct v4l2_ext_controls cs;
2501 struct v4l2_ext_control c1;
2502 memset(&cs,0,sizeof(cs));
2503 memset(&c1,0,sizeof(c1));
2504 cs.controls = &c1;
2505 cs.count = 1;
2506 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2507 c1.value = hdw->srate_val;
Hans Verkuil01f1e442007-08-21 18:32:42 -03002508 cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
Mike Iselyb30d2442006-06-25 20:05:01 -03002509 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002510
Mike Iselyd8554972006-06-26 20:58:46 -03002511 /* Scan i2c core at this point - before we clear all the dirty
2512 bits. Various parts of the i2c core will notice dirty bits as
2513 appropriate and arrange to broadcast or directly send updates to
2514 the client drivers in order to keep everything in sync */
2515 pvr2_i2c_core_check_stale(hdw);
2516
Mike Iselyc05c0462006-06-25 20:04:25 -03002517 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002518 cptr = hdw->controls + idx;
2519 if (!cptr->info->clear_dirty) continue;
2520 cptr->info->clear_dirty(cptr);
2521 }
2522
2523 /* Now execute i2c core update */
2524 pvr2_i2c_core_sync(hdw);
2525
2526 pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
2527 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
2528
2529 return 0;
2530}
2531
2532
2533int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2534{
2535 LOCK_TAKE(hdw->big_lock); do {
2536 pvr2_hdw_commit_ctl_internal(hdw);
2537 } while (0); LOCK_GIVE(hdw->big_lock);
2538 return 0;
2539}
2540
2541
2542void pvr2_hdw_poll(struct pvr2_hdw *hdw)
2543{
2544 LOCK_TAKE(hdw->big_lock); do {
2545 pvr2_i2c_core_sync(hdw);
2546 } while (0); LOCK_GIVE(hdw->big_lock);
2547}
2548
2549
2550void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
2551 void (*func)(void *),
2552 void *data)
2553{
2554 LOCK_TAKE(hdw->big_lock); do {
2555 hdw->poll_trigger_func = func;
2556 hdw->poll_trigger_data = data;
2557 } while (0); LOCK_GIVE(hdw->big_lock);
2558}
2559
2560
2561void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
2562{
2563 if (hdw->poll_trigger_func) {
2564 hdw->poll_trigger_func(hdw->poll_trigger_data);
2565 }
2566}
2567
Mike Iselyd8554972006-06-26 20:58:46 -03002568/* Return name for this driver instance */
2569const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2570{
2571 return hdw->name;
2572}
2573
2574
Mike Iselyd8554972006-06-26 20:58:46 -03002575int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2576{
2577 int result;
2578 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03002579 hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED;
Mike Iselyd8554972006-06-26 20:58:46 -03002580 result = pvr2_send_request(hdw,
2581 hdw->cmd_buffer,1,
2582 hdw->cmd_buffer,1);
2583 if (result < 0) break;
2584 result = (hdw->cmd_buffer[0] != 0);
2585 } while(0); LOCK_GIVE(hdw->ctl_lock);
2586 return result;
2587}
2588
2589
Mike Isely18103c572007-01-20 00:09:47 -03002590/* Execute poll of tuner status */
2591void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002592{
Mike Iselyd8554972006-06-26 20:58:46 -03002593 LOCK_TAKE(hdw->big_lock); do {
Mike Isely18103c572007-01-20 00:09:47 -03002594 pvr2_i2c_core_status_poll(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002595 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely18103c572007-01-20 00:09:47 -03002596}
2597
2598
2599/* Return information about the tuner */
2600int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
2601{
2602 LOCK_TAKE(hdw->big_lock); do {
2603 if (hdw->tuner_signal_stale) {
2604 pvr2_i2c_core_status_poll(hdw);
2605 }
2606 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
2607 } while (0); LOCK_GIVE(hdw->big_lock);
2608 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002609}
2610
2611
2612/* Get handle to video output stream */
2613struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2614{
2615 return hp->vid_stream;
2616}
2617
2618
2619void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2620{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002621 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002622 LOCK_TAKE(hdw->big_lock); do {
2623 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002624 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002625 pvr2_i2c_core_check_stale(hdw);
2626 hdw->log_requested = 0;
2627 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002628 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002629 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely4f1a3e52006-06-25 20:04:31 -03002630 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002631 } while (0); LOCK_GIVE(hdw->big_lock);
2632}
2633
Mike Isely4db666c2007-09-08 22:16:27 -03002634
2635/* Grab EEPROM contents, needed for direct method. */
2636#define EEPROM_SIZE 8192
2637#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
2638static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw)
2639{
2640 struct i2c_msg msg[2];
2641 u8 *eeprom;
2642 u8 iadd[2];
2643 u8 addr;
2644 u16 eepromSize;
2645 unsigned int offs;
2646 int ret;
2647 int mode16 = 0;
2648 unsigned pcnt,tcnt;
2649 eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
2650 if (!eeprom) {
2651 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2652 "Failed to allocate memory"
2653 " required to read eeprom");
2654 return NULL;
2655 }
2656
2657 trace_eeprom("Value for eeprom addr from controller was 0x%x",
2658 hdw->eeprom_addr);
2659 addr = hdw->eeprom_addr;
2660 /* Seems that if the high bit is set, then the *real* eeprom
2661 address is shifted right now bit position (noticed this in
2662 newer PVR USB2 hardware) */
2663 if (addr & 0x80) addr >>= 1;
2664
2665 /* FX2 documentation states that a 16bit-addressed eeprom is
2666 expected if the I2C address is an odd number (yeah, this is
2667 strange but it's what they do) */
2668 mode16 = (addr & 1);
2669 eepromSize = (mode16 ? EEPROM_SIZE : 256);
2670 trace_eeprom("Examining %d byte eeprom at location 0x%x"
2671 " using %d bit addressing",eepromSize,addr,
2672 mode16 ? 16 : 8);
2673
2674 msg[0].addr = addr;
2675 msg[0].flags = 0;
2676 msg[0].len = mode16 ? 2 : 1;
2677 msg[0].buf = iadd;
2678 msg[1].addr = addr;
2679 msg[1].flags = I2C_M_RD;
2680
2681 /* We have to do the actual eeprom data fetch ourselves, because
2682 (1) we're only fetching part of the eeprom, and (2) if we were
2683 getting the whole thing our I2C driver can't grab it in one
2684 pass - which is what tveeprom is otherwise going to attempt */
2685 memset(eeprom,0,EEPROM_SIZE);
2686 for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
2687 pcnt = 16;
2688 if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
2689 offs = tcnt + (eepromSize - EEPROM_SIZE);
2690 if (mode16) {
2691 iadd[0] = offs >> 8;
2692 iadd[1] = offs;
2693 } else {
2694 iadd[0] = offs;
2695 }
2696 msg[1].len = pcnt;
2697 msg[1].buf = eeprom+tcnt;
2698 if ((ret = i2c_transfer(&hdw->i2c_adap,
2699 msg,ARRAY_SIZE(msg))) != 2) {
2700 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2701 "eeprom fetch set offs err=%d",ret);
2702 kfree(eeprom);
2703 return NULL;
2704 }
2705 }
2706 return eeprom;
2707}
2708
2709
2710void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
2711 int prom_flag,
2712 int enable_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002713{
2714 int ret;
2715 u16 address;
2716 unsigned int pipe;
2717 LOCK_TAKE(hdw->big_lock); do {
2718 if ((hdw->fw_buffer == 0) == !enable_flag) break;
2719
2720 if (!enable_flag) {
2721 pvr2_trace(PVR2_TRACE_FIRMWARE,
2722 "Cleaning up after CPU firmware fetch");
2723 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002724 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002725 hdw->fw_size = 0;
Mike Isely4db666c2007-09-08 22:16:27 -03002726 if (hdw->fw_cpu_flag) {
2727 /* Now release the CPU. It will disconnect
2728 and reconnect later. */
2729 pvr2_hdw_cpureset_assert(hdw,0);
2730 }
Mike Iselyd8554972006-06-26 20:58:46 -03002731 break;
2732 }
2733
Mike Isely4db666c2007-09-08 22:16:27 -03002734 hdw->fw_cpu_flag = (prom_flag == 0);
2735 if (hdw->fw_cpu_flag) {
2736 pvr2_trace(PVR2_TRACE_FIRMWARE,
2737 "Preparing to suck out CPU firmware");
2738 hdw->fw_size = 0x2000;
2739 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
2740 if (!hdw->fw_buffer) {
2741 hdw->fw_size = 0;
2742 break;
2743 }
2744
2745 /* We have to hold the CPU during firmware upload. */
2746 pvr2_hdw_cpureset_assert(hdw,1);
2747
2748 /* download the firmware from address 0000-1fff in 2048
2749 (=0x800) bytes chunk. */
2750
2751 pvr2_trace(PVR2_TRACE_FIRMWARE,
2752 "Grabbing CPU firmware");
2753 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2754 for(address = 0; address < hdw->fw_size;
2755 address += 0x800) {
2756 ret = usb_control_msg(hdw->usb_dev,pipe,
2757 0xa0,0xc0,
2758 address,0,
2759 hdw->fw_buffer+address,
2760 0x800,HZ);
2761 if (ret < 0) break;
2762 }
2763
2764 pvr2_trace(PVR2_TRACE_FIRMWARE,
2765 "Done grabbing CPU firmware");
2766 } else {
2767 pvr2_trace(PVR2_TRACE_FIRMWARE,
2768 "Sucking down EEPROM contents");
2769 hdw->fw_buffer = pvr2_full_eeprom_fetch(hdw);
2770 if (!hdw->fw_buffer) {
2771 pvr2_trace(PVR2_TRACE_FIRMWARE,
2772 "EEPROM content suck failed.");
2773 break;
2774 }
2775 hdw->fw_size = EEPROM_SIZE;
2776 pvr2_trace(PVR2_TRACE_FIRMWARE,
2777 "Done sucking down EEPROM contents");
Mike Iselyd8554972006-06-26 20:58:46 -03002778 }
2779
Mike Iselyd8554972006-06-26 20:58:46 -03002780 } while (0); LOCK_GIVE(hdw->big_lock);
2781}
2782
2783
2784/* Return true if we're in a mode for retrieval CPU firmware */
2785int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2786{
2787 return hdw->fw_buffer != 0;
2788}
2789
2790
2791int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2792 char *buf,unsigned int cnt)
2793{
2794 int ret = -EINVAL;
2795 LOCK_TAKE(hdw->big_lock); do {
2796 if (!buf) break;
2797 if (!cnt) break;
2798
2799 if (!hdw->fw_buffer) {
2800 ret = -EIO;
2801 break;
2802 }
2803
2804 if (offs >= hdw->fw_size) {
2805 pvr2_trace(PVR2_TRACE_FIRMWARE,
2806 "Read firmware data offs=%d EOF",
2807 offs);
2808 ret = 0;
2809 break;
2810 }
2811
2812 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2813
2814 memcpy(buf,hdw->fw_buffer+offs,cnt);
2815
2816 pvr2_trace(PVR2_TRACE_FIRMWARE,
2817 "Read firmware data offs=%d cnt=%d",
2818 offs,cnt);
2819 ret = cnt;
2820 } while (0); LOCK_GIVE(hdw->big_lock);
2821
2822 return ret;
2823}
2824
2825
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002826int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002827 enum pvr2_v4l_type index)
Mike Iselyd8554972006-06-26 20:58:46 -03002828{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002829 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002830 case pvr2_v4l_type_video: return hdw->v4l_minor_number_video;
2831 case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi;
2832 case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002833 default: return -1;
2834 }
Mike Iselyd8554972006-06-26 20:58:46 -03002835}
2836
2837
Pantelis Koukousoulas2fdf3d92006-12-27 23:07:58 -03002838/* Store a v4l minor device number */
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002839void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002840 enum pvr2_v4l_type index,int v)
Mike Iselyd8554972006-06-26 20:58:46 -03002841{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002842 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002843 case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
2844 case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
2845 case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002846 default: break;
2847 }
Mike Iselyd8554972006-06-26 20:58:46 -03002848}
2849
2850
David Howells7d12e782006-10-05 14:55:46 +01002851static void pvr2_ctl_write_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002852{
2853 struct pvr2_hdw *hdw = urb->context;
2854 hdw->ctl_write_pend_flag = 0;
2855 if (hdw->ctl_read_pend_flag) return;
2856 complete(&hdw->ctl_done);
2857}
2858
2859
David Howells7d12e782006-10-05 14:55:46 +01002860static void pvr2_ctl_read_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002861{
2862 struct pvr2_hdw *hdw = urb->context;
2863 hdw->ctl_read_pend_flag = 0;
2864 if (hdw->ctl_write_pend_flag) return;
2865 complete(&hdw->ctl_done);
2866}
2867
2868
2869static void pvr2_ctl_timeout(unsigned long data)
2870{
2871 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2872 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2873 hdw->ctl_timeout_flag = !0;
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002874 if (hdw->ctl_write_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002875 usb_unlink_urb(hdw->ctl_write_urb);
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002876 if (hdw->ctl_read_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002877 usb_unlink_urb(hdw->ctl_read_urb);
Mike Iselyd8554972006-06-26 20:58:46 -03002878 }
2879}
2880
2881
Mike Iselye61b6fc2006-07-18 22:42:18 -03002882/* Issue a command and get a response from the device. This extended
2883 version includes a probe flag (which if set means that device errors
2884 should not be logged or treated as fatal) and a timeout in jiffies.
2885 This can be used to non-lethally probe the health of endpoint 1. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002886static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2887 unsigned int timeout,int probe_fl,
2888 void *write_data,unsigned int write_len,
2889 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002890{
2891 unsigned int idx;
2892 int status = 0;
2893 struct timer_list timer;
2894 if (!hdw->ctl_lock_held) {
2895 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2896 "Attempted to execute control transfer"
2897 " without lock!!");
2898 return -EDEADLK;
2899 }
2900 if ((!hdw->flag_ok) && !probe_fl) {
2901 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2902 "Attempted to execute control transfer"
2903 " when device not ok");
2904 return -EIO;
2905 }
2906 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2907 if (!probe_fl) {
2908 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2909 "Attempted to execute control transfer"
2910 " when USB is disconnected");
2911 }
2912 return -ENOTTY;
2913 }
2914
2915 /* Ensure that we have sane parameters */
2916 if (!write_data) write_len = 0;
2917 if (!read_data) read_len = 0;
2918 if (write_len > PVR2_CTL_BUFFSIZE) {
2919 pvr2_trace(
2920 PVR2_TRACE_ERROR_LEGS,
2921 "Attempted to execute %d byte"
2922 " control-write transfer (limit=%d)",
2923 write_len,PVR2_CTL_BUFFSIZE);
2924 return -EINVAL;
2925 }
2926 if (read_len > PVR2_CTL_BUFFSIZE) {
2927 pvr2_trace(
2928 PVR2_TRACE_ERROR_LEGS,
2929 "Attempted to execute %d byte"
2930 " control-read transfer (limit=%d)",
2931 write_len,PVR2_CTL_BUFFSIZE);
2932 return -EINVAL;
2933 }
2934 if ((!write_len) && (!read_len)) {
2935 pvr2_trace(
2936 PVR2_TRACE_ERROR_LEGS,
2937 "Attempted to execute null control transfer?");
2938 return -EINVAL;
2939 }
2940
2941
2942 hdw->cmd_debug_state = 1;
2943 if (write_len) {
2944 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2945 } else {
2946 hdw->cmd_debug_code = 0;
2947 }
2948 hdw->cmd_debug_write_len = write_len;
2949 hdw->cmd_debug_read_len = read_len;
2950
2951 /* Initialize common stuff */
2952 init_completion(&hdw->ctl_done);
2953 hdw->ctl_timeout_flag = 0;
2954 hdw->ctl_write_pend_flag = 0;
2955 hdw->ctl_read_pend_flag = 0;
2956 init_timer(&timer);
2957 timer.expires = jiffies + timeout;
2958 timer.data = (unsigned long)hdw;
2959 timer.function = pvr2_ctl_timeout;
2960
2961 if (write_len) {
2962 hdw->cmd_debug_state = 2;
2963 /* Transfer write data to internal buffer */
2964 for (idx = 0; idx < write_len; idx++) {
2965 hdw->ctl_write_buffer[idx] =
2966 ((unsigned char *)write_data)[idx];
2967 }
2968 /* Initiate a write request */
2969 usb_fill_bulk_urb(hdw->ctl_write_urb,
2970 hdw->usb_dev,
2971 usb_sndbulkpipe(hdw->usb_dev,
2972 PVR2_CTL_WRITE_ENDPOINT),
2973 hdw->ctl_write_buffer,
2974 write_len,
2975 pvr2_ctl_write_complete,
2976 hdw);
2977 hdw->ctl_write_urb->actual_length = 0;
2978 hdw->ctl_write_pend_flag = !0;
2979 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2980 if (status < 0) {
2981 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2982 "Failed to submit write-control"
2983 " URB status=%d",status);
2984 hdw->ctl_write_pend_flag = 0;
2985 goto done;
2986 }
2987 }
2988
2989 if (read_len) {
2990 hdw->cmd_debug_state = 3;
2991 memset(hdw->ctl_read_buffer,0x43,read_len);
2992 /* Initiate a read request */
2993 usb_fill_bulk_urb(hdw->ctl_read_urb,
2994 hdw->usb_dev,
2995 usb_rcvbulkpipe(hdw->usb_dev,
2996 PVR2_CTL_READ_ENDPOINT),
2997 hdw->ctl_read_buffer,
2998 read_len,
2999 pvr2_ctl_read_complete,
3000 hdw);
3001 hdw->ctl_read_urb->actual_length = 0;
3002 hdw->ctl_read_pend_flag = !0;
3003 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
3004 if (status < 0) {
3005 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3006 "Failed to submit read-control"
3007 " URB status=%d",status);
3008 hdw->ctl_read_pend_flag = 0;
3009 goto done;
3010 }
3011 }
3012
3013 /* Start timer */
3014 add_timer(&timer);
3015
3016 /* Now wait for all I/O to complete */
3017 hdw->cmd_debug_state = 4;
3018 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
3019 wait_for_completion(&hdw->ctl_done);
3020 }
3021 hdw->cmd_debug_state = 5;
3022
3023 /* Stop timer */
3024 del_timer_sync(&timer);
3025
3026 hdw->cmd_debug_state = 6;
3027 status = 0;
3028
3029 if (hdw->ctl_timeout_flag) {
3030 status = -ETIMEDOUT;
3031 if (!probe_fl) {
3032 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3033 "Timed out control-write");
3034 }
3035 goto done;
3036 }
3037
3038 if (write_len) {
3039 /* Validate results of write request */
3040 if ((hdw->ctl_write_urb->status != 0) &&
3041 (hdw->ctl_write_urb->status != -ENOENT) &&
3042 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
3043 (hdw->ctl_write_urb->status != -ECONNRESET)) {
3044 /* USB subsystem is reporting some kind of failure
3045 on the write */
3046 status = hdw->ctl_write_urb->status;
3047 if (!probe_fl) {
3048 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3049 "control-write URB failure,"
3050 " status=%d",
3051 status);
3052 }
3053 goto done;
3054 }
3055 if (hdw->ctl_write_urb->actual_length < write_len) {
3056 /* Failed to write enough data */
3057 status = -EIO;
3058 if (!probe_fl) {
3059 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3060 "control-write URB short,"
3061 " expected=%d got=%d",
3062 write_len,
3063 hdw->ctl_write_urb->actual_length);
3064 }
3065 goto done;
3066 }
3067 }
3068 if (read_len) {
3069 /* Validate results of read request */
3070 if ((hdw->ctl_read_urb->status != 0) &&
3071 (hdw->ctl_read_urb->status != -ENOENT) &&
3072 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
3073 (hdw->ctl_read_urb->status != -ECONNRESET)) {
3074 /* USB subsystem is reporting some kind of failure
3075 on the read */
3076 status = hdw->ctl_read_urb->status;
3077 if (!probe_fl) {
3078 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3079 "control-read URB failure,"
3080 " status=%d",
3081 status);
3082 }
3083 goto done;
3084 }
3085 if (hdw->ctl_read_urb->actual_length < read_len) {
3086 /* Failed to read enough data */
3087 status = -EIO;
3088 if (!probe_fl) {
3089 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3090 "control-read URB short,"
3091 " expected=%d got=%d",
3092 read_len,
3093 hdw->ctl_read_urb->actual_length);
3094 }
3095 goto done;
3096 }
3097 /* Transfer retrieved data out from internal buffer */
3098 for (idx = 0; idx < read_len; idx++) {
3099 ((unsigned char *)read_data)[idx] =
3100 hdw->ctl_read_buffer[idx];
3101 }
3102 }
3103
3104 done:
3105
3106 hdw->cmd_debug_state = 0;
3107 if ((status < 0) && (!probe_fl)) {
3108 pvr2_hdw_render_useless_unlocked(hdw);
3109 }
3110 return status;
3111}
3112
3113
3114int pvr2_send_request(struct pvr2_hdw *hdw,
3115 void *write_data,unsigned int write_len,
3116 void *read_data,unsigned int read_len)
3117{
3118 return pvr2_send_request_ex(hdw,HZ*4,0,
3119 write_data,write_len,
3120 read_data,read_len);
3121}
3122
3123int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
3124{
3125 int ret;
3126
3127 LOCK_TAKE(hdw->ctl_lock);
3128
Michael Krufky8d364362007-01-22 02:17:55 -03003129 hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03003130 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
3131 hdw->cmd_buffer[5] = 0;
3132 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3133 hdw->cmd_buffer[7] = reg & 0xff;
3134
3135
3136 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
3137
3138 LOCK_GIVE(hdw->ctl_lock);
3139
3140 return ret;
3141}
3142
3143
Adrian Bunk07e337e2006-06-30 11:30:20 -03003144static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03003145{
3146 int ret = 0;
3147
3148 LOCK_TAKE(hdw->ctl_lock);
3149
Michael Krufky8d364362007-01-22 02:17:55 -03003150 hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03003151 hdw->cmd_buffer[1] = 0;
3152 hdw->cmd_buffer[2] = 0;
3153 hdw->cmd_buffer[3] = 0;
3154 hdw->cmd_buffer[4] = 0;
3155 hdw->cmd_buffer[5] = 0;
3156 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3157 hdw->cmd_buffer[7] = reg & 0xff;
3158
3159 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
3160 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
3161
3162 LOCK_GIVE(hdw->ctl_lock);
3163
3164 return ret;
3165}
3166
3167
Adrian Bunk07e337e2006-06-30 11:30:20 -03003168static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003169{
3170 if (!hdw->flag_ok) return;
3171 pvr2_trace(PVR2_TRACE_INIT,"render_useless");
3172 hdw->flag_ok = 0;
3173 if (hdw->vid_stream) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003174 pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003175 }
3176 hdw->flag_streaming_enabled = 0;
3177 hdw->subsys_enabled_mask = 0;
3178}
3179
3180
3181void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
3182{
3183 LOCK_TAKE(hdw->ctl_lock);
3184 pvr2_hdw_render_useless_unlocked(hdw);
3185 LOCK_GIVE(hdw->ctl_lock);
3186}
3187
3188
3189void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
3190{
3191 int ret;
3192 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003193 ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -03003194 if (ret == 1) {
3195 ret = usb_reset_device(hdw->usb_dev);
3196 usb_unlock_device(hdw->usb_dev);
3197 } else {
3198 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3199 "Failed to lock USB device ret=%d",ret);
3200 }
3201 if (init_pause_msec) {
3202 pvr2_trace(PVR2_TRACE_INFO,
3203 "Waiting %u msec for hardware to settle",
3204 init_pause_msec);
3205 msleep(init_pause_msec);
3206 }
3207
3208}
3209
3210
3211void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
3212{
3213 char da[1];
3214 unsigned int pipe;
3215 int ret;
3216
3217 if (!hdw->usb_dev) return;
3218
3219 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
3220
3221 da[0] = val ? 0x01 : 0x00;
3222
3223 /* Write the CPUCS register on the 8051. The lsb of the register
3224 is the reset bit; a 1 asserts reset while a 0 clears it. */
3225 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
3226 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
3227 if (ret < 0) {
3228 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3229 "cpureset_assert(%d) error=%d",val,ret);
3230 pvr2_hdw_render_useless(hdw);
3231 }
3232}
3233
3234
3235int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
3236{
3237 int status;
3238 LOCK_TAKE(hdw->ctl_lock); do {
3239 pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
3240 hdw->flag_ok = !0;
Michael Krufky8d364362007-01-22 02:17:55 -03003241 hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003242 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003243 } while (0); LOCK_GIVE(hdw->ctl_lock);
3244 return status;
3245}
3246
3247
3248int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
3249{
3250 int status;
3251 LOCK_TAKE(hdw->ctl_lock); do {
3252 pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
Michael Krufky8d364362007-01-22 02:17:55 -03003253 hdw->cmd_buffer[0] = FX2CMD_POWER_ON;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003254 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003255 } while (0); LOCK_GIVE(hdw->ctl_lock);
3256 return status;
3257}
3258
3259
3260int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
3261{
3262 if (!hdw->decoder_ctrl) {
3263 pvr2_trace(PVR2_TRACE_INIT,
3264 "Unable to reset decoder: nothing attached");
3265 return -ENOTTY;
3266 }
3267
3268 if (!hdw->decoder_ctrl->force_reset) {
3269 pvr2_trace(PVR2_TRACE_INIT,
3270 "Unable to reset decoder: not implemented");
3271 return -ENOTTY;
3272 }
3273
3274 pvr2_trace(PVR2_TRACE_INIT,
3275 "Requesting decoder reset");
3276 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
3277 return 0;
3278}
3279
3280
Mike Iselye61b6fc2006-07-18 22:42:18 -03003281/* Stop / start video stream transport */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003282static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03003283{
3284 int status;
3285 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03003286 hdw->cmd_buffer[0] =
3287 (runFl ? FX2CMD_STREAMING_ON : FX2CMD_STREAMING_OFF);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003288 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003289 } while (0); LOCK_GIVE(hdw->ctl_lock);
3290 if (!status) {
3291 hdw->subsys_enabled_mask =
3292 ((hdw->subsys_enabled_mask &
3293 ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
3294 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
3295 }
3296 return status;
3297}
3298
3299
3300void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
3301 struct pvr2_hdw_debug_info *ptr)
3302{
3303 ptr->big_lock_held = hdw->big_lock_held;
3304 ptr->ctl_lock_held = hdw->ctl_lock_held;
3305 ptr->flag_ok = hdw->flag_ok;
3306 ptr->flag_disconnected = hdw->flag_disconnected;
3307 ptr->flag_init_ok = hdw->flag_init_ok;
3308 ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
3309 ptr->subsys_flags = hdw->subsys_enabled_mask;
3310 ptr->cmd_debug_state = hdw->cmd_debug_state;
3311 ptr->cmd_code = hdw->cmd_debug_code;
3312 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
3313 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
3314 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
3315 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
3316 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
3317 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
3318 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
3319}
3320
3321
3322int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
3323{
3324 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
3325}
3326
3327
3328int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
3329{
3330 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
3331}
3332
3333
3334int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
3335{
3336 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
3337}
3338
3339
3340int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
3341{
3342 u32 cval,nval;
3343 int ret;
3344 if (~msk) {
3345 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
3346 if (ret) return ret;
3347 nval = (cval & ~msk) | (val & msk);
3348 pvr2_trace(PVR2_TRACE_GPIO,
3349 "GPIO direction changing 0x%x:0x%x"
3350 " from 0x%x to 0x%x",
3351 msk,val,cval,nval);
3352 } else {
3353 nval = val;
3354 pvr2_trace(PVR2_TRACE_GPIO,
3355 "GPIO direction changing to 0x%x",nval);
3356 }
3357 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
3358}
3359
3360
3361int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
3362{
3363 u32 cval,nval;
3364 int ret;
3365 if (~msk) {
3366 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
3367 if (ret) return ret;
3368 nval = (cval & ~msk) | (val & msk);
3369 pvr2_trace(PVR2_TRACE_GPIO,
3370 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
3371 msk,val,cval,nval);
3372 } else {
3373 nval = val;
3374 pvr2_trace(PVR2_TRACE_GPIO,
3375 "GPIO output changing to 0x%x",nval);
3376 }
3377 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
3378}
3379
3380
Mike Iselye61b6fc2006-07-18 22:42:18 -03003381/* Find I2C address of eeprom */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003382static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003383{
3384 int result;
3385 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03003386 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03003387 result = pvr2_send_request(hdw,
3388 hdw->cmd_buffer,1,
3389 hdw->cmd_buffer,1);
3390 if (result < 0) break;
3391 result = hdw->cmd_buffer[0];
3392 } while(0); LOCK_GIVE(hdw->ctl_lock);
3393 return result;
3394}
3395
3396
Mike Isely32ffa9a2006-09-23 22:26:52 -03003397int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
Hans Verkuilf3d092b2007-02-23 20:55:14 -03003398 u32 match_type, u32 match_chip, u64 reg_id,
3399 int setFl,u64 *val_ptr)
Mike Isely32ffa9a2006-09-23 22:26:52 -03003400{
3401#ifdef CONFIG_VIDEO_ADV_DEBUG
3402 struct list_head *item;
3403 struct pvr2_i2c_client *cp;
3404 struct v4l2_register req;
Mike Isely6d988162006-09-28 17:53:49 -03003405 int stat = 0;
3406 int okFl = 0;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003407
Mike Isely201f5c92007-01-28 16:08:36 -03003408 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
3409
Hans Verkuilf3d092b2007-02-23 20:55:14 -03003410 req.match_type = match_type;
3411 req.match_chip = match_chip;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003412 req.reg = reg_id;
3413 if (setFl) req.val = *val_ptr;
3414 mutex_lock(&hdw->i2c_list_lock); do {
3415 list_for_each(item,&hdw->i2c_clients) {
3416 cp = list_entry(item,struct pvr2_i2c_client,list);
Mike Isely8481a752007-04-27 12:31:31 -03003417 if (!v4l2_chip_match_i2c_client(
3418 cp->client,
3419 req.match_type, req.match_chip)) {
Hans Verkuilf3d092b2007-02-23 20:55:14 -03003420 continue;
3421 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03003422 stat = pvr2_i2c_client_cmd(
Trent Piepho52ebc762007-01-23 22:38:13 -03003423 cp,(setFl ? VIDIOC_DBG_S_REGISTER :
3424 VIDIOC_DBG_G_REGISTER),&req);
Mike Isely32ffa9a2006-09-23 22:26:52 -03003425 if (!setFl) *val_ptr = req.val;
Mike Isely6d988162006-09-28 17:53:49 -03003426 okFl = !0;
3427 break;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003428 }
3429 } while (0); mutex_unlock(&hdw->i2c_list_lock);
Mike Isely6d988162006-09-28 17:53:49 -03003430 if (okFl) {
3431 return stat;
3432 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03003433 return -EINVAL;
3434#else
3435 return -ENOSYS;
3436#endif
3437}
3438
3439
Mike Iselyd8554972006-06-26 20:58:46 -03003440/*
3441 Stuff for Emacs to see, in order to encourage consistent editing style:
3442 *** Local Variables: ***
3443 *** mode: c ***
3444 *** fill-column: 75 ***
3445 *** tab-width: 8 ***
3446 *** c-basic-offset: 8 ***
3447 *** End: ***
3448 */