blob: 4ccbd53c715e896d826e28f5a3b90514178124f2 [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 Iselyb2bbaa92006-06-25 20:03:59 -030027#include <asm/semaphore.h>
Mike Iselyd8554972006-06-26 20:58:46 -030028#include "pvrusb2.h"
29#include "pvrusb2-std.h"
30#include "pvrusb2-util.h"
31#include "pvrusb2-hdw.h"
32#include "pvrusb2-i2c-core.h"
33#include "pvrusb2-tuner.h"
34#include "pvrusb2-eeprom.h"
35#include "pvrusb2-hdw-internal.h"
36#include "pvrusb2-encoder.h"
37#include "pvrusb2-debug.h"
38
39struct usb_device_id pvr2_device_table[] = {
40 [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
41#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
42 [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
43#endif
44 { }
45};
46
47MODULE_DEVICE_TABLE(usb, pvr2_device_table);
48
49static const char *pvr2_device_names[] = {
50 [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
51#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
52 [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
53#endif
54};
55
56struct pvr2_string_table {
57 const char **lst;
58 unsigned int cnt;
59};
60
61#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
62// Names of other client modules to request for 24xxx model hardware
63static const char *pvr2_client_24xxx[] = {
64 "cx25840",
65 "tuner",
Mike Iselyd8554972006-06-26 20:58:46 -030066 "wm8775",
67};
68#endif
69
70// Names of other client modules to request for 29xxx model hardware
71static const char *pvr2_client_29xxx[] = {
72 "msp3400",
73 "saa7115",
74 "tuner",
Mike Iselyd8554972006-06-26 20:58:46 -030075};
76
77static struct pvr2_string_table pvr2_client_lists[] = {
78 [PVR2_HDW_TYPE_29XXX] = {
79 pvr2_client_29xxx,
80 sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]),
81 },
82#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
83 [PVR2_HDW_TYPE_24XXX] = {
84 pvr2_client_24xxx,
85 sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]),
86 },
87#endif
88};
89
Mike Iselya0fd1cb2006-06-30 11:35:28 -030090static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
Adrian Bunk07e337e2006-06-30 11:30:20 -030091static DECLARE_MUTEX(pvr2_unit_sem);
Mike Iselyd8554972006-06-26 20:58:46 -030092
93static int ctlchg = 0;
94static int initusbreset = 1;
95static int procreload = 0;
96static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
97static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
98static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
99static int init_pause_msec = 0;
100
101module_param(ctlchg, int, S_IRUGO|S_IWUSR);
102MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
103module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
104MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
105module_param(initusbreset, int, S_IRUGO|S_IWUSR);
106MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
107module_param(procreload, int, S_IRUGO|S_IWUSR);
108MODULE_PARM_DESC(procreload,
109 "Attempt init failure recovery with firmware reload");
110module_param_array(tuner, int, NULL, 0444);
111MODULE_PARM_DESC(tuner,"specify installed tuner type");
112module_param_array(video_std, int, NULL, 0444);
113MODULE_PARM_DESC(video_std,"specify initial video standard");
114module_param_array(tolerance, int, NULL, 0444);
115MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
116
117#define PVR2_CTL_WRITE_ENDPOINT 0x01
118#define PVR2_CTL_READ_ENDPOINT 0x81
119
120#define PVR2_GPIO_IN 0x9008
121#define PVR2_GPIO_OUT 0x900c
122#define PVR2_GPIO_DIR 0x9020
123
124#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
125
126#define PVR2_FIRMWARE_ENDPOINT 0x02
127
128/* size of a firmware chunk */
129#define FIRMWARE_CHUNK_SIZE 0x2000
130
Mike Iselyb30d2442006-06-25 20:05:01 -0300131/* Define the list of additional controls we'll dynamically construct based
132 on query of the cx2341x module. */
133struct pvr2_mpeg_ids {
134 const char *strid;
135 int id;
136};
137static const struct pvr2_mpeg_ids mpeg_ids[] = {
138 {
139 .strid = "audio_layer",
140 .id = V4L2_CID_MPEG_AUDIO_ENCODING,
141 },{
142 .strid = "audio_bitrate",
143 .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE,
144 },{
145 /* Already using audio_mode elsewhere :-( */
146 .strid = "mpeg_audio_mode",
147 .id = V4L2_CID_MPEG_AUDIO_MODE,
148 },{
149 .strid = "mpeg_audio_mode_extension",
150 .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
151 },{
152 .strid = "audio_emphasis",
153 .id = V4L2_CID_MPEG_AUDIO_EMPHASIS,
154 },{
155 .strid = "audio_crc",
156 .id = V4L2_CID_MPEG_AUDIO_CRC,
157 },{
158 .strid = "video_aspect",
159 .id = V4L2_CID_MPEG_VIDEO_ASPECT,
160 },{
161 .strid = "video_b_frames",
162 .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
163 },{
164 .strid = "video_gop_size",
165 .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
166 },{
167 .strid = "video_gop_closure",
168 .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
169 },{
170 .strid = "video_pulldown",
171 .id = V4L2_CID_MPEG_VIDEO_PULLDOWN,
172 },{
173 .strid = "video_bitrate_mode",
174 .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
175 },{
176 .strid = "video_bitrate",
177 .id = V4L2_CID_MPEG_VIDEO_BITRATE,
178 },{
179 .strid = "video_bitrate_peak",
180 .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
181 },{
182 .strid = "video_temporal_decimation",
183 .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
184 },{
185 .strid = "stream_type",
186 .id = V4L2_CID_MPEG_STREAM_TYPE,
187 },{
188 .strid = "video_spatial_filter_mode",
189 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
190 },{
191 .strid = "video_spatial_filter",
192 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
193 },{
194 .strid = "video_luma_spatial_filter_type",
195 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
196 },{
197 .strid = "video_chroma_spatial_filter_type",
198 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
199 },{
200 .strid = "video_temporal_filter_mode",
201 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
202 },{
203 .strid = "video_temporal_filter",
204 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
205 },{
206 .strid = "video_median_filter_type",
207 .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
208 },{
209 .strid = "video_luma_median_filter_top",
210 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
211 },{
212 .strid = "video_luma_median_filter_bottom",
213 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
214 },{
215 .strid = "video_chroma_median_filter_top",
216 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
217 },{
218 .strid = "video_chroma_median_filter_bottom",
219 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
220 }
221};
222#define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0]))
Mike Iselyc05c0462006-06-25 20:04:25 -0300223
Mike Iselyd8554972006-06-26 20:58:46 -0300224
Mike Isely434449f2006-08-08 09:10:06 -0300225static const char *control_values_srate[] = {
226 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100] = "44.1 kHz",
227 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000] = "48 kHz",
228 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000] = "32 kHz",
229};
Mike Iselyd8554972006-06-26 20:58:46 -0300230
Mike Iselyd8554972006-06-26 20:58:46 -0300231
232
233static const char *control_values_input[] = {
234 [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
235 [PVR2_CVAL_INPUT_RADIO] = "radio",
236 [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
237 [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
238};
239
240
241static const char *control_values_audiomode[] = {
242 [V4L2_TUNER_MODE_MONO] = "Mono",
243 [V4L2_TUNER_MODE_STEREO] = "Stereo",
244 [V4L2_TUNER_MODE_LANG1] = "Lang1",
245 [V4L2_TUNER_MODE_LANG2] = "Lang2",
246 [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
247};
248
249
250static const char *control_values_hsm[] = {
251 [PVR2_CVAL_HSM_FAIL] = "Fail",
252 [PVR2_CVAL_HSM_HIGH] = "High",
253 [PVR2_CVAL_HSM_FULL] = "Full",
254};
255
256
257static const char *control_values_subsystem[] = {
258 [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware",
259 [PVR2_SUBSYS_B_ENC_CFG] = "enc_config",
260 [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run",
261 [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run",
262 [PVR2_SUBSYS_B_ENC_RUN] = "enc_run",
263};
264
Adrian Bunk07e337e2006-06-30 11:30:20 -0300265static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
266static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
267static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
268static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw);
269static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
270static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
271static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw);
272static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
273 unsigned long msk,
274 unsigned long val);
275static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
276 unsigned long msk,
277 unsigned long val);
278static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
279 unsigned int timeout,int probe_fl,
280 void *write_data,unsigned int write_len,
281 void *read_data,unsigned int read_len);
282static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res);
283static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res);
Mike Iselyd8554972006-06-26 20:58:46 -0300284
285static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
286{
287 struct pvr2_hdw *hdw = cptr->hdw;
288 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
289 *vp = hdw->freqTable[hdw->freqProgSlot-1];
290 } else {
291 *vp = 0;
292 }
293 return 0;
294}
295
296static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
297{
298 struct pvr2_hdw *hdw = cptr->hdw;
299 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
300 hdw->freqTable[hdw->freqProgSlot-1] = v;
301 }
302 return 0;
303}
304
305static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
306{
307 *vp = cptr->hdw->freqProgSlot;
308 return 0;
309}
310
311static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
312{
313 struct pvr2_hdw *hdw = cptr->hdw;
314 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
315 hdw->freqProgSlot = v;
316 }
317 return 0;
318}
319
320static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
321{
322 *vp = cptr->hdw->freqSlot;
323 return 0;
324}
325
326static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v)
327{
328 unsigned freq = 0;
329 struct pvr2_hdw *hdw = cptr->hdw;
330 hdw->freqSlot = v;
331 if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) {
332 freq = hdw->freqTable[hdw->freqSlot-1];
333 }
334 if (freq && (freq != hdw->freqVal)) {
335 hdw->freqVal = freq;
336 hdw->freqDirty = !0;
337 }
338 return 0;
339}
340
341static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
342{
343 *vp = cptr->hdw->freqVal;
344 return 0;
345}
346
347static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
348{
349 return cptr->hdw->freqDirty != 0;
350}
351
352static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
353{
354 cptr->hdw->freqDirty = 0;
355}
356
357static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
358{
359 struct pvr2_hdw *hdw = cptr->hdw;
360 hdw->freqVal = v;
361 hdw->freqDirty = !0;
362 hdw->freqSlot = 0;
363 return 0;
364}
365
Mike Iselyb30d2442006-06-25 20:05:01 -0300366static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
367{
368 return cptr->hdw->enc_stale != 0;
369}
370
371static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
372{
373 cptr->hdw->enc_stale = 0;
374}
375
376static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
377{
378 int ret;
379 struct v4l2_ext_controls cs;
380 struct v4l2_ext_control c1;
381 memset(&cs,0,sizeof(cs));
382 memset(&c1,0,sizeof(c1));
383 cs.controls = &c1;
384 cs.count = 1;
385 c1.id = cptr->info->v4l_id;
386 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
387 VIDIOC_G_EXT_CTRLS);
388 if (ret) return ret;
389 *vp = c1.value;
390 return 0;
391}
392
393static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
394{
395 int ret;
396 struct v4l2_ext_controls cs;
397 struct v4l2_ext_control c1;
398 memset(&cs,0,sizeof(cs));
399 memset(&c1,0,sizeof(c1));
400 cs.controls = &c1;
401 cs.count = 1;
402 c1.id = cptr->info->v4l_id;
403 c1.value = v;
404 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
405 VIDIOC_S_EXT_CTRLS);
406 if (ret) return ret;
407 cptr->hdw->enc_stale = !0;
408 return 0;
409}
410
411static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
412{
413 struct v4l2_queryctrl qctrl;
414 struct pvr2_ctl_info *info;
415 qctrl.id = cptr->info->v4l_id;
416 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
417 /* Strip out the const so we can adjust a function pointer. It's
418 OK to do this here because we know this is a dynamically created
419 control, so the underlying storage for the info pointer is (a)
420 private to us, and (b) not in read-only storage. Either we do
421 this or we significantly complicate the underlying control
422 implementation. */
423 info = (struct pvr2_ctl_info *)(cptr->info);
424 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
425 if (info->set_value) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300426 info->set_value = NULL;
Mike Iselyb30d2442006-06-25 20:05:01 -0300427 }
428 } else {
429 if (!(info->set_value)) {
430 info->set_value = ctrl_cx2341x_set;
431 }
432 }
433 return qctrl.flags;
434}
435
Mike Iselyd8554972006-06-26 20:58:46 -0300436static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
437{
438 *vp = cptr->hdw->flag_streaming_enabled;
439 return 0;
440}
441
442static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
443{
444 int result = pvr2_hdw_is_hsm(cptr->hdw);
445 *vp = PVR2_CVAL_HSM_FULL;
446 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
447 if (result) *vp = PVR2_CVAL_HSM_HIGH;
448 return 0;
449}
450
451static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
452{
453 *vp = cptr->hdw->std_mask_avail;
454 return 0;
455}
456
457static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
458{
459 struct pvr2_hdw *hdw = cptr->hdw;
460 v4l2_std_id ns;
461 ns = hdw->std_mask_avail;
462 ns = (ns & ~m) | (v & m);
463 if (ns == hdw->std_mask_avail) return 0;
464 hdw->std_mask_avail = ns;
465 pvr2_hdw_internal_set_std_avail(hdw);
466 pvr2_hdw_internal_find_stdenum(hdw);
467 return 0;
468}
469
470static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
471 char *bufPtr,unsigned int bufSize,
472 unsigned int *len)
473{
474 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
475 return 0;
476}
477
478static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
479 const char *bufPtr,unsigned int bufSize,
480 int *mskp,int *valp)
481{
482 int ret;
483 v4l2_std_id id;
484 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
485 if (ret < 0) return ret;
486 if (mskp) *mskp = id;
487 if (valp) *valp = id;
488 return 0;
489}
490
491static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
492{
493 *vp = cptr->hdw->std_mask_cur;
494 return 0;
495}
496
497static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
498{
499 struct pvr2_hdw *hdw = cptr->hdw;
500 v4l2_std_id ns;
501 ns = hdw->std_mask_cur;
502 ns = (ns & ~m) | (v & m);
503 if (ns == hdw->std_mask_cur) return 0;
504 hdw->std_mask_cur = ns;
505 hdw->std_dirty = !0;
506 pvr2_hdw_internal_find_stdenum(hdw);
507 return 0;
508}
509
510static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
511{
512 return cptr->hdw->std_dirty != 0;
513}
514
515static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
516{
517 cptr->hdw->std_dirty = 0;
518}
519
520static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
521{
522 *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
523 PVR2_SIGNAL_OK) ? 1 : 0);
524 return 0;
525}
526
527static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
528{
529 *vp = cptr->hdw->subsys_enabled_mask;
530 return 0;
531}
532
533static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
534{
535 pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
536 return 0;
537}
538
539static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
540{
541 *vp = cptr->hdw->subsys_stream_mask;
542 return 0;
543}
544
545static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
546{
547 pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
548 return 0;
549}
550
551static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
552{
553 struct pvr2_hdw *hdw = cptr->hdw;
554 if (v < 0) return -EINVAL;
555 if (v > hdw->std_enum_cnt) return -EINVAL;
556 hdw->std_enum_cur = v;
557 if (!v) return 0;
558 v--;
559 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
560 hdw->std_mask_cur = hdw->std_defs[v].id;
561 hdw->std_dirty = !0;
562 return 0;
563}
564
565
566static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
567{
568 *vp = cptr->hdw->std_enum_cur;
569 return 0;
570}
571
572
573static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
574{
575 return cptr->hdw->std_dirty != 0;
576}
577
578
579static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
580{
581 cptr->hdw->std_dirty = 0;
582}
583
584
585#define DEFINT(vmin,vmax) \
586 .type = pvr2_ctl_int, \
587 .def.type_int.min_value = vmin, \
588 .def.type_int.max_value = vmax
589
590#define DEFENUM(tab) \
591 .type = pvr2_ctl_enum, \
592 .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \
593 .def.type_enum.value_names = tab
594
Mike Isely33213962006-06-25 20:04:40 -0300595#define DEFBOOL \
596 .type = pvr2_ctl_bool
597
Mike Iselyd8554972006-06-26 20:58:46 -0300598#define DEFMASK(msk,tab) \
599 .type = pvr2_ctl_bitmask, \
600 .def.type_bitmask.valid_bits = msk, \
601 .def.type_bitmask.bit_names = tab
602
603#define DEFREF(vname) \
604 .set_value = ctrl_set_##vname, \
605 .get_value = ctrl_get_##vname, \
606 .is_dirty = ctrl_isdirty_##vname, \
607 .clear_dirty = ctrl_cleardirty_##vname
608
609
610#define VCREATE_FUNCS(vname) \
611static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
612{*vp = cptr->hdw->vname##_val; return 0;} \
613static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
614{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
615static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
616{return cptr->hdw->vname##_dirty != 0;} \
617static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
618{cptr->hdw->vname##_dirty = 0;}
619
620VCREATE_FUNCS(brightness)
621VCREATE_FUNCS(contrast)
622VCREATE_FUNCS(saturation)
623VCREATE_FUNCS(hue)
624VCREATE_FUNCS(volume)
625VCREATE_FUNCS(balance)
626VCREATE_FUNCS(bass)
627VCREATE_FUNCS(treble)
628VCREATE_FUNCS(mute)
Mike Iselyc05c0462006-06-25 20:04:25 -0300629VCREATE_FUNCS(input)
630VCREATE_FUNCS(audiomode)
631VCREATE_FUNCS(res_hor)
632VCREATE_FUNCS(res_ver)
Mike Iselyd8554972006-06-26 20:58:46 -0300633VCREATE_FUNCS(srate)
Mike Iselyd8554972006-06-26 20:58:46 -0300634
635#define MIN_FREQ 55250000L
636#define MAX_FREQ 850000000L
637
638/* Table definition of all controls which can be manipulated */
639static const struct pvr2_ctl_info control_defs[] = {
640 {
641 .v4l_id = V4L2_CID_BRIGHTNESS,
642 .desc = "Brightness",
643 .name = "brightness",
644 .default_value = 128,
645 DEFREF(brightness),
646 DEFINT(0,255),
647 },{
648 .v4l_id = V4L2_CID_CONTRAST,
649 .desc = "Contrast",
650 .name = "contrast",
651 .default_value = 68,
652 DEFREF(contrast),
653 DEFINT(0,127),
654 },{
655 .v4l_id = V4L2_CID_SATURATION,
656 .desc = "Saturation",
657 .name = "saturation",
658 .default_value = 64,
659 DEFREF(saturation),
660 DEFINT(0,127),
661 },{
662 .v4l_id = V4L2_CID_HUE,
663 .desc = "Hue",
664 .name = "hue",
665 .default_value = 0,
666 DEFREF(hue),
667 DEFINT(-128,127),
668 },{
669 .v4l_id = V4L2_CID_AUDIO_VOLUME,
670 .desc = "Volume",
671 .name = "volume",
672 .default_value = 65535,
673 DEFREF(volume),
674 DEFINT(0,65535),
675 },{
676 .v4l_id = V4L2_CID_AUDIO_BALANCE,
677 .desc = "Balance",
678 .name = "balance",
679 .default_value = 0,
680 DEFREF(balance),
681 DEFINT(-32768,32767),
682 },{
683 .v4l_id = V4L2_CID_AUDIO_BASS,
684 .desc = "Bass",
685 .name = "bass",
686 .default_value = 0,
687 DEFREF(bass),
688 DEFINT(-32768,32767),
689 },{
690 .v4l_id = V4L2_CID_AUDIO_TREBLE,
691 .desc = "Treble",
692 .name = "treble",
693 .default_value = 0,
694 DEFREF(treble),
695 DEFINT(-32768,32767),
696 },{
697 .v4l_id = V4L2_CID_AUDIO_MUTE,
698 .desc = "Mute",
699 .name = "mute",
700 .default_value = 0,
701 DEFREF(mute),
Mike Isely33213962006-06-25 20:04:40 -0300702 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300703 },{
Mike Iselyc05c0462006-06-25 20:04:25 -0300704 .desc = "Video Source",
705 .name = "input",
706 .internal_id = PVR2_CID_INPUT,
707 .default_value = PVR2_CVAL_INPUT_TV,
708 DEFREF(input),
709 DEFENUM(control_values_input),
710 },{
711 .desc = "Audio Mode",
712 .name = "audio_mode",
713 .internal_id = PVR2_CID_AUDIOMODE,
714 .default_value = V4L2_TUNER_MODE_STEREO,
715 DEFREF(audiomode),
716 DEFENUM(control_values_audiomode),
717 },{
718 .desc = "Horizontal capture resolution",
719 .name = "resolution_hor",
720 .internal_id = PVR2_CID_HRES,
721 .default_value = 720,
722 DEFREF(res_hor),
723 DEFINT(320,720),
724 },{
725 .desc = "Vertical capture resolution",
726 .name = "resolution_ver",
727 .internal_id = PVR2_CID_VRES,
728 .default_value = 480,
729 DEFREF(res_ver),
730 DEFINT(200,625),
731 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300732 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
Mike Isely434449f2006-08-08 09:10:06 -0300733 .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
734 .desc = "Audio Sampling Frequency",
Mike Iselyd8554972006-06-26 20:58:46 -0300735 .name = "srate",
Mike Iselyd8554972006-06-26 20:58:46 -0300736 DEFREF(srate),
737 DEFENUM(control_values_srate),
738 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300739 .desc = "Tuner Frequency (Hz)",
740 .name = "frequency",
741 .internal_id = PVR2_CID_FREQUENCY,
742 .default_value = 175250000L,
743 .set_value = ctrl_freq_set,
744 .get_value = ctrl_freq_get,
745 .is_dirty = ctrl_freq_is_dirty,
746 .clear_dirty = ctrl_freq_clear_dirty,
747 DEFINT(MIN_FREQ,MAX_FREQ),
748 },{
749 .desc = "Channel",
750 .name = "channel",
751 .set_value = ctrl_channel_set,
752 .get_value = ctrl_channel_get,
753 DEFINT(0,FREQTABLE_SIZE),
754 },{
755 .desc = "Channel Program Frequency",
756 .name = "freq_table_value",
757 .set_value = ctrl_channelfreq_set,
758 .get_value = ctrl_channelfreq_get,
759 DEFINT(MIN_FREQ,MAX_FREQ),
760 },{
761 .desc = "Channel Program ID",
762 .name = "freq_table_channel",
763 .set_value = ctrl_channelprog_set,
764 .get_value = ctrl_channelprog_get,
765 DEFINT(0,FREQTABLE_SIZE),
766 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300767 .desc = "Streaming Enabled",
768 .name = "streaming_enabled",
769 .get_value = ctrl_streamingenabled_get,
Mike Isely33213962006-06-25 20:04:40 -0300770 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300771 },{
772 .desc = "USB Speed",
773 .name = "usb_speed",
774 .get_value = ctrl_hsm_get,
775 DEFENUM(control_values_hsm),
776 },{
777 .desc = "Signal Present",
778 .name = "signal_present",
779 .get_value = ctrl_signal_get,
Mike Isely33213962006-06-25 20:04:40 -0300780 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300781 },{
782 .desc = "Video Standards Available Mask",
783 .name = "video_standard_mask_available",
784 .internal_id = PVR2_CID_STDAVAIL,
785 .skip_init = !0,
786 .get_value = ctrl_stdavail_get,
787 .set_value = ctrl_stdavail_set,
788 .val_to_sym = ctrl_std_val_to_sym,
789 .sym_to_val = ctrl_std_sym_to_val,
790 .type = pvr2_ctl_bitmask,
791 },{
792 .desc = "Video Standards In Use Mask",
793 .name = "video_standard_mask_active",
794 .internal_id = PVR2_CID_STDCUR,
795 .skip_init = !0,
796 .get_value = ctrl_stdcur_get,
797 .set_value = ctrl_stdcur_set,
798 .is_dirty = ctrl_stdcur_is_dirty,
799 .clear_dirty = ctrl_stdcur_clear_dirty,
800 .val_to_sym = ctrl_std_val_to_sym,
801 .sym_to_val = ctrl_std_sym_to_val,
802 .type = pvr2_ctl_bitmask,
803 },{
804 .desc = "Subsystem enabled mask",
805 .name = "debug_subsys_mask",
806 .skip_init = !0,
807 .get_value = ctrl_subsys_get,
808 .set_value = ctrl_subsys_set,
809 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
810 },{
811 .desc = "Subsystem stream mask",
812 .name = "debug_subsys_stream_mask",
813 .skip_init = !0,
814 .get_value = ctrl_subsys_stream_get,
815 .set_value = ctrl_subsys_stream_set,
816 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
817 },{
818 .desc = "Video Standard Name",
819 .name = "video_standard",
820 .internal_id = PVR2_CID_STDENUM,
821 .skip_init = !0,
822 .get_value = ctrl_stdenumcur_get,
823 .set_value = ctrl_stdenumcur_set,
824 .is_dirty = ctrl_stdenumcur_is_dirty,
825 .clear_dirty = ctrl_stdenumcur_clear_dirty,
826 .type = pvr2_ctl_enum,
827 }
828};
829
Mike Iselyc05c0462006-06-25 20:04:25 -0300830#define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
Mike Iselyd8554972006-06-26 20:58:46 -0300831
832
833const char *pvr2_config_get_name(enum pvr2_config cfg)
834{
835 switch (cfg) {
836 case pvr2_config_empty: return "empty";
837 case pvr2_config_mpeg: return "mpeg";
838 case pvr2_config_vbi: return "vbi";
839 case pvr2_config_radio: return "radio";
840 }
841 return "<unknown>";
842}
843
844
845struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
846{
847 return hdw->usb_dev;
848}
849
850
851unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
852{
853 return hdw->serial_number;
854}
855
Mike Iselyd8554972006-06-26 20:58:46 -0300856int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
857{
858 return hdw->unit_number;
859}
860
861
862/* Attempt to locate one of the given set of files. Messages are logged
863 appropriate to what has been found. The return value will be 0 or
864 greater on success (it will be the index of the file name found) and
865 fw_entry will be filled in. Otherwise a negative error is returned on
866 failure. If the return value is -ENOENT then no viable firmware file
867 could be located. */
868static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
869 const struct firmware **fw_entry,
870 const char *fwtypename,
871 unsigned int fwcount,
872 const char *fwnames[])
873{
874 unsigned int idx;
875 int ret = -EINVAL;
876 for (idx = 0; idx < fwcount; idx++) {
877 ret = request_firmware(fw_entry,
878 fwnames[idx],
879 &hdw->usb_dev->dev);
880 if (!ret) {
881 trace_firmware("Located %s firmware: %s;"
882 " uploading...",
883 fwtypename,
884 fwnames[idx]);
885 return idx;
886 }
887 if (ret == -ENOENT) continue;
888 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
889 "request_firmware fatal error with code=%d",ret);
890 return ret;
891 }
892 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
893 "***WARNING***"
894 " Device %s firmware"
895 " seems to be missing.",
896 fwtypename);
897 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
898 "Did you install the pvrusb2 firmware files"
899 " in their proper location?");
900 if (fwcount == 1) {
901 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
902 "request_firmware unable to locate %s file %s",
903 fwtypename,fwnames[0]);
904 } else {
905 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
906 "request_firmware unable to locate"
907 " one of the following %s files:",
908 fwtypename);
909 for (idx = 0; idx < fwcount; idx++) {
910 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
911 "request_firmware: Failed to find %s",
912 fwnames[idx]);
913 }
914 }
915 return ret;
916}
917
918
919/*
920 * pvr2_upload_firmware1().
921 *
922 * Send the 8051 firmware to the device. After the upload, arrange for
923 * device to re-enumerate.
924 *
925 * NOTE : the pointer to the firmware data given by request_firmware()
926 * is not suitable for an usb transaction.
927 *
928 */
Adrian Bunk07e337e2006-06-30 11:30:20 -0300929static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -0300930{
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300931 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -0300932 void *fw_ptr;
933 unsigned int pipe;
934 int ret;
935 u16 address;
936 static const char *fw_files_29xxx[] = {
937 "v4l-pvrusb2-29xxx-01.fw",
938 };
939#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
940 static const char *fw_files_24xxx[] = {
941 "v4l-pvrusb2-24xxx-01.fw",
942 };
943#endif
944 static const struct pvr2_string_table fw_file_defs[] = {
945 [PVR2_HDW_TYPE_29XXX] = {
946 fw_files_29xxx,
947 sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
948 },
949#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
950 [PVR2_HDW_TYPE_24XXX] = {
951 fw_files_24xxx,
952 sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]),
953 },
954#endif
955 };
956 hdw->fw1_state = FW1_STATE_FAILED; // default result
957
958 trace_firmware("pvr2_upload_firmware1");
959
960 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
961 fw_file_defs[hdw->hdw_type].cnt,
962 fw_file_defs[hdw->hdw_type].lst);
963 if (ret < 0) {
964 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
965 return ret;
966 }
967
968 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
969 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
970
971 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
972
973 if (fw_entry->size != 0x2000){
974 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
975 release_firmware(fw_entry);
976 return -ENOMEM;
977 }
978
979 fw_ptr = kmalloc(0x800, GFP_KERNEL);
980 if (fw_ptr == NULL){
981 release_firmware(fw_entry);
982 return -ENOMEM;
983 }
984
985 /* We have to hold the CPU during firmware upload. */
986 pvr2_hdw_cpureset_assert(hdw,1);
987
988 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
989 chunk. */
990
991 ret = 0;
992 for(address = 0; address < fw_entry->size; address += 0x800) {
993 memcpy(fw_ptr, fw_entry->data + address, 0x800);
994 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
995 0, fw_ptr, 0x800, HZ);
996 }
997
998 trace_firmware("Upload done, releasing device's CPU");
999
1000 /* Now release the CPU. It will disconnect and reconnect later. */
1001 pvr2_hdw_cpureset_assert(hdw,0);
1002
1003 kfree(fw_ptr);
1004 release_firmware(fw_entry);
1005
1006 trace_firmware("Upload done (%d bytes sent)",ret);
1007
1008 /* We should have written 8192 bytes */
1009 if (ret == 8192) {
1010 hdw->fw1_state = FW1_STATE_RELOAD;
1011 return 0;
1012 }
1013
1014 return -EIO;
1015}
1016
1017
1018/*
1019 * pvr2_upload_firmware2()
1020 *
1021 * This uploads encoder firmware on endpoint 2.
1022 *
1023 */
1024
1025int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
1026{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001027 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001028 void *fw_ptr;
1029 unsigned int pipe, fw_len, fw_done;
1030 int actual_length;
1031 int ret = 0;
1032 int fwidx;
1033 static const char *fw_files[] = {
1034 CX2341X_FIRM_ENC_FILENAME,
1035 };
1036
1037 trace_firmware("pvr2_upload_firmware2");
1038
1039 ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
1040 sizeof(fw_files)/sizeof(fw_files[0]),
1041 fw_files);
1042 if (ret < 0) return ret;
1043 fwidx = ret;
1044 ret = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001045 /* Since we're about to completely reinitialize the encoder,
1046 invalidate our cached copy of its configuration state. Next
1047 time we configure the encoder, then we'll fully configure it. */
1048 hdw->enc_cur_valid = 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001049
1050 /* First prepare firmware loading */
1051 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
1052 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
1053 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1054 ret |= pvr2_hdw_cmd_deep_reset(hdw);
1055 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
1056 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
1057 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1058 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
1059 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
1060 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
1061 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
1062 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
1063 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
1064 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
1065 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
1066 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
1067 ret |= pvr2_write_u8(hdw, 0x52, 0);
1068 ret |= pvr2_write_u16(hdw, 0x0600, 0);
1069
1070 if (ret) {
1071 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1072 "firmware2 upload prep failed, ret=%d",ret);
1073 release_firmware(fw_entry);
1074 return ret;
1075 }
1076
1077 /* Now send firmware */
1078
1079 fw_len = fw_entry->size;
1080
1081 if (fw_len % FIRMWARE_CHUNK_SIZE) {
1082 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1083 "size of %s firmware"
1084 " must be a multiple of 8192B",
1085 fw_files[fwidx]);
1086 release_firmware(fw_entry);
1087 return -1;
1088 }
1089
1090 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1091 if (fw_ptr == NULL){
1092 release_firmware(fw_entry);
1093 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1094 "failed to allocate memory for firmware2 upload");
1095 return -ENOMEM;
1096 }
1097
1098 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1099
1100 for (fw_done = 0 ; (fw_done < fw_len) && !ret ;
1101 fw_done += FIRMWARE_CHUNK_SIZE ) {
1102 int i;
1103 memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE);
1104 /* Usbsnoop log shows that we must swap bytes... */
1105 for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++)
1106 ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]);
1107
1108 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,
1109 FIRMWARE_CHUNK_SIZE,
1110 &actual_length, HZ);
1111 ret |= (actual_length != FIRMWARE_CHUNK_SIZE);
1112 }
1113
1114 trace_firmware("upload of %s : %i / %i ",
1115 fw_files[fwidx],fw_done,fw_len);
1116
1117 kfree(fw_ptr);
1118 release_firmware(fw_entry);
1119
1120 if (ret) {
1121 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1122 "firmware2 upload transfer failure");
1123 return ret;
1124 }
1125
1126 /* Finish upload */
1127
1128 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1129 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
1130 ret |= pvr2_write_u16(hdw, 0x0600, 0);
1131
1132 if (ret) {
1133 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1134 "firmware2 upload post-proc failure");
1135 } else {
1136 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
1137 }
1138 return ret;
1139}
1140
1141
1142#define FIRMWARE_RECOVERY_BITS \
1143 ((1<<PVR2_SUBSYS_B_ENC_CFG) | \
1144 (1<<PVR2_SUBSYS_B_ENC_RUN) | \
1145 (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \
1146 (1<<PVR2_SUBSYS_B_USBSTREAM_RUN))
1147
1148/*
1149
1150 This single function is key to pretty much everything. The pvrusb2
1151 device can logically be viewed as a series of subsystems which can be
1152 stopped / started or unconfigured / configured. To get things streaming,
1153 one must configure everything and start everything, but there may be
1154 various reasons over time to deconfigure something or stop something.
1155 This function handles all of this activity. Everything EVERYWHERE that
1156 must affect a subsystem eventually comes here to do the work.
1157
1158 The current state of all subsystems is represented by a single bit mask,
1159 known as subsys_enabled_mask. The bit positions are defined by the
1160 PVR2_SUBSYS_xxxx macros, with one subsystem per bit position. At any
1161 time the set of configured or active subsystems can be queried just by
1162 looking at that mask. To change bits in that mask, this function here
1163 must be called. The "msk" argument indicates which bit positions to
1164 change, and the "val" argument defines the new values for the positions
1165 defined by "msk".
1166
1167 There is a priority ordering of starting / stopping things, and for
1168 multiple requested changes, this function implements that ordering.
1169 (Thus we will act on a request to load encoder firmware before we
1170 configure the encoder.) In addition to priority ordering, there is a
1171 recovery strategy implemented here. If a particular step fails and we
1172 detect that failure, this function will clear the affected subsystem bits
1173 and restart. Thus we have a means for recovering from a dead encoder:
1174 Clear all bits that correspond to subsystems that we need to restart /
1175 reconfigure and start over.
1176
1177*/
Adrian Bunk07e337e2006-06-30 11:30:20 -03001178static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
1179 unsigned long msk,
1180 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001181{
1182 unsigned long nmsk;
1183 unsigned long vmsk;
1184 int ret;
1185 unsigned int tryCount = 0;
1186
1187 if (!hdw->flag_ok) return;
1188
1189 msk &= PVR2_SUBSYS_ALL;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001190 nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk);
1191 nmsk &= PVR2_SUBSYS_ALL;
Mike Iselyd8554972006-06-26 20:58:46 -03001192
1193 for (;;) {
1194 tryCount++;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001195 if (!((nmsk ^ hdw->subsys_enabled_mask) &
1196 PVR2_SUBSYS_ALL)) break;
Mike Iselyd8554972006-06-26 20:58:46 -03001197 if (tryCount > 4) {
1198 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1199 "Too many retries when configuring device;"
1200 " giving up");
1201 pvr2_hdw_render_useless(hdw);
1202 break;
1203 }
1204 if (tryCount > 1) {
1205 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1206 "Retrying device reconfiguration");
1207 }
1208 pvr2_trace(PVR2_TRACE_INIT,
1209 "subsys mask changing 0x%lx:0x%lx"
1210 " from 0x%lx to 0x%lx",
1211 msk,val,hdw->subsys_enabled_mask,nmsk);
1212
1213 vmsk = (nmsk ^ hdw->subsys_enabled_mask) &
1214 hdw->subsys_enabled_mask;
1215 if (vmsk) {
1216 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1217 pvr2_trace(PVR2_TRACE_CTL,
1218 "/*---TRACE_CTL----*/"
1219 " pvr2_encoder_stop");
1220 ret = pvr2_encoder_stop(hdw);
1221 if (ret) {
1222 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1223 "Error recovery initiated");
1224 hdw->subsys_enabled_mask &=
1225 ~FIRMWARE_RECOVERY_BITS;
1226 continue;
1227 }
1228 }
1229 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1230 pvr2_trace(PVR2_TRACE_CTL,
1231 "/*---TRACE_CTL----*/"
1232 " pvr2_hdw_cmd_usbstream(0)");
1233 pvr2_hdw_cmd_usbstream(hdw,0);
1234 }
1235 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1236 pvr2_trace(PVR2_TRACE_CTL,
1237 "/*---TRACE_CTL----*/"
1238 " decoder disable");
1239 if (hdw->decoder_ctrl) {
1240 hdw->decoder_ctrl->enable(
1241 hdw->decoder_ctrl->ctxt,0);
1242 } else {
1243 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1244 "WARNING:"
1245 " No decoder present");
1246 }
1247 hdw->subsys_enabled_mask &=
1248 ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1249 }
1250 if (vmsk & PVR2_SUBSYS_CFG_ALL) {
1251 hdw->subsys_enabled_mask &=
1252 ~(vmsk & PVR2_SUBSYS_CFG_ALL);
1253 }
1254 }
1255 vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk;
1256 if (vmsk) {
1257 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) {
1258 pvr2_trace(PVR2_TRACE_CTL,
1259 "/*---TRACE_CTL----*/"
1260 " pvr2_upload_firmware2");
1261 ret = pvr2_upload_firmware2(hdw);
1262 if (ret) {
1263 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1264 "Failure uploading encoder"
1265 " firmware");
1266 pvr2_hdw_render_useless(hdw);
1267 break;
1268 }
1269 }
1270 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) {
1271 pvr2_trace(PVR2_TRACE_CTL,
1272 "/*---TRACE_CTL----*/"
1273 " pvr2_encoder_configure");
1274 ret = pvr2_encoder_configure(hdw);
1275 if (ret) {
1276 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1277 "Error recovery initiated");
1278 hdw->subsys_enabled_mask &=
1279 ~FIRMWARE_RECOVERY_BITS;
1280 continue;
1281 }
1282 }
1283 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1284 pvr2_trace(PVR2_TRACE_CTL,
1285 "/*---TRACE_CTL----*/"
1286 " decoder enable");
1287 if (hdw->decoder_ctrl) {
1288 hdw->decoder_ctrl->enable(
1289 hdw->decoder_ctrl->ctxt,!0);
1290 } else {
1291 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1292 "WARNING:"
1293 " No decoder present");
1294 }
1295 hdw->subsys_enabled_mask |=
1296 (1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1297 }
1298 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1299 pvr2_trace(PVR2_TRACE_CTL,
1300 "/*---TRACE_CTL----*/"
1301 " pvr2_hdw_cmd_usbstream(1)");
1302 pvr2_hdw_cmd_usbstream(hdw,!0);
1303 }
1304 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1305 pvr2_trace(PVR2_TRACE_CTL,
1306 "/*---TRACE_CTL----*/"
1307 " pvr2_encoder_start");
1308 ret = pvr2_encoder_start(hdw);
1309 if (ret) {
1310 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1311 "Error recovery initiated");
1312 hdw->subsys_enabled_mask &=
1313 ~FIRMWARE_RECOVERY_BITS;
1314 continue;
1315 }
1316 }
1317 }
1318 }
1319}
1320
1321
1322void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
1323 unsigned long msk,unsigned long val)
1324{
1325 LOCK_TAKE(hdw->big_lock); do {
1326 pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val);
1327 } while (0); LOCK_GIVE(hdw->big_lock);
1328}
1329
1330
Mike Iselyd8554972006-06-26 20:58:46 -03001331unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw)
1332{
1333 return hdw->subsys_enabled_mask;
1334}
1335
1336
1337unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw)
1338{
1339 return hdw->subsys_stream_mask;
1340}
1341
1342
Adrian Bunk07e337e2006-06-30 11:30:20 -03001343static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
1344 unsigned long msk,
1345 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001346{
1347 unsigned long val2;
1348 msk &= PVR2_SUBSYS_ALL;
1349 val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk));
1350 pvr2_trace(PVR2_TRACE_INIT,
1351 "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx",
1352 msk,val,hdw->subsys_stream_mask,val2);
1353 hdw->subsys_stream_mask = val2;
1354}
1355
1356
1357void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
1358 unsigned long msk,
1359 unsigned long val)
1360{
1361 LOCK_TAKE(hdw->big_lock); do {
1362 pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val);
1363 } while (0); LOCK_GIVE(hdw->big_lock);
1364}
1365
1366
Adrian Bunk07e337e2006-06-30 11:30:20 -03001367static int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl)
Mike Iselyd8554972006-06-26 20:58:46 -03001368{
1369 if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0;
1370 if (enableFl) {
1371 pvr2_trace(PVR2_TRACE_START_STOP,
1372 "/*--TRACE_STREAM--*/ enable");
1373 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0);
1374 } else {
1375 pvr2_trace(PVR2_TRACE_START_STOP,
1376 "/*--TRACE_STREAM--*/ disable");
1377 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1378 }
1379 if (!hdw->flag_ok) return -EIO;
1380 hdw->flag_streaming_enabled = enableFl != 0;
1381 return 0;
1382}
1383
1384
1385int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1386{
1387 return hdw->flag_streaming_enabled != 0;
1388}
1389
1390
1391int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1392{
1393 int ret;
1394 LOCK_TAKE(hdw->big_lock); do {
1395 ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag);
1396 } while (0); LOCK_GIVE(hdw->big_lock);
1397 return ret;
1398}
1399
1400
Adrian Bunk07e337e2006-06-30 11:30:20 -03001401static int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw,
1402 enum pvr2_config config)
Mike Iselyd8554972006-06-26 20:58:46 -03001403{
1404 unsigned long sm = hdw->subsys_enabled_mask;
1405 if (!hdw->flag_ok) return -EIO;
1406 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1407 hdw->config = config;
1408 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm);
1409 return 0;
1410}
1411
1412
1413int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1414{
1415 int ret;
1416 if (!hdw->flag_ok) return -EIO;
1417 LOCK_TAKE(hdw->big_lock);
1418 ret = pvr2_hdw_set_stream_type_no_lock(hdw,config);
1419 LOCK_GIVE(hdw->big_lock);
1420 return ret;
1421}
1422
1423
1424static int get_default_tuner_type(struct pvr2_hdw *hdw)
1425{
1426 int unit_number = hdw->unit_number;
1427 int tp = -1;
1428 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1429 tp = tuner[unit_number];
1430 }
1431 if (tp < 0) return -EINVAL;
1432 hdw->tuner_type = tp;
1433 return 0;
1434}
1435
1436
1437static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1438{
1439 int unit_number = hdw->unit_number;
1440 int tp = 0;
1441 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1442 tp = video_std[unit_number];
1443 }
1444 return tp;
1445}
1446
1447
1448static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1449{
1450 int unit_number = hdw->unit_number;
1451 int tp = 0;
1452 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1453 tp = tolerance[unit_number];
1454 }
1455 return tp;
1456}
1457
1458
1459static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1460{
1461 /* Try a harmless request to fetch the eeprom's address over
1462 endpoint 1. See what happens. Only the full FX2 image can
1463 respond to this. If this probe fails then likely the FX2
1464 firmware needs be loaded. */
1465 int result;
1466 LOCK_TAKE(hdw->ctl_lock); do {
1467 hdw->cmd_buffer[0] = 0xeb;
1468 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1469 hdw->cmd_buffer,1,
1470 hdw->cmd_buffer,1);
1471 if (result < 0) break;
1472 } while(0); LOCK_GIVE(hdw->ctl_lock);
1473 if (result) {
1474 pvr2_trace(PVR2_TRACE_INIT,
1475 "Probe of device endpoint 1 result status %d",
1476 result);
1477 } else {
1478 pvr2_trace(PVR2_TRACE_INIT,
1479 "Probe of device endpoint 1 succeeded");
1480 }
1481 return result == 0;
1482}
1483
1484static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1485{
1486 char buf[40];
1487 unsigned int bcnt;
1488 v4l2_std_id std1,std2;
1489
1490 std1 = get_default_standard(hdw);
1491
1492 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
1493 pvr2_trace(PVR2_TRACE_INIT,
1494 "Supported video standard(s) reported by eeprom: %.*s",
1495 bcnt,buf);
1496
1497 hdw->std_mask_avail = hdw->std_mask_eeprom;
1498
1499 std2 = std1 & ~hdw->std_mask_avail;
1500 if (std2) {
1501 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
1502 pvr2_trace(PVR2_TRACE_INIT,
1503 "Expanding supported video standards"
1504 " to include: %.*s",
1505 bcnt,buf);
1506 hdw->std_mask_avail |= std2;
1507 }
1508
1509 pvr2_hdw_internal_set_std_avail(hdw);
1510
1511 if (std1) {
1512 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
1513 pvr2_trace(PVR2_TRACE_INIT,
1514 "Initial video standard forced to %.*s",
1515 bcnt,buf);
1516 hdw->std_mask_cur = std1;
1517 hdw->std_dirty = !0;
1518 pvr2_hdw_internal_find_stdenum(hdw);
1519 return;
1520 }
1521
1522 if (hdw->std_enum_cnt > 1) {
1523 // Autoselect the first listed standard
1524 hdw->std_enum_cur = 1;
1525 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1526 hdw->std_dirty = !0;
1527 pvr2_trace(PVR2_TRACE_INIT,
1528 "Initial video standard auto-selected to %s",
1529 hdw->std_defs[hdw->std_enum_cur-1].name);
1530 return;
1531 }
1532
Mike Isely0885ba12006-06-25 21:30:47 -03001533 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
Mike Iselyd8554972006-06-26 20:58:46 -03001534 "Unable to select a viable initial video standard");
1535}
1536
1537
1538static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1539{
1540 int ret;
1541 unsigned int idx;
1542 struct pvr2_ctrl *cptr;
1543 int reloadFl = 0;
1544 if (!reloadFl) {
1545 reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1546 == 0);
1547 if (reloadFl) {
1548 pvr2_trace(PVR2_TRACE_INIT,
1549 "USB endpoint config looks strange"
1550 "; possibly firmware needs to be loaded");
1551 }
1552 }
1553 if (!reloadFl) {
1554 reloadFl = !pvr2_hdw_check_firmware(hdw);
1555 if (reloadFl) {
1556 pvr2_trace(PVR2_TRACE_INIT,
1557 "Check for FX2 firmware failed"
1558 "; possibly firmware needs to be loaded");
1559 }
1560 }
1561 if (reloadFl) {
1562 if (pvr2_upload_firmware1(hdw) != 0) {
1563 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1564 "Failure uploading firmware1");
1565 }
1566 return;
1567 }
1568 hdw->fw1_state = FW1_STATE_OK;
1569
1570 if (initusbreset) {
1571 pvr2_hdw_device_reset(hdw);
1572 }
1573 if (!pvr2_hdw_dev_ok(hdw)) return;
1574
1575 for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) {
1576 request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]);
1577 }
1578
1579 pvr2_hdw_cmd_powerup(hdw);
1580 if (!pvr2_hdw_dev_ok(hdw)) return;
1581
1582 if (pvr2_upload_firmware2(hdw)){
1583 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
1584 pvr2_hdw_render_useless(hdw);
1585 return;
1586 }
1587
1588 // This step MUST happen after the earlier powerup step.
1589 pvr2_i2c_core_init(hdw);
1590 if (!pvr2_hdw_dev_ok(hdw)) return;
1591
Mike Iselyc05c0462006-06-25 20:04:25 -03001592 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001593 cptr = hdw->controls + idx;
1594 if (cptr->info->skip_init) continue;
1595 if (!cptr->info->set_value) continue;
1596 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1597 }
1598
1599 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1600 // thread-safe against the normal pvr2_send_request() mechanism.
1601 // (We should make it thread safe).
1602
1603 ret = pvr2_hdw_get_eeprom_addr(hdw);
1604 if (!pvr2_hdw_dev_ok(hdw)) return;
1605 if (ret < 0) {
1606 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1607 "Unable to determine location of eeprom, skipping");
1608 } else {
1609 hdw->eeprom_addr = ret;
1610 pvr2_eeprom_analyze(hdw);
1611 if (!pvr2_hdw_dev_ok(hdw)) return;
1612 }
1613
1614 pvr2_hdw_setup_std(hdw);
1615
1616 if (!get_default_tuner_type(hdw)) {
1617 pvr2_trace(PVR2_TRACE_INIT,
1618 "pvr2_hdw_setup: Tuner type overridden to %d",
1619 hdw->tuner_type);
1620 }
1621
1622 hdw->tuner_updated = !0;
1623 pvr2_i2c_core_check_stale(hdw);
1624 hdw->tuner_updated = 0;
1625
1626 if (!pvr2_hdw_dev_ok(hdw)) return;
1627
1628 pvr2_hdw_commit_ctl_internal(hdw);
1629 if (!pvr2_hdw_dev_ok(hdw)) return;
1630
1631 hdw->vid_stream = pvr2_stream_create();
1632 if (!pvr2_hdw_dev_ok(hdw)) return;
1633 pvr2_trace(PVR2_TRACE_INIT,
1634 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1635 if (hdw->vid_stream) {
1636 idx = get_default_error_tolerance(hdw);
1637 if (idx) {
1638 pvr2_trace(PVR2_TRACE_INIT,
1639 "pvr2_hdw_setup: video stream %p"
1640 " setting tolerance %u",
1641 hdw->vid_stream,idx);
1642 }
1643 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1644 PVR2_VID_ENDPOINT,idx);
1645 }
1646
1647 if (!pvr2_hdw_dev_ok(hdw)) return;
1648
1649 /* Make sure everything is up to date */
1650 pvr2_i2c_core_sync(hdw);
1651
1652 if (!pvr2_hdw_dev_ok(hdw)) return;
1653
1654 hdw->flag_init_ok = !0;
1655}
1656
1657
1658int pvr2_hdw_setup(struct pvr2_hdw *hdw)
1659{
1660 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
1661 LOCK_TAKE(hdw->big_lock); do {
1662 pvr2_hdw_setup_low(hdw);
1663 pvr2_trace(PVR2_TRACE_INIT,
1664 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
1665 hdw,hdw->flag_ok,hdw->flag_init_ok);
1666 if (pvr2_hdw_dev_ok(hdw)) {
1667 if (pvr2_hdw_init_ok(hdw)) {
1668 pvr2_trace(
1669 PVR2_TRACE_INFO,
1670 "Device initialization"
1671 " completed successfully.");
1672 break;
1673 }
1674 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1675 pvr2_trace(
1676 PVR2_TRACE_INFO,
1677 "Device microcontroller firmware"
1678 " (re)loaded; it should now reset"
1679 " and reconnect.");
1680 break;
1681 }
1682 pvr2_trace(
1683 PVR2_TRACE_ERROR_LEGS,
1684 "Device initialization was not successful.");
1685 if (hdw->fw1_state == FW1_STATE_MISSING) {
1686 pvr2_trace(
1687 PVR2_TRACE_ERROR_LEGS,
1688 "Giving up since device"
1689 " microcontroller firmware"
1690 " appears to be missing.");
1691 break;
1692 }
1693 }
1694 if (procreload) {
1695 pvr2_trace(
1696 PVR2_TRACE_ERROR_LEGS,
1697 "Attempting pvrusb2 recovery by reloading"
1698 " primary firmware.");
1699 pvr2_trace(
1700 PVR2_TRACE_ERROR_LEGS,
1701 "If this works, device should disconnect"
1702 " and reconnect in a sane state.");
1703 hdw->fw1_state = FW1_STATE_UNKNOWN;
1704 pvr2_upload_firmware1(hdw);
1705 } else {
1706 pvr2_trace(
1707 PVR2_TRACE_ERROR_LEGS,
1708 "***WARNING*** pvrusb2 device hardware"
1709 " appears to be jammed"
1710 " and I can't clear it.");
1711 pvr2_trace(
1712 PVR2_TRACE_ERROR_LEGS,
1713 "You might need to power cycle"
1714 " the pvrusb2 device"
1715 " in order to recover.");
1716 }
1717 } while (0); LOCK_GIVE(hdw->big_lock);
1718 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
1719 return hdw->flag_init_ok;
1720}
1721
1722
1723/* Create and return a structure for interacting with the underlying
1724 hardware */
1725struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1726 const struct usb_device_id *devid)
1727{
1728 unsigned int idx,cnt1,cnt2;
1729 struct pvr2_hdw *hdw;
1730 unsigned int hdw_type;
1731 int valid_std_mask;
1732 struct pvr2_ctrl *cptr;
1733 __u8 ifnum;
Mike Iselyb30d2442006-06-25 20:05:01 -03001734 struct v4l2_queryctrl qctrl;
1735 struct pvr2_ctl_info *ciptr;
Mike Iselyd8554972006-06-26 20:58:46 -03001736
1737 hdw_type = devid - pvr2_device_table;
1738 if (hdw_type >=
1739 sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) {
1740 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1741 "Bogus device type of %u reported",hdw_type);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001742 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001743 }
1744
1745 hdw = kmalloc(sizeof(*hdw),GFP_KERNEL);
1746 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
1747 hdw,pvr2_device_names[hdw_type]);
1748 if (!hdw) goto fail;
1749 memset(hdw,0,sizeof(*hdw));
Mike Iselyb30d2442006-06-25 20:05:01 -03001750 cx2341x_fill_defaults(&hdw->enc_ctl_state);
Mike Iselyd8554972006-06-26 20:58:46 -03001751
Mike Iselyc05c0462006-06-25 20:04:25 -03001752 hdw->control_cnt = CTRLDEF_COUNT;
Mike Iselyb30d2442006-06-25 20:05:01 -03001753 hdw->control_cnt += MPEGDEF_COUNT;
Mike Iselyc05c0462006-06-25 20:04:25 -03001754 hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001755 GFP_KERNEL);
1756 if (!hdw->controls) goto fail;
Mike Iselyc05c0462006-06-25 20:04:25 -03001757 memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * hdw->control_cnt);
Mike Iselyd8554972006-06-26 20:58:46 -03001758 hdw->hdw_type = hdw_type;
Mike Iselyc05c0462006-06-25 20:04:25 -03001759 for (idx = 0; idx < hdw->control_cnt; idx++) {
1760 cptr = hdw->controls + idx;
1761 cptr->hdw = hdw;
1762 }
Mike Iselyd8554972006-06-26 20:58:46 -03001763 for (idx = 0; idx < 32; idx++) {
1764 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1765 }
Mike Iselyc05c0462006-06-25 20:04:25 -03001766 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001767 cptr = hdw->controls + idx;
Mike Iselyd8554972006-06-26 20:58:46 -03001768 cptr->info = control_defs+idx;
1769 }
Mike Iselyb30d2442006-06-25 20:05:01 -03001770 /* Define and configure additional controls from cx2341x module. */
1771 hdw->mpeg_ctrl_info = kmalloc(
1772 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
1773 if (!hdw->mpeg_ctrl_info) goto fail;
1774 memset(hdw->mpeg_ctrl_info,0,
1775 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT);
1776 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
1777 cptr = hdw->controls + idx + CTRLDEF_COUNT;
1778 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
1779 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
1780 ciptr->name = mpeg_ids[idx].strid;
1781 ciptr->v4l_id = mpeg_ids[idx].id;
1782 ciptr->skip_init = !0;
1783 ciptr->get_value = ctrl_cx2341x_get;
1784 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
1785 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
1786 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
1787 qctrl.id = ciptr->v4l_id;
1788 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
1789 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
1790 ciptr->set_value = ctrl_cx2341x_set;
1791 }
1792 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
1793 PVR2_CTLD_INFO_DESC_SIZE);
1794 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
1795 ciptr->default_value = qctrl.default_value;
1796 switch (qctrl.type) {
1797 default:
1798 case V4L2_CTRL_TYPE_INTEGER:
1799 ciptr->type = pvr2_ctl_int;
1800 ciptr->def.type_int.min_value = qctrl.minimum;
1801 ciptr->def.type_int.max_value = qctrl.maximum;
1802 break;
1803 case V4L2_CTRL_TYPE_BOOLEAN:
1804 ciptr->type = pvr2_ctl_bool;
1805 break;
1806 case V4L2_CTRL_TYPE_MENU:
1807 ciptr->type = pvr2_ctl_enum;
1808 ciptr->def.type_enum.value_names =
1809 cx2341x_ctrl_get_menu(ciptr->v4l_id);
1810 for (cnt1 = 0;
1811 ciptr->def.type_enum.value_names[cnt1] != NULL;
1812 cnt1++) { }
1813 ciptr->def.type_enum.count = cnt1;
1814 break;
1815 }
1816 cptr->info = ciptr;
1817 }
Mike Iselyd8554972006-06-26 20:58:46 -03001818
1819 // Initialize video standard enum dynamic control
1820 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
1821 if (cptr) {
1822 memcpy(&hdw->std_info_enum,cptr->info,
1823 sizeof(hdw->std_info_enum));
1824 cptr->info = &hdw->std_info_enum;
1825
1826 }
1827 // Initialize control data regarding video standard masks
1828 valid_std_mask = pvr2_std_get_usable();
1829 for (idx = 0; idx < 32; idx++) {
1830 if (!(valid_std_mask & (1 << idx))) continue;
1831 cnt1 = pvr2_std_id_to_str(
1832 hdw->std_mask_names[idx],
1833 sizeof(hdw->std_mask_names[idx])-1,
1834 1 << idx);
1835 hdw->std_mask_names[idx][cnt1] = 0;
1836 }
1837 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
1838 if (cptr) {
1839 memcpy(&hdw->std_info_avail,cptr->info,
1840 sizeof(hdw->std_info_avail));
1841 cptr->info = &hdw->std_info_avail;
1842 hdw->std_info_avail.def.type_bitmask.bit_names =
1843 hdw->std_mask_ptrs;
1844 hdw->std_info_avail.def.type_bitmask.valid_bits =
1845 valid_std_mask;
1846 }
1847 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
1848 if (cptr) {
1849 memcpy(&hdw->std_info_cur,cptr->info,
1850 sizeof(hdw->std_info_cur));
1851 cptr->info = &hdw->std_info_cur;
1852 hdw->std_info_cur.def.type_bitmask.bit_names =
1853 hdw->std_mask_ptrs;
1854 hdw->std_info_avail.def.type_bitmask.valid_bits =
1855 valid_std_mask;
1856 }
1857
1858 hdw->eeprom_addr = -1;
1859 hdw->unit_number = -1;
1860 hdw->v4l_minor_number = -1;
1861 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
1862 if (!hdw->ctl_write_buffer) goto fail;
1863 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
1864 if (!hdw->ctl_read_buffer) goto fail;
1865 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
1866 if (!hdw->ctl_write_urb) goto fail;
1867 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
1868 if (!hdw->ctl_read_urb) goto fail;
1869
1870 down(&pvr2_unit_sem); do {
1871 for (idx = 0; idx < PVR_NUM; idx++) {
1872 if (unit_pointers[idx]) continue;
1873 hdw->unit_number = idx;
1874 unit_pointers[idx] = hdw;
1875 break;
1876 }
1877 } while (0); up(&pvr2_unit_sem);
1878
1879 cnt1 = 0;
1880 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
1881 cnt1 += cnt2;
1882 if (hdw->unit_number >= 0) {
1883 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
1884 ('a' + hdw->unit_number));
1885 cnt1 += cnt2;
1886 }
1887 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
1888 hdw->name[cnt1] = 0;
1889
1890 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
1891 hdw->unit_number,hdw->name);
1892
1893 hdw->tuner_type = -1;
1894 hdw->flag_ok = !0;
1895 /* Initialize the mask of subsystems that we will shut down when we
1896 stop streaming. */
1897 hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
1898 hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
1899
1900 pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
1901 hdw->subsys_stream_mask);
1902
1903 hdw->usb_intf = intf;
1904 hdw->usb_dev = interface_to_usbdev(intf);
1905
1906 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
1907 usb_set_interface(hdw->usb_dev,ifnum,0);
1908
1909 mutex_init(&hdw->ctl_lock_mutex);
1910 mutex_init(&hdw->big_lock_mutex);
1911
1912 return hdw;
1913 fail:
1914 if (hdw) {
1915 if (hdw->ctl_read_urb) usb_free_urb(hdw->ctl_read_urb);
1916 if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb);
1917 if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer);
1918 if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer);
1919 if (hdw->controls) kfree(hdw->controls);
Mike Iselyb30d2442006-06-25 20:05:01 -03001920 if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info);
Mike Iselyd8554972006-06-26 20:58:46 -03001921 kfree(hdw);
1922 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001923 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001924}
1925
1926
1927/* Remove _all_ associations between this driver and the underlying USB
1928 layer. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03001929static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001930{
1931 if (hdw->flag_disconnected) return;
1932 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
1933 if (hdw->ctl_read_urb) {
1934 usb_kill_urb(hdw->ctl_read_urb);
1935 usb_free_urb(hdw->ctl_read_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001936 hdw->ctl_read_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001937 }
1938 if (hdw->ctl_write_urb) {
1939 usb_kill_urb(hdw->ctl_write_urb);
1940 usb_free_urb(hdw->ctl_write_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001941 hdw->ctl_write_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001942 }
1943 if (hdw->ctl_read_buffer) {
1944 kfree(hdw->ctl_read_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001945 hdw->ctl_read_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001946 }
1947 if (hdw->ctl_write_buffer) {
1948 kfree(hdw->ctl_write_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001949 hdw->ctl_write_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001950 }
1951 pvr2_hdw_render_useless_unlocked(hdw);
1952 hdw->flag_disconnected = !0;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001953 hdw->usb_dev = NULL;
1954 hdw->usb_intf = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001955}
1956
1957
1958/* Destroy hardware interaction structure */
1959void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
1960{
1961 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
1962 if (hdw->fw_buffer) {
1963 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001964 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001965 }
1966 if (hdw->vid_stream) {
1967 pvr2_stream_destroy(hdw->vid_stream);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001968 hdw->vid_stream = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001969 }
1970 if (hdw->audio_stat) {
1971 hdw->audio_stat->detach(hdw->audio_stat->ctxt);
1972 }
1973 if (hdw->decoder_ctrl) {
1974 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
1975 }
1976 pvr2_i2c_core_done(hdw);
1977 pvr2_hdw_remove_usb_stuff(hdw);
1978 down(&pvr2_unit_sem); do {
1979 if ((hdw->unit_number >= 0) &&
1980 (hdw->unit_number < PVR_NUM) &&
1981 (unit_pointers[hdw->unit_number] == hdw)) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001982 unit_pointers[hdw->unit_number] = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001983 }
1984 } while (0); up(&pvr2_unit_sem);
Mike Iselyc05c0462006-06-25 20:04:25 -03001985 if (hdw->controls) kfree(hdw->controls);
Mike Iselyb30d2442006-06-25 20:05:01 -03001986 if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info);
Mike Iselyd8554972006-06-26 20:58:46 -03001987 if (hdw->std_defs) kfree(hdw->std_defs);
1988 if (hdw->std_enum_names) kfree(hdw->std_enum_names);
1989 kfree(hdw);
1990}
1991
1992
1993int pvr2_hdw_init_ok(struct pvr2_hdw *hdw)
1994{
1995 return hdw->flag_init_ok;
1996}
1997
1998
1999int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2000{
2001 return (hdw && hdw->flag_ok);
2002}
2003
2004
2005/* Called when hardware has been unplugged */
2006void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2007{
2008 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2009 LOCK_TAKE(hdw->big_lock);
2010 LOCK_TAKE(hdw->ctl_lock);
2011 pvr2_hdw_remove_usb_stuff(hdw);
2012 LOCK_GIVE(hdw->ctl_lock);
2013 LOCK_GIVE(hdw->big_lock);
2014}
2015
2016
2017// Attempt to autoselect an appropriate value for std_enum_cur given
2018// whatever is currently in std_mask_cur
Adrian Bunk07e337e2006-06-30 11:30:20 -03002019static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002020{
2021 unsigned int idx;
2022 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2023 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2024 hdw->std_enum_cur = idx;
2025 return;
2026 }
2027 }
2028 hdw->std_enum_cur = 0;
2029}
2030
2031
2032// Calculate correct set of enumerated standards based on currently known
2033// set of available standards bits.
Adrian Bunk07e337e2006-06-30 11:30:20 -03002034static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002035{
2036 struct v4l2_standard *newstd;
2037 unsigned int std_cnt;
2038 unsigned int idx;
2039
2040 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2041
2042 if (hdw->std_defs) {
2043 kfree(hdw->std_defs);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002044 hdw->std_defs = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002045 }
2046 hdw->std_enum_cnt = 0;
2047 if (hdw->std_enum_names) {
2048 kfree(hdw->std_enum_names);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002049 hdw->std_enum_names = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002050 }
2051
2052 if (!std_cnt) {
2053 pvr2_trace(
2054 PVR2_TRACE_ERROR_LEGS,
2055 "WARNING: Failed to identify any viable standards");
2056 }
2057 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2058 hdw->std_enum_names[0] = "none";
2059 for (idx = 0; idx < std_cnt; idx++) {
2060 hdw->std_enum_names[idx+1] =
2061 newstd[idx].name;
2062 }
2063 // Set up the dynamic control for this standard
2064 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2065 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2066 hdw->std_defs = newstd;
2067 hdw->std_enum_cnt = std_cnt+1;
2068 hdw->std_enum_cur = 0;
2069 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2070}
2071
2072
2073int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2074 struct v4l2_standard *std,
2075 unsigned int idx)
2076{
2077 int ret = -EINVAL;
2078 if (!idx) return ret;
2079 LOCK_TAKE(hdw->big_lock); do {
2080 if (idx >= hdw->std_enum_cnt) break;
2081 idx--;
2082 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2083 ret = 0;
2084 } while (0); LOCK_GIVE(hdw->big_lock);
2085 return ret;
2086}
2087
2088
2089/* Get the number of defined controls */
2090unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2091{
Mike Iselyc05c0462006-06-25 20:04:25 -03002092 return hdw->control_cnt;
Mike Iselyd8554972006-06-26 20:58:46 -03002093}
2094
2095
2096/* Retrieve a control handle given its index (0..count-1) */
2097struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2098 unsigned int idx)
2099{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002100 if (idx >= hdw->control_cnt) return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002101 return hdw->controls + idx;
2102}
2103
2104
2105/* Retrieve a control handle given its index (0..count-1) */
2106struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2107 unsigned int ctl_id)
2108{
2109 struct pvr2_ctrl *cptr;
2110 unsigned int idx;
2111 int i;
2112
2113 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002114 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002115 cptr = hdw->controls + idx;
2116 i = cptr->info->internal_id;
2117 if (i && (i == ctl_id)) return cptr;
2118 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002119 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002120}
2121
2122
Mike Iselya761f432006-06-25 20:04:44 -03002123/* Given a V4L ID, retrieve the control structure associated with it. */
Mike Iselyd8554972006-06-26 20:58:46 -03002124struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2125{
2126 struct pvr2_ctrl *cptr;
2127 unsigned int idx;
2128 int i;
2129
2130 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002131 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002132 cptr = hdw->controls + idx;
2133 i = cptr->info->v4l_id;
2134 if (i && (i == ctl_id)) return cptr;
2135 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002136 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002137}
2138
2139
Mike Iselya761f432006-06-25 20:04:44 -03002140/* Given a V4L ID for its immediate predecessor, retrieve the control
2141 structure associated with it. */
2142struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2143 unsigned int ctl_id)
2144{
2145 struct pvr2_ctrl *cptr,*cp2;
2146 unsigned int idx;
2147 int i;
2148
2149 /* This could be made a lot more efficient, but for now... */
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002150 cp2 = NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002151 for (idx = 0; idx < hdw->control_cnt; idx++) {
2152 cptr = hdw->controls + idx;
2153 i = cptr->info->v4l_id;
2154 if (!i) continue;
2155 if (i <= ctl_id) continue;
2156 if (cp2 && (cp2->info->v4l_id < i)) continue;
2157 cp2 = cptr;
2158 }
2159 return cp2;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002160 return NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002161}
2162
2163
Mike Iselyd8554972006-06-26 20:58:46 -03002164static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2165{
2166 switch (tp) {
2167 case pvr2_ctl_int: return "integer";
2168 case pvr2_ctl_enum: return "enum";
Mike Isely33213962006-06-25 20:04:40 -03002169 case pvr2_ctl_bool: return "boolean";
Mike Iselyd8554972006-06-26 20:58:46 -03002170 case pvr2_ctl_bitmask: return "bitmask";
2171 }
2172 return "";
2173}
2174
2175
2176/* Commit all control changes made up to this point. Subsystems can be
2177 indirectly affected by these changes. For a given set of things being
2178 committed, we'll clear the affected subsystem bits and then once we're
2179 done committing everything we'll make a request to restore the subsystem
2180 state(s) back to their previous value before this function was called.
2181 Thus we can automatically reconfigure affected pieces of the driver as
2182 controls are changed. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002183static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002184{
2185 unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
2186 unsigned long stale_subsys_mask = 0;
2187 unsigned int idx;
2188 struct pvr2_ctrl *cptr;
2189 int value;
2190 int commit_flag = 0;
2191 char buf[100];
2192 unsigned int bcnt,ccnt;
2193
Mike Iselyc05c0462006-06-25 20:04:25 -03002194 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002195 cptr = hdw->controls + idx;
2196 if (cptr->info->is_dirty == 0) continue;
2197 if (!cptr->info->is_dirty(cptr)) continue;
2198 if (!commit_flag) {
2199 commit_flag = !0;
2200 }
2201
2202 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2203 cptr->info->name);
2204 value = 0;
2205 cptr->info->get_value(cptr,&value);
2206 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2207 buf+bcnt,
2208 sizeof(buf)-bcnt,&ccnt);
2209 bcnt += ccnt;
2210 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2211 get_ctrl_typename(cptr->info->type));
2212 pvr2_trace(PVR2_TRACE_CTL,
2213 "/*--TRACE_COMMIT--*/ %.*s",
2214 bcnt,buf);
2215 }
2216
2217 if (!commit_flag) {
2218 /* Nothing has changed */
2219 return 0;
2220 }
2221
2222 /* When video standard changes, reset the hres and vres values -
2223 but if the user has pending changes there, then let the changes
2224 take priority. */
2225 if (hdw->std_dirty) {
2226 /* Rewrite the vertical resolution to be appropriate to the
2227 video standard that has been selected. */
2228 int nvres;
2229 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2230 nvres = 480;
2231 } else {
2232 nvres = 576;
2233 }
2234 if (nvres != hdw->res_ver_val) {
2235 hdw->res_ver_val = nvres;
2236 hdw->res_ver_dirty = !0;
2237 }
Mike Iselyd8554972006-06-26 20:58:46 -03002238 }
2239
2240 if (hdw->std_dirty ||
Mike Isely434449f2006-08-08 09:10:06 -03002241 hdw->enc_stale ||
2242 hdw->srate_dirty ||
2243 hdw->res_ver_dirty ||
2244 hdw->res_hor_dirty ||
Mike Iselyb46cfa82006-06-25 20:04:53 -03002245 0) {
Mike Iselyd8554972006-06-26 20:58:46 -03002246 /* If any of this changes, then the encoder needs to be
2247 reconfigured, and we need to reset the stream. */
2248 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
Mike Iselyd8554972006-06-26 20:58:46 -03002249 }
2250
Mike Iselyb30d2442006-06-25 20:05:01 -03002251 if (hdw->srate_dirty) {
2252 /* Write new sample rate into control structure since
2253 * the master copy is stale. We must track srate
2254 * separate from the mpeg control structure because
2255 * other logic also uses this value. */
2256 struct v4l2_ext_controls cs;
2257 struct v4l2_ext_control c1;
2258 memset(&cs,0,sizeof(cs));
2259 memset(&c1,0,sizeof(c1));
2260 cs.controls = &c1;
2261 cs.count = 1;
2262 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2263 c1.value = hdw->srate_val;
2264 cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS);
2265 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002266
Mike Iselyd8554972006-06-26 20:58:46 -03002267 /* Scan i2c core at this point - before we clear all the dirty
2268 bits. Various parts of the i2c core will notice dirty bits as
2269 appropriate and arrange to broadcast or directly send updates to
2270 the client drivers in order to keep everything in sync */
2271 pvr2_i2c_core_check_stale(hdw);
2272
Mike Iselyc05c0462006-06-25 20:04:25 -03002273 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002274 cptr = hdw->controls + idx;
2275 if (!cptr->info->clear_dirty) continue;
2276 cptr->info->clear_dirty(cptr);
2277 }
2278
2279 /* Now execute i2c core update */
2280 pvr2_i2c_core_sync(hdw);
2281
2282 pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
2283 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
2284
2285 return 0;
2286}
2287
2288
2289int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2290{
2291 LOCK_TAKE(hdw->big_lock); do {
2292 pvr2_hdw_commit_ctl_internal(hdw);
2293 } while (0); LOCK_GIVE(hdw->big_lock);
2294 return 0;
2295}
2296
2297
2298void pvr2_hdw_poll(struct pvr2_hdw *hdw)
2299{
2300 LOCK_TAKE(hdw->big_lock); do {
2301 pvr2_i2c_core_sync(hdw);
2302 } while (0); LOCK_GIVE(hdw->big_lock);
2303}
2304
2305
2306void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
2307 void (*func)(void *),
2308 void *data)
2309{
2310 LOCK_TAKE(hdw->big_lock); do {
2311 hdw->poll_trigger_func = func;
2312 hdw->poll_trigger_data = data;
2313 } while (0); LOCK_GIVE(hdw->big_lock);
2314}
2315
2316
2317void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
2318{
2319 if (hdw->poll_trigger_func) {
2320 hdw->poll_trigger_func(hdw->poll_trigger_data);
2321 }
2322}
2323
Mike Iselyd8554972006-06-26 20:58:46 -03002324/* Return name for this driver instance */
2325const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2326{
2327 return hdw->name;
2328}
2329
2330
2331/* Return bit mask indicating signal status */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002332static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002333{
2334 unsigned int msk = 0;
2335 switch (hdw->input_val) {
2336 case PVR2_CVAL_INPUT_TV:
2337 case PVR2_CVAL_INPUT_RADIO:
2338 if (hdw->decoder_ctrl &&
2339 hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) {
2340 msk |= PVR2_SIGNAL_OK;
2341 if (hdw->audio_stat &&
2342 hdw->audio_stat->status(hdw->audio_stat->ctxt)) {
2343 if (hdw->flag_stereo) {
2344 msk |= PVR2_SIGNAL_STEREO;
2345 }
2346 if (hdw->flag_bilingual) {
2347 msk |= PVR2_SIGNAL_SAP;
2348 }
2349 }
2350 }
2351 break;
2352 default:
2353 msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO;
2354 }
2355 return msk;
2356}
2357
2358
2359int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2360{
2361 int result;
2362 LOCK_TAKE(hdw->ctl_lock); do {
2363 hdw->cmd_buffer[0] = 0x0b;
2364 result = pvr2_send_request(hdw,
2365 hdw->cmd_buffer,1,
2366 hdw->cmd_buffer,1);
2367 if (result < 0) break;
2368 result = (hdw->cmd_buffer[0] != 0);
2369 } while(0); LOCK_GIVE(hdw->ctl_lock);
2370 return result;
2371}
2372
2373
2374/* Return bit mask indicating signal status */
2375unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw)
2376{
2377 unsigned int msk = 0;
2378 LOCK_TAKE(hdw->big_lock); do {
2379 msk = pvr2_hdw_get_signal_status_internal(hdw);
2380 } while (0); LOCK_GIVE(hdw->big_lock);
2381 return msk;
2382}
2383
2384
2385/* Get handle to video output stream */
2386struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2387{
2388 return hp->vid_stream;
2389}
2390
2391
2392void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2393{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002394 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002395 LOCK_TAKE(hdw->big_lock); do {
2396 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002397 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002398 pvr2_i2c_core_check_stale(hdw);
2399 hdw->log_requested = 0;
2400 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002401 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002402 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely4f1a3e52006-06-25 20:04:31 -03002403 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002404 } while (0); LOCK_GIVE(hdw->big_lock);
2405}
2406
2407void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
2408{
2409 int ret;
2410 u16 address;
2411 unsigned int pipe;
2412 LOCK_TAKE(hdw->big_lock); do {
2413 if ((hdw->fw_buffer == 0) == !enable_flag) break;
2414
2415 if (!enable_flag) {
2416 pvr2_trace(PVR2_TRACE_FIRMWARE,
2417 "Cleaning up after CPU firmware fetch");
2418 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002419 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002420 hdw->fw_size = 0;
2421 /* Now release the CPU. It will disconnect and
2422 reconnect later. */
2423 pvr2_hdw_cpureset_assert(hdw,0);
2424 break;
2425 }
2426
2427 pvr2_trace(PVR2_TRACE_FIRMWARE,
2428 "Preparing to suck out CPU firmware");
2429 hdw->fw_size = 0x2000;
2430 hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL);
2431 if (!hdw->fw_buffer) {
2432 hdw->fw_size = 0;
2433 break;
2434 }
2435
2436 memset(hdw->fw_buffer,0,hdw->fw_size);
2437
2438 /* We have to hold the CPU during firmware upload. */
2439 pvr2_hdw_cpureset_assert(hdw,1);
2440
2441 /* download the firmware from address 0000-1fff in 2048
2442 (=0x800) bytes chunk. */
2443
2444 pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
2445 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2446 for(address = 0; address < hdw->fw_size; address += 0x800) {
2447 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
2448 address,0,
2449 hdw->fw_buffer+address,0x800,HZ);
2450 if (ret < 0) break;
2451 }
2452
2453 pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
2454
2455 } while (0); LOCK_GIVE(hdw->big_lock);
2456}
2457
2458
2459/* Return true if we're in a mode for retrieval CPU firmware */
2460int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2461{
2462 return hdw->fw_buffer != 0;
2463}
2464
2465
2466int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2467 char *buf,unsigned int cnt)
2468{
2469 int ret = -EINVAL;
2470 LOCK_TAKE(hdw->big_lock); do {
2471 if (!buf) break;
2472 if (!cnt) break;
2473
2474 if (!hdw->fw_buffer) {
2475 ret = -EIO;
2476 break;
2477 }
2478
2479 if (offs >= hdw->fw_size) {
2480 pvr2_trace(PVR2_TRACE_FIRMWARE,
2481 "Read firmware data offs=%d EOF",
2482 offs);
2483 ret = 0;
2484 break;
2485 }
2486
2487 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2488
2489 memcpy(buf,hdw->fw_buffer+offs,cnt);
2490
2491 pvr2_trace(PVR2_TRACE_FIRMWARE,
2492 "Read firmware data offs=%d cnt=%d",
2493 offs,cnt);
2494 ret = cnt;
2495 } while (0); LOCK_GIVE(hdw->big_lock);
2496
2497 return ret;
2498}
2499
2500
2501int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw)
2502{
2503 return hdw->v4l_minor_number;
2504}
2505
2506
2507/* Store the v4l minor device number */
2508void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v)
2509{
2510 hdw->v4l_minor_number = v;
2511}
2512
2513
Mike Iselyd8554972006-06-26 20:58:46 -03002514static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs)
2515{
2516 struct pvr2_hdw *hdw = urb->context;
2517 hdw->ctl_write_pend_flag = 0;
2518 if (hdw->ctl_read_pend_flag) return;
2519 complete(&hdw->ctl_done);
2520}
2521
2522
2523static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs)
2524{
2525 struct pvr2_hdw *hdw = urb->context;
2526 hdw->ctl_read_pend_flag = 0;
2527 if (hdw->ctl_write_pend_flag) return;
2528 complete(&hdw->ctl_done);
2529}
2530
2531
2532static void pvr2_ctl_timeout(unsigned long data)
2533{
2534 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2535 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2536 hdw->ctl_timeout_flag = !0;
2537 if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) {
2538 usb_unlink_urb(hdw->ctl_write_urb);
2539 }
2540 if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) {
2541 usb_unlink_urb(hdw->ctl_read_urb);
2542 }
2543 }
2544}
2545
2546
Mike Iselye61b6fc2006-07-18 22:42:18 -03002547/* Issue a command and get a response from the device. This extended
2548 version includes a probe flag (which if set means that device errors
2549 should not be logged or treated as fatal) and a timeout in jiffies.
2550 This can be used to non-lethally probe the health of endpoint 1. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002551static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2552 unsigned int timeout,int probe_fl,
2553 void *write_data,unsigned int write_len,
2554 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002555{
2556 unsigned int idx;
2557 int status = 0;
2558 struct timer_list timer;
2559 if (!hdw->ctl_lock_held) {
2560 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2561 "Attempted to execute control transfer"
2562 " without lock!!");
2563 return -EDEADLK;
2564 }
2565 if ((!hdw->flag_ok) && !probe_fl) {
2566 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2567 "Attempted to execute control transfer"
2568 " when device not ok");
2569 return -EIO;
2570 }
2571 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2572 if (!probe_fl) {
2573 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2574 "Attempted to execute control transfer"
2575 " when USB is disconnected");
2576 }
2577 return -ENOTTY;
2578 }
2579
2580 /* Ensure that we have sane parameters */
2581 if (!write_data) write_len = 0;
2582 if (!read_data) read_len = 0;
2583 if (write_len > PVR2_CTL_BUFFSIZE) {
2584 pvr2_trace(
2585 PVR2_TRACE_ERROR_LEGS,
2586 "Attempted to execute %d byte"
2587 " control-write transfer (limit=%d)",
2588 write_len,PVR2_CTL_BUFFSIZE);
2589 return -EINVAL;
2590 }
2591 if (read_len > PVR2_CTL_BUFFSIZE) {
2592 pvr2_trace(
2593 PVR2_TRACE_ERROR_LEGS,
2594 "Attempted to execute %d byte"
2595 " control-read transfer (limit=%d)",
2596 write_len,PVR2_CTL_BUFFSIZE);
2597 return -EINVAL;
2598 }
2599 if ((!write_len) && (!read_len)) {
2600 pvr2_trace(
2601 PVR2_TRACE_ERROR_LEGS,
2602 "Attempted to execute null control transfer?");
2603 return -EINVAL;
2604 }
2605
2606
2607 hdw->cmd_debug_state = 1;
2608 if (write_len) {
2609 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2610 } else {
2611 hdw->cmd_debug_code = 0;
2612 }
2613 hdw->cmd_debug_write_len = write_len;
2614 hdw->cmd_debug_read_len = read_len;
2615
2616 /* Initialize common stuff */
2617 init_completion(&hdw->ctl_done);
2618 hdw->ctl_timeout_flag = 0;
2619 hdw->ctl_write_pend_flag = 0;
2620 hdw->ctl_read_pend_flag = 0;
2621 init_timer(&timer);
2622 timer.expires = jiffies + timeout;
2623 timer.data = (unsigned long)hdw;
2624 timer.function = pvr2_ctl_timeout;
2625
2626 if (write_len) {
2627 hdw->cmd_debug_state = 2;
2628 /* Transfer write data to internal buffer */
2629 for (idx = 0; idx < write_len; idx++) {
2630 hdw->ctl_write_buffer[idx] =
2631 ((unsigned char *)write_data)[idx];
2632 }
2633 /* Initiate a write request */
2634 usb_fill_bulk_urb(hdw->ctl_write_urb,
2635 hdw->usb_dev,
2636 usb_sndbulkpipe(hdw->usb_dev,
2637 PVR2_CTL_WRITE_ENDPOINT),
2638 hdw->ctl_write_buffer,
2639 write_len,
2640 pvr2_ctl_write_complete,
2641 hdw);
2642 hdw->ctl_write_urb->actual_length = 0;
2643 hdw->ctl_write_pend_flag = !0;
2644 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2645 if (status < 0) {
2646 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2647 "Failed to submit write-control"
2648 " URB status=%d",status);
2649 hdw->ctl_write_pend_flag = 0;
2650 goto done;
2651 }
2652 }
2653
2654 if (read_len) {
2655 hdw->cmd_debug_state = 3;
2656 memset(hdw->ctl_read_buffer,0x43,read_len);
2657 /* Initiate a read request */
2658 usb_fill_bulk_urb(hdw->ctl_read_urb,
2659 hdw->usb_dev,
2660 usb_rcvbulkpipe(hdw->usb_dev,
2661 PVR2_CTL_READ_ENDPOINT),
2662 hdw->ctl_read_buffer,
2663 read_len,
2664 pvr2_ctl_read_complete,
2665 hdw);
2666 hdw->ctl_read_urb->actual_length = 0;
2667 hdw->ctl_read_pend_flag = !0;
2668 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
2669 if (status < 0) {
2670 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2671 "Failed to submit read-control"
2672 " URB status=%d",status);
2673 hdw->ctl_read_pend_flag = 0;
2674 goto done;
2675 }
2676 }
2677
2678 /* Start timer */
2679 add_timer(&timer);
2680
2681 /* Now wait for all I/O to complete */
2682 hdw->cmd_debug_state = 4;
2683 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2684 wait_for_completion(&hdw->ctl_done);
2685 }
2686 hdw->cmd_debug_state = 5;
2687
2688 /* Stop timer */
2689 del_timer_sync(&timer);
2690
2691 hdw->cmd_debug_state = 6;
2692 status = 0;
2693
2694 if (hdw->ctl_timeout_flag) {
2695 status = -ETIMEDOUT;
2696 if (!probe_fl) {
2697 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2698 "Timed out control-write");
2699 }
2700 goto done;
2701 }
2702
2703 if (write_len) {
2704 /* Validate results of write request */
2705 if ((hdw->ctl_write_urb->status != 0) &&
2706 (hdw->ctl_write_urb->status != -ENOENT) &&
2707 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
2708 (hdw->ctl_write_urb->status != -ECONNRESET)) {
2709 /* USB subsystem is reporting some kind of failure
2710 on the write */
2711 status = hdw->ctl_write_urb->status;
2712 if (!probe_fl) {
2713 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2714 "control-write URB failure,"
2715 " status=%d",
2716 status);
2717 }
2718 goto done;
2719 }
2720 if (hdw->ctl_write_urb->actual_length < write_len) {
2721 /* Failed to write enough data */
2722 status = -EIO;
2723 if (!probe_fl) {
2724 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2725 "control-write URB short,"
2726 " expected=%d got=%d",
2727 write_len,
2728 hdw->ctl_write_urb->actual_length);
2729 }
2730 goto done;
2731 }
2732 }
2733 if (read_len) {
2734 /* Validate results of read request */
2735 if ((hdw->ctl_read_urb->status != 0) &&
2736 (hdw->ctl_read_urb->status != -ENOENT) &&
2737 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
2738 (hdw->ctl_read_urb->status != -ECONNRESET)) {
2739 /* USB subsystem is reporting some kind of failure
2740 on the read */
2741 status = hdw->ctl_read_urb->status;
2742 if (!probe_fl) {
2743 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2744 "control-read URB failure,"
2745 " status=%d",
2746 status);
2747 }
2748 goto done;
2749 }
2750 if (hdw->ctl_read_urb->actual_length < read_len) {
2751 /* Failed to read enough data */
2752 status = -EIO;
2753 if (!probe_fl) {
2754 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2755 "control-read URB short,"
2756 " expected=%d got=%d",
2757 read_len,
2758 hdw->ctl_read_urb->actual_length);
2759 }
2760 goto done;
2761 }
2762 /* Transfer retrieved data out from internal buffer */
2763 for (idx = 0; idx < read_len; idx++) {
2764 ((unsigned char *)read_data)[idx] =
2765 hdw->ctl_read_buffer[idx];
2766 }
2767 }
2768
2769 done:
2770
2771 hdw->cmd_debug_state = 0;
2772 if ((status < 0) && (!probe_fl)) {
2773 pvr2_hdw_render_useless_unlocked(hdw);
2774 }
2775 return status;
2776}
2777
2778
2779int pvr2_send_request(struct pvr2_hdw *hdw,
2780 void *write_data,unsigned int write_len,
2781 void *read_data,unsigned int read_len)
2782{
2783 return pvr2_send_request_ex(hdw,HZ*4,0,
2784 write_data,write_len,
2785 read_data,read_len);
2786}
2787
2788int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
2789{
2790 int ret;
2791
2792 LOCK_TAKE(hdw->ctl_lock);
2793
2794 hdw->cmd_buffer[0] = 0x04; /* write register prefix */
2795 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
2796 hdw->cmd_buffer[5] = 0;
2797 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2798 hdw->cmd_buffer[7] = reg & 0xff;
2799
2800
2801 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
2802
2803 LOCK_GIVE(hdw->ctl_lock);
2804
2805 return ret;
2806}
2807
2808
Adrian Bunk07e337e2006-06-30 11:30:20 -03002809static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03002810{
2811 int ret = 0;
2812
2813 LOCK_TAKE(hdw->ctl_lock);
2814
2815 hdw->cmd_buffer[0] = 0x05; /* read register prefix */
2816 hdw->cmd_buffer[1] = 0;
2817 hdw->cmd_buffer[2] = 0;
2818 hdw->cmd_buffer[3] = 0;
2819 hdw->cmd_buffer[4] = 0;
2820 hdw->cmd_buffer[5] = 0;
2821 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2822 hdw->cmd_buffer[7] = reg & 0xff;
2823
2824 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
2825 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
2826
2827 LOCK_GIVE(hdw->ctl_lock);
2828
2829 return ret;
2830}
2831
2832
Adrian Bunk07e337e2006-06-30 11:30:20 -03002833static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03002834{
2835 int ret;
2836
2837 LOCK_TAKE(hdw->ctl_lock);
2838
2839 hdw->cmd_buffer[0] = (data >> 8) & 0xff;
2840 hdw->cmd_buffer[1] = data & 0xff;
2841
2842 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
2843
2844 LOCK_GIVE(hdw->ctl_lock);
2845
2846 return ret;
2847}
2848
2849
Adrian Bunk07e337e2006-06-30 11:30:20 -03002850static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03002851{
2852 int ret;
2853
2854 LOCK_TAKE(hdw->ctl_lock);
2855
2856 hdw->cmd_buffer[0] = data;
2857
2858 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
2859
2860 LOCK_GIVE(hdw->ctl_lock);
2861
2862 return ret;
2863}
2864
2865
Adrian Bunk07e337e2006-06-30 11:30:20 -03002866static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002867{
2868 if (!hdw->flag_ok) return;
2869 pvr2_trace(PVR2_TRACE_INIT,"render_useless");
2870 hdw->flag_ok = 0;
2871 if (hdw->vid_stream) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002872 pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
Mike Iselyd8554972006-06-26 20:58:46 -03002873 }
2874 hdw->flag_streaming_enabled = 0;
2875 hdw->subsys_enabled_mask = 0;
2876}
2877
2878
2879void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
2880{
2881 LOCK_TAKE(hdw->ctl_lock);
2882 pvr2_hdw_render_useless_unlocked(hdw);
2883 LOCK_GIVE(hdw->ctl_lock);
2884}
2885
2886
2887void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
2888{
2889 int ret;
2890 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002891 ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -03002892 if (ret == 1) {
2893 ret = usb_reset_device(hdw->usb_dev);
2894 usb_unlock_device(hdw->usb_dev);
2895 } else {
2896 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2897 "Failed to lock USB device ret=%d",ret);
2898 }
2899 if (init_pause_msec) {
2900 pvr2_trace(PVR2_TRACE_INFO,
2901 "Waiting %u msec for hardware to settle",
2902 init_pause_msec);
2903 msleep(init_pause_msec);
2904 }
2905
2906}
2907
2908
2909void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
2910{
2911 char da[1];
2912 unsigned int pipe;
2913 int ret;
2914
2915 if (!hdw->usb_dev) return;
2916
2917 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
2918
2919 da[0] = val ? 0x01 : 0x00;
2920
2921 /* Write the CPUCS register on the 8051. The lsb of the register
2922 is the reset bit; a 1 asserts reset while a 0 clears it. */
2923 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
2924 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
2925 if (ret < 0) {
2926 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2927 "cpureset_assert(%d) error=%d",val,ret);
2928 pvr2_hdw_render_useless(hdw);
2929 }
2930}
2931
2932
2933int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
2934{
2935 int status;
2936 LOCK_TAKE(hdw->ctl_lock); do {
2937 pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
2938 hdw->flag_ok = !0;
2939 hdw->cmd_buffer[0] = 0xdd;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002940 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03002941 } while (0); LOCK_GIVE(hdw->ctl_lock);
2942 return status;
2943}
2944
2945
2946int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
2947{
2948 int status;
2949 LOCK_TAKE(hdw->ctl_lock); do {
2950 pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
2951 hdw->cmd_buffer[0] = 0xde;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002952 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03002953 } while (0); LOCK_GIVE(hdw->ctl_lock);
2954 return status;
2955}
2956
2957
2958int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
2959{
2960 if (!hdw->decoder_ctrl) {
2961 pvr2_trace(PVR2_TRACE_INIT,
2962 "Unable to reset decoder: nothing attached");
2963 return -ENOTTY;
2964 }
2965
2966 if (!hdw->decoder_ctrl->force_reset) {
2967 pvr2_trace(PVR2_TRACE_INIT,
2968 "Unable to reset decoder: not implemented");
2969 return -ENOTTY;
2970 }
2971
2972 pvr2_trace(PVR2_TRACE_INIT,
2973 "Requesting decoder reset");
2974 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
2975 return 0;
2976}
2977
2978
Mike Iselye61b6fc2006-07-18 22:42:18 -03002979/* Stop / start video stream transport */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002980static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03002981{
2982 int status;
2983 LOCK_TAKE(hdw->ctl_lock); do {
2984 hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002985 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03002986 } while (0); LOCK_GIVE(hdw->ctl_lock);
2987 if (!status) {
2988 hdw->subsys_enabled_mask =
2989 ((hdw->subsys_enabled_mask &
2990 ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
2991 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
2992 }
2993 return status;
2994}
2995
2996
2997void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
2998 struct pvr2_hdw_debug_info *ptr)
2999{
3000 ptr->big_lock_held = hdw->big_lock_held;
3001 ptr->ctl_lock_held = hdw->ctl_lock_held;
3002 ptr->flag_ok = hdw->flag_ok;
3003 ptr->flag_disconnected = hdw->flag_disconnected;
3004 ptr->flag_init_ok = hdw->flag_init_ok;
3005 ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
3006 ptr->subsys_flags = hdw->subsys_enabled_mask;
3007 ptr->cmd_debug_state = hdw->cmd_debug_state;
3008 ptr->cmd_code = hdw->cmd_debug_code;
3009 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
3010 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
3011 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
3012 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
3013 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
3014 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
3015 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
3016}
3017
3018
3019int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
3020{
3021 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
3022}
3023
3024
3025int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
3026{
3027 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
3028}
3029
3030
3031int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
3032{
3033 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
3034}
3035
3036
3037int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
3038{
3039 u32 cval,nval;
3040 int ret;
3041 if (~msk) {
3042 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
3043 if (ret) return ret;
3044 nval = (cval & ~msk) | (val & msk);
3045 pvr2_trace(PVR2_TRACE_GPIO,
3046 "GPIO direction changing 0x%x:0x%x"
3047 " from 0x%x to 0x%x",
3048 msk,val,cval,nval);
3049 } else {
3050 nval = val;
3051 pvr2_trace(PVR2_TRACE_GPIO,
3052 "GPIO direction changing to 0x%x",nval);
3053 }
3054 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
3055}
3056
3057
3058int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
3059{
3060 u32 cval,nval;
3061 int ret;
3062 if (~msk) {
3063 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
3064 if (ret) return ret;
3065 nval = (cval & ~msk) | (val & msk);
3066 pvr2_trace(PVR2_TRACE_GPIO,
3067 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
3068 msk,val,cval,nval);
3069 } else {
3070 nval = val;
3071 pvr2_trace(PVR2_TRACE_GPIO,
3072 "GPIO output changing to 0x%x",nval);
3073 }
3074 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
3075}
3076
3077
Mike Iselye61b6fc2006-07-18 22:42:18 -03003078/* Find I2C address of eeprom */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003079static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003080{
3081 int result;
3082 LOCK_TAKE(hdw->ctl_lock); do {
3083 hdw->cmd_buffer[0] = 0xeb;
3084 result = pvr2_send_request(hdw,
3085 hdw->cmd_buffer,1,
3086 hdw->cmd_buffer,1);
3087 if (result < 0) break;
3088 result = hdw->cmd_buffer[0];
3089 } while(0); LOCK_GIVE(hdw->ctl_lock);
3090 return result;
3091}
3092
3093
3094/*
3095 Stuff for Emacs to see, in order to encourage consistent editing style:
3096 *** Local Variables: ***
3097 *** mode: c ***
3098 *** fill-column: 75 ***
3099 *** tab-width: 8 ***
3100 *** c-basic-offset: 8 ***
3101 *** End: ***
3102 */