blob: 38e165913dd60f7284c37dd20bac587b627b0e13 [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
Mike Isely1bde0282006-12-27 23:30:13 -030040#define TV_MIN_FREQ 55250000L
41#define TV_MAX_FREQ 850000000L
42#define RADIO_MIN_FREQ 87000000L
Mike Isely98752102006-12-27 23:13:53 -030043#define RADIO_MAX_FREQ 108000000L
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -030044
Mike Iselyd8554972006-06-26 20:58:46 -030045struct usb_device_id pvr2_device_table[] = {
46 [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) },
Mike Iselyd8554972006-06-26 20:58:46 -030047 [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) },
Mike Iselyd8554972006-06-26 20:58:46 -030048 { }
49};
50
51MODULE_DEVICE_TABLE(usb, pvr2_device_table);
52
53static const char *pvr2_device_names[] = {
54 [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx",
Mike Iselyd8554972006-06-26 20:58:46 -030055 [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx",
Mike Iselyd8554972006-06-26 20:58:46 -030056};
57
58struct pvr2_string_table {
59 const char **lst;
60 unsigned int cnt;
61};
62
Mike Iselyd8554972006-06-26 20:58:46 -030063// Names of other client modules to request for 24xxx model hardware
64static const char *pvr2_client_24xxx[] = {
65 "cx25840",
66 "tuner",
Mike Iselyd8554972006-06-26 20:58:46 -030067 "wm8775",
68};
Mike Iselyd8554972006-06-26 20:58:46 -030069
70// Names of other client modules to request for 29xxx model hardware
71static const char *pvr2_client_29xxx[] = {
72 "msp3400",
73 "saa7115",
74 "tuner",
Mike Iselyd8554972006-06-26 20:58:46 -030075};
76
77static struct pvr2_string_table pvr2_client_lists[] = {
78 [PVR2_HDW_TYPE_29XXX] = {
79 pvr2_client_29xxx,
80 sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]),
81 },
Mike Iselyd8554972006-06-26 20:58:46 -030082 [PVR2_HDW_TYPE_24XXX] = {
83 pvr2_client_24xxx,
84 sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]),
85 },
Mike Iselyd8554972006-06-26 20:58:46 -030086};
87
Mike Iselya0fd1cb2006-06-30 11:35:28 -030088static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
Adrian Bunk07e337e2006-06-30 11:30:20 -030089static DECLARE_MUTEX(pvr2_unit_sem);
Mike Iselyd8554972006-06-26 20:58:46 -030090
91static int ctlchg = 0;
92static int initusbreset = 1;
93static int procreload = 0;
94static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
95static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
96static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
Mike Isely1bde0282006-12-27 23:30:13 -030097static int auto_mode_switch[PVR_NUM];
Mike Iselyd8554972006-06-26 20:58:46 -030098static 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");
Mike Isely1bde0282006-12-27 23:30:13 -0300115module_param_array(auto_mode_switch, int, NULL, 0444);
116MODULE_PARM_DESC(auto_mode_switch,"Enable TV/Radio automatic mode switch based on freq");
Mike Iselyd8554972006-06-26 20:58:46 -0300117
118#define PVR2_CTL_WRITE_ENDPOINT 0x01
119#define PVR2_CTL_READ_ENDPOINT 0x81
120
121#define PVR2_GPIO_IN 0x9008
122#define PVR2_GPIO_OUT 0x900c
123#define PVR2_GPIO_DIR 0x9020
124
125#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
126
127#define PVR2_FIRMWARE_ENDPOINT 0x02
128
129/* size of a firmware chunk */
130#define FIRMWARE_CHUNK_SIZE 0x2000
131
Mike Iselyb30d2442006-06-25 20:05:01 -0300132/* Define the list of additional controls we'll dynamically construct based
133 on query of the cx2341x module. */
134struct pvr2_mpeg_ids {
135 const char *strid;
136 int id;
137};
138static const struct pvr2_mpeg_ids mpeg_ids[] = {
139 {
140 .strid = "audio_layer",
141 .id = V4L2_CID_MPEG_AUDIO_ENCODING,
142 },{
143 .strid = "audio_bitrate",
144 .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE,
145 },{
146 /* Already using audio_mode elsewhere :-( */
147 .strid = "mpeg_audio_mode",
148 .id = V4L2_CID_MPEG_AUDIO_MODE,
149 },{
150 .strid = "mpeg_audio_mode_extension",
151 .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
152 },{
153 .strid = "audio_emphasis",
154 .id = V4L2_CID_MPEG_AUDIO_EMPHASIS,
155 },{
156 .strid = "audio_crc",
157 .id = V4L2_CID_MPEG_AUDIO_CRC,
158 },{
159 .strid = "video_aspect",
160 .id = V4L2_CID_MPEG_VIDEO_ASPECT,
161 },{
162 .strid = "video_b_frames",
163 .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
164 },{
165 .strid = "video_gop_size",
166 .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
167 },{
168 .strid = "video_gop_closure",
169 .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
170 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300171 .strid = "video_bitrate_mode",
172 .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
173 },{
174 .strid = "video_bitrate",
175 .id = V4L2_CID_MPEG_VIDEO_BITRATE,
176 },{
177 .strid = "video_bitrate_peak",
178 .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
179 },{
180 .strid = "video_temporal_decimation",
181 .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
182 },{
183 .strid = "stream_type",
184 .id = V4L2_CID_MPEG_STREAM_TYPE,
185 },{
186 .strid = "video_spatial_filter_mode",
187 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
188 },{
189 .strid = "video_spatial_filter",
190 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
191 },{
192 .strid = "video_luma_spatial_filter_type",
193 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
194 },{
195 .strid = "video_chroma_spatial_filter_type",
196 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
197 },{
198 .strid = "video_temporal_filter_mode",
199 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
200 },{
201 .strid = "video_temporal_filter",
202 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
203 },{
204 .strid = "video_median_filter_type",
205 .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
206 },{
207 .strid = "video_luma_median_filter_top",
208 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
209 },{
210 .strid = "video_luma_median_filter_bottom",
211 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
212 },{
213 .strid = "video_chroma_median_filter_top",
214 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
215 },{
216 .strid = "video_chroma_median_filter_bottom",
217 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
218 }
219};
220#define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0]))
Mike Iselyc05c0462006-06-25 20:04:25 -0300221
Mike Iselyd8554972006-06-26 20:58:46 -0300222
Mike Isely434449f2006-08-08 09:10:06 -0300223static const char *control_values_srate[] = {
224 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100] = "44.1 kHz",
225 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000] = "48 kHz",
226 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000] = "32 kHz",
227};
Mike Iselyd8554972006-06-26 20:58:46 -0300228
Mike Iselyd8554972006-06-26 20:58:46 -0300229
230
231static const char *control_values_input[] = {
232 [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
233 [PVR2_CVAL_INPUT_RADIO] = "radio",
234 [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
235 [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
236};
237
238
239static const char *control_values_audiomode[] = {
240 [V4L2_TUNER_MODE_MONO] = "Mono",
241 [V4L2_TUNER_MODE_STEREO] = "Stereo",
242 [V4L2_TUNER_MODE_LANG1] = "Lang1",
243 [V4L2_TUNER_MODE_LANG2] = "Lang2",
244 [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
245};
246
247
248static const char *control_values_hsm[] = {
249 [PVR2_CVAL_HSM_FAIL] = "Fail",
250 [PVR2_CVAL_HSM_HIGH] = "High",
251 [PVR2_CVAL_HSM_FULL] = "Full",
252};
253
254
255static const char *control_values_subsystem[] = {
256 [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware",
257 [PVR2_SUBSYS_B_ENC_CFG] = "enc_config",
258 [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run",
259 [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run",
260 [PVR2_SUBSYS_B_ENC_RUN] = "enc_run",
261};
262
Mike Isely1bde0282006-12-27 23:30:13 -0300263static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300264static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
265static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
266static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
267static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw);
268static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
269static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
270static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw);
271static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
272 unsigned long msk,
273 unsigned long val);
274static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
275 unsigned long msk,
276 unsigned long val);
277static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
278 unsigned int timeout,int probe_fl,
279 void *write_data,unsigned int write_len,
280 void *read_data,unsigned int read_len);
281static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res);
282static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res);
Mike Iselyd8554972006-06-26 20:58:46 -0300283
284static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
285{
286 struct pvr2_hdw *hdw = cptr->hdw;
287 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
288 *vp = hdw->freqTable[hdw->freqProgSlot-1];
289 } else {
290 *vp = 0;
291 }
292 return 0;
293}
294
295static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
296{
297 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300298 unsigned int slotId = hdw->freqProgSlot;
299 if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) {
300 hdw->freqTable[slotId-1] = v;
301 /* Handle side effects correctly - if we're tuned to this
302 slot, then forgot the slot id relation since the stored
303 frequency has been changed. */
304 if (hdw->freqSelector) {
305 if (hdw->freqSlotRadio == slotId) {
306 hdw->freqSlotRadio = 0;
307 }
308 } else {
309 if (hdw->freqSlotTelevision == slotId) {
310 hdw->freqSlotTelevision = 0;
311 }
312 }
Mike Iselyd8554972006-06-26 20:58:46 -0300313 }
314 return 0;
315}
316
317static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
318{
319 *vp = cptr->hdw->freqProgSlot;
320 return 0;
321}
322
323static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
324{
325 struct pvr2_hdw *hdw = cptr->hdw;
326 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
327 hdw->freqProgSlot = v;
328 }
329 return 0;
330}
331
332static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
333{
Mike Isely1bde0282006-12-27 23:30:13 -0300334 struct pvr2_hdw *hdw = cptr->hdw;
335 *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision;
Mike Iselyd8554972006-06-26 20:58:46 -0300336 return 0;
337}
338
Mike Isely1bde0282006-12-27 23:30:13 -0300339static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId)
Mike Iselyd8554972006-06-26 20:58:46 -0300340{
341 unsigned freq = 0;
342 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300343 if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0;
344 if (slotId > 0) {
345 freq = hdw->freqTable[slotId-1];
346 if (!freq) return 0;
347 pvr2_hdw_set_cur_freq(hdw,freq);
Mike Iselyd8554972006-06-26 20:58:46 -0300348 }
Mike Isely1bde0282006-12-27 23:30:13 -0300349 if (hdw->freqSelector) {
350 hdw->freqSlotRadio = slotId;
351 } else {
352 hdw->freqSlotTelevision = slotId;
Mike Iselyd8554972006-06-26 20:58:46 -0300353 }
354 return 0;
355}
356
357static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
358{
Mike Isely1bde0282006-12-27 23:30:13 -0300359 *vp = pvr2_hdw_get_cur_freq(cptr->hdw);
Mike Iselyd8554972006-06-26 20:58:46 -0300360 return 0;
361}
362
363static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
364{
365 return cptr->hdw->freqDirty != 0;
366}
367
368static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
369{
370 cptr->hdw->freqDirty = 0;
371}
372
373static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
374{
Mike Isely1bde0282006-12-27 23:30:13 -0300375 pvr2_hdw_set_cur_freq(cptr->hdw,v);
Mike Iselyd8554972006-06-26 20:58:46 -0300376 return 0;
377}
378
Mike Isely3ad9fc32006-09-02 22:37:52 -0300379static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
380{
381 /* Actual maximum depends on the video standard in effect. */
382 if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
383 *vp = 480;
384 } else {
385 *vp = 576;
386 }
387 return 0;
388}
389
390static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
391{
392 /* Actual minimum depends on device type. */
393 if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
394 *vp = 75;
395 } else {
396 *vp = 17;
397 }
398 return 0;
399}
400
Mike Isely1bde0282006-12-27 23:30:13 -0300401static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
402{
403 *vp = cptr->hdw->input_val;
404 return 0;
405}
406
407static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
408{
409 struct pvr2_hdw *hdw = cptr->hdw;
410
411 if (hdw->input_val != v) {
412 hdw->input_val = v;
413 hdw->input_dirty = !0;
414 }
415
416 /* Handle side effects - if we switch to a mode that needs the RF
417 tuner, then select the right frequency choice as well and mark
418 it dirty. */
419 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
420 hdw->freqSelector = 0;
421 hdw->freqDirty = !0;
422 } else if (hdw->input_val == PVR2_CVAL_INPUT_TV) {
423 hdw->freqSelector = 1;
424 hdw->freqDirty = !0;
425 }
426 return 0;
427}
428
429static int ctrl_isdirty_input(struct pvr2_ctrl *cptr)
430{
431 return cptr->hdw->input_dirty != 0;
432}
433
434static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr)
435{
436 cptr->hdw->input_dirty = 0;
437}
438
Mike Isely5549f542006-12-27 23:28:54 -0300439static int ctrl_freq_check(struct pvr2_ctrl *cptr,int v)
440{
Mike Isely1bde0282006-12-27 23:30:13 -0300441 /* Both ranges are simultaneously considered legal, in order to
442 permit implicit mode switching, i.e. set a frequency in the
443 other range and the mode will switch */
444 return (((v >= RADIO_MIN_FREQ) && (v <= RADIO_MAX_FREQ)) ||
445 ((v >= TV_MIN_FREQ) && (v <= TV_MAX_FREQ)));
Mike Isely5549f542006-12-27 23:28:54 -0300446}
447
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300448static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
449{
450 /* Actual maximum depends on radio/tv mode */
451 if (cptr->hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
452 *vp = RADIO_MAX_FREQ;
453 } else {
454 *vp = TV_MAX_FREQ;
455 }
456 return 0;
457}
458
459static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
460{
461 /* Actual minimum depends on radio/tv mode */
462 if (cptr->hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
463 *vp = RADIO_MIN_FREQ;
464 } else {
465 *vp = TV_MIN_FREQ;
466 }
467 return 0;
468}
469
Mike Iselyb30d2442006-06-25 20:05:01 -0300470static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
471{
472 return cptr->hdw->enc_stale != 0;
473}
474
475static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
476{
477 cptr->hdw->enc_stale = 0;
478}
479
480static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
481{
482 int ret;
483 struct v4l2_ext_controls cs;
484 struct v4l2_ext_control c1;
485 memset(&cs,0,sizeof(cs));
486 memset(&c1,0,sizeof(c1));
487 cs.controls = &c1;
488 cs.count = 1;
489 c1.id = cptr->info->v4l_id;
490 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
491 VIDIOC_G_EXT_CTRLS);
492 if (ret) return ret;
493 *vp = c1.value;
494 return 0;
495}
496
497static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
498{
499 int ret;
500 struct v4l2_ext_controls cs;
501 struct v4l2_ext_control c1;
502 memset(&cs,0,sizeof(cs));
503 memset(&c1,0,sizeof(c1));
504 cs.controls = &c1;
505 cs.count = 1;
506 c1.id = cptr->info->v4l_id;
507 c1.value = v;
508 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
509 VIDIOC_S_EXT_CTRLS);
510 if (ret) return ret;
511 cptr->hdw->enc_stale = !0;
512 return 0;
513}
514
515static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
516{
517 struct v4l2_queryctrl qctrl;
518 struct pvr2_ctl_info *info;
519 qctrl.id = cptr->info->v4l_id;
520 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
521 /* Strip out the const so we can adjust a function pointer. It's
522 OK to do this here because we know this is a dynamically created
523 control, so the underlying storage for the info pointer is (a)
524 private to us, and (b) not in read-only storage. Either we do
525 this or we significantly complicate the underlying control
526 implementation. */
527 info = (struct pvr2_ctl_info *)(cptr->info);
528 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
529 if (info->set_value) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300530 info->set_value = NULL;
Mike Iselyb30d2442006-06-25 20:05:01 -0300531 }
532 } else {
533 if (!(info->set_value)) {
534 info->set_value = ctrl_cx2341x_set;
535 }
536 }
537 return qctrl.flags;
538}
539
Mike Iselyd8554972006-06-26 20:58:46 -0300540static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
541{
542 *vp = cptr->hdw->flag_streaming_enabled;
543 return 0;
544}
545
546static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
547{
548 int result = pvr2_hdw_is_hsm(cptr->hdw);
549 *vp = PVR2_CVAL_HSM_FULL;
550 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
551 if (result) *vp = PVR2_CVAL_HSM_HIGH;
552 return 0;
553}
554
555static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
556{
557 *vp = cptr->hdw->std_mask_avail;
558 return 0;
559}
560
561static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
562{
563 struct pvr2_hdw *hdw = cptr->hdw;
564 v4l2_std_id ns;
565 ns = hdw->std_mask_avail;
566 ns = (ns & ~m) | (v & m);
567 if (ns == hdw->std_mask_avail) return 0;
568 hdw->std_mask_avail = ns;
569 pvr2_hdw_internal_set_std_avail(hdw);
570 pvr2_hdw_internal_find_stdenum(hdw);
571 return 0;
572}
573
574static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
575 char *bufPtr,unsigned int bufSize,
576 unsigned int *len)
577{
578 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
579 return 0;
580}
581
582static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
583 const char *bufPtr,unsigned int bufSize,
584 int *mskp,int *valp)
585{
586 int ret;
587 v4l2_std_id id;
588 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
589 if (ret < 0) return ret;
590 if (mskp) *mskp = id;
591 if (valp) *valp = id;
592 return 0;
593}
594
595static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
596{
597 *vp = cptr->hdw->std_mask_cur;
598 return 0;
599}
600
601static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
602{
603 struct pvr2_hdw *hdw = cptr->hdw;
604 v4l2_std_id ns;
605 ns = hdw->std_mask_cur;
606 ns = (ns & ~m) | (v & m);
607 if (ns == hdw->std_mask_cur) return 0;
608 hdw->std_mask_cur = ns;
609 hdw->std_dirty = !0;
610 pvr2_hdw_internal_find_stdenum(hdw);
611 return 0;
612}
613
614static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
615{
616 return cptr->hdw->std_dirty != 0;
617}
618
619static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
620{
621 cptr->hdw->std_dirty = 0;
622}
623
624static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
625{
626 *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) &
627 PVR2_SIGNAL_OK) ? 1 : 0);
628 return 0;
629}
630
631static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
632{
633 *vp = cptr->hdw->subsys_enabled_mask;
634 return 0;
635}
636
637static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
638{
639 pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
640 return 0;
641}
642
643static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
644{
645 *vp = cptr->hdw->subsys_stream_mask;
646 return 0;
647}
648
649static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
650{
651 pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
652 return 0;
653}
654
655static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
656{
657 struct pvr2_hdw *hdw = cptr->hdw;
658 if (v < 0) return -EINVAL;
659 if (v > hdw->std_enum_cnt) return -EINVAL;
660 hdw->std_enum_cur = v;
661 if (!v) return 0;
662 v--;
663 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
664 hdw->std_mask_cur = hdw->std_defs[v].id;
665 hdw->std_dirty = !0;
666 return 0;
667}
668
669
670static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
671{
672 *vp = cptr->hdw->std_enum_cur;
673 return 0;
674}
675
676
677static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
678{
679 return cptr->hdw->std_dirty != 0;
680}
681
682
683static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
684{
685 cptr->hdw->std_dirty = 0;
686}
687
688
689#define DEFINT(vmin,vmax) \
690 .type = pvr2_ctl_int, \
691 .def.type_int.min_value = vmin, \
692 .def.type_int.max_value = vmax
693
694#define DEFENUM(tab) \
695 .type = pvr2_ctl_enum, \
696 .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \
697 .def.type_enum.value_names = tab
698
Mike Isely33213962006-06-25 20:04:40 -0300699#define DEFBOOL \
700 .type = pvr2_ctl_bool
701
Mike Iselyd8554972006-06-26 20:58:46 -0300702#define DEFMASK(msk,tab) \
703 .type = pvr2_ctl_bitmask, \
704 .def.type_bitmask.valid_bits = msk, \
705 .def.type_bitmask.bit_names = tab
706
707#define DEFREF(vname) \
708 .set_value = ctrl_set_##vname, \
709 .get_value = ctrl_get_##vname, \
710 .is_dirty = ctrl_isdirty_##vname, \
711 .clear_dirty = ctrl_cleardirty_##vname
712
713
714#define VCREATE_FUNCS(vname) \
715static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
716{*vp = cptr->hdw->vname##_val; return 0;} \
717static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
718{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
719static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
720{return cptr->hdw->vname##_dirty != 0;} \
721static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
722{cptr->hdw->vname##_dirty = 0;}
723
724VCREATE_FUNCS(brightness)
725VCREATE_FUNCS(contrast)
726VCREATE_FUNCS(saturation)
727VCREATE_FUNCS(hue)
728VCREATE_FUNCS(volume)
729VCREATE_FUNCS(balance)
730VCREATE_FUNCS(bass)
731VCREATE_FUNCS(treble)
732VCREATE_FUNCS(mute)
Mike Iselyc05c0462006-06-25 20:04:25 -0300733VCREATE_FUNCS(audiomode)
734VCREATE_FUNCS(res_hor)
735VCREATE_FUNCS(res_ver)
Mike Iselyd8554972006-06-26 20:58:46 -0300736VCREATE_FUNCS(srate)
Mike Isely1bde0282006-12-27 23:30:13 -0300737VCREATE_FUNCS(automodeswitch)
Mike Iselyd8554972006-06-26 20:58:46 -0300738
Mike Iselyd8554972006-06-26 20:58:46 -0300739/* Table definition of all controls which can be manipulated */
740static const struct pvr2_ctl_info control_defs[] = {
741 {
742 .v4l_id = V4L2_CID_BRIGHTNESS,
743 .desc = "Brightness",
744 .name = "brightness",
745 .default_value = 128,
746 DEFREF(brightness),
747 DEFINT(0,255),
748 },{
749 .v4l_id = V4L2_CID_CONTRAST,
750 .desc = "Contrast",
751 .name = "contrast",
752 .default_value = 68,
753 DEFREF(contrast),
754 DEFINT(0,127),
755 },{
756 .v4l_id = V4L2_CID_SATURATION,
757 .desc = "Saturation",
758 .name = "saturation",
759 .default_value = 64,
760 DEFREF(saturation),
761 DEFINT(0,127),
762 },{
763 .v4l_id = V4L2_CID_HUE,
764 .desc = "Hue",
765 .name = "hue",
766 .default_value = 0,
767 DEFREF(hue),
768 DEFINT(-128,127),
769 },{
770 .v4l_id = V4L2_CID_AUDIO_VOLUME,
771 .desc = "Volume",
772 .name = "volume",
773 .default_value = 65535,
774 DEFREF(volume),
775 DEFINT(0,65535),
776 },{
777 .v4l_id = V4L2_CID_AUDIO_BALANCE,
778 .desc = "Balance",
779 .name = "balance",
780 .default_value = 0,
781 DEFREF(balance),
782 DEFINT(-32768,32767),
783 },{
784 .v4l_id = V4L2_CID_AUDIO_BASS,
785 .desc = "Bass",
786 .name = "bass",
787 .default_value = 0,
788 DEFREF(bass),
789 DEFINT(-32768,32767),
790 },{
791 .v4l_id = V4L2_CID_AUDIO_TREBLE,
792 .desc = "Treble",
793 .name = "treble",
794 .default_value = 0,
795 DEFREF(treble),
796 DEFINT(-32768,32767),
797 },{
798 .v4l_id = V4L2_CID_AUDIO_MUTE,
799 .desc = "Mute",
800 .name = "mute",
801 .default_value = 0,
802 DEFREF(mute),
Mike Isely33213962006-06-25 20:04:40 -0300803 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300804 },{
Mike Iselyc05c0462006-06-25 20:04:25 -0300805 .desc = "Video Source",
806 .name = "input",
807 .internal_id = PVR2_CID_INPUT,
808 .default_value = PVR2_CVAL_INPUT_TV,
809 DEFREF(input),
810 DEFENUM(control_values_input),
811 },{
812 .desc = "Audio Mode",
813 .name = "audio_mode",
814 .internal_id = PVR2_CID_AUDIOMODE,
815 .default_value = V4L2_TUNER_MODE_STEREO,
816 DEFREF(audiomode),
817 DEFENUM(control_values_audiomode),
818 },{
819 .desc = "Horizontal capture resolution",
820 .name = "resolution_hor",
821 .internal_id = PVR2_CID_HRES,
822 .default_value = 720,
823 DEFREF(res_hor),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300824 DEFINT(19,720),
Mike Iselyc05c0462006-06-25 20:04:25 -0300825 },{
826 .desc = "Vertical capture resolution",
827 .name = "resolution_ver",
828 .internal_id = PVR2_CID_VRES,
829 .default_value = 480,
830 DEFREF(res_ver),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300831 DEFINT(17,576),
832 /* Hook in check for video standard and adjust maximum
833 depending on the standard. */
834 .get_max_value = ctrl_vres_max_get,
835 .get_min_value = ctrl_vres_min_get,
Mike Iselyc05c0462006-06-25 20:04:25 -0300836 },{
Mike Isely1bde0282006-12-27 23:30:13 -0300837 .v4l_id = V4L2_CID_AUDIO_MUTE,
838 .desc = "Automatic TV / Radio mode switch based on frequency",
839 .name = "auto_mode_switch",
840 .default_value = 0,
841 DEFREF(automodeswitch),
842 DEFBOOL,
843 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300844 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
Mike Isely434449f2006-08-08 09:10:06 -0300845 .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
846 .desc = "Audio Sampling Frequency",
Mike Iselyd8554972006-06-26 20:58:46 -0300847 .name = "srate",
Mike Iselyd8554972006-06-26 20:58:46 -0300848 DEFREF(srate),
849 DEFENUM(control_values_srate),
850 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300851 .desc = "Tuner Frequency (Hz)",
852 .name = "frequency",
853 .internal_id = PVR2_CID_FREQUENCY,
Mike Isely1bde0282006-12-27 23:30:13 -0300854 .default_value = 0,
Mike Iselyd8554972006-06-26 20:58:46 -0300855 .set_value = ctrl_freq_set,
856 .get_value = ctrl_freq_get,
857 .is_dirty = ctrl_freq_is_dirty,
858 .clear_dirty = ctrl_freq_clear_dirty,
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300859 DEFINT(TV_MIN_FREQ,TV_MAX_FREQ),
860 /* Hook in check for input value (tv/radio) and adjust
861 max/min values accordingly */
Mike Isely5549f542006-12-27 23:28:54 -0300862 .check_value = ctrl_freq_check,
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300863 .get_max_value = ctrl_freq_max_get,
864 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300865 },{
866 .desc = "Channel",
867 .name = "channel",
868 .set_value = ctrl_channel_set,
869 .get_value = ctrl_channel_get,
870 DEFINT(0,FREQTABLE_SIZE),
871 },{
872 .desc = "Channel Program Frequency",
873 .name = "freq_table_value",
874 .set_value = ctrl_channelfreq_set,
875 .get_value = ctrl_channelfreq_get,
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300876 DEFINT(TV_MIN_FREQ,TV_MAX_FREQ),
Mike Isely1bde0282006-12-27 23:30:13 -0300877 /* Hook in check for input value (tv/radio) and adjust
878 max/min values accordingly */
879 .check_value = ctrl_freq_check,
880 .get_max_value = ctrl_freq_max_get,
881 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300882 },{
883 .desc = "Channel Program ID",
884 .name = "freq_table_channel",
885 .set_value = ctrl_channelprog_set,
886 .get_value = ctrl_channelprog_get,
887 DEFINT(0,FREQTABLE_SIZE),
888 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300889 .desc = "Streaming Enabled",
890 .name = "streaming_enabled",
891 .get_value = ctrl_streamingenabled_get,
Mike Isely33213962006-06-25 20:04:40 -0300892 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300893 },{
894 .desc = "USB Speed",
895 .name = "usb_speed",
896 .get_value = ctrl_hsm_get,
897 DEFENUM(control_values_hsm),
898 },{
899 .desc = "Signal Present",
900 .name = "signal_present",
901 .get_value = ctrl_signal_get,
Mike Isely33213962006-06-25 20:04:40 -0300902 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300903 },{
904 .desc = "Video Standards Available Mask",
905 .name = "video_standard_mask_available",
906 .internal_id = PVR2_CID_STDAVAIL,
907 .skip_init = !0,
908 .get_value = ctrl_stdavail_get,
909 .set_value = ctrl_stdavail_set,
910 .val_to_sym = ctrl_std_val_to_sym,
911 .sym_to_val = ctrl_std_sym_to_val,
912 .type = pvr2_ctl_bitmask,
913 },{
914 .desc = "Video Standards In Use Mask",
915 .name = "video_standard_mask_active",
916 .internal_id = PVR2_CID_STDCUR,
917 .skip_init = !0,
918 .get_value = ctrl_stdcur_get,
919 .set_value = ctrl_stdcur_set,
920 .is_dirty = ctrl_stdcur_is_dirty,
921 .clear_dirty = ctrl_stdcur_clear_dirty,
922 .val_to_sym = ctrl_std_val_to_sym,
923 .sym_to_val = ctrl_std_sym_to_val,
924 .type = pvr2_ctl_bitmask,
925 },{
926 .desc = "Subsystem enabled mask",
927 .name = "debug_subsys_mask",
928 .skip_init = !0,
929 .get_value = ctrl_subsys_get,
930 .set_value = ctrl_subsys_set,
931 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
932 },{
933 .desc = "Subsystem stream mask",
934 .name = "debug_subsys_stream_mask",
935 .skip_init = !0,
936 .get_value = ctrl_subsys_stream_get,
937 .set_value = ctrl_subsys_stream_set,
938 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
939 },{
940 .desc = "Video Standard Name",
941 .name = "video_standard",
942 .internal_id = PVR2_CID_STDENUM,
943 .skip_init = !0,
944 .get_value = ctrl_stdenumcur_get,
945 .set_value = ctrl_stdenumcur_set,
946 .is_dirty = ctrl_stdenumcur_is_dirty,
947 .clear_dirty = ctrl_stdenumcur_clear_dirty,
948 .type = pvr2_ctl_enum,
949 }
950};
951
Mike Iselyc05c0462006-06-25 20:04:25 -0300952#define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
Mike Iselyd8554972006-06-26 20:58:46 -0300953
954
955const char *pvr2_config_get_name(enum pvr2_config cfg)
956{
957 switch (cfg) {
958 case pvr2_config_empty: return "empty";
959 case pvr2_config_mpeg: return "mpeg";
960 case pvr2_config_vbi: return "vbi";
961 case pvr2_config_radio: return "radio";
962 }
963 return "<unknown>";
964}
965
966
967struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
968{
969 return hdw->usb_dev;
970}
971
972
973unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
974{
975 return hdw->serial_number;
976}
977
Mike Isely1bde0282006-12-27 23:30:13 -0300978unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
979{
980 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
981}
982
983/* Set the currently tuned frequency and account for all possible
984 driver-core side effects of this action. */
985void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val)
986{
987 int mode = 0;
988
989 /* If hdw->automodeswitch_val is set, then we do something clever:
990 Look at the desired frequency and see if it looks like FM or TV.
991 Execute a possible mode switch based on this result. Otherwise
992 we use the current input setting to determine which frequency
993 register we need to adjust. */
994 if (hdw->automodeswitch_val) {
995 /* Note that since FM RADIO frequency range sits *inside*
996 the TV spectrum that we must therefore check the radio
997 range first... */
998 if ((val >= RADIO_MIN_FREQ) && (val <= RADIO_MAX_FREQ)) {
999 mode = 1;
1000 } else if ((val >= TV_MIN_FREQ) && (val <= TV_MAX_FREQ)) {
1001 mode = 2;
1002 }
1003 } else {
1004 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
1005 mode = 1;
1006 } else {
1007 mode = 2;
1008 }
1009 }
1010
1011 switch (mode) {
1012 case 1:
1013 if (hdw->freqSelector) {
1014 /* Swing over to radio frequency selection */
1015 hdw->freqSelector = 0;
1016 hdw->freqDirty = !0;
1017 }
1018 if (hdw->input_val == PVR2_CVAL_INPUT_TV) {
1019 /* Force switch to radio mode */
1020 hdw->input_val = PVR2_CVAL_INPUT_RADIO;
1021 hdw->input_dirty = !0;
1022 }
1023 if (hdw->freqValRadio != val) {
1024 hdw->freqValRadio = val;
1025 hdw->freqSlotRadio = 0;
1026 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
1027 hdw->freqDirty = !0;
1028 }
1029 }
1030 break;
1031 case 2:
1032 if (!(hdw->freqSelector)) {
1033 /* Swing over to television frequency selection */
1034 hdw->freqSelector = 1;
1035 hdw->freqDirty = !0;
1036 }
1037 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
1038 /* Force switch to television mode */
1039 hdw->input_val = PVR2_CVAL_INPUT_TV;
1040 hdw->input_dirty = !0;
1041 }
1042 if (hdw->freqValTelevision != val) {
1043 hdw->freqValTelevision = val;
1044 hdw->freqSlotTelevision = 0;
1045 if (hdw->input_val == PVR2_CVAL_INPUT_TV) {
1046 hdw->freqDirty = !0;
1047 }
1048 }
1049 break;
1050 default:
1051 break;
1052 }
1053}
1054
Mike Iselyd8554972006-06-26 20:58:46 -03001055int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
1056{
1057 return hdw->unit_number;
1058}
1059
1060
1061/* Attempt to locate one of the given set of files. Messages are logged
1062 appropriate to what has been found. The return value will be 0 or
1063 greater on success (it will be the index of the file name found) and
1064 fw_entry will be filled in. Otherwise a negative error is returned on
1065 failure. If the return value is -ENOENT then no viable firmware file
1066 could be located. */
1067static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
1068 const struct firmware **fw_entry,
1069 const char *fwtypename,
1070 unsigned int fwcount,
1071 const char *fwnames[])
1072{
1073 unsigned int idx;
1074 int ret = -EINVAL;
1075 for (idx = 0; idx < fwcount; idx++) {
1076 ret = request_firmware(fw_entry,
1077 fwnames[idx],
1078 &hdw->usb_dev->dev);
1079 if (!ret) {
1080 trace_firmware("Located %s firmware: %s;"
1081 " uploading...",
1082 fwtypename,
1083 fwnames[idx]);
1084 return idx;
1085 }
1086 if (ret == -ENOENT) continue;
1087 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1088 "request_firmware fatal error with code=%d",ret);
1089 return ret;
1090 }
1091 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1092 "***WARNING***"
1093 " Device %s firmware"
1094 " seems to be missing.",
1095 fwtypename);
1096 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1097 "Did you install the pvrusb2 firmware files"
1098 " in their proper location?");
1099 if (fwcount == 1) {
1100 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1101 "request_firmware unable to locate %s file %s",
1102 fwtypename,fwnames[0]);
1103 } else {
1104 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1105 "request_firmware unable to locate"
1106 " one of the following %s files:",
1107 fwtypename);
1108 for (idx = 0; idx < fwcount; idx++) {
1109 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1110 "request_firmware: Failed to find %s",
1111 fwnames[idx]);
1112 }
1113 }
1114 return ret;
1115}
1116
1117
1118/*
1119 * pvr2_upload_firmware1().
1120 *
1121 * Send the 8051 firmware to the device. After the upload, arrange for
1122 * device to re-enumerate.
1123 *
1124 * NOTE : the pointer to the firmware data given by request_firmware()
1125 * is not suitable for an usb transaction.
1126 *
1127 */
Adrian Bunk07e337e2006-06-30 11:30:20 -03001128static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001129{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001130 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001131 void *fw_ptr;
1132 unsigned int pipe;
1133 int ret;
1134 u16 address;
1135 static const char *fw_files_29xxx[] = {
1136 "v4l-pvrusb2-29xxx-01.fw",
1137 };
Mike Iselyd8554972006-06-26 20:58:46 -03001138 static const char *fw_files_24xxx[] = {
1139 "v4l-pvrusb2-24xxx-01.fw",
1140 };
Mike Iselyd8554972006-06-26 20:58:46 -03001141 static const struct pvr2_string_table fw_file_defs[] = {
1142 [PVR2_HDW_TYPE_29XXX] = {
1143 fw_files_29xxx,
1144 sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
1145 },
Mike Iselyd8554972006-06-26 20:58:46 -03001146 [PVR2_HDW_TYPE_24XXX] = {
1147 fw_files_24xxx,
1148 sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]),
1149 },
Mike Iselyd8554972006-06-26 20:58:46 -03001150 };
1151 hdw->fw1_state = FW1_STATE_FAILED; // default result
1152
1153 trace_firmware("pvr2_upload_firmware1");
1154
1155 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
1156 fw_file_defs[hdw->hdw_type].cnt,
1157 fw_file_defs[hdw->hdw_type].lst);
1158 if (ret < 0) {
1159 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
1160 return ret;
1161 }
1162
1163 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
1164 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
1165
1166 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
1167
1168 if (fw_entry->size != 0x2000){
1169 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
1170 release_firmware(fw_entry);
1171 return -ENOMEM;
1172 }
1173
1174 fw_ptr = kmalloc(0x800, GFP_KERNEL);
1175 if (fw_ptr == NULL){
1176 release_firmware(fw_entry);
1177 return -ENOMEM;
1178 }
1179
1180 /* We have to hold the CPU during firmware upload. */
1181 pvr2_hdw_cpureset_assert(hdw,1);
1182
1183 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
1184 chunk. */
1185
1186 ret = 0;
1187 for(address = 0; address < fw_entry->size; address += 0x800) {
1188 memcpy(fw_ptr, fw_entry->data + address, 0x800);
1189 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
1190 0, fw_ptr, 0x800, HZ);
1191 }
1192
1193 trace_firmware("Upload done, releasing device's CPU");
1194
1195 /* Now release the CPU. It will disconnect and reconnect later. */
1196 pvr2_hdw_cpureset_assert(hdw,0);
1197
1198 kfree(fw_ptr);
1199 release_firmware(fw_entry);
1200
1201 trace_firmware("Upload done (%d bytes sent)",ret);
1202
1203 /* We should have written 8192 bytes */
1204 if (ret == 8192) {
1205 hdw->fw1_state = FW1_STATE_RELOAD;
1206 return 0;
1207 }
1208
1209 return -EIO;
1210}
1211
1212
1213/*
1214 * pvr2_upload_firmware2()
1215 *
1216 * This uploads encoder firmware on endpoint 2.
1217 *
1218 */
1219
1220int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
1221{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001222 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001223 void *fw_ptr;
1224 unsigned int pipe, fw_len, fw_done;
1225 int actual_length;
1226 int ret = 0;
1227 int fwidx;
1228 static const char *fw_files[] = {
1229 CX2341X_FIRM_ENC_FILENAME,
1230 };
1231
1232 trace_firmware("pvr2_upload_firmware2");
1233
1234 ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
1235 sizeof(fw_files)/sizeof(fw_files[0]),
1236 fw_files);
1237 if (ret < 0) return ret;
1238 fwidx = ret;
1239 ret = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001240 /* Since we're about to completely reinitialize the encoder,
1241 invalidate our cached copy of its configuration state. Next
1242 time we configure the encoder, then we'll fully configure it. */
1243 hdw->enc_cur_valid = 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001244
1245 /* First prepare firmware loading */
1246 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
1247 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
1248 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1249 ret |= pvr2_hdw_cmd_deep_reset(hdw);
1250 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
1251 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
1252 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1253 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
1254 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
1255 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
1256 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
1257 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
1258 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
1259 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
1260 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
1261 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
1262 ret |= pvr2_write_u8(hdw, 0x52, 0);
1263 ret |= pvr2_write_u16(hdw, 0x0600, 0);
1264
1265 if (ret) {
1266 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1267 "firmware2 upload prep failed, ret=%d",ret);
1268 release_firmware(fw_entry);
1269 return ret;
1270 }
1271
1272 /* Now send firmware */
1273
1274 fw_len = fw_entry->size;
1275
1276 if (fw_len % FIRMWARE_CHUNK_SIZE) {
1277 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1278 "size of %s firmware"
1279 " must be a multiple of 8192B",
1280 fw_files[fwidx]);
1281 release_firmware(fw_entry);
1282 return -1;
1283 }
1284
1285 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1286 if (fw_ptr == NULL){
1287 release_firmware(fw_entry);
1288 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1289 "failed to allocate memory for firmware2 upload");
1290 return -ENOMEM;
1291 }
1292
1293 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1294
1295 for (fw_done = 0 ; (fw_done < fw_len) && !ret ;
1296 fw_done += FIRMWARE_CHUNK_SIZE ) {
1297 int i;
1298 memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE);
1299 /* Usbsnoop log shows that we must swap bytes... */
1300 for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++)
1301 ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]);
1302
1303 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,
1304 FIRMWARE_CHUNK_SIZE,
1305 &actual_length, HZ);
1306 ret |= (actual_length != FIRMWARE_CHUNK_SIZE);
1307 }
1308
1309 trace_firmware("upload of %s : %i / %i ",
1310 fw_files[fwidx],fw_done,fw_len);
1311
1312 kfree(fw_ptr);
1313 release_firmware(fw_entry);
1314
1315 if (ret) {
1316 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1317 "firmware2 upload transfer failure");
1318 return ret;
1319 }
1320
1321 /* Finish upload */
1322
1323 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1324 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
1325 ret |= pvr2_write_u16(hdw, 0x0600, 0);
1326
1327 if (ret) {
1328 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1329 "firmware2 upload post-proc failure");
1330 } else {
1331 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
1332 }
1333 return ret;
1334}
1335
1336
1337#define FIRMWARE_RECOVERY_BITS \
1338 ((1<<PVR2_SUBSYS_B_ENC_CFG) | \
1339 (1<<PVR2_SUBSYS_B_ENC_RUN) | \
1340 (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \
1341 (1<<PVR2_SUBSYS_B_USBSTREAM_RUN))
1342
1343/*
1344
1345 This single function is key to pretty much everything. The pvrusb2
1346 device can logically be viewed as a series of subsystems which can be
1347 stopped / started or unconfigured / configured. To get things streaming,
1348 one must configure everything and start everything, but there may be
1349 various reasons over time to deconfigure something or stop something.
1350 This function handles all of this activity. Everything EVERYWHERE that
1351 must affect a subsystem eventually comes here to do the work.
1352
1353 The current state of all subsystems is represented by a single bit mask,
1354 known as subsys_enabled_mask. The bit positions are defined by the
1355 PVR2_SUBSYS_xxxx macros, with one subsystem per bit position. At any
1356 time the set of configured or active subsystems can be queried just by
1357 looking at that mask. To change bits in that mask, this function here
1358 must be called. The "msk" argument indicates which bit positions to
1359 change, and the "val" argument defines the new values for the positions
1360 defined by "msk".
1361
1362 There is a priority ordering of starting / stopping things, and for
1363 multiple requested changes, this function implements that ordering.
1364 (Thus we will act on a request to load encoder firmware before we
1365 configure the encoder.) In addition to priority ordering, there is a
1366 recovery strategy implemented here. If a particular step fails and we
1367 detect that failure, this function will clear the affected subsystem bits
1368 and restart. Thus we have a means for recovering from a dead encoder:
1369 Clear all bits that correspond to subsystems that we need to restart /
1370 reconfigure and start over.
1371
1372*/
Adrian Bunk07e337e2006-06-30 11:30:20 -03001373static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
1374 unsigned long msk,
1375 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001376{
1377 unsigned long nmsk;
1378 unsigned long vmsk;
1379 int ret;
1380 unsigned int tryCount = 0;
1381
1382 if (!hdw->flag_ok) return;
1383
1384 msk &= PVR2_SUBSYS_ALL;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001385 nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk);
1386 nmsk &= PVR2_SUBSYS_ALL;
Mike Iselyd8554972006-06-26 20:58:46 -03001387
1388 for (;;) {
1389 tryCount++;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001390 if (!((nmsk ^ hdw->subsys_enabled_mask) &
1391 PVR2_SUBSYS_ALL)) break;
Mike Iselyd8554972006-06-26 20:58:46 -03001392 if (tryCount > 4) {
1393 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1394 "Too many retries when configuring device;"
1395 " giving up");
1396 pvr2_hdw_render_useless(hdw);
1397 break;
1398 }
1399 if (tryCount > 1) {
1400 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1401 "Retrying device reconfiguration");
1402 }
1403 pvr2_trace(PVR2_TRACE_INIT,
1404 "subsys mask changing 0x%lx:0x%lx"
1405 " from 0x%lx to 0x%lx",
1406 msk,val,hdw->subsys_enabled_mask,nmsk);
1407
1408 vmsk = (nmsk ^ hdw->subsys_enabled_mask) &
1409 hdw->subsys_enabled_mask;
1410 if (vmsk) {
1411 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1412 pvr2_trace(PVR2_TRACE_CTL,
1413 "/*---TRACE_CTL----*/"
1414 " pvr2_encoder_stop");
1415 ret = pvr2_encoder_stop(hdw);
1416 if (ret) {
1417 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1418 "Error recovery initiated");
1419 hdw->subsys_enabled_mask &=
1420 ~FIRMWARE_RECOVERY_BITS;
1421 continue;
1422 }
1423 }
1424 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1425 pvr2_trace(PVR2_TRACE_CTL,
1426 "/*---TRACE_CTL----*/"
1427 " pvr2_hdw_cmd_usbstream(0)");
1428 pvr2_hdw_cmd_usbstream(hdw,0);
1429 }
1430 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1431 pvr2_trace(PVR2_TRACE_CTL,
1432 "/*---TRACE_CTL----*/"
1433 " decoder disable");
1434 if (hdw->decoder_ctrl) {
1435 hdw->decoder_ctrl->enable(
1436 hdw->decoder_ctrl->ctxt,0);
1437 } else {
1438 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1439 "WARNING:"
1440 " No decoder present");
1441 }
1442 hdw->subsys_enabled_mask &=
1443 ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1444 }
1445 if (vmsk & PVR2_SUBSYS_CFG_ALL) {
1446 hdw->subsys_enabled_mask &=
1447 ~(vmsk & PVR2_SUBSYS_CFG_ALL);
1448 }
1449 }
1450 vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk;
1451 if (vmsk) {
1452 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) {
1453 pvr2_trace(PVR2_TRACE_CTL,
1454 "/*---TRACE_CTL----*/"
1455 " pvr2_upload_firmware2");
1456 ret = pvr2_upload_firmware2(hdw);
1457 if (ret) {
1458 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1459 "Failure uploading encoder"
1460 " firmware");
1461 pvr2_hdw_render_useless(hdw);
1462 break;
1463 }
1464 }
1465 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) {
1466 pvr2_trace(PVR2_TRACE_CTL,
1467 "/*---TRACE_CTL----*/"
1468 " pvr2_encoder_configure");
1469 ret = pvr2_encoder_configure(hdw);
1470 if (ret) {
1471 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1472 "Error recovery initiated");
1473 hdw->subsys_enabled_mask &=
1474 ~FIRMWARE_RECOVERY_BITS;
1475 continue;
1476 }
1477 }
1478 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1479 pvr2_trace(PVR2_TRACE_CTL,
1480 "/*---TRACE_CTL----*/"
1481 " decoder enable");
1482 if (hdw->decoder_ctrl) {
1483 hdw->decoder_ctrl->enable(
1484 hdw->decoder_ctrl->ctxt,!0);
1485 } else {
1486 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1487 "WARNING:"
1488 " No decoder present");
1489 }
1490 hdw->subsys_enabled_mask |=
1491 (1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1492 }
1493 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1494 pvr2_trace(PVR2_TRACE_CTL,
1495 "/*---TRACE_CTL----*/"
1496 " pvr2_hdw_cmd_usbstream(1)");
1497 pvr2_hdw_cmd_usbstream(hdw,!0);
1498 }
1499 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1500 pvr2_trace(PVR2_TRACE_CTL,
1501 "/*---TRACE_CTL----*/"
1502 " pvr2_encoder_start");
1503 ret = pvr2_encoder_start(hdw);
1504 if (ret) {
1505 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1506 "Error recovery initiated");
1507 hdw->subsys_enabled_mask &=
1508 ~FIRMWARE_RECOVERY_BITS;
1509 continue;
1510 }
1511 }
1512 }
1513 }
1514}
1515
1516
1517void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
1518 unsigned long msk,unsigned long val)
1519{
1520 LOCK_TAKE(hdw->big_lock); do {
1521 pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val);
1522 } while (0); LOCK_GIVE(hdw->big_lock);
1523}
1524
1525
Mike Iselyd8554972006-06-26 20:58:46 -03001526unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw)
1527{
1528 return hdw->subsys_enabled_mask;
1529}
1530
1531
1532unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw)
1533{
1534 return hdw->subsys_stream_mask;
1535}
1536
1537
Adrian Bunk07e337e2006-06-30 11:30:20 -03001538static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
1539 unsigned long msk,
1540 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001541{
1542 unsigned long val2;
1543 msk &= PVR2_SUBSYS_ALL;
1544 val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk));
1545 pvr2_trace(PVR2_TRACE_INIT,
1546 "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx",
1547 msk,val,hdw->subsys_stream_mask,val2);
1548 hdw->subsys_stream_mask = val2;
1549}
1550
1551
1552void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
1553 unsigned long msk,
1554 unsigned long val)
1555{
1556 LOCK_TAKE(hdw->big_lock); do {
1557 pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val);
1558 } while (0); LOCK_GIVE(hdw->big_lock);
1559}
1560
1561
Adrian Bunk07e337e2006-06-30 11:30:20 -03001562static int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl)
Mike Iselyd8554972006-06-26 20:58:46 -03001563{
1564 if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0;
1565 if (enableFl) {
1566 pvr2_trace(PVR2_TRACE_START_STOP,
1567 "/*--TRACE_STREAM--*/ enable");
1568 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0);
1569 } else {
1570 pvr2_trace(PVR2_TRACE_START_STOP,
1571 "/*--TRACE_STREAM--*/ disable");
1572 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1573 }
1574 if (!hdw->flag_ok) return -EIO;
1575 hdw->flag_streaming_enabled = enableFl != 0;
1576 return 0;
1577}
1578
1579
1580int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1581{
1582 return hdw->flag_streaming_enabled != 0;
1583}
1584
1585
1586int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1587{
1588 int ret;
1589 LOCK_TAKE(hdw->big_lock); do {
1590 ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag);
1591 } while (0); LOCK_GIVE(hdw->big_lock);
1592 return ret;
1593}
1594
1595
Adrian Bunk07e337e2006-06-30 11:30:20 -03001596static int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw,
1597 enum pvr2_config config)
Mike Iselyd8554972006-06-26 20:58:46 -03001598{
1599 unsigned long sm = hdw->subsys_enabled_mask;
1600 if (!hdw->flag_ok) return -EIO;
1601 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1602 hdw->config = config;
1603 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm);
1604 return 0;
1605}
1606
1607
1608int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1609{
1610 int ret;
1611 if (!hdw->flag_ok) return -EIO;
1612 LOCK_TAKE(hdw->big_lock);
1613 ret = pvr2_hdw_set_stream_type_no_lock(hdw,config);
1614 LOCK_GIVE(hdw->big_lock);
1615 return ret;
1616}
1617
1618
1619static int get_default_tuner_type(struct pvr2_hdw *hdw)
1620{
1621 int unit_number = hdw->unit_number;
1622 int tp = -1;
1623 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1624 tp = tuner[unit_number];
1625 }
1626 if (tp < 0) return -EINVAL;
1627 hdw->tuner_type = tp;
1628 return 0;
1629}
1630
1631
1632static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1633{
1634 int unit_number = hdw->unit_number;
1635 int tp = 0;
1636 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1637 tp = video_std[unit_number];
1638 }
1639 return tp;
1640}
1641
1642
1643static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1644{
1645 int unit_number = hdw->unit_number;
1646 int tp = 0;
1647 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1648 tp = tolerance[unit_number];
1649 }
1650 return tp;
1651}
1652
1653
1654static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1655{
1656 /* Try a harmless request to fetch the eeprom's address over
1657 endpoint 1. See what happens. Only the full FX2 image can
1658 respond to this. If this probe fails then likely the FX2
1659 firmware needs be loaded. */
1660 int result;
1661 LOCK_TAKE(hdw->ctl_lock); do {
1662 hdw->cmd_buffer[0] = 0xeb;
1663 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1664 hdw->cmd_buffer,1,
1665 hdw->cmd_buffer,1);
1666 if (result < 0) break;
1667 } while(0); LOCK_GIVE(hdw->ctl_lock);
1668 if (result) {
1669 pvr2_trace(PVR2_TRACE_INIT,
1670 "Probe of device endpoint 1 result status %d",
1671 result);
1672 } else {
1673 pvr2_trace(PVR2_TRACE_INIT,
1674 "Probe of device endpoint 1 succeeded");
1675 }
1676 return result == 0;
1677}
1678
1679static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1680{
1681 char buf[40];
1682 unsigned int bcnt;
1683 v4l2_std_id std1,std2;
1684
1685 std1 = get_default_standard(hdw);
1686
1687 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
1688 pvr2_trace(PVR2_TRACE_INIT,
1689 "Supported video standard(s) reported by eeprom: %.*s",
1690 bcnt,buf);
1691
1692 hdw->std_mask_avail = hdw->std_mask_eeprom;
1693
1694 std2 = std1 & ~hdw->std_mask_avail;
1695 if (std2) {
1696 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
1697 pvr2_trace(PVR2_TRACE_INIT,
1698 "Expanding supported video standards"
1699 " to include: %.*s",
1700 bcnt,buf);
1701 hdw->std_mask_avail |= std2;
1702 }
1703
1704 pvr2_hdw_internal_set_std_avail(hdw);
1705
1706 if (std1) {
1707 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
1708 pvr2_trace(PVR2_TRACE_INIT,
1709 "Initial video standard forced to %.*s",
1710 bcnt,buf);
1711 hdw->std_mask_cur = std1;
1712 hdw->std_dirty = !0;
1713 pvr2_hdw_internal_find_stdenum(hdw);
1714 return;
1715 }
1716
1717 if (hdw->std_enum_cnt > 1) {
1718 // Autoselect the first listed standard
1719 hdw->std_enum_cur = 1;
1720 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1721 hdw->std_dirty = !0;
1722 pvr2_trace(PVR2_TRACE_INIT,
1723 "Initial video standard auto-selected to %s",
1724 hdw->std_defs[hdw->std_enum_cur-1].name);
1725 return;
1726 }
1727
Mike Isely0885ba12006-06-25 21:30:47 -03001728 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
Mike Iselyd8554972006-06-26 20:58:46 -03001729 "Unable to select a viable initial video standard");
1730}
1731
1732
1733static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1734{
1735 int ret;
1736 unsigned int idx;
1737 struct pvr2_ctrl *cptr;
1738 int reloadFl = 0;
1739 if (!reloadFl) {
1740 reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1741 == 0);
1742 if (reloadFl) {
1743 pvr2_trace(PVR2_TRACE_INIT,
1744 "USB endpoint config looks strange"
1745 "; possibly firmware needs to be loaded");
1746 }
1747 }
1748 if (!reloadFl) {
1749 reloadFl = !pvr2_hdw_check_firmware(hdw);
1750 if (reloadFl) {
1751 pvr2_trace(PVR2_TRACE_INIT,
1752 "Check for FX2 firmware failed"
1753 "; possibly firmware needs to be loaded");
1754 }
1755 }
1756 if (reloadFl) {
1757 if (pvr2_upload_firmware1(hdw) != 0) {
1758 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1759 "Failure uploading firmware1");
1760 }
1761 return;
1762 }
1763 hdw->fw1_state = FW1_STATE_OK;
1764
1765 if (initusbreset) {
1766 pvr2_hdw_device_reset(hdw);
1767 }
1768 if (!pvr2_hdw_dev_ok(hdw)) return;
1769
1770 for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) {
1771 request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]);
1772 }
1773
1774 pvr2_hdw_cmd_powerup(hdw);
1775 if (!pvr2_hdw_dev_ok(hdw)) return;
1776
1777 if (pvr2_upload_firmware2(hdw)){
1778 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
1779 pvr2_hdw_render_useless(hdw);
1780 return;
1781 }
1782
1783 // This step MUST happen after the earlier powerup step.
1784 pvr2_i2c_core_init(hdw);
1785 if (!pvr2_hdw_dev_ok(hdw)) return;
1786
Mike Iselyc05c0462006-06-25 20:04:25 -03001787 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001788 cptr = hdw->controls + idx;
1789 if (cptr->info->skip_init) continue;
1790 if (!cptr->info->set_value) continue;
1791 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1792 }
1793
Mike Isely1bde0282006-12-27 23:30:13 -03001794 /* Set up special default values for the television and radio
1795 frequencies here. It's not really important what these defaults
1796 are, but I set them to something usable in the Chicago area just
1797 to make driver testing a little easier. */
1798
1799 /* US Broadcast channel 7 (175.25 MHz) */
1800 hdw->freqValTelevision = 175250000L;
1801 /* 104.3 MHz, a usable FM station for my area */
1802 hdw->freqValRadio = 104300000L;
1803
1804 /* Default value for auto mode switch based on module option */
1805 if ((hdw->unit_number >= 0) && (hdw->unit_number < PVR_NUM)) {
1806 hdw->automodeswitch_val = auto_mode_switch[hdw->unit_number];
1807 }
1808
Mike Iselyd8554972006-06-26 20:58:46 -03001809 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1810 // thread-safe against the normal pvr2_send_request() mechanism.
1811 // (We should make it thread safe).
1812
1813 ret = pvr2_hdw_get_eeprom_addr(hdw);
1814 if (!pvr2_hdw_dev_ok(hdw)) return;
1815 if (ret < 0) {
1816 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1817 "Unable to determine location of eeprom, skipping");
1818 } else {
1819 hdw->eeprom_addr = ret;
1820 pvr2_eeprom_analyze(hdw);
1821 if (!pvr2_hdw_dev_ok(hdw)) return;
1822 }
1823
1824 pvr2_hdw_setup_std(hdw);
1825
1826 if (!get_default_tuner_type(hdw)) {
1827 pvr2_trace(PVR2_TRACE_INIT,
1828 "pvr2_hdw_setup: Tuner type overridden to %d",
1829 hdw->tuner_type);
1830 }
1831
1832 hdw->tuner_updated = !0;
1833 pvr2_i2c_core_check_stale(hdw);
1834 hdw->tuner_updated = 0;
1835
1836 if (!pvr2_hdw_dev_ok(hdw)) return;
1837
1838 pvr2_hdw_commit_ctl_internal(hdw);
1839 if (!pvr2_hdw_dev_ok(hdw)) return;
1840
1841 hdw->vid_stream = pvr2_stream_create();
1842 if (!pvr2_hdw_dev_ok(hdw)) return;
1843 pvr2_trace(PVR2_TRACE_INIT,
1844 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1845 if (hdw->vid_stream) {
1846 idx = get_default_error_tolerance(hdw);
1847 if (idx) {
1848 pvr2_trace(PVR2_TRACE_INIT,
1849 "pvr2_hdw_setup: video stream %p"
1850 " setting tolerance %u",
1851 hdw->vid_stream,idx);
1852 }
1853 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1854 PVR2_VID_ENDPOINT,idx);
1855 }
1856
1857 if (!pvr2_hdw_dev_ok(hdw)) return;
1858
1859 /* Make sure everything is up to date */
1860 pvr2_i2c_core_sync(hdw);
1861
1862 if (!pvr2_hdw_dev_ok(hdw)) return;
1863
1864 hdw->flag_init_ok = !0;
1865}
1866
1867
1868int pvr2_hdw_setup(struct pvr2_hdw *hdw)
1869{
1870 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
1871 LOCK_TAKE(hdw->big_lock); do {
1872 pvr2_hdw_setup_low(hdw);
1873 pvr2_trace(PVR2_TRACE_INIT,
1874 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
1875 hdw,hdw->flag_ok,hdw->flag_init_ok);
1876 if (pvr2_hdw_dev_ok(hdw)) {
1877 if (pvr2_hdw_init_ok(hdw)) {
1878 pvr2_trace(
1879 PVR2_TRACE_INFO,
1880 "Device initialization"
1881 " completed successfully.");
1882 break;
1883 }
1884 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1885 pvr2_trace(
1886 PVR2_TRACE_INFO,
1887 "Device microcontroller firmware"
1888 " (re)loaded; it should now reset"
1889 " and reconnect.");
1890 break;
1891 }
1892 pvr2_trace(
1893 PVR2_TRACE_ERROR_LEGS,
1894 "Device initialization was not successful.");
1895 if (hdw->fw1_state == FW1_STATE_MISSING) {
1896 pvr2_trace(
1897 PVR2_TRACE_ERROR_LEGS,
1898 "Giving up since device"
1899 " microcontroller firmware"
1900 " appears to be missing.");
1901 break;
1902 }
1903 }
1904 if (procreload) {
1905 pvr2_trace(
1906 PVR2_TRACE_ERROR_LEGS,
1907 "Attempting pvrusb2 recovery by reloading"
1908 " primary firmware.");
1909 pvr2_trace(
1910 PVR2_TRACE_ERROR_LEGS,
1911 "If this works, device should disconnect"
1912 " and reconnect in a sane state.");
1913 hdw->fw1_state = FW1_STATE_UNKNOWN;
1914 pvr2_upload_firmware1(hdw);
1915 } else {
1916 pvr2_trace(
1917 PVR2_TRACE_ERROR_LEGS,
1918 "***WARNING*** pvrusb2 device hardware"
1919 " appears to be jammed"
1920 " and I can't clear it.");
1921 pvr2_trace(
1922 PVR2_TRACE_ERROR_LEGS,
1923 "You might need to power cycle"
1924 " the pvrusb2 device"
1925 " in order to recover.");
1926 }
1927 } while (0); LOCK_GIVE(hdw->big_lock);
1928 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
1929 return hdw->flag_init_ok;
1930}
1931
1932
1933/* Create and return a structure for interacting with the underlying
1934 hardware */
1935struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1936 const struct usb_device_id *devid)
1937{
1938 unsigned int idx,cnt1,cnt2;
1939 struct pvr2_hdw *hdw;
1940 unsigned int hdw_type;
1941 int valid_std_mask;
1942 struct pvr2_ctrl *cptr;
1943 __u8 ifnum;
Mike Iselyb30d2442006-06-25 20:05:01 -03001944 struct v4l2_queryctrl qctrl;
1945 struct pvr2_ctl_info *ciptr;
Mike Iselyd8554972006-06-26 20:58:46 -03001946
1947 hdw_type = devid - pvr2_device_table;
1948 if (hdw_type >=
1949 sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) {
1950 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1951 "Bogus device type of %u reported",hdw_type);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001952 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001953 }
1954
1955 hdw = kmalloc(sizeof(*hdw),GFP_KERNEL);
1956 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
1957 hdw,pvr2_device_names[hdw_type]);
1958 if (!hdw) goto fail;
1959 memset(hdw,0,sizeof(*hdw));
Mike Iselyb30d2442006-06-25 20:05:01 -03001960 cx2341x_fill_defaults(&hdw->enc_ctl_state);
Mike Iselyd8554972006-06-26 20:58:46 -03001961
Mike Iselyc05c0462006-06-25 20:04:25 -03001962 hdw->control_cnt = CTRLDEF_COUNT;
Mike Iselyb30d2442006-06-25 20:05:01 -03001963 hdw->control_cnt += MPEGDEF_COUNT;
Mike Iselyc05c0462006-06-25 20:04:25 -03001964 hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001965 GFP_KERNEL);
1966 if (!hdw->controls) goto fail;
Mike Iselyc05c0462006-06-25 20:04:25 -03001967 memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * hdw->control_cnt);
Mike Iselyd8554972006-06-26 20:58:46 -03001968 hdw->hdw_type = hdw_type;
Mike Iselyc05c0462006-06-25 20:04:25 -03001969 for (idx = 0; idx < hdw->control_cnt; idx++) {
1970 cptr = hdw->controls + idx;
1971 cptr->hdw = hdw;
1972 }
Mike Iselyd8554972006-06-26 20:58:46 -03001973 for (idx = 0; idx < 32; idx++) {
1974 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1975 }
Mike Iselyc05c0462006-06-25 20:04:25 -03001976 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001977 cptr = hdw->controls + idx;
Mike Iselyd8554972006-06-26 20:58:46 -03001978 cptr->info = control_defs+idx;
1979 }
Mike Iselyb30d2442006-06-25 20:05:01 -03001980 /* Define and configure additional controls from cx2341x module. */
1981 hdw->mpeg_ctrl_info = kmalloc(
1982 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
1983 if (!hdw->mpeg_ctrl_info) goto fail;
1984 memset(hdw->mpeg_ctrl_info,0,
1985 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT);
1986 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
1987 cptr = hdw->controls + idx + CTRLDEF_COUNT;
1988 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
1989 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
1990 ciptr->name = mpeg_ids[idx].strid;
1991 ciptr->v4l_id = mpeg_ids[idx].id;
1992 ciptr->skip_init = !0;
1993 ciptr->get_value = ctrl_cx2341x_get;
1994 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
1995 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
1996 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
1997 qctrl.id = ciptr->v4l_id;
1998 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
1999 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
2000 ciptr->set_value = ctrl_cx2341x_set;
2001 }
2002 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
2003 PVR2_CTLD_INFO_DESC_SIZE);
2004 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
2005 ciptr->default_value = qctrl.default_value;
2006 switch (qctrl.type) {
2007 default:
2008 case V4L2_CTRL_TYPE_INTEGER:
2009 ciptr->type = pvr2_ctl_int;
2010 ciptr->def.type_int.min_value = qctrl.minimum;
2011 ciptr->def.type_int.max_value = qctrl.maximum;
2012 break;
2013 case V4L2_CTRL_TYPE_BOOLEAN:
2014 ciptr->type = pvr2_ctl_bool;
2015 break;
2016 case V4L2_CTRL_TYPE_MENU:
2017 ciptr->type = pvr2_ctl_enum;
2018 ciptr->def.type_enum.value_names =
2019 cx2341x_ctrl_get_menu(ciptr->v4l_id);
2020 for (cnt1 = 0;
2021 ciptr->def.type_enum.value_names[cnt1] != NULL;
2022 cnt1++) { }
2023 ciptr->def.type_enum.count = cnt1;
2024 break;
2025 }
2026 cptr->info = ciptr;
2027 }
Mike Iselyd8554972006-06-26 20:58:46 -03002028
2029 // Initialize video standard enum dynamic control
2030 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
2031 if (cptr) {
2032 memcpy(&hdw->std_info_enum,cptr->info,
2033 sizeof(hdw->std_info_enum));
2034 cptr->info = &hdw->std_info_enum;
2035
2036 }
2037 // Initialize control data regarding video standard masks
2038 valid_std_mask = pvr2_std_get_usable();
2039 for (idx = 0; idx < 32; idx++) {
2040 if (!(valid_std_mask & (1 << idx))) continue;
2041 cnt1 = pvr2_std_id_to_str(
2042 hdw->std_mask_names[idx],
2043 sizeof(hdw->std_mask_names[idx])-1,
2044 1 << idx);
2045 hdw->std_mask_names[idx][cnt1] = 0;
2046 }
2047 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
2048 if (cptr) {
2049 memcpy(&hdw->std_info_avail,cptr->info,
2050 sizeof(hdw->std_info_avail));
2051 cptr->info = &hdw->std_info_avail;
2052 hdw->std_info_avail.def.type_bitmask.bit_names =
2053 hdw->std_mask_ptrs;
2054 hdw->std_info_avail.def.type_bitmask.valid_bits =
2055 valid_std_mask;
2056 }
2057 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
2058 if (cptr) {
2059 memcpy(&hdw->std_info_cur,cptr->info,
2060 sizeof(hdw->std_info_cur));
2061 cptr->info = &hdw->std_info_cur;
2062 hdw->std_info_cur.def.type_bitmask.bit_names =
2063 hdw->std_mask_ptrs;
2064 hdw->std_info_avail.def.type_bitmask.valid_bits =
2065 valid_std_mask;
2066 }
2067
2068 hdw->eeprom_addr = -1;
2069 hdw->unit_number = -1;
Mike Isely80793842006-12-27 23:12:28 -03002070 hdw->v4l_minor_number_video = -1;
2071 hdw->v4l_minor_number_vbi = -1;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002072 hdw->v4l_minor_number_radio = -1;
Mike Iselyd8554972006-06-26 20:58:46 -03002073 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2074 if (!hdw->ctl_write_buffer) goto fail;
2075 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2076 if (!hdw->ctl_read_buffer) goto fail;
2077 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
2078 if (!hdw->ctl_write_urb) goto fail;
2079 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
2080 if (!hdw->ctl_read_urb) goto fail;
2081
2082 down(&pvr2_unit_sem); do {
2083 for (idx = 0; idx < PVR_NUM; idx++) {
2084 if (unit_pointers[idx]) continue;
2085 hdw->unit_number = idx;
2086 unit_pointers[idx] = hdw;
2087 break;
2088 }
2089 } while (0); up(&pvr2_unit_sem);
2090
2091 cnt1 = 0;
2092 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
2093 cnt1 += cnt2;
2094 if (hdw->unit_number >= 0) {
2095 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
2096 ('a' + hdw->unit_number));
2097 cnt1 += cnt2;
2098 }
2099 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
2100 hdw->name[cnt1] = 0;
2101
2102 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
2103 hdw->unit_number,hdw->name);
2104
2105 hdw->tuner_type = -1;
2106 hdw->flag_ok = !0;
2107 /* Initialize the mask of subsystems that we will shut down when we
2108 stop streaming. */
2109 hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
2110 hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
2111
2112 pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
2113 hdw->subsys_stream_mask);
2114
2115 hdw->usb_intf = intf;
2116 hdw->usb_dev = interface_to_usbdev(intf);
2117
2118 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2119 usb_set_interface(hdw->usb_dev,ifnum,0);
2120
2121 mutex_init(&hdw->ctl_lock_mutex);
2122 mutex_init(&hdw->big_lock_mutex);
2123
2124 return hdw;
2125 fail:
2126 if (hdw) {
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002127 usb_free_urb(hdw->ctl_read_urb);
2128 usb_free_urb(hdw->ctl_write_urb);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002129 kfree(hdw->ctl_read_buffer);
2130 kfree(hdw->ctl_write_buffer);
2131 kfree(hdw->controls);
2132 kfree(hdw->mpeg_ctrl_info);
Mike Iselyd8554972006-06-26 20:58:46 -03002133 kfree(hdw);
2134 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002135 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002136}
2137
2138
2139/* Remove _all_ associations between this driver and the underlying USB
2140 layer. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002141static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002142{
2143 if (hdw->flag_disconnected) return;
2144 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
2145 if (hdw->ctl_read_urb) {
2146 usb_kill_urb(hdw->ctl_read_urb);
2147 usb_free_urb(hdw->ctl_read_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002148 hdw->ctl_read_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002149 }
2150 if (hdw->ctl_write_urb) {
2151 usb_kill_urb(hdw->ctl_write_urb);
2152 usb_free_urb(hdw->ctl_write_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002153 hdw->ctl_write_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002154 }
2155 if (hdw->ctl_read_buffer) {
2156 kfree(hdw->ctl_read_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002157 hdw->ctl_read_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002158 }
2159 if (hdw->ctl_write_buffer) {
2160 kfree(hdw->ctl_write_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002161 hdw->ctl_write_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002162 }
2163 pvr2_hdw_render_useless_unlocked(hdw);
2164 hdw->flag_disconnected = !0;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002165 hdw->usb_dev = NULL;
2166 hdw->usb_intf = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002167}
2168
2169
2170/* Destroy hardware interaction structure */
2171void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2172{
2173 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
2174 if (hdw->fw_buffer) {
2175 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002176 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002177 }
2178 if (hdw->vid_stream) {
2179 pvr2_stream_destroy(hdw->vid_stream);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002180 hdw->vid_stream = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002181 }
2182 if (hdw->audio_stat) {
2183 hdw->audio_stat->detach(hdw->audio_stat->ctxt);
2184 }
2185 if (hdw->decoder_ctrl) {
2186 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2187 }
2188 pvr2_i2c_core_done(hdw);
2189 pvr2_hdw_remove_usb_stuff(hdw);
2190 down(&pvr2_unit_sem); do {
2191 if ((hdw->unit_number >= 0) &&
2192 (hdw->unit_number < PVR_NUM) &&
2193 (unit_pointers[hdw->unit_number] == hdw)) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002194 unit_pointers[hdw->unit_number] = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002195 }
2196 } while (0); up(&pvr2_unit_sem);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002197 kfree(hdw->controls);
2198 kfree(hdw->mpeg_ctrl_info);
2199 kfree(hdw->std_defs);
2200 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002201 kfree(hdw);
2202}
2203
2204
2205int pvr2_hdw_init_ok(struct pvr2_hdw *hdw)
2206{
2207 return hdw->flag_init_ok;
2208}
2209
2210
2211int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2212{
2213 return (hdw && hdw->flag_ok);
2214}
2215
2216
2217/* Called when hardware has been unplugged */
2218void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2219{
2220 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2221 LOCK_TAKE(hdw->big_lock);
2222 LOCK_TAKE(hdw->ctl_lock);
2223 pvr2_hdw_remove_usb_stuff(hdw);
2224 LOCK_GIVE(hdw->ctl_lock);
2225 LOCK_GIVE(hdw->big_lock);
2226}
2227
2228
2229// Attempt to autoselect an appropriate value for std_enum_cur given
2230// whatever is currently in std_mask_cur
Adrian Bunk07e337e2006-06-30 11:30:20 -03002231static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002232{
2233 unsigned int idx;
2234 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2235 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2236 hdw->std_enum_cur = idx;
2237 return;
2238 }
2239 }
2240 hdw->std_enum_cur = 0;
2241}
2242
2243
2244// Calculate correct set of enumerated standards based on currently known
2245// set of available standards bits.
Adrian Bunk07e337e2006-06-30 11:30:20 -03002246static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002247{
2248 struct v4l2_standard *newstd;
2249 unsigned int std_cnt;
2250 unsigned int idx;
2251
2252 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2253
2254 if (hdw->std_defs) {
2255 kfree(hdw->std_defs);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002256 hdw->std_defs = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002257 }
2258 hdw->std_enum_cnt = 0;
2259 if (hdw->std_enum_names) {
2260 kfree(hdw->std_enum_names);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002261 hdw->std_enum_names = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002262 }
2263
2264 if (!std_cnt) {
2265 pvr2_trace(
2266 PVR2_TRACE_ERROR_LEGS,
2267 "WARNING: Failed to identify any viable standards");
2268 }
2269 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2270 hdw->std_enum_names[0] = "none";
2271 for (idx = 0; idx < std_cnt; idx++) {
2272 hdw->std_enum_names[idx+1] =
2273 newstd[idx].name;
2274 }
2275 // Set up the dynamic control for this standard
2276 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2277 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2278 hdw->std_defs = newstd;
2279 hdw->std_enum_cnt = std_cnt+1;
2280 hdw->std_enum_cur = 0;
2281 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2282}
2283
2284
2285int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2286 struct v4l2_standard *std,
2287 unsigned int idx)
2288{
2289 int ret = -EINVAL;
2290 if (!idx) return ret;
2291 LOCK_TAKE(hdw->big_lock); do {
2292 if (idx >= hdw->std_enum_cnt) break;
2293 idx--;
2294 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2295 ret = 0;
2296 } while (0); LOCK_GIVE(hdw->big_lock);
2297 return ret;
2298}
2299
2300
2301/* Get the number of defined controls */
2302unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2303{
Mike Iselyc05c0462006-06-25 20:04:25 -03002304 return hdw->control_cnt;
Mike Iselyd8554972006-06-26 20:58:46 -03002305}
2306
2307
2308/* Retrieve a control handle given its index (0..count-1) */
2309struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2310 unsigned int idx)
2311{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002312 if (idx >= hdw->control_cnt) return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002313 return hdw->controls + idx;
2314}
2315
2316
2317/* Retrieve a control handle given its index (0..count-1) */
2318struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2319 unsigned int ctl_id)
2320{
2321 struct pvr2_ctrl *cptr;
2322 unsigned int idx;
2323 int i;
2324
2325 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002326 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002327 cptr = hdw->controls + idx;
2328 i = cptr->info->internal_id;
2329 if (i && (i == ctl_id)) return cptr;
2330 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002331 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002332}
2333
2334
Mike Iselya761f432006-06-25 20:04:44 -03002335/* Given a V4L ID, retrieve the control structure associated with it. */
Mike Iselyd8554972006-06-26 20:58:46 -03002336struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2337{
2338 struct pvr2_ctrl *cptr;
2339 unsigned int idx;
2340 int i;
2341
2342 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002343 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002344 cptr = hdw->controls + idx;
2345 i = cptr->info->v4l_id;
2346 if (i && (i == ctl_id)) return cptr;
2347 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002348 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002349}
2350
2351
Mike Iselya761f432006-06-25 20:04:44 -03002352/* Given a V4L ID for its immediate predecessor, retrieve the control
2353 structure associated with it. */
2354struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2355 unsigned int ctl_id)
2356{
2357 struct pvr2_ctrl *cptr,*cp2;
2358 unsigned int idx;
2359 int i;
2360
2361 /* This could be made a lot more efficient, but for now... */
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002362 cp2 = NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002363 for (idx = 0; idx < hdw->control_cnt; idx++) {
2364 cptr = hdw->controls + idx;
2365 i = cptr->info->v4l_id;
2366 if (!i) continue;
2367 if (i <= ctl_id) continue;
2368 if (cp2 && (cp2->info->v4l_id < i)) continue;
2369 cp2 = cptr;
2370 }
2371 return cp2;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002372 return NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002373}
2374
2375
Mike Iselyd8554972006-06-26 20:58:46 -03002376static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2377{
2378 switch (tp) {
2379 case pvr2_ctl_int: return "integer";
2380 case pvr2_ctl_enum: return "enum";
Mike Isely33213962006-06-25 20:04:40 -03002381 case pvr2_ctl_bool: return "boolean";
Mike Iselyd8554972006-06-26 20:58:46 -03002382 case pvr2_ctl_bitmask: return "bitmask";
2383 }
2384 return "";
2385}
2386
2387
2388/* Commit all control changes made up to this point. Subsystems can be
2389 indirectly affected by these changes. For a given set of things being
2390 committed, we'll clear the affected subsystem bits and then once we're
2391 done committing everything we'll make a request to restore the subsystem
2392 state(s) back to their previous value before this function was called.
2393 Thus we can automatically reconfigure affected pieces of the driver as
2394 controls are changed. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002395static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002396{
2397 unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
2398 unsigned long stale_subsys_mask = 0;
2399 unsigned int idx;
2400 struct pvr2_ctrl *cptr;
2401 int value;
2402 int commit_flag = 0;
2403 char buf[100];
2404 unsigned int bcnt,ccnt;
2405
Mike Iselyc05c0462006-06-25 20:04:25 -03002406 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002407 cptr = hdw->controls + idx;
2408 if (cptr->info->is_dirty == 0) continue;
2409 if (!cptr->info->is_dirty(cptr)) continue;
2410 if (!commit_flag) {
2411 commit_flag = !0;
2412 }
2413
2414 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2415 cptr->info->name);
2416 value = 0;
2417 cptr->info->get_value(cptr,&value);
2418 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2419 buf+bcnt,
2420 sizeof(buf)-bcnt,&ccnt);
2421 bcnt += ccnt;
2422 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2423 get_ctrl_typename(cptr->info->type));
2424 pvr2_trace(PVR2_TRACE_CTL,
2425 "/*--TRACE_COMMIT--*/ %.*s",
2426 bcnt,buf);
2427 }
2428
2429 if (!commit_flag) {
2430 /* Nothing has changed */
2431 return 0;
2432 }
2433
2434 /* When video standard changes, reset the hres and vres values -
2435 but if the user has pending changes there, then let the changes
2436 take priority. */
2437 if (hdw->std_dirty) {
2438 /* Rewrite the vertical resolution to be appropriate to the
2439 video standard that has been selected. */
2440 int nvres;
2441 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2442 nvres = 480;
2443 } else {
2444 nvres = 576;
2445 }
2446 if (nvres != hdw->res_ver_val) {
2447 hdw->res_ver_val = nvres;
2448 hdw->res_ver_dirty = !0;
2449 }
Mike Iselyd8554972006-06-26 20:58:46 -03002450 }
2451
2452 if (hdw->std_dirty ||
Mike Isely434449f2006-08-08 09:10:06 -03002453 hdw->enc_stale ||
2454 hdw->srate_dirty ||
2455 hdw->res_ver_dirty ||
2456 hdw->res_hor_dirty ||
Mike Iselyb46cfa82006-06-25 20:04:53 -03002457 0) {
Mike Iselyd8554972006-06-26 20:58:46 -03002458 /* If any of this changes, then the encoder needs to be
2459 reconfigured, and we need to reset the stream. */
2460 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
Mike Iselyd8554972006-06-26 20:58:46 -03002461 }
2462
Pantelis Koukousoulas275b2e22006-12-27 23:05:19 -03002463 if (hdw->input_dirty) {
2464 /* pk: If input changes to or from radio, then the encoder
2465 needs to be restarted (for ENC_MUTE_VIDEO to work) */
2466 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
2467 }
2468
2469
Mike Iselyb30d2442006-06-25 20:05:01 -03002470 if (hdw->srate_dirty) {
2471 /* Write new sample rate into control structure since
2472 * the master copy is stale. We must track srate
2473 * separate from the mpeg control structure because
2474 * other logic also uses this value. */
2475 struct v4l2_ext_controls cs;
2476 struct v4l2_ext_control c1;
2477 memset(&cs,0,sizeof(cs));
2478 memset(&c1,0,sizeof(c1));
2479 cs.controls = &c1;
2480 cs.count = 1;
2481 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2482 c1.value = hdw->srate_val;
2483 cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS);
2484 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002485
Mike Iselyd8554972006-06-26 20:58:46 -03002486 /* Scan i2c core at this point - before we clear all the dirty
2487 bits. Various parts of the i2c core will notice dirty bits as
2488 appropriate and arrange to broadcast or directly send updates to
2489 the client drivers in order to keep everything in sync */
2490 pvr2_i2c_core_check_stale(hdw);
2491
Mike Iselyc05c0462006-06-25 20:04:25 -03002492 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002493 cptr = hdw->controls + idx;
2494 if (!cptr->info->clear_dirty) continue;
2495 cptr->info->clear_dirty(cptr);
2496 }
2497
2498 /* Now execute i2c core update */
2499 pvr2_i2c_core_sync(hdw);
2500
2501 pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
2502 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
2503
2504 return 0;
2505}
2506
2507
2508int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2509{
2510 LOCK_TAKE(hdw->big_lock); do {
2511 pvr2_hdw_commit_ctl_internal(hdw);
2512 } while (0); LOCK_GIVE(hdw->big_lock);
2513 return 0;
2514}
2515
2516
2517void pvr2_hdw_poll(struct pvr2_hdw *hdw)
2518{
2519 LOCK_TAKE(hdw->big_lock); do {
2520 pvr2_i2c_core_sync(hdw);
2521 } while (0); LOCK_GIVE(hdw->big_lock);
2522}
2523
2524
2525void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
2526 void (*func)(void *),
2527 void *data)
2528{
2529 LOCK_TAKE(hdw->big_lock); do {
2530 hdw->poll_trigger_func = func;
2531 hdw->poll_trigger_data = data;
2532 } while (0); LOCK_GIVE(hdw->big_lock);
2533}
2534
2535
2536void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
2537{
2538 if (hdw->poll_trigger_func) {
2539 hdw->poll_trigger_func(hdw->poll_trigger_data);
2540 }
2541}
2542
Mike Iselyd8554972006-06-26 20:58:46 -03002543/* Return name for this driver instance */
2544const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2545{
2546 return hdw->name;
2547}
2548
2549
2550/* Return bit mask indicating signal status */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002551static unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002552{
2553 unsigned int msk = 0;
2554 switch (hdw->input_val) {
2555 case PVR2_CVAL_INPUT_TV:
2556 case PVR2_CVAL_INPUT_RADIO:
2557 if (hdw->decoder_ctrl &&
2558 hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) {
2559 msk |= PVR2_SIGNAL_OK;
2560 if (hdw->audio_stat &&
2561 hdw->audio_stat->status(hdw->audio_stat->ctxt)) {
2562 if (hdw->flag_stereo) {
2563 msk |= PVR2_SIGNAL_STEREO;
2564 }
2565 if (hdw->flag_bilingual) {
2566 msk |= PVR2_SIGNAL_SAP;
2567 }
2568 }
2569 }
2570 break;
2571 default:
2572 msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO;
2573 }
2574 return msk;
2575}
2576
2577
2578int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2579{
2580 int result;
2581 LOCK_TAKE(hdw->ctl_lock); do {
2582 hdw->cmd_buffer[0] = 0x0b;
2583 result = pvr2_send_request(hdw,
2584 hdw->cmd_buffer,1,
2585 hdw->cmd_buffer,1);
2586 if (result < 0) break;
2587 result = (hdw->cmd_buffer[0] != 0);
2588 } while(0); LOCK_GIVE(hdw->ctl_lock);
2589 return result;
2590}
2591
2592
2593/* Return bit mask indicating signal status */
2594unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw)
2595{
2596 unsigned int msk = 0;
2597 LOCK_TAKE(hdw->big_lock); do {
2598 msk = pvr2_hdw_get_signal_status_internal(hdw);
2599 } while (0); LOCK_GIVE(hdw->big_lock);
2600 return msk;
2601}
2602
2603
2604/* Get handle to video output stream */
2605struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2606{
2607 return hp->vid_stream;
2608}
2609
2610
2611void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2612{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002613 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002614 LOCK_TAKE(hdw->big_lock); do {
2615 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002616 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002617 pvr2_i2c_core_check_stale(hdw);
2618 hdw->log_requested = 0;
2619 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002620 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002621 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely4f1a3e52006-06-25 20:04:31 -03002622 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002623 } while (0); LOCK_GIVE(hdw->big_lock);
2624}
2625
2626void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
2627{
2628 int ret;
2629 u16 address;
2630 unsigned int pipe;
2631 LOCK_TAKE(hdw->big_lock); do {
2632 if ((hdw->fw_buffer == 0) == !enable_flag) break;
2633
2634 if (!enable_flag) {
2635 pvr2_trace(PVR2_TRACE_FIRMWARE,
2636 "Cleaning up after CPU firmware fetch");
2637 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002638 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002639 hdw->fw_size = 0;
2640 /* Now release the CPU. It will disconnect and
2641 reconnect later. */
2642 pvr2_hdw_cpureset_assert(hdw,0);
2643 break;
2644 }
2645
2646 pvr2_trace(PVR2_TRACE_FIRMWARE,
2647 "Preparing to suck out CPU firmware");
2648 hdw->fw_size = 0x2000;
2649 hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL);
2650 if (!hdw->fw_buffer) {
2651 hdw->fw_size = 0;
2652 break;
2653 }
2654
2655 memset(hdw->fw_buffer,0,hdw->fw_size);
2656
2657 /* We have to hold the CPU during firmware upload. */
2658 pvr2_hdw_cpureset_assert(hdw,1);
2659
2660 /* download the firmware from address 0000-1fff in 2048
2661 (=0x800) bytes chunk. */
2662
2663 pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
2664 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2665 for(address = 0; address < hdw->fw_size; address += 0x800) {
2666 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
2667 address,0,
2668 hdw->fw_buffer+address,0x800,HZ);
2669 if (ret < 0) break;
2670 }
2671
2672 pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
2673
2674 } while (0); LOCK_GIVE(hdw->big_lock);
2675}
2676
2677
2678/* Return true if we're in a mode for retrieval CPU firmware */
2679int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2680{
2681 return hdw->fw_buffer != 0;
2682}
2683
2684
2685int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2686 char *buf,unsigned int cnt)
2687{
2688 int ret = -EINVAL;
2689 LOCK_TAKE(hdw->big_lock); do {
2690 if (!buf) break;
2691 if (!cnt) break;
2692
2693 if (!hdw->fw_buffer) {
2694 ret = -EIO;
2695 break;
2696 }
2697
2698 if (offs >= hdw->fw_size) {
2699 pvr2_trace(PVR2_TRACE_FIRMWARE,
2700 "Read firmware data offs=%d EOF",
2701 offs);
2702 ret = 0;
2703 break;
2704 }
2705
2706 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2707
2708 memcpy(buf,hdw->fw_buffer+offs,cnt);
2709
2710 pvr2_trace(PVR2_TRACE_FIRMWARE,
2711 "Read firmware data offs=%d cnt=%d",
2712 offs,cnt);
2713 ret = cnt;
2714 } while (0); LOCK_GIVE(hdw->big_lock);
2715
2716 return ret;
2717}
2718
2719
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002720int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002721 enum pvr2_v4l_type index)
Mike Iselyd8554972006-06-26 20:58:46 -03002722{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002723 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002724 case pvr2_v4l_type_video: return hdw->v4l_minor_number_video;
2725 case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi;
2726 case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002727 default: return -1;
2728 }
Mike Iselyd8554972006-06-26 20:58:46 -03002729}
2730
2731
Pantelis Koukousoulas2fdf3d92006-12-27 23:07:58 -03002732/* Store a v4l minor device number */
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002733void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002734 enum pvr2_v4l_type index,int v)
Mike Iselyd8554972006-06-26 20:58:46 -03002735{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002736 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002737 case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
2738 case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
2739 case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002740 default: break;
2741 }
Mike Iselyd8554972006-06-26 20:58:46 -03002742}
2743
2744
David Howells7d12e782006-10-05 14:55:46 +01002745static void pvr2_ctl_write_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002746{
2747 struct pvr2_hdw *hdw = urb->context;
2748 hdw->ctl_write_pend_flag = 0;
2749 if (hdw->ctl_read_pend_flag) return;
2750 complete(&hdw->ctl_done);
2751}
2752
2753
David Howells7d12e782006-10-05 14:55:46 +01002754static void pvr2_ctl_read_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002755{
2756 struct pvr2_hdw *hdw = urb->context;
2757 hdw->ctl_read_pend_flag = 0;
2758 if (hdw->ctl_write_pend_flag) return;
2759 complete(&hdw->ctl_done);
2760}
2761
2762
2763static void pvr2_ctl_timeout(unsigned long data)
2764{
2765 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2766 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2767 hdw->ctl_timeout_flag = !0;
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002768 if (hdw->ctl_write_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002769 usb_unlink_urb(hdw->ctl_write_urb);
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002770 if (hdw->ctl_read_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002771 usb_unlink_urb(hdw->ctl_read_urb);
Mike Iselyd8554972006-06-26 20:58:46 -03002772 }
2773}
2774
2775
Mike Iselye61b6fc2006-07-18 22:42:18 -03002776/* Issue a command and get a response from the device. This extended
2777 version includes a probe flag (which if set means that device errors
2778 should not be logged or treated as fatal) and a timeout in jiffies.
2779 This can be used to non-lethally probe the health of endpoint 1. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002780static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2781 unsigned int timeout,int probe_fl,
2782 void *write_data,unsigned int write_len,
2783 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002784{
2785 unsigned int idx;
2786 int status = 0;
2787 struct timer_list timer;
2788 if (!hdw->ctl_lock_held) {
2789 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2790 "Attempted to execute control transfer"
2791 " without lock!!");
2792 return -EDEADLK;
2793 }
2794 if ((!hdw->flag_ok) && !probe_fl) {
2795 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2796 "Attempted to execute control transfer"
2797 " when device not ok");
2798 return -EIO;
2799 }
2800 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2801 if (!probe_fl) {
2802 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2803 "Attempted to execute control transfer"
2804 " when USB is disconnected");
2805 }
2806 return -ENOTTY;
2807 }
2808
2809 /* Ensure that we have sane parameters */
2810 if (!write_data) write_len = 0;
2811 if (!read_data) read_len = 0;
2812 if (write_len > PVR2_CTL_BUFFSIZE) {
2813 pvr2_trace(
2814 PVR2_TRACE_ERROR_LEGS,
2815 "Attempted to execute %d byte"
2816 " control-write transfer (limit=%d)",
2817 write_len,PVR2_CTL_BUFFSIZE);
2818 return -EINVAL;
2819 }
2820 if (read_len > PVR2_CTL_BUFFSIZE) {
2821 pvr2_trace(
2822 PVR2_TRACE_ERROR_LEGS,
2823 "Attempted to execute %d byte"
2824 " control-read transfer (limit=%d)",
2825 write_len,PVR2_CTL_BUFFSIZE);
2826 return -EINVAL;
2827 }
2828 if ((!write_len) && (!read_len)) {
2829 pvr2_trace(
2830 PVR2_TRACE_ERROR_LEGS,
2831 "Attempted to execute null control transfer?");
2832 return -EINVAL;
2833 }
2834
2835
2836 hdw->cmd_debug_state = 1;
2837 if (write_len) {
2838 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2839 } else {
2840 hdw->cmd_debug_code = 0;
2841 }
2842 hdw->cmd_debug_write_len = write_len;
2843 hdw->cmd_debug_read_len = read_len;
2844
2845 /* Initialize common stuff */
2846 init_completion(&hdw->ctl_done);
2847 hdw->ctl_timeout_flag = 0;
2848 hdw->ctl_write_pend_flag = 0;
2849 hdw->ctl_read_pend_flag = 0;
2850 init_timer(&timer);
2851 timer.expires = jiffies + timeout;
2852 timer.data = (unsigned long)hdw;
2853 timer.function = pvr2_ctl_timeout;
2854
2855 if (write_len) {
2856 hdw->cmd_debug_state = 2;
2857 /* Transfer write data to internal buffer */
2858 for (idx = 0; idx < write_len; idx++) {
2859 hdw->ctl_write_buffer[idx] =
2860 ((unsigned char *)write_data)[idx];
2861 }
2862 /* Initiate a write request */
2863 usb_fill_bulk_urb(hdw->ctl_write_urb,
2864 hdw->usb_dev,
2865 usb_sndbulkpipe(hdw->usb_dev,
2866 PVR2_CTL_WRITE_ENDPOINT),
2867 hdw->ctl_write_buffer,
2868 write_len,
2869 pvr2_ctl_write_complete,
2870 hdw);
2871 hdw->ctl_write_urb->actual_length = 0;
2872 hdw->ctl_write_pend_flag = !0;
2873 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2874 if (status < 0) {
2875 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2876 "Failed to submit write-control"
2877 " URB status=%d",status);
2878 hdw->ctl_write_pend_flag = 0;
2879 goto done;
2880 }
2881 }
2882
2883 if (read_len) {
2884 hdw->cmd_debug_state = 3;
2885 memset(hdw->ctl_read_buffer,0x43,read_len);
2886 /* Initiate a read request */
2887 usb_fill_bulk_urb(hdw->ctl_read_urb,
2888 hdw->usb_dev,
2889 usb_rcvbulkpipe(hdw->usb_dev,
2890 PVR2_CTL_READ_ENDPOINT),
2891 hdw->ctl_read_buffer,
2892 read_len,
2893 pvr2_ctl_read_complete,
2894 hdw);
2895 hdw->ctl_read_urb->actual_length = 0;
2896 hdw->ctl_read_pend_flag = !0;
2897 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
2898 if (status < 0) {
2899 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2900 "Failed to submit read-control"
2901 " URB status=%d",status);
2902 hdw->ctl_read_pend_flag = 0;
2903 goto done;
2904 }
2905 }
2906
2907 /* Start timer */
2908 add_timer(&timer);
2909
2910 /* Now wait for all I/O to complete */
2911 hdw->cmd_debug_state = 4;
2912 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2913 wait_for_completion(&hdw->ctl_done);
2914 }
2915 hdw->cmd_debug_state = 5;
2916
2917 /* Stop timer */
2918 del_timer_sync(&timer);
2919
2920 hdw->cmd_debug_state = 6;
2921 status = 0;
2922
2923 if (hdw->ctl_timeout_flag) {
2924 status = -ETIMEDOUT;
2925 if (!probe_fl) {
2926 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2927 "Timed out control-write");
2928 }
2929 goto done;
2930 }
2931
2932 if (write_len) {
2933 /* Validate results of write request */
2934 if ((hdw->ctl_write_urb->status != 0) &&
2935 (hdw->ctl_write_urb->status != -ENOENT) &&
2936 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
2937 (hdw->ctl_write_urb->status != -ECONNRESET)) {
2938 /* USB subsystem is reporting some kind of failure
2939 on the write */
2940 status = hdw->ctl_write_urb->status;
2941 if (!probe_fl) {
2942 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2943 "control-write URB failure,"
2944 " status=%d",
2945 status);
2946 }
2947 goto done;
2948 }
2949 if (hdw->ctl_write_urb->actual_length < write_len) {
2950 /* Failed to write enough data */
2951 status = -EIO;
2952 if (!probe_fl) {
2953 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2954 "control-write URB short,"
2955 " expected=%d got=%d",
2956 write_len,
2957 hdw->ctl_write_urb->actual_length);
2958 }
2959 goto done;
2960 }
2961 }
2962 if (read_len) {
2963 /* Validate results of read request */
2964 if ((hdw->ctl_read_urb->status != 0) &&
2965 (hdw->ctl_read_urb->status != -ENOENT) &&
2966 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
2967 (hdw->ctl_read_urb->status != -ECONNRESET)) {
2968 /* USB subsystem is reporting some kind of failure
2969 on the read */
2970 status = hdw->ctl_read_urb->status;
2971 if (!probe_fl) {
2972 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2973 "control-read URB failure,"
2974 " status=%d",
2975 status);
2976 }
2977 goto done;
2978 }
2979 if (hdw->ctl_read_urb->actual_length < read_len) {
2980 /* Failed to read enough data */
2981 status = -EIO;
2982 if (!probe_fl) {
2983 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2984 "control-read URB short,"
2985 " expected=%d got=%d",
2986 read_len,
2987 hdw->ctl_read_urb->actual_length);
2988 }
2989 goto done;
2990 }
2991 /* Transfer retrieved data out from internal buffer */
2992 for (idx = 0; idx < read_len; idx++) {
2993 ((unsigned char *)read_data)[idx] =
2994 hdw->ctl_read_buffer[idx];
2995 }
2996 }
2997
2998 done:
2999
3000 hdw->cmd_debug_state = 0;
3001 if ((status < 0) && (!probe_fl)) {
3002 pvr2_hdw_render_useless_unlocked(hdw);
3003 }
3004 return status;
3005}
3006
3007
3008int pvr2_send_request(struct pvr2_hdw *hdw,
3009 void *write_data,unsigned int write_len,
3010 void *read_data,unsigned int read_len)
3011{
3012 return pvr2_send_request_ex(hdw,HZ*4,0,
3013 write_data,write_len,
3014 read_data,read_len);
3015}
3016
3017int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
3018{
3019 int ret;
3020
3021 LOCK_TAKE(hdw->ctl_lock);
3022
3023 hdw->cmd_buffer[0] = 0x04; /* write register prefix */
3024 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
3025 hdw->cmd_buffer[5] = 0;
3026 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3027 hdw->cmd_buffer[7] = reg & 0xff;
3028
3029
3030 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
3031
3032 LOCK_GIVE(hdw->ctl_lock);
3033
3034 return ret;
3035}
3036
3037
Adrian Bunk07e337e2006-06-30 11:30:20 -03003038static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03003039{
3040 int ret = 0;
3041
3042 LOCK_TAKE(hdw->ctl_lock);
3043
3044 hdw->cmd_buffer[0] = 0x05; /* read register prefix */
3045 hdw->cmd_buffer[1] = 0;
3046 hdw->cmd_buffer[2] = 0;
3047 hdw->cmd_buffer[3] = 0;
3048 hdw->cmd_buffer[4] = 0;
3049 hdw->cmd_buffer[5] = 0;
3050 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3051 hdw->cmd_buffer[7] = reg & 0xff;
3052
3053 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
3054 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
3055
3056 LOCK_GIVE(hdw->ctl_lock);
3057
3058 return ret;
3059}
3060
3061
Adrian Bunk07e337e2006-06-30 11:30:20 -03003062static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03003063{
3064 int ret;
3065
3066 LOCK_TAKE(hdw->ctl_lock);
3067
3068 hdw->cmd_buffer[0] = (data >> 8) & 0xff;
3069 hdw->cmd_buffer[1] = data & 0xff;
3070
3071 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
3072
3073 LOCK_GIVE(hdw->ctl_lock);
3074
3075 return ret;
3076}
3077
3078
Adrian Bunk07e337e2006-06-30 11:30:20 -03003079static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03003080{
3081 int ret;
3082
3083 LOCK_TAKE(hdw->ctl_lock);
3084
3085 hdw->cmd_buffer[0] = data;
3086
3087 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
3088
3089 LOCK_GIVE(hdw->ctl_lock);
3090
3091 return ret;
3092}
3093
3094
Adrian Bunk07e337e2006-06-30 11:30:20 -03003095static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003096{
3097 if (!hdw->flag_ok) return;
3098 pvr2_trace(PVR2_TRACE_INIT,"render_useless");
3099 hdw->flag_ok = 0;
3100 if (hdw->vid_stream) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003101 pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003102 }
3103 hdw->flag_streaming_enabled = 0;
3104 hdw->subsys_enabled_mask = 0;
3105}
3106
3107
3108void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
3109{
3110 LOCK_TAKE(hdw->ctl_lock);
3111 pvr2_hdw_render_useless_unlocked(hdw);
3112 LOCK_GIVE(hdw->ctl_lock);
3113}
3114
3115
3116void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
3117{
3118 int ret;
3119 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003120 ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -03003121 if (ret == 1) {
3122 ret = usb_reset_device(hdw->usb_dev);
3123 usb_unlock_device(hdw->usb_dev);
3124 } else {
3125 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3126 "Failed to lock USB device ret=%d",ret);
3127 }
3128 if (init_pause_msec) {
3129 pvr2_trace(PVR2_TRACE_INFO,
3130 "Waiting %u msec for hardware to settle",
3131 init_pause_msec);
3132 msleep(init_pause_msec);
3133 }
3134
3135}
3136
3137
3138void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
3139{
3140 char da[1];
3141 unsigned int pipe;
3142 int ret;
3143
3144 if (!hdw->usb_dev) return;
3145
3146 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
3147
3148 da[0] = val ? 0x01 : 0x00;
3149
3150 /* Write the CPUCS register on the 8051. The lsb of the register
3151 is the reset bit; a 1 asserts reset while a 0 clears it. */
3152 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
3153 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
3154 if (ret < 0) {
3155 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3156 "cpureset_assert(%d) error=%d",val,ret);
3157 pvr2_hdw_render_useless(hdw);
3158 }
3159}
3160
3161
3162int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
3163{
3164 int status;
3165 LOCK_TAKE(hdw->ctl_lock); do {
3166 pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
3167 hdw->flag_ok = !0;
3168 hdw->cmd_buffer[0] = 0xdd;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003169 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003170 } while (0); LOCK_GIVE(hdw->ctl_lock);
3171 return status;
3172}
3173
3174
3175int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
3176{
3177 int status;
3178 LOCK_TAKE(hdw->ctl_lock); do {
3179 pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
3180 hdw->cmd_buffer[0] = 0xde;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003181 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003182 } while (0); LOCK_GIVE(hdw->ctl_lock);
3183 return status;
3184}
3185
3186
3187int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
3188{
3189 if (!hdw->decoder_ctrl) {
3190 pvr2_trace(PVR2_TRACE_INIT,
3191 "Unable to reset decoder: nothing attached");
3192 return -ENOTTY;
3193 }
3194
3195 if (!hdw->decoder_ctrl->force_reset) {
3196 pvr2_trace(PVR2_TRACE_INIT,
3197 "Unable to reset decoder: not implemented");
3198 return -ENOTTY;
3199 }
3200
3201 pvr2_trace(PVR2_TRACE_INIT,
3202 "Requesting decoder reset");
3203 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
3204 return 0;
3205}
3206
3207
Mike Iselye61b6fc2006-07-18 22:42:18 -03003208/* Stop / start video stream transport */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003209static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03003210{
3211 int status;
3212 LOCK_TAKE(hdw->ctl_lock); do {
3213 hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003214 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003215 } while (0); LOCK_GIVE(hdw->ctl_lock);
3216 if (!status) {
3217 hdw->subsys_enabled_mask =
3218 ((hdw->subsys_enabled_mask &
3219 ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
3220 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
3221 }
3222 return status;
3223}
3224
3225
3226void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
3227 struct pvr2_hdw_debug_info *ptr)
3228{
3229 ptr->big_lock_held = hdw->big_lock_held;
3230 ptr->ctl_lock_held = hdw->ctl_lock_held;
3231 ptr->flag_ok = hdw->flag_ok;
3232 ptr->flag_disconnected = hdw->flag_disconnected;
3233 ptr->flag_init_ok = hdw->flag_init_ok;
3234 ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
3235 ptr->subsys_flags = hdw->subsys_enabled_mask;
3236 ptr->cmd_debug_state = hdw->cmd_debug_state;
3237 ptr->cmd_code = hdw->cmd_debug_code;
3238 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
3239 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
3240 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
3241 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
3242 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
3243 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
3244 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
3245}
3246
3247
3248int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
3249{
3250 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
3251}
3252
3253
3254int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
3255{
3256 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
3257}
3258
3259
3260int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
3261{
3262 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
3263}
3264
3265
3266int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
3267{
3268 u32 cval,nval;
3269 int ret;
3270 if (~msk) {
3271 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
3272 if (ret) return ret;
3273 nval = (cval & ~msk) | (val & msk);
3274 pvr2_trace(PVR2_TRACE_GPIO,
3275 "GPIO direction changing 0x%x:0x%x"
3276 " from 0x%x to 0x%x",
3277 msk,val,cval,nval);
3278 } else {
3279 nval = val;
3280 pvr2_trace(PVR2_TRACE_GPIO,
3281 "GPIO direction changing to 0x%x",nval);
3282 }
3283 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
3284}
3285
3286
3287int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
3288{
3289 u32 cval,nval;
3290 int ret;
3291 if (~msk) {
3292 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
3293 if (ret) return ret;
3294 nval = (cval & ~msk) | (val & msk);
3295 pvr2_trace(PVR2_TRACE_GPIO,
3296 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
3297 msk,val,cval,nval);
3298 } else {
3299 nval = val;
3300 pvr2_trace(PVR2_TRACE_GPIO,
3301 "GPIO output changing to 0x%x",nval);
3302 }
3303 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
3304}
3305
3306
Mike Iselye61b6fc2006-07-18 22:42:18 -03003307/* Find I2C address of eeprom */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003308static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003309{
3310 int result;
3311 LOCK_TAKE(hdw->ctl_lock); do {
3312 hdw->cmd_buffer[0] = 0xeb;
3313 result = pvr2_send_request(hdw,
3314 hdw->cmd_buffer,1,
3315 hdw->cmd_buffer,1);
3316 if (result < 0) break;
3317 result = hdw->cmd_buffer[0];
3318 } while(0); LOCK_GIVE(hdw->ctl_lock);
3319 return result;
3320}
3321
3322
Mike Isely32ffa9a2006-09-23 22:26:52 -03003323int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
3324 u32 chip_id,unsigned long reg_id,
3325 int setFl,u32 *val_ptr)
3326{
3327#ifdef CONFIG_VIDEO_ADV_DEBUG
3328 struct list_head *item;
3329 struct pvr2_i2c_client *cp;
3330 struct v4l2_register req;
Mike Isely6d988162006-09-28 17:53:49 -03003331 int stat = 0;
3332 int okFl = 0;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003333
3334 req.i2c_id = chip_id;
3335 req.reg = reg_id;
3336 if (setFl) req.val = *val_ptr;
3337 mutex_lock(&hdw->i2c_list_lock); do {
3338 list_for_each(item,&hdw->i2c_clients) {
3339 cp = list_entry(item,struct pvr2_i2c_client,list);
3340 if (cp->client->driver->id != chip_id) continue;
3341 stat = pvr2_i2c_client_cmd(
3342 cp,(setFl ? VIDIOC_INT_S_REGISTER :
3343 VIDIOC_INT_G_REGISTER),&req);
3344 if (!setFl) *val_ptr = req.val;
Mike Isely6d988162006-09-28 17:53:49 -03003345 okFl = !0;
3346 break;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003347 }
3348 } while (0); mutex_unlock(&hdw->i2c_list_lock);
Mike Isely6d988162006-09-28 17:53:49 -03003349 if (okFl) {
3350 return stat;
3351 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03003352 return -EINVAL;
3353#else
3354 return -ENOSYS;
3355#endif
3356}
3357
3358
Mike Iselyd8554972006-06-26 20:58:46 -03003359/*
3360 Stuff for Emacs to see, in order to encourage consistent editing style:
3361 *** Local Variables: ***
3362 *** mode: c ***
3363 *** fill-column: 75 ***
3364 *** tab-width: 8 ***
3365 *** c-basic-offset: 8 ***
3366 *** End: ***
3367 */