blob: 9638591cc06fd59797b0fc84dedf329c581897f7 [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
90static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0};
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 -0300224static const char *control_values_srate[] = {
225 [PVR2_CVAL_SRATE_48] = "48KHz",
226 [PVR2_CVAL_SRATE_44_1] = "44.1KHz",
227};
228
229
Mike Iselyd8554972006-06-26 20:58:46 -0300230
231
232static const char *control_values_input[] = {
233 [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
234 [PVR2_CVAL_INPUT_RADIO] = "radio",
235 [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
236 [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
237};
238
239
240static const char *control_values_audiomode[] = {
241 [V4L2_TUNER_MODE_MONO] = "Mono",
242 [V4L2_TUNER_MODE_STEREO] = "Stereo",
243 [V4L2_TUNER_MODE_LANG1] = "Lang1",
244 [V4L2_TUNER_MODE_LANG2] = "Lang2",
245 [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
246};
247
248
249static const char *control_values_hsm[] = {
250 [PVR2_CVAL_HSM_FAIL] = "Fail",
251 [PVR2_CVAL_HSM_HIGH] = "High",
252 [PVR2_CVAL_HSM_FULL] = "Full",
253};
254
255
256static const char *control_values_subsystem[] = {
257 [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware",
258 [PVR2_SUBSYS_B_ENC_CFG] = "enc_config",
259 [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run",
260 [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run",
261 [PVR2_SUBSYS_B_ENC_RUN] = "enc_run",
262};
263
Adrian Bunk07e337e2006-06-30 11:30:20 -0300264static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
265static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
266static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
267static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw);
268static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
269static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
270static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw);
271static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
272 unsigned long msk,
273 unsigned long val);
274static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
275 unsigned long msk,
276 unsigned long val);
277static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
278 unsigned int timeout,int probe_fl,
279 void *write_data,unsigned int write_len,
280 void *read_data,unsigned int read_len);
281static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res);
282static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res);
Mike Iselyd8554972006-06-26 20:58:46 -0300283
284static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
285{
286 struct pvr2_hdw *hdw = cptr->hdw;
287 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
288 *vp = hdw->freqTable[hdw->freqProgSlot-1];
289 } else {
290 *vp = 0;
291 }
292 return 0;
293}
294
295static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
296{
297 struct pvr2_hdw *hdw = cptr->hdw;
298 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
299 hdw->freqTable[hdw->freqProgSlot-1] = v;
300 }
301 return 0;
302}
303
304static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
305{
306 *vp = cptr->hdw->freqProgSlot;
307 return 0;
308}
309
310static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
311{
312 struct pvr2_hdw *hdw = cptr->hdw;
313 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
314 hdw->freqProgSlot = v;
315 }
316 return 0;
317}
318
319static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
320{
321 *vp = cptr->hdw->freqSlot;
322 return 0;
323}
324
325static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v)
326{
327 unsigned freq = 0;
328 struct pvr2_hdw *hdw = cptr->hdw;
329 hdw->freqSlot = v;
330 if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) {
331 freq = hdw->freqTable[hdw->freqSlot-1];
332 }
333 if (freq && (freq != hdw->freqVal)) {
334 hdw->freqVal = freq;
335 hdw->freqDirty = !0;
336 }
337 return 0;
338}
339
340static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
341{
342 *vp = cptr->hdw->freqVal;
343 return 0;
344}
345
346static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
347{
348 return cptr->hdw->freqDirty != 0;
349}
350
351static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
352{
353 cptr->hdw->freqDirty = 0;
354}
355
356static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
357{
358 struct pvr2_hdw *hdw = cptr->hdw;
359 hdw->freqVal = v;
360 hdw->freqDirty = !0;
361 hdw->freqSlot = 0;
362 return 0;
363}
364
Mike Iselyb30d2442006-06-25 20:05:01 -0300365static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
366{
367 return cptr->hdw->enc_stale != 0;
368}
369
370static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
371{
372 cptr->hdw->enc_stale = 0;
373}
374
375static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
376{
377 int ret;
378 struct v4l2_ext_controls cs;
379 struct v4l2_ext_control c1;
380 memset(&cs,0,sizeof(cs));
381 memset(&c1,0,sizeof(c1));
382 cs.controls = &c1;
383 cs.count = 1;
384 c1.id = cptr->info->v4l_id;
385 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
386 VIDIOC_G_EXT_CTRLS);
387 if (ret) return ret;
388 *vp = c1.value;
389 return 0;
390}
391
392static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
393{
394 int ret;
395 struct v4l2_ext_controls cs;
396 struct v4l2_ext_control c1;
397 memset(&cs,0,sizeof(cs));
398 memset(&c1,0,sizeof(c1));
399 cs.controls = &c1;
400 cs.count = 1;
401 c1.id = cptr->info->v4l_id;
402 c1.value = v;
403 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
404 VIDIOC_S_EXT_CTRLS);
405 if (ret) return ret;
406 cptr->hdw->enc_stale = !0;
407 return 0;
408}
409
410static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
411{
412 struct v4l2_queryctrl qctrl;
413 struct pvr2_ctl_info *info;
414 qctrl.id = cptr->info->v4l_id;
415 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
416 /* Strip out the const so we can adjust a function pointer. It's
417 OK to do this here because we know this is a dynamically created
418 control, so the underlying storage for the info pointer is (a)
419 private to us, and (b) not in read-only storage. Either we do
420 this or we significantly complicate the underlying control
421 implementation. */
422 info = (struct pvr2_ctl_info *)(cptr->info);
423 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
424 if (info->set_value) {
425 info->set_value = 0;
426 }
427 } else {
428 if (!(info->set_value)) {
429 info->set_value = ctrl_cx2341x_set;
430 }
431 }
432 return qctrl.flags;
433}
434
Mike Iselyd8554972006-06-26 20:58:46 -0300435static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
436{
437 *vp = cptr->hdw->flag_streaming_enabled;
438 return 0;
439}
440
441static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
442{
443 int result = pvr2_hdw_is_hsm(cptr->hdw);
444 *vp = PVR2_CVAL_HSM_FULL;
445 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
446 if (result) *vp = PVR2_CVAL_HSM_HIGH;
447 return 0;
448}
449
450static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
451{
452 *vp = cptr->hdw->std_mask_avail;
453 return 0;
454}
455
456static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
457{
458 struct pvr2_hdw *hdw = cptr->hdw;
459 v4l2_std_id ns;
460 ns = hdw->std_mask_avail;
461 ns = (ns & ~m) | (v & m);
462 if (ns == hdw->std_mask_avail) return 0;
463 hdw->std_mask_avail = ns;
464 pvr2_hdw_internal_set_std_avail(hdw);
465 pvr2_hdw_internal_find_stdenum(hdw);
466 return 0;
467}
468
469static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
470 char *bufPtr,unsigned int bufSize,
471 unsigned int *len)
472{
473 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
474 return 0;
475}
476
477static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
478 const char *bufPtr,unsigned int bufSize,
479 int *mskp,int *valp)
480{
481 int ret;
482 v4l2_std_id id;
483 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
484 if (ret < 0) return ret;
485 if (mskp) *mskp = id;
486 if (valp) *valp = id;
487 return 0;
488}
489
490static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
491{
492 *vp = cptr->hdw->std_mask_cur;
493 return 0;
494}
495
496static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
497{
498 struct pvr2_hdw *hdw = cptr->hdw;
499 v4l2_std_id ns;
500 ns = hdw->std_mask_cur;
501 ns = (ns & ~m) | (v & m);
502 if (ns == hdw->std_mask_cur) return 0;
503 hdw->std_mask_cur = ns;
504 hdw->std_dirty = !0;
505 pvr2_hdw_internal_find_stdenum(hdw);
506 return 0;
507}
508
509static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
510{
511 return cptr->hdw->std_dirty != 0;
512}
513
514static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
515{
516 cptr->hdw->std_dirty = 0;
517}
518
519static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
520{
521 *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
522 PVR2_SIGNAL_OK) ? 1 : 0);
523 return 0;
524}
525
526static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
527{
528 *vp = cptr->hdw->subsys_enabled_mask;
529 return 0;
530}
531
532static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
533{
534 pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
535 return 0;
536}
537
538static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
539{
540 *vp = cptr->hdw->subsys_stream_mask;
541 return 0;
542}
543
544static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
545{
546 pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
547 return 0;
548}
549
550static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
551{
552 struct pvr2_hdw *hdw = cptr->hdw;
553 if (v < 0) return -EINVAL;
554 if (v > hdw->std_enum_cnt) return -EINVAL;
555 hdw->std_enum_cur = v;
556 if (!v) return 0;
557 v--;
558 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
559 hdw->std_mask_cur = hdw->std_defs[v].id;
560 hdw->std_dirty = !0;
561 return 0;
562}
563
564
565static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
566{
567 *vp = cptr->hdw->std_enum_cur;
568 return 0;
569}
570
571
572static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
573{
574 return cptr->hdw->std_dirty != 0;
575}
576
577
578static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
579{
580 cptr->hdw->std_dirty = 0;
581}
582
583
584#define DEFINT(vmin,vmax) \
585 .type = pvr2_ctl_int, \
586 .def.type_int.min_value = vmin, \
587 .def.type_int.max_value = vmax
588
589#define DEFENUM(tab) \
590 .type = pvr2_ctl_enum, \
591 .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \
592 .def.type_enum.value_names = tab
593
Mike Isely33213962006-06-25 20:04:40 -0300594#define DEFBOOL \
595 .type = pvr2_ctl_bool
596
Mike Iselyd8554972006-06-26 20:58:46 -0300597#define DEFMASK(msk,tab) \
598 .type = pvr2_ctl_bitmask, \
599 .def.type_bitmask.valid_bits = msk, \
600 .def.type_bitmask.bit_names = tab
601
602#define DEFREF(vname) \
603 .set_value = ctrl_set_##vname, \
604 .get_value = ctrl_get_##vname, \
605 .is_dirty = ctrl_isdirty_##vname, \
606 .clear_dirty = ctrl_cleardirty_##vname
607
608
609#define VCREATE_FUNCS(vname) \
610static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
611{*vp = cptr->hdw->vname##_val; return 0;} \
612static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
613{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
614static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
615{return cptr->hdw->vname##_dirty != 0;} \
616static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
617{cptr->hdw->vname##_dirty = 0;}
618
619VCREATE_FUNCS(brightness)
620VCREATE_FUNCS(contrast)
621VCREATE_FUNCS(saturation)
622VCREATE_FUNCS(hue)
623VCREATE_FUNCS(volume)
624VCREATE_FUNCS(balance)
625VCREATE_FUNCS(bass)
626VCREATE_FUNCS(treble)
627VCREATE_FUNCS(mute)
Mike Iselyc05c0462006-06-25 20:04:25 -0300628VCREATE_FUNCS(input)
629VCREATE_FUNCS(audiomode)
630VCREATE_FUNCS(res_hor)
631VCREATE_FUNCS(res_ver)
Mike Iselyd8554972006-06-26 20:58:46 -0300632VCREATE_FUNCS(srate)
Mike Iselyd8554972006-06-26 20:58:46 -0300633
634#define MIN_FREQ 55250000L
635#define MAX_FREQ 850000000L
636
637/* Table definition of all controls which can be manipulated */
638static const struct pvr2_ctl_info control_defs[] = {
639 {
640 .v4l_id = V4L2_CID_BRIGHTNESS,
641 .desc = "Brightness",
642 .name = "brightness",
643 .default_value = 128,
644 DEFREF(brightness),
645 DEFINT(0,255),
646 },{
647 .v4l_id = V4L2_CID_CONTRAST,
648 .desc = "Contrast",
649 .name = "contrast",
650 .default_value = 68,
651 DEFREF(contrast),
652 DEFINT(0,127),
653 },{
654 .v4l_id = V4L2_CID_SATURATION,
655 .desc = "Saturation",
656 .name = "saturation",
657 .default_value = 64,
658 DEFREF(saturation),
659 DEFINT(0,127),
660 },{
661 .v4l_id = V4L2_CID_HUE,
662 .desc = "Hue",
663 .name = "hue",
664 .default_value = 0,
665 DEFREF(hue),
666 DEFINT(-128,127),
667 },{
668 .v4l_id = V4L2_CID_AUDIO_VOLUME,
669 .desc = "Volume",
670 .name = "volume",
671 .default_value = 65535,
672 DEFREF(volume),
673 DEFINT(0,65535),
674 },{
675 .v4l_id = V4L2_CID_AUDIO_BALANCE,
676 .desc = "Balance",
677 .name = "balance",
678 .default_value = 0,
679 DEFREF(balance),
680 DEFINT(-32768,32767),
681 },{
682 .v4l_id = V4L2_CID_AUDIO_BASS,
683 .desc = "Bass",
684 .name = "bass",
685 .default_value = 0,
686 DEFREF(bass),
687 DEFINT(-32768,32767),
688 },{
689 .v4l_id = V4L2_CID_AUDIO_TREBLE,
690 .desc = "Treble",
691 .name = "treble",
692 .default_value = 0,
693 DEFREF(treble),
694 DEFINT(-32768,32767),
695 },{
696 .v4l_id = V4L2_CID_AUDIO_MUTE,
697 .desc = "Mute",
698 .name = "mute",
699 .default_value = 0,
700 DEFREF(mute),
Mike Isely33213962006-06-25 20:04:40 -0300701 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300702 },{
Mike Iselyc05c0462006-06-25 20:04:25 -0300703 .desc = "Video Source",
704 .name = "input",
705 .internal_id = PVR2_CID_INPUT,
706 .default_value = PVR2_CVAL_INPUT_TV,
707 DEFREF(input),
708 DEFENUM(control_values_input),
709 },{
710 .desc = "Audio Mode",
711 .name = "audio_mode",
712 .internal_id = PVR2_CID_AUDIOMODE,
713 .default_value = V4L2_TUNER_MODE_STEREO,
714 DEFREF(audiomode),
715 DEFENUM(control_values_audiomode),
716 },{
717 .desc = "Horizontal capture resolution",
718 .name = "resolution_hor",
719 .internal_id = PVR2_CID_HRES,
720 .default_value = 720,
721 DEFREF(res_hor),
722 DEFINT(320,720),
723 },{
724 .desc = "Vertical capture resolution",
725 .name = "resolution_ver",
726 .internal_id = PVR2_CID_VRES,
727 .default_value = 480,
728 DEFREF(res_ver),
729 DEFINT(200,625),
730 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300731 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
Mike Iselyd8554972006-06-26 20:58:46 -0300732 .desc = "Sample rate",
733 .name = "srate",
734 .default_value = PVR2_CVAL_SRATE_48,
735 DEFREF(srate),
736 DEFENUM(control_values_srate),
737 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300738 .desc = "Tuner Frequency (Hz)",
739 .name = "frequency",
740 .internal_id = PVR2_CID_FREQUENCY,
741 .default_value = 175250000L,
742 .set_value = ctrl_freq_set,
743 .get_value = ctrl_freq_get,
744 .is_dirty = ctrl_freq_is_dirty,
745 .clear_dirty = ctrl_freq_clear_dirty,
746 DEFINT(MIN_FREQ,MAX_FREQ),
747 },{
748 .desc = "Channel",
749 .name = "channel",
750 .set_value = ctrl_channel_set,
751 .get_value = ctrl_channel_get,
752 DEFINT(0,FREQTABLE_SIZE),
753 },{
754 .desc = "Channel Program Frequency",
755 .name = "freq_table_value",
756 .set_value = ctrl_channelfreq_set,
757 .get_value = ctrl_channelfreq_get,
758 DEFINT(MIN_FREQ,MAX_FREQ),
759 },{
760 .desc = "Channel Program ID",
761 .name = "freq_table_channel",
762 .set_value = ctrl_channelprog_set,
763 .get_value = ctrl_channelprog_get,
764 DEFINT(0,FREQTABLE_SIZE),
765 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300766 .desc = "Streaming Enabled",
767 .name = "streaming_enabled",
768 .get_value = ctrl_streamingenabled_get,
Mike Isely33213962006-06-25 20:04:40 -0300769 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300770 },{
771 .desc = "USB Speed",
772 .name = "usb_speed",
773 .get_value = ctrl_hsm_get,
774 DEFENUM(control_values_hsm),
775 },{
776 .desc = "Signal Present",
777 .name = "signal_present",
778 .get_value = ctrl_signal_get,
Mike Isely33213962006-06-25 20:04:40 -0300779 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300780 },{
781 .desc = "Video Standards Available Mask",
782 .name = "video_standard_mask_available",
783 .internal_id = PVR2_CID_STDAVAIL,
784 .skip_init = !0,
785 .get_value = ctrl_stdavail_get,
786 .set_value = ctrl_stdavail_set,
787 .val_to_sym = ctrl_std_val_to_sym,
788 .sym_to_val = ctrl_std_sym_to_val,
789 .type = pvr2_ctl_bitmask,
790 },{
791 .desc = "Video Standards In Use Mask",
792 .name = "video_standard_mask_active",
793 .internal_id = PVR2_CID_STDCUR,
794 .skip_init = !0,
795 .get_value = ctrl_stdcur_get,
796 .set_value = ctrl_stdcur_set,
797 .is_dirty = ctrl_stdcur_is_dirty,
798 .clear_dirty = ctrl_stdcur_clear_dirty,
799 .val_to_sym = ctrl_std_val_to_sym,
800 .sym_to_val = ctrl_std_sym_to_val,
801 .type = pvr2_ctl_bitmask,
802 },{
803 .desc = "Subsystem enabled mask",
804 .name = "debug_subsys_mask",
805 .skip_init = !0,
806 .get_value = ctrl_subsys_get,
807 .set_value = ctrl_subsys_set,
808 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
809 },{
810 .desc = "Subsystem stream mask",
811 .name = "debug_subsys_stream_mask",
812 .skip_init = !0,
813 .get_value = ctrl_subsys_stream_get,
814 .set_value = ctrl_subsys_stream_set,
815 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
816 },{
817 .desc = "Video Standard Name",
818 .name = "video_standard",
819 .internal_id = PVR2_CID_STDENUM,
820 .skip_init = !0,
821 .get_value = ctrl_stdenumcur_get,
822 .set_value = ctrl_stdenumcur_set,
823 .is_dirty = ctrl_stdenumcur_is_dirty,
824 .clear_dirty = ctrl_stdenumcur_clear_dirty,
825 .type = pvr2_ctl_enum,
826 }
827};
828
Mike Iselyc05c0462006-06-25 20:04:25 -0300829#define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
Mike Iselyd8554972006-06-26 20:58:46 -0300830
831
832const char *pvr2_config_get_name(enum pvr2_config cfg)
833{
834 switch (cfg) {
835 case pvr2_config_empty: return "empty";
836 case pvr2_config_mpeg: return "mpeg";
837 case pvr2_config_vbi: return "vbi";
838 case pvr2_config_radio: return "radio";
839 }
840 return "<unknown>";
841}
842
843
844struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
845{
846 return hdw->usb_dev;
847}
848
849
850unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
851{
852 return hdw->serial_number;
853}
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{
931 const struct firmware *fw_entry = 0;
932 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{
1027 const struct firmware *fw_entry = 0;
1028 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);
1742 return 0;
1743 }
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 }
1923 return 0;
1924}
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);
1936 hdw->ctl_read_urb = 0;
1937 }
1938 if (hdw->ctl_write_urb) {
1939 usb_kill_urb(hdw->ctl_write_urb);
1940 usb_free_urb(hdw->ctl_write_urb);
1941 hdw->ctl_write_urb = 0;
1942 }
1943 if (hdw->ctl_read_buffer) {
1944 kfree(hdw->ctl_read_buffer);
1945 hdw->ctl_read_buffer = 0;
1946 }
1947 if (hdw->ctl_write_buffer) {
1948 kfree(hdw->ctl_write_buffer);
1949 hdw->ctl_write_buffer = 0;
1950 }
1951 pvr2_hdw_render_useless_unlocked(hdw);
1952 hdw->flag_disconnected = !0;
1953 hdw->usb_dev = 0;
1954 hdw->usb_intf = 0;
1955}
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);
1964 hdw->fw_buffer = 0;
1965 }
1966 if (hdw->vid_stream) {
1967 pvr2_stream_destroy(hdw->vid_stream);
1968 hdw->vid_stream = 0;
1969 }
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)) {
1982 unit_pointers[hdw->unit_number] = 0;
1983 }
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);
2044 hdw->std_defs = 0;
2045 }
2046 hdw->std_enum_cnt = 0;
2047 if (hdw->std_enum_names) {
2048 kfree(hdw->std_enum_names);
2049 hdw->std_enum_names = 0;
2050 }
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 Iselyc05c0462006-06-25 20:04:25 -03002100 if (idx >= hdw->control_cnt) return 0;
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 }
2119 return 0;
2120}
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 }
2136 return 0;
2137}
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... */
2150 cp2 = 0;
2151 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;
2160 return 0;
2161}
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 Iselyb46cfa82006-06-25 20:04:53 -03002241 0) {
Mike Iselyd8554972006-06-26 20:58:46 -03002242 /* If any of this changes, then the encoder needs to be
2243 reconfigured, and we need to reset the stream. */
2244 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
2245 stale_subsys_mask |= hdw->subsys_stream_mask;
2246 }
2247
Mike Iselyb30d2442006-06-25 20:05:01 -03002248 if (hdw->srate_dirty) {
2249 /* Write new sample rate into control structure since
2250 * the master copy is stale. We must track srate
2251 * separate from the mpeg control structure because
2252 * other logic also uses this value. */
2253 struct v4l2_ext_controls cs;
2254 struct v4l2_ext_control c1;
2255 memset(&cs,0,sizeof(cs));
2256 memset(&c1,0,sizeof(c1));
2257 cs.controls = &c1;
2258 cs.count = 1;
2259 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2260 c1.value = hdw->srate_val;
2261 cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS);
2262 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002263
Mike Iselyd8554972006-06-26 20:58:46 -03002264 /* Scan i2c core at this point - before we clear all the dirty
2265 bits. Various parts of the i2c core will notice dirty bits as
2266 appropriate and arrange to broadcast or directly send updates to
2267 the client drivers in order to keep everything in sync */
2268 pvr2_i2c_core_check_stale(hdw);
2269
Mike Iselyc05c0462006-06-25 20:04:25 -03002270 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002271 cptr = hdw->controls + idx;
2272 if (!cptr->info->clear_dirty) continue;
2273 cptr->info->clear_dirty(cptr);
2274 }
2275
2276 /* Now execute i2c core update */
2277 pvr2_i2c_core_sync(hdw);
2278
2279 pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
2280 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
2281
2282 return 0;
2283}
2284
2285
2286int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2287{
2288 LOCK_TAKE(hdw->big_lock); do {
2289 pvr2_hdw_commit_ctl_internal(hdw);
2290 } while (0); LOCK_GIVE(hdw->big_lock);
2291 return 0;
2292}
2293
2294
2295void pvr2_hdw_poll(struct pvr2_hdw *hdw)
2296{
2297 LOCK_TAKE(hdw->big_lock); do {
2298 pvr2_i2c_core_sync(hdw);
2299 } while (0); LOCK_GIVE(hdw->big_lock);
2300}
2301
2302
2303void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
2304 void (*func)(void *),
2305 void *data)
2306{
2307 LOCK_TAKE(hdw->big_lock); do {
2308 hdw->poll_trigger_func = func;
2309 hdw->poll_trigger_data = data;
2310 } while (0); LOCK_GIVE(hdw->big_lock);
2311}
2312
2313
2314void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
2315{
2316 if (hdw->poll_trigger_func) {
2317 hdw->poll_trigger_func(hdw->poll_trigger_data);
2318 }
2319}
2320
2321
Mike Iselyd8554972006-06-26 20:58:46 -03002322/* Return name for this driver instance */
2323const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2324{
2325 return hdw->name;
2326}
2327
2328
2329/* Return bit mask indicating signal status */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002330static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002331{
2332 unsigned int msk = 0;
2333 switch (hdw->input_val) {
2334 case PVR2_CVAL_INPUT_TV:
2335 case PVR2_CVAL_INPUT_RADIO:
2336 if (hdw->decoder_ctrl &&
2337 hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) {
2338 msk |= PVR2_SIGNAL_OK;
2339 if (hdw->audio_stat &&
2340 hdw->audio_stat->status(hdw->audio_stat->ctxt)) {
2341 if (hdw->flag_stereo) {
2342 msk |= PVR2_SIGNAL_STEREO;
2343 }
2344 if (hdw->flag_bilingual) {
2345 msk |= PVR2_SIGNAL_SAP;
2346 }
2347 }
2348 }
2349 break;
2350 default:
2351 msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO;
2352 }
2353 return msk;
2354}
2355
2356
2357int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2358{
2359 int result;
2360 LOCK_TAKE(hdw->ctl_lock); do {
2361 hdw->cmd_buffer[0] = 0x0b;
2362 result = pvr2_send_request(hdw,
2363 hdw->cmd_buffer,1,
2364 hdw->cmd_buffer,1);
2365 if (result < 0) break;
2366 result = (hdw->cmd_buffer[0] != 0);
2367 } while(0); LOCK_GIVE(hdw->ctl_lock);
2368 return result;
2369}
2370
2371
2372/* Return bit mask indicating signal status */
2373unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw)
2374{
2375 unsigned int msk = 0;
2376 LOCK_TAKE(hdw->big_lock); do {
2377 msk = pvr2_hdw_get_signal_status_internal(hdw);
2378 } while (0); LOCK_GIVE(hdw->big_lock);
2379 return msk;
2380}
2381
2382
2383/* Get handle to video output stream */
2384struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2385{
2386 return hp->vid_stream;
2387}
2388
2389
2390void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2391{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002392 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002393 LOCK_TAKE(hdw->big_lock); do {
2394 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002395 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002396 pvr2_i2c_core_check_stale(hdw);
2397 hdw->log_requested = 0;
2398 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002399 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002400 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely4f1a3e52006-06-25 20:04:31 -03002401 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002402 } while (0); LOCK_GIVE(hdw->big_lock);
2403}
2404
2405void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
2406{
2407 int ret;
2408 u16 address;
2409 unsigned int pipe;
2410 LOCK_TAKE(hdw->big_lock); do {
2411 if ((hdw->fw_buffer == 0) == !enable_flag) break;
2412
2413 if (!enable_flag) {
2414 pvr2_trace(PVR2_TRACE_FIRMWARE,
2415 "Cleaning up after CPU firmware fetch");
2416 kfree(hdw->fw_buffer);
2417 hdw->fw_buffer = 0;
2418 hdw->fw_size = 0;
2419 /* Now release the CPU. It will disconnect and
2420 reconnect later. */
2421 pvr2_hdw_cpureset_assert(hdw,0);
2422 break;
2423 }
2424
2425 pvr2_trace(PVR2_TRACE_FIRMWARE,
2426 "Preparing to suck out CPU firmware");
2427 hdw->fw_size = 0x2000;
2428 hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL);
2429 if (!hdw->fw_buffer) {
2430 hdw->fw_size = 0;
2431 break;
2432 }
2433
2434 memset(hdw->fw_buffer,0,hdw->fw_size);
2435
2436 /* We have to hold the CPU during firmware upload. */
2437 pvr2_hdw_cpureset_assert(hdw,1);
2438
2439 /* download the firmware from address 0000-1fff in 2048
2440 (=0x800) bytes chunk. */
2441
2442 pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
2443 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2444 for(address = 0; address < hdw->fw_size; address += 0x800) {
2445 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
2446 address,0,
2447 hdw->fw_buffer+address,0x800,HZ);
2448 if (ret < 0) break;
2449 }
2450
2451 pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
2452
2453 } while (0); LOCK_GIVE(hdw->big_lock);
2454}
2455
2456
2457/* Return true if we're in a mode for retrieval CPU firmware */
2458int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2459{
2460 return hdw->fw_buffer != 0;
2461}
2462
2463
2464int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2465 char *buf,unsigned int cnt)
2466{
2467 int ret = -EINVAL;
2468 LOCK_TAKE(hdw->big_lock); do {
2469 if (!buf) break;
2470 if (!cnt) break;
2471
2472 if (!hdw->fw_buffer) {
2473 ret = -EIO;
2474 break;
2475 }
2476
2477 if (offs >= hdw->fw_size) {
2478 pvr2_trace(PVR2_TRACE_FIRMWARE,
2479 "Read firmware data offs=%d EOF",
2480 offs);
2481 ret = 0;
2482 break;
2483 }
2484
2485 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2486
2487 memcpy(buf,hdw->fw_buffer+offs,cnt);
2488
2489 pvr2_trace(PVR2_TRACE_FIRMWARE,
2490 "Read firmware data offs=%d cnt=%d",
2491 offs,cnt);
2492 ret = cnt;
2493 } while (0); LOCK_GIVE(hdw->big_lock);
2494
2495 return ret;
2496}
2497
2498
2499int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw)
2500{
2501 return hdw->v4l_minor_number;
2502}
2503
2504
2505/* Store the v4l minor device number */
2506void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v)
2507{
2508 hdw->v4l_minor_number = v;
2509}
2510
2511
Mike Iselyd8554972006-06-26 20:58:46 -03002512static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs)
2513{
2514 struct pvr2_hdw *hdw = urb->context;
2515 hdw->ctl_write_pend_flag = 0;
2516 if (hdw->ctl_read_pend_flag) return;
2517 complete(&hdw->ctl_done);
2518}
2519
2520
2521static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs)
2522{
2523 struct pvr2_hdw *hdw = urb->context;
2524 hdw->ctl_read_pend_flag = 0;
2525 if (hdw->ctl_write_pend_flag) return;
2526 complete(&hdw->ctl_done);
2527}
2528
2529
2530static void pvr2_ctl_timeout(unsigned long data)
2531{
2532 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2533 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2534 hdw->ctl_timeout_flag = !0;
2535 if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) {
2536 usb_unlink_urb(hdw->ctl_write_urb);
2537 }
2538 if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) {
2539 usb_unlink_urb(hdw->ctl_read_urb);
2540 }
2541 }
2542}
2543
2544
Adrian Bunk07e337e2006-06-30 11:30:20 -03002545static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2546 unsigned int timeout,int probe_fl,
2547 void *write_data,unsigned int write_len,
2548 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002549{
2550 unsigned int idx;
2551 int status = 0;
2552 struct timer_list timer;
2553 if (!hdw->ctl_lock_held) {
2554 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2555 "Attempted to execute control transfer"
2556 " without lock!!");
2557 return -EDEADLK;
2558 }
2559 if ((!hdw->flag_ok) && !probe_fl) {
2560 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2561 "Attempted to execute control transfer"
2562 " when device not ok");
2563 return -EIO;
2564 }
2565 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2566 if (!probe_fl) {
2567 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2568 "Attempted to execute control transfer"
2569 " when USB is disconnected");
2570 }
2571 return -ENOTTY;
2572 }
2573
2574 /* Ensure that we have sane parameters */
2575 if (!write_data) write_len = 0;
2576 if (!read_data) read_len = 0;
2577 if (write_len > PVR2_CTL_BUFFSIZE) {
2578 pvr2_trace(
2579 PVR2_TRACE_ERROR_LEGS,
2580 "Attempted to execute %d byte"
2581 " control-write transfer (limit=%d)",
2582 write_len,PVR2_CTL_BUFFSIZE);
2583 return -EINVAL;
2584 }
2585 if (read_len > PVR2_CTL_BUFFSIZE) {
2586 pvr2_trace(
2587 PVR2_TRACE_ERROR_LEGS,
2588 "Attempted to execute %d byte"
2589 " control-read transfer (limit=%d)",
2590 write_len,PVR2_CTL_BUFFSIZE);
2591 return -EINVAL;
2592 }
2593 if ((!write_len) && (!read_len)) {
2594 pvr2_trace(
2595 PVR2_TRACE_ERROR_LEGS,
2596 "Attempted to execute null control transfer?");
2597 return -EINVAL;
2598 }
2599
2600
2601 hdw->cmd_debug_state = 1;
2602 if (write_len) {
2603 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2604 } else {
2605 hdw->cmd_debug_code = 0;
2606 }
2607 hdw->cmd_debug_write_len = write_len;
2608 hdw->cmd_debug_read_len = read_len;
2609
2610 /* Initialize common stuff */
2611 init_completion(&hdw->ctl_done);
2612 hdw->ctl_timeout_flag = 0;
2613 hdw->ctl_write_pend_flag = 0;
2614 hdw->ctl_read_pend_flag = 0;
2615 init_timer(&timer);
2616 timer.expires = jiffies + timeout;
2617 timer.data = (unsigned long)hdw;
2618 timer.function = pvr2_ctl_timeout;
2619
2620 if (write_len) {
2621 hdw->cmd_debug_state = 2;
2622 /* Transfer write data to internal buffer */
2623 for (idx = 0; idx < write_len; idx++) {
2624 hdw->ctl_write_buffer[idx] =
2625 ((unsigned char *)write_data)[idx];
2626 }
2627 /* Initiate a write request */
2628 usb_fill_bulk_urb(hdw->ctl_write_urb,
2629 hdw->usb_dev,
2630 usb_sndbulkpipe(hdw->usb_dev,
2631 PVR2_CTL_WRITE_ENDPOINT),
2632 hdw->ctl_write_buffer,
2633 write_len,
2634 pvr2_ctl_write_complete,
2635 hdw);
2636 hdw->ctl_write_urb->actual_length = 0;
2637 hdw->ctl_write_pend_flag = !0;
2638 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2639 if (status < 0) {
2640 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2641 "Failed to submit write-control"
2642 " URB status=%d",status);
2643 hdw->ctl_write_pend_flag = 0;
2644 goto done;
2645 }
2646 }
2647
2648 if (read_len) {
2649 hdw->cmd_debug_state = 3;
2650 memset(hdw->ctl_read_buffer,0x43,read_len);
2651 /* Initiate a read request */
2652 usb_fill_bulk_urb(hdw->ctl_read_urb,
2653 hdw->usb_dev,
2654 usb_rcvbulkpipe(hdw->usb_dev,
2655 PVR2_CTL_READ_ENDPOINT),
2656 hdw->ctl_read_buffer,
2657 read_len,
2658 pvr2_ctl_read_complete,
2659 hdw);
2660 hdw->ctl_read_urb->actual_length = 0;
2661 hdw->ctl_read_pend_flag = !0;
2662 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
2663 if (status < 0) {
2664 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2665 "Failed to submit read-control"
2666 " URB status=%d",status);
2667 hdw->ctl_read_pend_flag = 0;
2668 goto done;
2669 }
2670 }
2671
2672 /* Start timer */
2673 add_timer(&timer);
2674
2675 /* Now wait for all I/O to complete */
2676 hdw->cmd_debug_state = 4;
2677 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2678 wait_for_completion(&hdw->ctl_done);
2679 }
2680 hdw->cmd_debug_state = 5;
2681
2682 /* Stop timer */
2683 del_timer_sync(&timer);
2684
2685 hdw->cmd_debug_state = 6;
2686 status = 0;
2687
2688 if (hdw->ctl_timeout_flag) {
2689 status = -ETIMEDOUT;
2690 if (!probe_fl) {
2691 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2692 "Timed out control-write");
2693 }
2694 goto done;
2695 }
2696
2697 if (write_len) {
2698 /* Validate results of write request */
2699 if ((hdw->ctl_write_urb->status != 0) &&
2700 (hdw->ctl_write_urb->status != -ENOENT) &&
2701 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
2702 (hdw->ctl_write_urb->status != -ECONNRESET)) {
2703 /* USB subsystem is reporting some kind of failure
2704 on the write */
2705 status = hdw->ctl_write_urb->status;
2706 if (!probe_fl) {
2707 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2708 "control-write URB failure,"
2709 " status=%d",
2710 status);
2711 }
2712 goto done;
2713 }
2714 if (hdw->ctl_write_urb->actual_length < write_len) {
2715 /* Failed to write enough data */
2716 status = -EIO;
2717 if (!probe_fl) {
2718 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2719 "control-write URB short,"
2720 " expected=%d got=%d",
2721 write_len,
2722 hdw->ctl_write_urb->actual_length);
2723 }
2724 goto done;
2725 }
2726 }
2727 if (read_len) {
2728 /* Validate results of read request */
2729 if ((hdw->ctl_read_urb->status != 0) &&
2730 (hdw->ctl_read_urb->status != -ENOENT) &&
2731 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
2732 (hdw->ctl_read_urb->status != -ECONNRESET)) {
2733 /* USB subsystem is reporting some kind of failure
2734 on the read */
2735 status = hdw->ctl_read_urb->status;
2736 if (!probe_fl) {
2737 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2738 "control-read URB failure,"
2739 " status=%d",
2740 status);
2741 }
2742 goto done;
2743 }
2744 if (hdw->ctl_read_urb->actual_length < read_len) {
2745 /* Failed to read enough data */
2746 status = -EIO;
2747 if (!probe_fl) {
2748 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2749 "control-read URB short,"
2750 " expected=%d got=%d",
2751 read_len,
2752 hdw->ctl_read_urb->actual_length);
2753 }
2754 goto done;
2755 }
2756 /* Transfer retrieved data out from internal buffer */
2757 for (idx = 0; idx < read_len; idx++) {
2758 ((unsigned char *)read_data)[idx] =
2759 hdw->ctl_read_buffer[idx];
2760 }
2761 }
2762
2763 done:
2764
2765 hdw->cmd_debug_state = 0;
2766 if ((status < 0) && (!probe_fl)) {
2767 pvr2_hdw_render_useless_unlocked(hdw);
2768 }
2769 return status;
2770}
2771
2772
2773int pvr2_send_request(struct pvr2_hdw *hdw,
2774 void *write_data,unsigned int write_len,
2775 void *read_data,unsigned int read_len)
2776{
2777 return pvr2_send_request_ex(hdw,HZ*4,0,
2778 write_data,write_len,
2779 read_data,read_len);
2780}
2781
2782int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
2783{
2784 int ret;
2785
2786 LOCK_TAKE(hdw->ctl_lock);
2787
2788 hdw->cmd_buffer[0] = 0x04; /* write register prefix */
2789 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
2790 hdw->cmd_buffer[5] = 0;
2791 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2792 hdw->cmd_buffer[7] = reg & 0xff;
2793
2794
2795 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
2796
2797 LOCK_GIVE(hdw->ctl_lock);
2798
2799 return ret;
2800}
2801
2802
Adrian Bunk07e337e2006-06-30 11:30:20 -03002803static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03002804{
2805 int ret = 0;
2806
2807 LOCK_TAKE(hdw->ctl_lock);
2808
2809 hdw->cmd_buffer[0] = 0x05; /* read register prefix */
2810 hdw->cmd_buffer[1] = 0;
2811 hdw->cmd_buffer[2] = 0;
2812 hdw->cmd_buffer[3] = 0;
2813 hdw->cmd_buffer[4] = 0;
2814 hdw->cmd_buffer[5] = 0;
2815 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2816 hdw->cmd_buffer[7] = reg & 0xff;
2817
2818 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
2819 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
2820
2821 LOCK_GIVE(hdw->ctl_lock);
2822
2823 return ret;
2824}
2825
2826
Adrian Bunk07e337e2006-06-30 11:30:20 -03002827static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03002828{
2829 int ret;
2830
2831 LOCK_TAKE(hdw->ctl_lock);
2832
2833 hdw->cmd_buffer[0] = (data >> 8) & 0xff;
2834 hdw->cmd_buffer[1] = data & 0xff;
2835
2836 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
2837
2838 LOCK_GIVE(hdw->ctl_lock);
2839
2840 return ret;
2841}
2842
2843
Adrian Bunk07e337e2006-06-30 11:30:20 -03002844static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03002845{
2846 int ret;
2847
2848 LOCK_TAKE(hdw->ctl_lock);
2849
2850 hdw->cmd_buffer[0] = data;
2851
2852 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
2853
2854 LOCK_GIVE(hdw->ctl_lock);
2855
2856 return ret;
2857}
2858
2859
Adrian Bunk07e337e2006-06-30 11:30:20 -03002860static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002861{
2862 if (!hdw->flag_ok) return;
2863 pvr2_trace(PVR2_TRACE_INIT,"render_useless");
2864 hdw->flag_ok = 0;
2865 if (hdw->vid_stream) {
2866 pvr2_stream_setup(hdw->vid_stream,0,0,0);
2867 }
2868 hdw->flag_streaming_enabled = 0;
2869 hdw->subsys_enabled_mask = 0;
2870}
2871
2872
2873void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
2874{
2875 LOCK_TAKE(hdw->ctl_lock);
2876 pvr2_hdw_render_useless_unlocked(hdw);
2877 LOCK_GIVE(hdw->ctl_lock);
2878}
2879
2880
2881void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
2882{
2883 int ret;
2884 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
2885 ret = usb_lock_device_for_reset(hdw->usb_dev,0);
2886 if (ret == 1) {
2887 ret = usb_reset_device(hdw->usb_dev);
2888 usb_unlock_device(hdw->usb_dev);
2889 } else {
2890 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2891 "Failed to lock USB device ret=%d",ret);
2892 }
2893 if (init_pause_msec) {
2894 pvr2_trace(PVR2_TRACE_INFO,
2895 "Waiting %u msec for hardware to settle",
2896 init_pause_msec);
2897 msleep(init_pause_msec);
2898 }
2899
2900}
2901
2902
2903void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
2904{
2905 char da[1];
2906 unsigned int pipe;
2907 int ret;
2908
2909 if (!hdw->usb_dev) return;
2910
2911 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
2912
2913 da[0] = val ? 0x01 : 0x00;
2914
2915 /* Write the CPUCS register on the 8051. The lsb of the register
2916 is the reset bit; a 1 asserts reset while a 0 clears it. */
2917 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
2918 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
2919 if (ret < 0) {
2920 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2921 "cpureset_assert(%d) error=%d",val,ret);
2922 pvr2_hdw_render_useless(hdw);
2923 }
2924}
2925
2926
2927int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
2928{
2929 int status;
2930 LOCK_TAKE(hdw->ctl_lock); do {
2931 pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
2932 hdw->flag_ok = !0;
2933 hdw->cmd_buffer[0] = 0xdd;
2934 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
2935 } while (0); LOCK_GIVE(hdw->ctl_lock);
2936 return status;
2937}
2938
2939
2940int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
2941{
2942 int status;
2943 LOCK_TAKE(hdw->ctl_lock); do {
2944 pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
2945 hdw->cmd_buffer[0] = 0xde;
2946 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
2947 } while (0); LOCK_GIVE(hdw->ctl_lock);
2948 return status;
2949}
2950
2951
2952int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
2953{
2954 if (!hdw->decoder_ctrl) {
2955 pvr2_trace(PVR2_TRACE_INIT,
2956 "Unable to reset decoder: nothing attached");
2957 return -ENOTTY;
2958 }
2959
2960 if (!hdw->decoder_ctrl->force_reset) {
2961 pvr2_trace(PVR2_TRACE_INIT,
2962 "Unable to reset decoder: not implemented");
2963 return -ENOTTY;
2964 }
2965
2966 pvr2_trace(PVR2_TRACE_INIT,
2967 "Requesting decoder reset");
2968 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
2969 return 0;
2970}
2971
2972
Adrian Bunk07e337e2006-06-30 11:30:20 -03002973static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03002974{
2975 int status;
2976 LOCK_TAKE(hdw->ctl_lock); do {
2977 hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
2978 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
2979 } while (0); LOCK_GIVE(hdw->ctl_lock);
2980 if (!status) {
2981 hdw->subsys_enabled_mask =
2982 ((hdw->subsys_enabled_mask &
2983 ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
2984 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
2985 }
2986 return status;
2987}
2988
2989
2990void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
2991 struct pvr2_hdw_debug_info *ptr)
2992{
2993 ptr->big_lock_held = hdw->big_lock_held;
2994 ptr->ctl_lock_held = hdw->ctl_lock_held;
2995 ptr->flag_ok = hdw->flag_ok;
2996 ptr->flag_disconnected = hdw->flag_disconnected;
2997 ptr->flag_init_ok = hdw->flag_init_ok;
2998 ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
2999 ptr->subsys_flags = hdw->subsys_enabled_mask;
3000 ptr->cmd_debug_state = hdw->cmd_debug_state;
3001 ptr->cmd_code = hdw->cmd_debug_code;
3002 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
3003 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
3004 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
3005 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
3006 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
3007 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
3008 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
3009}
3010
3011
3012int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
3013{
3014 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
3015}
3016
3017
3018int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
3019{
3020 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
3021}
3022
3023
3024int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
3025{
3026 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
3027}
3028
3029
3030int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
3031{
3032 u32 cval,nval;
3033 int ret;
3034 if (~msk) {
3035 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
3036 if (ret) return ret;
3037 nval = (cval & ~msk) | (val & msk);
3038 pvr2_trace(PVR2_TRACE_GPIO,
3039 "GPIO direction changing 0x%x:0x%x"
3040 " from 0x%x to 0x%x",
3041 msk,val,cval,nval);
3042 } else {
3043 nval = val;
3044 pvr2_trace(PVR2_TRACE_GPIO,
3045 "GPIO direction changing to 0x%x",nval);
3046 }
3047 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
3048}
3049
3050
3051int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
3052{
3053 u32 cval,nval;
3054 int ret;
3055 if (~msk) {
3056 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
3057 if (ret) return ret;
3058 nval = (cval & ~msk) | (val & msk);
3059 pvr2_trace(PVR2_TRACE_GPIO,
3060 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
3061 msk,val,cval,nval);
3062 } else {
3063 nval = val;
3064 pvr2_trace(PVR2_TRACE_GPIO,
3065 "GPIO output changing to 0x%x",nval);
3066 }
3067 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
3068}
3069
3070
Adrian Bunk07e337e2006-06-30 11:30:20 -03003071static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003072{
3073 int result;
3074 LOCK_TAKE(hdw->ctl_lock); do {
3075 hdw->cmd_buffer[0] = 0xeb;
3076 result = pvr2_send_request(hdw,
3077 hdw->cmd_buffer,1,
3078 hdw->cmd_buffer,1);
3079 if (result < 0) break;
3080 result = hdw->cmd_buffer[0];
3081 } while(0); LOCK_GIVE(hdw->ctl_lock);
3082 return result;
3083}
3084
3085
3086/*
3087 Stuff for Emacs to see, in order to encourage consistent editing style:
3088 *** Local Variables: ***
3089 *** mode: c ***
3090 *** fill-column: 75 ***
3091 *** tab-width: 8 ***
3092 *** c-basic-offset: 8 ***
3093 *** End: ***
3094 */