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