blob: 11890a0a72af5417a8ce7b0a0ee108574788a8fc [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 };
97static int init_pause_msec = 0;
98
99module_param(ctlchg, int, S_IRUGO|S_IWUSR);
100MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
101module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
102MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
103module_param(initusbreset, int, S_IRUGO|S_IWUSR);
104MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
105module_param(procreload, int, S_IRUGO|S_IWUSR);
106MODULE_PARM_DESC(procreload,
107 "Attempt init failure recovery with firmware reload");
108module_param_array(tuner, int, NULL, 0444);
109MODULE_PARM_DESC(tuner,"specify installed tuner type");
110module_param_array(video_std, int, NULL, 0444);
111MODULE_PARM_DESC(video_std,"specify initial video standard");
112module_param_array(tolerance, int, NULL, 0444);
113MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
114
115#define PVR2_CTL_WRITE_ENDPOINT 0x01
116#define PVR2_CTL_READ_ENDPOINT 0x81
117
118#define PVR2_GPIO_IN 0x9008
119#define PVR2_GPIO_OUT 0x900c
120#define PVR2_GPIO_DIR 0x9020
121
122#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
123
124#define PVR2_FIRMWARE_ENDPOINT 0x02
125
126/* size of a firmware chunk */
127#define FIRMWARE_CHUNK_SIZE 0x2000
128
Mike Iselyb30d2442006-06-25 20:05:01 -0300129/* Define the list of additional controls we'll dynamically construct based
130 on query of the cx2341x module. */
131struct pvr2_mpeg_ids {
132 const char *strid;
133 int id;
134};
135static const struct pvr2_mpeg_ids mpeg_ids[] = {
136 {
137 .strid = "audio_layer",
138 .id = V4L2_CID_MPEG_AUDIO_ENCODING,
139 },{
140 .strid = "audio_bitrate",
141 .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE,
142 },{
143 /* Already using audio_mode elsewhere :-( */
144 .strid = "mpeg_audio_mode",
145 .id = V4L2_CID_MPEG_AUDIO_MODE,
146 },{
147 .strid = "mpeg_audio_mode_extension",
148 .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
149 },{
150 .strid = "audio_emphasis",
151 .id = V4L2_CID_MPEG_AUDIO_EMPHASIS,
152 },{
153 .strid = "audio_crc",
154 .id = V4L2_CID_MPEG_AUDIO_CRC,
155 },{
156 .strid = "video_aspect",
157 .id = V4L2_CID_MPEG_VIDEO_ASPECT,
158 },{
159 .strid = "video_b_frames",
160 .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
161 },{
162 .strid = "video_gop_size",
163 .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
164 },{
165 .strid = "video_gop_closure",
166 .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
167 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300168 .strid = "video_bitrate_mode",
169 .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
170 },{
171 .strid = "video_bitrate",
172 .id = V4L2_CID_MPEG_VIDEO_BITRATE,
173 },{
174 .strid = "video_bitrate_peak",
175 .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
176 },{
177 .strid = "video_temporal_decimation",
178 .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
179 },{
180 .strid = "stream_type",
181 .id = V4L2_CID_MPEG_STREAM_TYPE,
182 },{
183 .strid = "video_spatial_filter_mode",
184 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
185 },{
186 .strid = "video_spatial_filter",
187 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
188 },{
189 .strid = "video_luma_spatial_filter_type",
190 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
191 },{
192 .strid = "video_chroma_spatial_filter_type",
193 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
194 },{
195 .strid = "video_temporal_filter_mode",
196 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
197 },{
198 .strid = "video_temporal_filter",
199 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
200 },{
201 .strid = "video_median_filter_type",
202 .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
203 },{
204 .strid = "video_luma_median_filter_top",
205 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
206 },{
207 .strid = "video_luma_median_filter_bottom",
208 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
209 },{
210 .strid = "video_chroma_median_filter_top",
211 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
212 },{
213 .strid = "video_chroma_median_filter_bottom",
214 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
215 }
216};
217#define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0]))
Mike Iselyc05c0462006-06-25 20:04:25 -0300218
Mike Iselyd8554972006-06-26 20:58:46 -0300219
Mike Isely434449f2006-08-08 09:10:06 -0300220static const char *control_values_srate[] = {
221 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100] = "44.1 kHz",
222 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000] = "48 kHz",
223 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000] = "32 kHz",
224};
Mike Iselyd8554972006-06-26 20:58:46 -0300225
Mike Iselyd8554972006-06-26 20:58:46 -0300226
227
228static const char *control_values_input[] = {
229 [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
230 [PVR2_CVAL_INPUT_RADIO] = "radio",
231 [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
232 [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
233};
234
235
236static const char *control_values_audiomode[] = {
237 [V4L2_TUNER_MODE_MONO] = "Mono",
238 [V4L2_TUNER_MODE_STEREO] = "Stereo",
239 [V4L2_TUNER_MODE_LANG1] = "Lang1",
240 [V4L2_TUNER_MODE_LANG2] = "Lang2",
241 [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
242};
243
244
245static const char *control_values_hsm[] = {
246 [PVR2_CVAL_HSM_FAIL] = "Fail",
247 [PVR2_CVAL_HSM_HIGH] = "High",
248 [PVR2_CVAL_HSM_FULL] = "Full",
249};
250
251
252static const char *control_values_subsystem[] = {
253 [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware",
254 [PVR2_SUBSYS_B_ENC_CFG] = "enc_config",
255 [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run",
256 [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run",
257 [PVR2_SUBSYS_B_ENC_RUN] = "enc_run",
258};
259
Mike Isely1bde0282006-12-27 23:30:13 -0300260static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300261static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
262static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw);
263static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300264static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
265static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
266static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw);
267static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
268 unsigned long msk,
269 unsigned long val);
270static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
271 unsigned long msk,
272 unsigned long val);
273static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
274 unsigned int timeout,int probe_fl,
275 void *write_data,unsigned int write_len,
276 void *read_data,unsigned int read_len);
277static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res);
278static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res);
Mike Iselyd8554972006-06-26 20:58:46 -0300279
280static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
281{
282 struct pvr2_hdw *hdw = cptr->hdw;
283 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
284 *vp = hdw->freqTable[hdw->freqProgSlot-1];
285 } else {
286 *vp = 0;
287 }
288 return 0;
289}
290
291static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
292{
293 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300294 unsigned int slotId = hdw->freqProgSlot;
295 if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) {
296 hdw->freqTable[slotId-1] = v;
297 /* Handle side effects correctly - if we're tuned to this
298 slot, then forgot the slot id relation since the stored
299 frequency has been changed. */
300 if (hdw->freqSelector) {
301 if (hdw->freqSlotRadio == slotId) {
302 hdw->freqSlotRadio = 0;
303 }
304 } else {
305 if (hdw->freqSlotTelevision == slotId) {
306 hdw->freqSlotTelevision = 0;
307 }
308 }
Mike Iselyd8554972006-06-26 20:58:46 -0300309 }
310 return 0;
311}
312
313static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
314{
315 *vp = cptr->hdw->freqProgSlot;
316 return 0;
317}
318
319static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
320{
321 struct pvr2_hdw *hdw = cptr->hdw;
322 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
323 hdw->freqProgSlot = v;
324 }
325 return 0;
326}
327
328static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
329{
Mike Isely1bde0282006-12-27 23:30:13 -0300330 struct pvr2_hdw *hdw = cptr->hdw;
331 *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision;
Mike Iselyd8554972006-06-26 20:58:46 -0300332 return 0;
333}
334
Mike Isely1bde0282006-12-27 23:30:13 -0300335static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId)
Mike Iselyd8554972006-06-26 20:58:46 -0300336{
337 unsigned freq = 0;
338 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300339 if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0;
340 if (slotId > 0) {
341 freq = hdw->freqTable[slotId-1];
342 if (!freq) return 0;
343 pvr2_hdw_set_cur_freq(hdw,freq);
Mike Iselyd8554972006-06-26 20:58:46 -0300344 }
Mike Isely1bde0282006-12-27 23:30:13 -0300345 if (hdw->freqSelector) {
346 hdw->freqSlotRadio = slotId;
347 } else {
348 hdw->freqSlotTelevision = slotId;
Mike Iselyd8554972006-06-26 20:58:46 -0300349 }
350 return 0;
351}
352
353static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
354{
Mike Isely1bde0282006-12-27 23:30:13 -0300355 *vp = pvr2_hdw_get_cur_freq(cptr->hdw);
Mike Iselyd8554972006-06-26 20:58:46 -0300356 return 0;
357}
358
359static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
360{
361 return cptr->hdw->freqDirty != 0;
362}
363
364static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
365{
366 cptr->hdw->freqDirty = 0;
367}
368
369static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
370{
Mike Isely1bde0282006-12-27 23:30:13 -0300371 pvr2_hdw_set_cur_freq(cptr->hdw,v);
Mike Iselyd8554972006-06-26 20:58:46 -0300372 return 0;
373}
374
Mike Isely3ad9fc32006-09-02 22:37:52 -0300375static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
376{
377 /* Actual maximum depends on the video standard in effect. */
378 if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
379 *vp = 480;
380 } else {
381 *vp = 576;
382 }
383 return 0;
384}
385
386static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
387{
388 /* Actual minimum depends on device type. */
389 if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
390 *vp = 75;
391 } else {
392 *vp = 17;
393 }
394 return 0;
395}
396
Mike Isely1bde0282006-12-27 23:30:13 -0300397static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
398{
399 *vp = cptr->hdw->input_val;
400 return 0;
401}
402
403static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
404{
405 struct pvr2_hdw *hdw = cptr->hdw;
406
407 if (hdw->input_val != v) {
408 hdw->input_val = v;
409 hdw->input_dirty = !0;
410 }
411
412 /* Handle side effects - if we switch to a mode that needs the RF
413 tuner, then select the right frequency choice as well and mark
414 it dirty. */
415 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
416 hdw->freqSelector = 0;
417 hdw->freqDirty = !0;
418 } else if (hdw->input_val == PVR2_CVAL_INPUT_TV) {
419 hdw->freqSelector = 1;
420 hdw->freqDirty = !0;
421 }
422 return 0;
423}
424
425static int ctrl_isdirty_input(struct pvr2_ctrl *cptr)
426{
427 return cptr->hdw->input_dirty != 0;
428}
429
430static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr)
431{
432 cptr->hdw->input_dirty = 0;
433}
434
Mike Isely5549f542006-12-27 23:28:54 -0300435static int ctrl_freq_check(struct pvr2_ctrl *cptr,int v)
436{
Mike Isely1bde0282006-12-27 23:30:13 -0300437 /* Both ranges are simultaneously considered legal, in order to
438 permit implicit mode switching, i.e. set a frequency in the
439 other range and the mode will switch */
440 return (((v >= RADIO_MIN_FREQ) && (v <= RADIO_MAX_FREQ)) ||
441 ((v >= TV_MIN_FREQ) && (v <= TV_MAX_FREQ)));
Mike Isely5549f542006-12-27 23:28:54 -0300442}
443
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300444static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
445{
446 /* Actual maximum depends on radio/tv mode */
447 if (cptr->hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
448 *vp = RADIO_MAX_FREQ;
449 } else {
450 *vp = TV_MAX_FREQ;
451 }
452 return 0;
453}
454
455static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
456{
457 /* Actual minimum depends on radio/tv mode */
458 if (cptr->hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
459 *vp = RADIO_MIN_FREQ;
460 } else {
461 *vp = TV_MIN_FREQ;
462 }
463 return 0;
464}
465
Mike Iselyb30d2442006-06-25 20:05:01 -0300466static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
467{
468 return cptr->hdw->enc_stale != 0;
469}
470
471static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
472{
473 cptr->hdw->enc_stale = 0;
474}
475
476static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
477{
478 int ret;
479 struct v4l2_ext_controls cs;
480 struct v4l2_ext_control c1;
481 memset(&cs,0,sizeof(cs));
482 memset(&c1,0,sizeof(c1));
483 cs.controls = &c1;
484 cs.count = 1;
485 c1.id = cptr->info->v4l_id;
486 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
487 VIDIOC_G_EXT_CTRLS);
488 if (ret) return ret;
489 *vp = c1.value;
490 return 0;
491}
492
493static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
494{
495 int ret;
496 struct v4l2_ext_controls cs;
497 struct v4l2_ext_control c1;
498 memset(&cs,0,sizeof(cs));
499 memset(&c1,0,sizeof(c1));
500 cs.controls = &c1;
501 cs.count = 1;
502 c1.id = cptr->info->v4l_id;
503 c1.value = v;
504 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
505 VIDIOC_S_EXT_CTRLS);
506 if (ret) return ret;
507 cptr->hdw->enc_stale = !0;
508 return 0;
509}
510
511static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
512{
513 struct v4l2_queryctrl qctrl;
514 struct pvr2_ctl_info *info;
515 qctrl.id = cptr->info->v4l_id;
516 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
517 /* Strip out the const so we can adjust a function pointer. It's
518 OK to do this here because we know this is a dynamically created
519 control, so the underlying storage for the info pointer is (a)
520 private to us, and (b) not in read-only storage. Either we do
521 this or we significantly complicate the underlying control
522 implementation. */
523 info = (struct pvr2_ctl_info *)(cptr->info);
524 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
525 if (info->set_value) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300526 info->set_value = NULL;
Mike Iselyb30d2442006-06-25 20:05:01 -0300527 }
528 } else {
529 if (!(info->set_value)) {
530 info->set_value = ctrl_cx2341x_set;
531 }
532 }
533 return qctrl.flags;
534}
535
Mike Iselyd8554972006-06-26 20:58:46 -0300536static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
537{
538 *vp = cptr->hdw->flag_streaming_enabled;
539 return 0;
540}
541
542static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
543{
544 int result = pvr2_hdw_is_hsm(cptr->hdw);
545 *vp = PVR2_CVAL_HSM_FULL;
546 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
547 if (result) *vp = PVR2_CVAL_HSM_HIGH;
548 return 0;
549}
550
551static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
552{
553 *vp = cptr->hdw->std_mask_avail;
554 return 0;
555}
556
557static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
558{
559 struct pvr2_hdw *hdw = cptr->hdw;
560 v4l2_std_id ns;
561 ns = hdw->std_mask_avail;
562 ns = (ns & ~m) | (v & m);
563 if (ns == hdw->std_mask_avail) return 0;
564 hdw->std_mask_avail = ns;
565 pvr2_hdw_internal_set_std_avail(hdw);
566 pvr2_hdw_internal_find_stdenum(hdw);
567 return 0;
568}
569
570static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
571 char *bufPtr,unsigned int bufSize,
572 unsigned int *len)
573{
574 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
575 return 0;
576}
577
578static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
579 const char *bufPtr,unsigned int bufSize,
580 int *mskp,int *valp)
581{
582 int ret;
583 v4l2_std_id id;
584 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
585 if (ret < 0) return ret;
586 if (mskp) *mskp = id;
587 if (valp) *valp = id;
588 return 0;
589}
590
591static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
592{
593 *vp = cptr->hdw->std_mask_cur;
594 return 0;
595}
596
597static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
598{
599 struct pvr2_hdw *hdw = cptr->hdw;
600 v4l2_std_id ns;
601 ns = hdw->std_mask_cur;
602 ns = (ns & ~m) | (v & m);
603 if (ns == hdw->std_mask_cur) return 0;
604 hdw->std_mask_cur = ns;
605 hdw->std_dirty = !0;
606 pvr2_hdw_internal_find_stdenum(hdw);
607 return 0;
608}
609
610static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
611{
612 return cptr->hdw->std_dirty != 0;
613}
614
615static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
616{
617 cptr->hdw->std_dirty = 0;
618}
619
620static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
621{
Mike Isely18103c572007-01-20 00:09:47 -0300622 struct pvr2_hdw *hdw = cptr->hdw;
623 pvr2_i2c_core_status_poll(hdw);
624 *vp = hdw->tuner_signal_info.signal;
625 return 0;
626}
627
628static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
629{
630 int val = 0;
631 unsigned int subchan;
632 struct pvr2_hdw *hdw = cptr->hdw;
633 if (hdw->tuner_signal_stale) {
634 pvr2_i2c_core_status_poll(hdw);
635 }
636 subchan = hdw->tuner_signal_info.rxsubchans;
637 if (subchan & V4L2_TUNER_SUB_MONO) {
638 val |= (1 << V4L2_TUNER_MODE_MONO);
639 }
640 if (subchan & V4L2_TUNER_SUB_STEREO) {
641 val |= (1 << V4L2_TUNER_MODE_STEREO);
642 }
643 if (subchan & V4L2_TUNER_SUB_LANG1) {
644 val |= (1 << V4L2_TUNER_MODE_LANG1);
645 }
646 if (subchan & V4L2_TUNER_SUB_LANG2) {
647 val |= (1 << V4L2_TUNER_MODE_LANG2);
648 }
649 *vp = val;
Mike Iselyd8554972006-06-26 20:58:46 -0300650 return 0;
651}
652
653static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
654{
655 *vp = cptr->hdw->subsys_enabled_mask;
656 return 0;
657}
658
659static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
660{
661 pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
662 return 0;
663}
664
665static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
666{
667 *vp = cptr->hdw->subsys_stream_mask;
668 return 0;
669}
670
671static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
672{
673 pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
674 return 0;
675}
676
677static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
678{
679 struct pvr2_hdw *hdw = cptr->hdw;
680 if (v < 0) return -EINVAL;
681 if (v > hdw->std_enum_cnt) return -EINVAL;
682 hdw->std_enum_cur = v;
683 if (!v) return 0;
684 v--;
685 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
686 hdw->std_mask_cur = hdw->std_defs[v].id;
687 hdw->std_dirty = !0;
688 return 0;
689}
690
691
692static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
693{
694 *vp = cptr->hdw->std_enum_cur;
695 return 0;
696}
697
698
699static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
700{
701 return cptr->hdw->std_dirty != 0;
702}
703
704
705static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
706{
707 cptr->hdw->std_dirty = 0;
708}
709
710
711#define DEFINT(vmin,vmax) \
712 .type = pvr2_ctl_int, \
713 .def.type_int.min_value = vmin, \
714 .def.type_int.max_value = vmax
715
716#define DEFENUM(tab) \
717 .type = pvr2_ctl_enum, \
718 .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \
719 .def.type_enum.value_names = tab
720
Mike Isely33213962006-06-25 20:04:40 -0300721#define DEFBOOL \
722 .type = pvr2_ctl_bool
723
Mike Iselyd8554972006-06-26 20:58:46 -0300724#define DEFMASK(msk,tab) \
725 .type = pvr2_ctl_bitmask, \
726 .def.type_bitmask.valid_bits = msk, \
727 .def.type_bitmask.bit_names = tab
728
729#define DEFREF(vname) \
730 .set_value = ctrl_set_##vname, \
731 .get_value = ctrl_get_##vname, \
732 .is_dirty = ctrl_isdirty_##vname, \
733 .clear_dirty = ctrl_cleardirty_##vname
734
735
736#define VCREATE_FUNCS(vname) \
737static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
738{*vp = cptr->hdw->vname##_val; return 0;} \
739static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
740{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
741static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
742{return cptr->hdw->vname##_dirty != 0;} \
743static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
744{cptr->hdw->vname##_dirty = 0;}
745
746VCREATE_FUNCS(brightness)
747VCREATE_FUNCS(contrast)
748VCREATE_FUNCS(saturation)
749VCREATE_FUNCS(hue)
750VCREATE_FUNCS(volume)
751VCREATE_FUNCS(balance)
752VCREATE_FUNCS(bass)
753VCREATE_FUNCS(treble)
754VCREATE_FUNCS(mute)
Mike Iselyc05c0462006-06-25 20:04:25 -0300755VCREATE_FUNCS(audiomode)
756VCREATE_FUNCS(res_hor)
757VCREATE_FUNCS(res_ver)
Mike Iselyd8554972006-06-26 20:58:46 -0300758VCREATE_FUNCS(srate)
Mike Iselyd8554972006-06-26 20:58:46 -0300759
Mike Iselyd8554972006-06-26 20:58:46 -0300760/* Table definition of all controls which can be manipulated */
761static const struct pvr2_ctl_info control_defs[] = {
762 {
763 .v4l_id = V4L2_CID_BRIGHTNESS,
764 .desc = "Brightness",
765 .name = "brightness",
766 .default_value = 128,
767 DEFREF(brightness),
768 DEFINT(0,255),
769 },{
770 .v4l_id = V4L2_CID_CONTRAST,
771 .desc = "Contrast",
772 .name = "contrast",
773 .default_value = 68,
774 DEFREF(contrast),
775 DEFINT(0,127),
776 },{
777 .v4l_id = V4L2_CID_SATURATION,
778 .desc = "Saturation",
779 .name = "saturation",
780 .default_value = 64,
781 DEFREF(saturation),
782 DEFINT(0,127),
783 },{
784 .v4l_id = V4L2_CID_HUE,
785 .desc = "Hue",
786 .name = "hue",
787 .default_value = 0,
788 DEFREF(hue),
789 DEFINT(-128,127),
790 },{
791 .v4l_id = V4L2_CID_AUDIO_VOLUME,
792 .desc = "Volume",
793 .name = "volume",
Mike Isely139eecf2006-12-27 23:36:33 -0300794 .default_value = 62000,
Mike Iselyd8554972006-06-26 20:58:46 -0300795 DEFREF(volume),
796 DEFINT(0,65535),
797 },{
798 .v4l_id = V4L2_CID_AUDIO_BALANCE,
799 .desc = "Balance",
800 .name = "balance",
801 .default_value = 0,
802 DEFREF(balance),
803 DEFINT(-32768,32767),
804 },{
805 .v4l_id = V4L2_CID_AUDIO_BASS,
806 .desc = "Bass",
807 .name = "bass",
808 .default_value = 0,
809 DEFREF(bass),
810 DEFINT(-32768,32767),
811 },{
812 .v4l_id = V4L2_CID_AUDIO_TREBLE,
813 .desc = "Treble",
814 .name = "treble",
815 .default_value = 0,
816 DEFREF(treble),
817 DEFINT(-32768,32767),
818 },{
819 .v4l_id = V4L2_CID_AUDIO_MUTE,
820 .desc = "Mute",
821 .name = "mute",
822 .default_value = 0,
823 DEFREF(mute),
Mike Isely33213962006-06-25 20:04:40 -0300824 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300825 },{
Mike Iselyc05c0462006-06-25 20:04:25 -0300826 .desc = "Video Source",
827 .name = "input",
828 .internal_id = PVR2_CID_INPUT,
829 .default_value = PVR2_CVAL_INPUT_TV,
830 DEFREF(input),
831 DEFENUM(control_values_input),
832 },{
833 .desc = "Audio Mode",
834 .name = "audio_mode",
835 .internal_id = PVR2_CID_AUDIOMODE,
836 .default_value = V4L2_TUNER_MODE_STEREO,
837 DEFREF(audiomode),
838 DEFENUM(control_values_audiomode),
839 },{
840 .desc = "Horizontal capture resolution",
841 .name = "resolution_hor",
842 .internal_id = PVR2_CID_HRES,
843 .default_value = 720,
844 DEFREF(res_hor),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300845 DEFINT(19,720),
Mike Iselyc05c0462006-06-25 20:04:25 -0300846 },{
847 .desc = "Vertical capture resolution",
848 .name = "resolution_ver",
849 .internal_id = PVR2_CID_VRES,
850 .default_value = 480,
851 DEFREF(res_ver),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300852 DEFINT(17,576),
853 /* Hook in check for video standard and adjust maximum
854 depending on the standard. */
855 .get_max_value = ctrl_vres_max_get,
856 .get_min_value = ctrl_vres_min_get,
Mike Iselyc05c0462006-06-25 20:04:25 -0300857 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300858 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
Mike Isely434449f2006-08-08 09:10:06 -0300859 .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
860 .desc = "Audio Sampling Frequency",
Mike Iselyd8554972006-06-26 20:58:46 -0300861 .name = "srate",
Mike Iselyd8554972006-06-26 20:58:46 -0300862 DEFREF(srate),
863 DEFENUM(control_values_srate),
864 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300865 .desc = "Tuner Frequency (Hz)",
866 .name = "frequency",
867 .internal_id = PVR2_CID_FREQUENCY,
Mike Isely1bde0282006-12-27 23:30:13 -0300868 .default_value = 0,
Mike Iselyd8554972006-06-26 20:58:46 -0300869 .set_value = ctrl_freq_set,
870 .get_value = ctrl_freq_get,
871 .is_dirty = ctrl_freq_is_dirty,
872 .clear_dirty = ctrl_freq_clear_dirty,
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300873 DEFINT(TV_MIN_FREQ,TV_MAX_FREQ),
874 /* Hook in check for input value (tv/radio) and adjust
875 max/min values accordingly */
Mike Isely5549f542006-12-27 23:28:54 -0300876 .check_value = ctrl_freq_check,
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300877 .get_max_value = ctrl_freq_max_get,
878 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300879 },{
880 .desc = "Channel",
881 .name = "channel",
882 .set_value = ctrl_channel_set,
883 .get_value = ctrl_channel_get,
884 DEFINT(0,FREQTABLE_SIZE),
885 },{
886 .desc = "Channel Program Frequency",
887 .name = "freq_table_value",
888 .set_value = ctrl_channelfreq_set,
889 .get_value = ctrl_channelfreq_get,
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300890 DEFINT(TV_MIN_FREQ,TV_MAX_FREQ),
Mike Isely1bde0282006-12-27 23:30:13 -0300891 /* Hook in check for input value (tv/radio) and adjust
892 max/min values accordingly */
893 .check_value = ctrl_freq_check,
894 .get_max_value = ctrl_freq_max_get,
895 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300896 },{
897 .desc = "Channel Program ID",
898 .name = "freq_table_channel",
899 .set_value = ctrl_channelprog_set,
900 .get_value = ctrl_channelprog_get,
901 DEFINT(0,FREQTABLE_SIZE),
902 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300903 .desc = "Streaming Enabled",
904 .name = "streaming_enabled",
905 .get_value = ctrl_streamingenabled_get,
Mike Isely33213962006-06-25 20:04:40 -0300906 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300907 },{
908 .desc = "USB Speed",
909 .name = "usb_speed",
910 .get_value = ctrl_hsm_get,
911 DEFENUM(control_values_hsm),
912 },{
913 .desc = "Signal Present",
914 .name = "signal_present",
915 .get_value = ctrl_signal_get,
Mike Isely18103c572007-01-20 00:09:47 -0300916 DEFINT(0,65535),
917 },{
918 .desc = "Audio Modes Present",
919 .name = "audio_modes_present",
920 .get_value = ctrl_audio_modes_present_get,
921 /* For this type we "borrow" the V4L2_TUNER_MODE enum from
922 v4l. Nothing outside of this module cares about this,
923 but I reuse it in order to also reuse the
924 control_values_audiomode string table. */
925 DEFMASK(((1 << V4L2_TUNER_MODE_MONO)|
926 (1 << V4L2_TUNER_MODE_STEREO)|
927 (1 << V4L2_TUNER_MODE_LANG1)|
928 (1 << V4L2_TUNER_MODE_LANG2)),
929 control_values_audiomode),
Mike Iselyd8554972006-06-26 20:58:46 -0300930 },{
931 .desc = "Video Standards Available Mask",
932 .name = "video_standard_mask_available",
933 .internal_id = PVR2_CID_STDAVAIL,
934 .skip_init = !0,
935 .get_value = ctrl_stdavail_get,
936 .set_value = ctrl_stdavail_set,
937 .val_to_sym = ctrl_std_val_to_sym,
938 .sym_to_val = ctrl_std_sym_to_val,
939 .type = pvr2_ctl_bitmask,
940 },{
941 .desc = "Video Standards In Use Mask",
942 .name = "video_standard_mask_active",
943 .internal_id = PVR2_CID_STDCUR,
944 .skip_init = !0,
945 .get_value = ctrl_stdcur_get,
946 .set_value = ctrl_stdcur_set,
947 .is_dirty = ctrl_stdcur_is_dirty,
948 .clear_dirty = ctrl_stdcur_clear_dirty,
949 .val_to_sym = ctrl_std_val_to_sym,
950 .sym_to_val = ctrl_std_sym_to_val,
951 .type = pvr2_ctl_bitmask,
952 },{
953 .desc = "Subsystem enabled mask",
954 .name = "debug_subsys_mask",
955 .skip_init = !0,
956 .get_value = ctrl_subsys_get,
957 .set_value = ctrl_subsys_set,
958 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
959 },{
960 .desc = "Subsystem stream mask",
961 .name = "debug_subsys_stream_mask",
962 .skip_init = !0,
963 .get_value = ctrl_subsys_stream_get,
964 .set_value = ctrl_subsys_stream_set,
965 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
966 },{
967 .desc = "Video Standard Name",
968 .name = "video_standard",
969 .internal_id = PVR2_CID_STDENUM,
970 .skip_init = !0,
971 .get_value = ctrl_stdenumcur_get,
972 .set_value = ctrl_stdenumcur_set,
973 .is_dirty = ctrl_stdenumcur_is_dirty,
974 .clear_dirty = ctrl_stdenumcur_clear_dirty,
975 .type = pvr2_ctl_enum,
976 }
977};
978
Mike Iselyc05c0462006-06-25 20:04:25 -0300979#define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0]))
Mike Iselyd8554972006-06-26 20:58:46 -0300980
981
982const char *pvr2_config_get_name(enum pvr2_config cfg)
983{
984 switch (cfg) {
985 case pvr2_config_empty: return "empty";
986 case pvr2_config_mpeg: return "mpeg";
987 case pvr2_config_vbi: return "vbi";
Mike Isely16eb40d2006-12-30 18:27:32 -0300988 case pvr2_config_pcm: return "pcm";
989 case pvr2_config_rawvideo: return "raw video";
Mike Iselyd8554972006-06-26 20:58:46 -0300990 }
991 return "<unknown>";
992}
993
994
995struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
996{
997 return hdw->usb_dev;
998}
999
1000
1001unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
1002{
1003 return hdw->serial_number;
1004}
1005
Mike Isely1bde0282006-12-27 23:30:13 -03001006unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
1007{
1008 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
1009}
1010
1011/* Set the currently tuned frequency and account for all possible
1012 driver-core side effects of this action. */
1013void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val)
1014{
Mike Isely7c74e572007-01-20 00:15:41 -03001015 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
Mike Isely1bde0282006-12-27 23:30:13 -03001016 if (hdw->freqSelector) {
1017 /* Swing over to radio frequency selection */
1018 hdw->freqSelector = 0;
1019 hdw->freqDirty = !0;
1020 }
Mike Isely1bde0282006-12-27 23:30:13 -03001021 if (hdw->freqValRadio != val) {
1022 hdw->freqValRadio = val;
1023 hdw->freqSlotRadio = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001024 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001025 }
Mike Isely7c74e572007-01-20 00:15:41 -03001026 } else {
Mike Isely1bde0282006-12-27 23:30:13 -03001027 if (!(hdw->freqSelector)) {
1028 /* Swing over to television frequency selection */
1029 hdw->freqSelector = 1;
1030 hdw->freqDirty = !0;
1031 }
Mike Isely1bde0282006-12-27 23:30:13 -03001032 if (hdw->freqValTelevision != val) {
1033 hdw->freqValTelevision = val;
1034 hdw->freqSlotTelevision = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001035 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001036 }
Mike Isely1bde0282006-12-27 23:30:13 -03001037 }
1038}
1039
Mike Iselyd8554972006-06-26 20:58:46 -03001040int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
1041{
1042 return hdw->unit_number;
1043}
1044
1045
1046/* Attempt to locate one of the given set of files. Messages are logged
1047 appropriate to what has been found. The return value will be 0 or
1048 greater on success (it will be the index of the file name found) and
1049 fw_entry will be filled in. Otherwise a negative error is returned on
1050 failure. If the return value is -ENOENT then no viable firmware file
1051 could be located. */
1052static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
1053 const struct firmware **fw_entry,
1054 const char *fwtypename,
1055 unsigned int fwcount,
1056 const char *fwnames[])
1057{
1058 unsigned int idx;
1059 int ret = -EINVAL;
1060 for (idx = 0; idx < fwcount; idx++) {
1061 ret = request_firmware(fw_entry,
1062 fwnames[idx],
1063 &hdw->usb_dev->dev);
1064 if (!ret) {
1065 trace_firmware("Located %s firmware: %s;"
1066 " uploading...",
1067 fwtypename,
1068 fwnames[idx]);
1069 return idx;
1070 }
1071 if (ret == -ENOENT) continue;
1072 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1073 "request_firmware fatal error with code=%d",ret);
1074 return ret;
1075 }
1076 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1077 "***WARNING***"
1078 " Device %s firmware"
1079 " seems to be missing.",
1080 fwtypename);
1081 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1082 "Did you install the pvrusb2 firmware files"
1083 " in their proper location?");
1084 if (fwcount == 1) {
1085 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1086 "request_firmware unable to locate %s file %s",
1087 fwtypename,fwnames[0]);
1088 } else {
1089 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1090 "request_firmware unable to locate"
1091 " one of the following %s files:",
1092 fwtypename);
1093 for (idx = 0; idx < fwcount; idx++) {
1094 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1095 "request_firmware: Failed to find %s",
1096 fwnames[idx]);
1097 }
1098 }
1099 return ret;
1100}
1101
1102
1103/*
1104 * pvr2_upload_firmware1().
1105 *
1106 * Send the 8051 firmware to the device. After the upload, arrange for
1107 * device to re-enumerate.
1108 *
1109 * NOTE : the pointer to the firmware data given by request_firmware()
1110 * is not suitable for an usb transaction.
1111 *
1112 */
Adrian Bunk07e337e2006-06-30 11:30:20 -03001113static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001114{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001115 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001116 void *fw_ptr;
1117 unsigned int pipe;
1118 int ret;
1119 u16 address;
1120 static const char *fw_files_29xxx[] = {
1121 "v4l-pvrusb2-29xxx-01.fw",
1122 };
Mike Iselyd8554972006-06-26 20:58:46 -03001123 static const char *fw_files_24xxx[] = {
1124 "v4l-pvrusb2-24xxx-01.fw",
1125 };
Mike Iselyd8554972006-06-26 20:58:46 -03001126 static const struct pvr2_string_table fw_file_defs[] = {
1127 [PVR2_HDW_TYPE_29XXX] = {
1128 fw_files_29xxx,
1129 sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]),
1130 },
Mike Iselyd8554972006-06-26 20:58:46 -03001131 [PVR2_HDW_TYPE_24XXX] = {
1132 fw_files_24xxx,
1133 sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]),
1134 },
Mike Iselyd8554972006-06-26 20:58:46 -03001135 };
1136 hdw->fw1_state = FW1_STATE_FAILED; // default result
1137
1138 trace_firmware("pvr2_upload_firmware1");
1139
1140 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
1141 fw_file_defs[hdw->hdw_type].cnt,
1142 fw_file_defs[hdw->hdw_type].lst);
1143 if (ret < 0) {
1144 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
1145 return ret;
1146 }
1147
1148 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
1149 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
1150
1151 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
1152
1153 if (fw_entry->size != 0x2000){
1154 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
1155 release_firmware(fw_entry);
1156 return -ENOMEM;
1157 }
1158
1159 fw_ptr = kmalloc(0x800, GFP_KERNEL);
1160 if (fw_ptr == NULL){
1161 release_firmware(fw_entry);
1162 return -ENOMEM;
1163 }
1164
1165 /* We have to hold the CPU during firmware upload. */
1166 pvr2_hdw_cpureset_assert(hdw,1);
1167
1168 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
1169 chunk. */
1170
1171 ret = 0;
1172 for(address = 0; address < fw_entry->size; address += 0x800) {
1173 memcpy(fw_ptr, fw_entry->data + address, 0x800);
1174 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
1175 0, fw_ptr, 0x800, HZ);
1176 }
1177
1178 trace_firmware("Upload done, releasing device's CPU");
1179
1180 /* Now release the CPU. It will disconnect and reconnect later. */
1181 pvr2_hdw_cpureset_assert(hdw,0);
1182
1183 kfree(fw_ptr);
1184 release_firmware(fw_entry);
1185
1186 trace_firmware("Upload done (%d bytes sent)",ret);
1187
1188 /* We should have written 8192 bytes */
1189 if (ret == 8192) {
1190 hdw->fw1_state = FW1_STATE_RELOAD;
1191 return 0;
1192 }
1193
1194 return -EIO;
1195}
1196
1197
1198/*
1199 * pvr2_upload_firmware2()
1200 *
1201 * This uploads encoder firmware on endpoint 2.
1202 *
1203 */
1204
1205int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
1206{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001207 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001208 void *fw_ptr;
1209 unsigned int pipe, fw_len, fw_done;
1210 int actual_length;
1211 int ret = 0;
1212 int fwidx;
1213 static const char *fw_files[] = {
1214 CX2341X_FIRM_ENC_FILENAME,
1215 };
1216
1217 trace_firmware("pvr2_upload_firmware2");
1218
1219 ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
1220 sizeof(fw_files)/sizeof(fw_files[0]),
1221 fw_files);
1222 if (ret < 0) return ret;
1223 fwidx = ret;
1224 ret = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001225 /* Since we're about to completely reinitialize the encoder,
1226 invalidate our cached copy of its configuration state. Next
1227 time we configure the encoder, then we'll fully configure it. */
1228 hdw->enc_cur_valid = 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001229
1230 /* First prepare firmware loading */
1231 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
1232 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
1233 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1234 ret |= pvr2_hdw_cmd_deep_reset(hdw);
1235 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
1236 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
1237 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1238 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
1239 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
1240 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
1241 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
1242 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
1243 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
1244 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
1245 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
1246 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
1247 ret |= pvr2_write_u8(hdw, 0x52, 0);
1248 ret |= pvr2_write_u16(hdw, 0x0600, 0);
1249
1250 if (ret) {
1251 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1252 "firmware2 upload prep failed, ret=%d",ret);
1253 release_firmware(fw_entry);
1254 return ret;
1255 }
1256
1257 /* Now send firmware */
1258
1259 fw_len = fw_entry->size;
1260
1261 if (fw_len % FIRMWARE_CHUNK_SIZE) {
1262 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1263 "size of %s firmware"
1264 " must be a multiple of 8192B",
1265 fw_files[fwidx]);
1266 release_firmware(fw_entry);
1267 return -1;
1268 }
1269
1270 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1271 if (fw_ptr == NULL){
1272 release_firmware(fw_entry);
1273 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1274 "failed to allocate memory for firmware2 upload");
1275 return -ENOMEM;
1276 }
1277
1278 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1279
1280 for (fw_done = 0 ; (fw_done < fw_len) && !ret ;
1281 fw_done += FIRMWARE_CHUNK_SIZE ) {
1282 int i;
1283 memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE);
1284 /* Usbsnoop log shows that we must swap bytes... */
1285 for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++)
1286 ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]);
1287
1288 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,
1289 FIRMWARE_CHUNK_SIZE,
1290 &actual_length, HZ);
1291 ret |= (actual_length != FIRMWARE_CHUNK_SIZE);
1292 }
1293
1294 trace_firmware("upload of %s : %i / %i ",
1295 fw_files[fwidx],fw_done,fw_len);
1296
1297 kfree(fw_ptr);
1298 release_firmware(fw_entry);
1299
1300 if (ret) {
1301 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1302 "firmware2 upload transfer failure");
1303 return ret;
1304 }
1305
1306 /* Finish upload */
1307
1308 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1309 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
1310 ret |= pvr2_write_u16(hdw, 0x0600, 0);
1311
1312 if (ret) {
1313 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1314 "firmware2 upload post-proc failure");
1315 } else {
1316 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
1317 }
1318 return ret;
1319}
1320
1321
1322#define FIRMWARE_RECOVERY_BITS \
1323 ((1<<PVR2_SUBSYS_B_ENC_CFG) | \
1324 (1<<PVR2_SUBSYS_B_ENC_RUN) | \
1325 (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \
1326 (1<<PVR2_SUBSYS_B_USBSTREAM_RUN))
1327
1328/*
1329
1330 This single function is key to pretty much everything. The pvrusb2
1331 device can logically be viewed as a series of subsystems which can be
1332 stopped / started or unconfigured / configured. To get things streaming,
1333 one must configure everything and start everything, but there may be
1334 various reasons over time to deconfigure something or stop something.
1335 This function handles all of this activity. Everything EVERYWHERE that
1336 must affect a subsystem eventually comes here to do the work.
1337
1338 The current state of all subsystems is represented by a single bit mask,
1339 known as subsys_enabled_mask. The bit positions are defined by the
1340 PVR2_SUBSYS_xxxx macros, with one subsystem per bit position. At any
1341 time the set of configured or active subsystems can be queried just by
1342 looking at that mask. To change bits in that mask, this function here
1343 must be called. The "msk" argument indicates which bit positions to
1344 change, and the "val" argument defines the new values for the positions
1345 defined by "msk".
1346
1347 There is a priority ordering of starting / stopping things, and for
1348 multiple requested changes, this function implements that ordering.
1349 (Thus we will act on a request to load encoder firmware before we
1350 configure the encoder.) In addition to priority ordering, there is a
1351 recovery strategy implemented here. If a particular step fails and we
1352 detect that failure, this function will clear the affected subsystem bits
1353 and restart. Thus we have a means for recovering from a dead encoder:
1354 Clear all bits that correspond to subsystems that we need to restart /
1355 reconfigure and start over.
1356
1357*/
Adrian Bunk07e337e2006-06-30 11:30:20 -03001358static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
1359 unsigned long msk,
1360 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001361{
1362 unsigned long nmsk;
1363 unsigned long vmsk;
1364 int ret;
1365 unsigned int tryCount = 0;
1366
1367 if (!hdw->flag_ok) return;
1368
1369 msk &= PVR2_SUBSYS_ALL;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001370 nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk);
1371 nmsk &= PVR2_SUBSYS_ALL;
Mike Iselyd8554972006-06-26 20:58:46 -03001372
1373 for (;;) {
1374 tryCount++;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001375 if (!((nmsk ^ hdw->subsys_enabled_mask) &
1376 PVR2_SUBSYS_ALL)) break;
Mike Iselyd8554972006-06-26 20:58:46 -03001377 if (tryCount > 4) {
1378 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1379 "Too many retries when configuring device;"
1380 " giving up");
1381 pvr2_hdw_render_useless(hdw);
1382 break;
1383 }
1384 if (tryCount > 1) {
1385 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1386 "Retrying device reconfiguration");
1387 }
1388 pvr2_trace(PVR2_TRACE_INIT,
1389 "subsys mask changing 0x%lx:0x%lx"
1390 " from 0x%lx to 0x%lx",
1391 msk,val,hdw->subsys_enabled_mask,nmsk);
1392
1393 vmsk = (nmsk ^ hdw->subsys_enabled_mask) &
1394 hdw->subsys_enabled_mask;
1395 if (vmsk) {
1396 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1397 pvr2_trace(PVR2_TRACE_CTL,
1398 "/*---TRACE_CTL----*/"
1399 " pvr2_encoder_stop");
1400 ret = pvr2_encoder_stop(hdw);
1401 if (ret) {
1402 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1403 "Error recovery initiated");
1404 hdw->subsys_enabled_mask &=
1405 ~FIRMWARE_RECOVERY_BITS;
1406 continue;
1407 }
1408 }
1409 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1410 pvr2_trace(PVR2_TRACE_CTL,
1411 "/*---TRACE_CTL----*/"
1412 " pvr2_hdw_cmd_usbstream(0)");
1413 pvr2_hdw_cmd_usbstream(hdw,0);
1414 }
1415 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1416 pvr2_trace(PVR2_TRACE_CTL,
1417 "/*---TRACE_CTL----*/"
1418 " decoder disable");
1419 if (hdw->decoder_ctrl) {
1420 hdw->decoder_ctrl->enable(
1421 hdw->decoder_ctrl->ctxt,0);
1422 } else {
1423 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1424 "WARNING:"
1425 " No decoder present");
1426 }
1427 hdw->subsys_enabled_mask &=
1428 ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1429 }
1430 if (vmsk & PVR2_SUBSYS_CFG_ALL) {
1431 hdw->subsys_enabled_mask &=
1432 ~(vmsk & PVR2_SUBSYS_CFG_ALL);
1433 }
1434 }
1435 vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk;
1436 if (vmsk) {
1437 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) {
1438 pvr2_trace(PVR2_TRACE_CTL,
1439 "/*---TRACE_CTL----*/"
1440 " pvr2_upload_firmware2");
1441 ret = pvr2_upload_firmware2(hdw);
1442 if (ret) {
1443 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1444 "Failure uploading encoder"
1445 " firmware");
1446 pvr2_hdw_render_useless(hdw);
1447 break;
1448 }
1449 }
1450 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) {
1451 pvr2_trace(PVR2_TRACE_CTL,
1452 "/*---TRACE_CTL----*/"
1453 " pvr2_encoder_configure");
1454 ret = pvr2_encoder_configure(hdw);
1455 if (ret) {
1456 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1457 "Error recovery initiated");
1458 hdw->subsys_enabled_mask &=
1459 ~FIRMWARE_RECOVERY_BITS;
1460 continue;
1461 }
1462 }
1463 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1464 pvr2_trace(PVR2_TRACE_CTL,
1465 "/*---TRACE_CTL----*/"
1466 " decoder enable");
1467 if (hdw->decoder_ctrl) {
1468 hdw->decoder_ctrl->enable(
1469 hdw->decoder_ctrl->ctxt,!0);
1470 } else {
1471 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1472 "WARNING:"
1473 " No decoder present");
1474 }
1475 hdw->subsys_enabled_mask |=
1476 (1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1477 }
1478 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1479 pvr2_trace(PVR2_TRACE_CTL,
1480 "/*---TRACE_CTL----*/"
1481 " pvr2_hdw_cmd_usbstream(1)");
1482 pvr2_hdw_cmd_usbstream(hdw,!0);
1483 }
1484 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1485 pvr2_trace(PVR2_TRACE_CTL,
1486 "/*---TRACE_CTL----*/"
1487 " pvr2_encoder_start");
1488 ret = pvr2_encoder_start(hdw);
1489 if (ret) {
1490 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1491 "Error recovery initiated");
1492 hdw->subsys_enabled_mask &=
1493 ~FIRMWARE_RECOVERY_BITS;
1494 continue;
1495 }
1496 }
1497 }
1498 }
1499}
1500
1501
1502void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
1503 unsigned long msk,unsigned long val)
1504{
1505 LOCK_TAKE(hdw->big_lock); do {
1506 pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val);
1507 } while (0); LOCK_GIVE(hdw->big_lock);
1508}
1509
1510
Mike Iselyd8554972006-06-26 20:58:46 -03001511unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw)
1512{
1513 return hdw->subsys_enabled_mask;
1514}
1515
1516
1517unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw)
1518{
1519 return hdw->subsys_stream_mask;
1520}
1521
1522
Adrian Bunk07e337e2006-06-30 11:30:20 -03001523static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
1524 unsigned long msk,
1525 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001526{
1527 unsigned long val2;
1528 msk &= PVR2_SUBSYS_ALL;
1529 val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk));
1530 pvr2_trace(PVR2_TRACE_INIT,
1531 "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx",
1532 msk,val,hdw->subsys_stream_mask,val2);
1533 hdw->subsys_stream_mask = val2;
1534}
1535
1536
1537void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
1538 unsigned long msk,
1539 unsigned long val)
1540{
1541 LOCK_TAKE(hdw->big_lock); do {
1542 pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val);
1543 } while (0); LOCK_GIVE(hdw->big_lock);
1544}
1545
1546
Adrian Bunk07e337e2006-06-30 11:30:20 -03001547static int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl)
Mike Iselyd8554972006-06-26 20:58:46 -03001548{
1549 if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0;
1550 if (enableFl) {
1551 pvr2_trace(PVR2_TRACE_START_STOP,
1552 "/*--TRACE_STREAM--*/ enable");
1553 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0);
1554 } else {
1555 pvr2_trace(PVR2_TRACE_START_STOP,
1556 "/*--TRACE_STREAM--*/ disable");
1557 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1558 }
1559 if (!hdw->flag_ok) return -EIO;
1560 hdw->flag_streaming_enabled = enableFl != 0;
1561 return 0;
1562}
1563
1564
1565int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1566{
1567 return hdw->flag_streaming_enabled != 0;
1568}
1569
1570
1571int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1572{
1573 int ret;
1574 LOCK_TAKE(hdw->big_lock); do {
1575 ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag);
1576 } while (0); LOCK_GIVE(hdw->big_lock);
1577 return ret;
1578}
1579
1580
Adrian Bunk07e337e2006-06-30 11:30:20 -03001581static int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw,
1582 enum pvr2_config config)
Mike Iselyd8554972006-06-26 20:58:46 -03001583{
1584 unsigned long sm = hdw->subsys_enabled_mask;
1585 if (!hdw->flag_ok) return -EIO;
1586 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1587 hdw->config = config;
1588 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm);
1589 return 0;
1590}
1591
1592
1593int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1594{
1595 int ret;
1596 if (!hdw->flag_ok) return -EIO;
1597 LOCK_TAKE(hdw->big_lock);
1598 ret = pvr2_hdw_set_stream_type_no_lock(hdw,config);
1599 LOCK_GIVE(hdw->big_lock);
1600 return ret;
1601}
1602
1603
1604static int get_default_tuner_type(struct pvr2_hdw *hdw)
1605{
1606 int unit_number = hdw->unit_number;
1607 int tp = -1;
1608 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1609 tp = tuner[unit_number];
1610 }
1611 if (tp < 0) return -EINVAL;
1612 hdw->tuner_type = tp;
1613 return 0;
1614}
1615
1616
1617static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1618{
1619 int unit_number = hdw->unit_number;
1620 int tp = 0;
1621 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1622 tp = video_std[unit_number];
1623 }
1624 return tp;
1625}
1626
1627
1628static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1629{
1630 int unit_number = hdw->unit_number;
1631 int tp = 0;
1632 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1633 tp = tolerance[unit_number];
1634 }
1635 return tp;
1636}
1637
1638
1639static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1640{
1641 /* Try a harmless request to fetch the eeprom's address over
1642 endpoint 1. See what happens. Only the full FX2 image can
1643 respond to this. If this probe fails then likely the FX2
1644 firmware needs be loaded. */
1645 int result;
1646 LOCK_TAKE(hdw->ctl_lock); do {
1647 hdw->cmd_buffer[0] = 0xeb;
1648 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1649 hdw->cmd_buffer,1,
1650 hdw->cmd_buffer,1);
1651 if (result < 0) break;
1652 } while(0); LOCK_GIVE(hdw->ctl_lock);
1653 if (result) {
1654 pvr2_trace(PVR2_TRACE_INIT,
1655 "Probe of device endpoint 1 result status %d",
1656 result);
1657 } else {
1658 pvr2_trace(PVR2_TRACE_INIT,
1659 "Probe of device endpoint 1 succeeded");
1660 }
1661 return result == 0;
1662}
1663
1664static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1665{
1666 char buf[40];
1667 unsigned int bcnt;
1668 v4l2_std_id std1,std2;
1669
1670 std1 = get_default_standard(hdw);
1671
1672 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
1673 pvr2_trace(PVR2_TRACE_INIT,
1674 "Supported video standard(s) reported by eeprom: %.*s",
1675 bcnt,buf);
1676
1677 hdw->std_mask_avail = hdw->std_mask_eeprom;
1678
1679 std2 = std1 & ~hdw->std_mask_avail;
1680 if (std2) {
1681 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
1682 pvr2_trace(PVR2_TRACE_INIT,
1683 "Expanding supported video standards"
1684 " to include: %.*s",
1685 bcnt,buf);
1686 hdw->std_mask_avail |= std2;
1687 }
1688
1689 pvr2_hdw_internal_set_std_avail(hdw);
1690
1691 if (std1) {
1692 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
1693 pvr2_trace(PVR2_TRACE_INIT,
1694 "Initial video standard forced to %.*s",
1695 bcnt,buf);
1696 hdw->std_mask_cur = std1;
1697 hdw->std_dirty = !0;
1698 pvr2_hdw_internal_find_stdenum(hdw);
1699 return;
1700 }
1701
1702 if (hdw->std_enum_cnt > 1) {
1703 // Autoselect the first listed standard
1704 hdw->std_enum_cur = 1;
1705 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1706 hdw->std_dirty = !0;
1707 pvr2_trace(PVR2_TRACE_INIT,
1708 "Initial video standard auto-selected to %s",
1709 hdw->std_defs[hdw->std_enum_cur-1].name);
1710 return;
1711 }
1712
Mike Isely0885ba12006-06-25 21:30:47 -03001713 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
Mike Iselyd8554972006-06-26 20:58:46 -03001714 "Unable to select a viable initial video standard");
1715}
1716
1717
1718static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1719{
1720 int ret;
1721 unsigned int idx;
1722 struct pvr2_ctrl *cptr;
1723 int reloadFl = 0;
1724 if (!reloadFl) {
1725 reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1726 == 0);
1727 if (reloadFl) {
1728 pvr2_trace(PVR2_TRACE_INIT,
1729 "USB endpoint config looks strange"
1730 "; possibly firmware needs to be loaded");
1731 }
1732 }
1733 if (!reloadFl) {
1734 reloadFl = !pvr2_hdw_check_firmware(hdw);
1735 if (reloadFl) {
1736 pvr2_trace(PVR2_TRACE_INIT,
1737 "Check for FX2 firmware failed"
1738 "; possibly firmware needs to be loaded");
1739 }
1740 }
1741 if (reloadFl) {
1742 if (pvr2_upload_firmware1(hdw) != 0) {
1743 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1744 "Failure uploading firmware1");
1745 }
1746 return;
1747 }
1748 hdw->fw1_state = FW1_STATE_OK;
1749
1750 if (initusbreset) {
1751 pvr2_hdw_device_reset(hdw);
1752 }
1753 if (!pvr2_hdw_dev_ok(hdw)) return;
1754
1755 for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) {
1756 request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]);
1757 }
1758
1759 pvr2_hdw_cmd_powerup(hdw);
1760 if (!pvr2_hdw_dev_ok(hdw)) return;
1761
1762 if (pvr2_upload_firmware2(hdw)){
1763 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
1764 pvr2_hdw_render_useless(hdw);
1765 return;
1766 }
1767
1768 // This step MUST happen after the earlier powerup step.
1769 pvr2_i2c_core_init(hdw);
1770 if (!pvr2_hdw_dev_ok(hdw)) return;
1771
Mike Iselyc05c0462006-06-25 20:04:25 -03001772 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001773 cptr = hdw->controls + idx;
1774 if (cptr->info->skip_init) continue;
1775 if (!cptr->info->set_value) continue;
1776 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1777 }
1778
Mike Isely1bde0282006-12-27 23:30:13 -03001779 /* Set up special default values for the television and radio
1780 frequencies here. It's not really important what these defaults
1781 are, but I set them to something usable in the Chicago area just
1782 to make driver testing a little easier. */
1783
1784 /* US Broadcast channel 7 (175.25 MHz) */
1785 hdw->freqValTelevision = 175250000L;
1786 /* 104.3 MHz, a usable FM station for my area */
1787 hdw->freqValRadio = 104300000L;
1788
Mike Iselyd8554972006-06-26 20:58:46 -03001789 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1790 // thread-safe against the normal pvr2_send_request() mechanism.
1791 // (We should make it thread safe).
1792
1793 ret = pvr2_hdw_get_eeprom_addr(hdw);
1794 if (!pvr2_hdw_dev_ok(hdw)) return;
1795 if (ret < 0) {
1796 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1797 "Unable to determine location of eeprom, skipping");
1798 } else {
1799 hdw->eeprom_addr = ret;
1800 pvr2_eeprom_analyze(hdw);
1801 if (!pvr2_hdw_dev_ok(hdw)) return;
1802 }
1803
1804 pvr2_hdw_setup_std(hdw);
1805
1806 if (!get_default_tuner_type(hdw)) {
1807 pvr2_trace(PVR2_TRACE_INIT,
1808 "pvr2_hdw_setup: Tuner type overridden to %d",
1809 hdw->tuner_type);
1810 }
1811
1812 hdw->tuner_updated = !0;
1813 pvr2_i2c_core_check_stale(hdw);
1814 hdw->tuner_updated = 0;
1815
1816 if (!pvr2_hdw_dev_ok(hdw)) return;
1817
1818 pvr2_hdw_commit_ctl_internal(hdw);
1819 if (!pvr2_hdw_dev_ok(hdw)) return;
1820
1821 hdw->vid_stream = pvr2_stream_create();
1822 if (!pvr2_hdw_dev_ok(hdw)) return;
1823 pvr2_trace(PVR2_TRACE_INIT,
1824 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1825 if (hdw->vid_stream) {
1826 idx = get_default_error_tolerance(hdw);
1827 if (idx) {
1828 pvr2_trace(PVR2_TRACE_INIT,
1829 "pvr2_hdw_setup: video stream %p"
1830 " setting tolerance %u",
1831 hdw->vid_stream,idx);
1832 }
1833 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1834 PVR2_VID_ENDPOINT,idx);
1835 }
1836
1837 if (!pvr2_hdw_dev_ok(hdw)) return;
1838
1839 /* Make sure everything is up to date */
1840 pvr2_i2c_core_sync(hdw);
1841
1842 if (!pvr2_hdw_dev_ok(hdw)) return;
1843
1844 hdw->flag_init_ok = !0;
1845}
1846
1847
1848int pvr2_hdw_setup(struct pvr2_hdw *hdw)
1849{
1850 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
1851 LOCK_TAKE(hdw->big_lock); do {
1852 pvr2_hdw_setup_low(hdw);
1853 pvr2_trace(PVR2_TRACE_INIT,
1854 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
1855 hdw,hdw->flag_ok,hdw->flag_init_ok);
1856 if (pvr2_hdw_dev_ok(hdw)) {
1857 if (pvr2_hdw_init_ok(hdw)) {
1858 pvr2_trace(
1859 PVR2_TRACE_INFO,
1860 "Device initialization"
1861 " completed successfully.");
1862 break;
1863 }
1864 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1865 pvr2_trace(
1866 PVR2_TRACE_INFO,
1867 "Device microcontroller firmware"
1868 " (re)loaded; it should now reset"
1869 " and reconnect.");
1870 break;
1871 }
1872 pvr2_trace(
1873 PVR2_TRACE_ERROR_LEGS,
1874 "Device initialization was not successful.");
1875 if (hdw->fw1_state == FW1_STATE_MISSING) {
1876 pvr2_trace(
1877 PVR2_TRACE_ERROR_LEGS,
1878 "Giving up since device"
1879 " microcontroller firmware"
1880 " appears to be missing.");
1881 break;
1882 }
1883 }
1884 if (procreload) {
1885 pvr2_trace(
1886 PVR2_TRACE_ERROR_LEGS,
1887 "Attempting pvrusb2 recovery by reloading"
1888 " primary firmware.");
1889 pvr2_trace(
1890 PVR2_TRACE_ERROR_LEGS,
1891 "If this works, device should disconnect"
1892 " and reconnect in a sane state.");
1893 hdw->fw1_state = FW1_STATE_UNKNOWN;
1894 pvr2_upload_firmware1(hdw);
1895 } else {
1896 pvr2_trace(
1897 PVR2_TRACE_ERROR_LEGS,
1898 "***WARNING*** pvrusb2 device hardware"
1899 " appears to be jammed"
1900 " and I can't clear it.");
1901 pvr2_trace(
1902 PVR2_TRACE_ERROR_LEGS,
1903 "You might need to power cycle"
1904 " the pvrusb2 device"
1905 " in order to recover.");
1906 }
1907 } while (0); LOCK_GIVE(hdw->big_lock);
1908 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
1909 return hdw->flag_init_ok;
1910}
1911
1912
1913/* Create and return a structure for interacting with the underlying
1914 hardware */
1915struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1916 const struct usb_device_id *devid)
1917{
1918 unsigned int idx,cnt1,cnt2;
1919 struct pvr2_hdw *hdw;
1920 unsigned int hdw_type;
1921 int valid_std_mask;
1922 struct pvr2_ctrl *cptr;
1923 __u8 ifnum;
Mike Iselyb30d2442006-06-25 20:05:01 -03001924 struct v4l2_queryctrl qctrl;
1925 struct pvr2_ctl_info *ciptr;
Mike Iselyd8554972006-06-26 20:58:46 -03001926
1927 hdw_type = devid - pvr2_device_table;
1928 if (hdw_type >=
1929 sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) {
1930 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1931 "Bogus device type of %u reported",hdw_type);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001932 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001933 }
1934
1935 hdw = kmalloc(sizeof(*hdw),GFP_KERNEL);
1936 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
1937 hdw,pvr2_device_names[hdw_type]);
1938 if (!hdw) goto fail;
1939 memset(hdw,0,sizeof(*hdw));
Mike Isely18103c572007-01-20 00:09:47 -03001940 hdw->tuner_signal_stale = !0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001941 cx2341x_fill_defaults(&hdw->enc_ctl_state);
Mike Iselyd8554972006-06-26 20:58:46 -03001942
Mike Iselyc05c0462006-06-25 20:04:25 -03001943 hdw->control_cnt = CTRLDEF_COUNT;
Mike Iselyb30d2442006-06-25 20:05:01 -03001944 hdw->control_cnt += MPEGDEF_COUNT;
Mike Iselyc05c0462006-06-25 20:04:25 -03001945 hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001946 GFP_KERNEL);
1947 if (!hdw->controls) goto fail;
Mike Iselyc05c0462006-06-25 20:04:25 -03001948 memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * hdw->control_cnt);
Mike Iselyd8554972006-06-26 20:58:46 -03001949 hdw->hdw_type = hdw_type;
Mike Iselyc05c0462006-06-25 20:04:25 -03001950 for (idx = 0; idx < hdw->control_cnt; idx++) {
1951 cptr = hdw->controls + idx;
1952 cptr->hdw = hdw;
1953 }
Mike Iselyd8554972006-06-26 20:58:46 -03001954 for (idx = 0; idx < 32; idx++) {
1955 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1956 }
Mike Iselyc05c0462006-06-25 20:04:25 -03001957 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001958 cptr = hdw->controls + idx;
Mike Iselyd8554972006-06-26 20:58:46 -03001959 cptr->info = control_defs+idx;
1960 }
Mike Iselyb30d2442006-06-25 20:05:01 -03001961 /* Define and configure additional controls from cx2341x module. */
1962 hdw->mpeg_ctrl_info = kmalloc(
1963 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
1964 if (!hdw->mpeg_ctrl_info) goto fail;
1965 memset(hdw->mpeg_ctrl_info,0,
1966 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT);
1967 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
1968 cptr = hdw->controls + idx + CTRLDEF_COUNT;
1969 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
1970 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
1971 ciptr->name = mpeg_ids[idx].strid;
1972 ciptr->v4l_id = mpeg_ids[idx].id;
1973 ciptr->skip_init = !0;
1974 ciptr->get_value = ctrl_cx2341x_get;
1975 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
1976 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
1977 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
1978 qctrl.id = ciptr->v4l_id;
1979 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
1980 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
1981 ciptr->set_value = ctrl_cx2341x_set;
1982 }
1983 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
1984 PVR2_CTLD_INFO_DESC_SIZE);
1985 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
1986 ciptr->default_value = qctrl.default_value;
1987 switch (qctrl.type) {
1988 default:
1989 case V4L2_CTRL_TYPE_INTEGER:
1990 ciptr->type = pvr2_ctl_int;
1991 ciptr->def.type_int.min_value = qctrl.minimum;
1992 ciptr->def.type_int.max_value = qctrl.maximum;
1993 break;
1994 case V4L2_CTRL_TYPE_BOOLEAN:
1995 ciptr->type = pvr2_ctl_bool;
1996 break;
1997 case V4L2_CTRL_TYPE_MENU:
1998 ciptr->type = pvr2_ctl_enum;
1999 ciptr->def.type_enum.value_names =
2000 cx2341x_ctrl_get_menu(ciptr->v4l_id);
2001 for (cnt1 = 0;
2002 ciptr->def.type_enum.value_names[cnt1] != NULL;
2003 cnt1++) { }
2004 ciptr->def.type_enum.count = cnt1;
2005 break;
2006 }
2007 cptr->info = ciptr;
2008 }
Mike Iselyd8554972006-06-26 20:58:46 -03002009
2010 // Initialize video standard enum dynamic control
2011 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
2012 if (cptr) {
2013 memcpy(&hdw->std_info_enum,cptr->info,
2014 sizeof(hdw->std_info_enum));
2015 cptr->info = &hdw->std_info_enum;
2016
2017 }
2018 // Initialize control data regarding video standard masks
2019 valid_std_mask = pvr2_std_get_usable();
2020 for (idx = 0; idx < 32; idx++) {
2021 if (!(valid_std_mask & (1 << idx))) continue;
2022 cnt1 = pvr2_std_id_to_str(
2023 hdw->std_mask_names[idx],
2024 sizeof(hdw->std_mask_names[idx])-1,
2025 1 << idx);
2026 hdw->std_mask_names[idx][cnt1] = 0;
2027 }
2028 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
2029 if (cptr) {
2030 memcpy(&hdw->std_info_avail,cptr->info,
2031 sizeof(hdw->std_info_avail));
2032 cptr->info = &hdw->std_info_avail;
2033 hdw->std_info_avail.def.type_bitmask.bit_names =
2034 hdw->std_mask_ptrs;
2035 hdw->std_info_avail.def.type_bitmask.valid_bits =
2036 valid_std_mask;
2037 }
2038 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
2039 if (cptr) {
2040 memcpy(&hdw->std_info_cur,cptr->info,
2041 sizeof(hdw->std_info_cur));
2042 cptr->info = &hdw->std_info_cur;
2043 hdw->std_info_cur.def.type_bitmask.bit_names =
2044 hdw->std_mask_ptrs;
2045 hdw->std_info_avail.def.type_bitmask.valid_bits =
2046 valid_std_mask;
2047 }
2048
2049 hdw->eeprom_addr = -1;
2050 hdw->unit_number = -1;
Mike Isely80793842006-12-27 23:12:28 -03002051 hdw->v4l_minor_number_video = -1;
2052 hdw->v4l_minor_number_vbi = -1;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002053 hdw->v4l_minor_number_radio = -1;
Mike Iselyd8554972006-06-26 20:58:46 -03002054 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2055 if (!hdw->ctl_write_buffer) goto fail;
2056 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2057 if (!hdw->ctl_read_buffer) goto fail;
2058 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
2059 if (!hdw->ctl_write_urb) goto fail;
2060 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
2061 if (!hdw->ctl_read_urb) goto fail;
2062
2063 down(&pvr2_unit_sem); do {
2064 for (idx = 0; idx < PVR_NUM; idx++) {
2065 if (unit_pointers[idx]) continue;
2066 hdw->unit_number = idx;
2067 unit_pointers[idx] = hdw;
2068 break;
2069 }
2070 } while (0); up(&pvr2_unit_sem);
2071
2072 cnt1 = 0;
2073 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
2074 cnt1 += cnt2;
2075 if (hdw->unit_number >= 0) {
2076 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
2077 ('a' + hdw->unit_number));
2078 cnt1 += cnt2;
2079 }
2080 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
2081 hdw->name[cnt1] = 0;
2082
2083 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
2084 hdw->unit_number,hdw->name);
2085
2086 hdw->tuner_type = -1;
2087 hdw->flag_ok = !0;
2088 /* Initialize the mask of subsystems that we will shut down when we
2089 stop streaming. */
2090 hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
2091 hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
2092
2093 pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
2094 hdw->subsys_stream_mask);
2095
2096 hdw->usb_intf = intf;
2097 hdw->usb_dev = interface_to_usbdev(intf);
2098
2099 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2100 usb_set_interface(hdw->usb_dev,ifnum,0);
2101
2102 mutex_init(&hdw->ctl_lock_mutex);
2103 mutex_init(&hdw->big_lock_mutex);
2104
2105 return hdw;
2106 fail:
2107 if (hdw) {
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002108 usb_free_urb(hdw->ctl_read_urb);
2109 usb_free_urb(hdw->ctl_write_urb);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002110 kfree(hdw->ctl_read_buffer);
2111 kfree(hdw->ctl_write_buffer);
2112 kfree(hdw->controls);
2113 kfree(hdw->mpeg_ctrl_info);
Mike Iselyd8554972006-06-26 20:58:46 -03002114 kfree(hdw);
2115 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002116 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002117}
2118
2119
2120/* Remove _all_ associations between this driver and the underlying USB
2121 layer. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002122static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002123{
2124 if (hdw->flag_disconnected) return;
2125 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
2126 if (hdw->ctl_read_urb) {
2127 usb_kill_urb(hdw->ctl_read_urb);
2128 usb_free_urb(hdw->ctl_read_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002129 hdw->ctl_read_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002130 }
2131 if (hdw->ctl_write_urb) {
2132 usb_kill_urb(hdw->ctl_write_urb);
2133 usb_free_urb(hdw->ctl_write_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002134 hdw->ctl_write_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002135 }
2136 if (hdw->ctl_read_buffer) {
2137 kfree(hdw->ctl_read_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002138 hdw->ctl_read_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002139 }
2140 if (hdw->ctl_write_buffer) {
2141 kfree(hdw->ctl_write_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002142 hdw->ctl_write_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002143 }
2144 pvr2_hdw_render_useless_unlocked(hdw);
2145 hdw->flag_disconnected = !0;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002146 hdw->usb_dev = NULL;
2147 hdw->usb_intf = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002148}
2149
2150
2151/* Destroy hardware interaction structure */
2152void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2153{
2154 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
2155 if (hdw->fw_buffer) {
2156 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002157 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002158 }
2159 if (hdw->vid_stream) {
2160 pvr2_stream_destroy(hdw->vid_stream);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002161 hdw->vid_stream = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002162 }
Mike Iselyd8554972006-06-26 20:58:46 -03002163 if (hdw->decoder_ctrl) {
2164 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2165 }
2166 pvr2_i2c_core_done(hdw);
2167 pvr2_hdw_remove_usb_stuff(hdw);
2168 down(&pvr2_unit_sem); do {
2169 if ((hdw->unit_number >= 0) &&
2170 (hdw->unit_number < PVR_NUM) &&
2171 (unit_pointers[hdw->unit_number] == hdw)) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002172 unit_pointers[hdw->unit_number] = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002173 }
2174 } while (0); up(&pvr2_unit_sem);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002175 kfree(hdw->controls);
2176 kfree(hdw->mpeg_ctrl_info);
2177 kfree(hdw->std_defs);
2178 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002179 kfree(hdw);
2180}
2181
2182
2183int pvr2_hdw_init_ok(struct pvr2_hdw *hdw)
2184{
2185 return hdw->flag_init_ok;
2186}
2187
2188
2189int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2190{
2191 return (hdw && hdw->flag_ok);
2192}
2193
2194
2195/* Called when hardware has been unplugged */
2196void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2197{
2198 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2199 LOCK_TAKE(hdw->big_lock);
2200 LOCK_TAKE(hdw->ctl_lock);
2201 pvr2_hdw_remove_usb_stuff(hdw);
2202 LOCK_GIVE(hdw->ctl_lock);
2203 LOCK_GIVE(hdw->big_lock);
2204}
2205
2206
2207// Attempt to autoselect an appropriate value for std_enum_cur given
2208// whatever is currently in std_mask_cur
Adrian Bunk07e337e2006-06-30 11:30:20 -03002209static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002210{
2211 unsigned int idx;
2212 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2213 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2214 hdw->std_enum_cur = idx;
2215 return;
2216 }
2217 }
2218 hdw->std_enum_cur = 0;
2219}
2220
2221
2222// Calculate correct set of enumerated standards based on currently known
2223// set of available standards bits.
Adrian Bunk07e337e2006-06-30 11:30:20 -03002224static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002225{
2226 struct v4l2_standard *newstd;
2227 unsigned int std_cnt;
2228 unsigned int idx;
2229
2230 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2231
2232 if (hdw->std_defs) {
2233 kfree(hdw->std_defs);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002234 hdw->std_defs = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002235 }
2236 hdw->std_enum_cnt = 0;
2237 if (hdw->std_enum_names) {
2238 kfree(hdw->std_enum_names);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002239 hdw->std_enum_names = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002240 }
2241
2242 if (!std_cnt) {
2243 pvr2_trace(
2244 PVR2_TRACE_ERROR_LEGS,
2245 "WARNING: Failed to identify any viable standards");
2246 }
2247 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2248 hdw->std_enum_names[0] = "none";
2249 for (idx = 0; idx < std_cnt; idx++) {
2250 hdw->std_enum_names[idx+1] =
2251 newstd[idx].name;
2252 }
2253 // Set up the dynamic control for this standard
2254 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2255 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2256 hdw->std_defs = newstd;
2257 hdw->std_enum_cnt = std_cnt+1;
2258 hdw->std_enum_cur = 0;
2259 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2260}
2261
2262
2263int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2264 struct v4l2_standard *std,
2265 unsigned int idx)
2266{
2267 int ret = -EINVAL;
2268 if (!idx) return ret;
2269 LOCK_TAKE(hdw->big_lock); do {
2270 if (idx >= hdw->std_enum_cnt) break;
2271 idx--;
2272 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2273 ret = 0;
2274 } while (0); LOCK_GIVE(hdw->big_lock);
2275 return ret;
2276}
2277
2278
2279/* Get the number of defined controls */
2280unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2281{
Mike Iselyc05c0462006-06-25 20:04:25 -03002282 return hdw->control_cnt;
Mike Iselyd8554972006-06-26 20:58:46 -03002283}
2284
2285
2286/* Retrieve a control handle given its index (0..count-1) */
2287struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2288 unsigned int idx)
2289{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002290 if (idx >= hdw->control_cnt) return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002291 return hdw->controls + idx;
2292}
2293
2294
2295/* Retrieve a control handle given its index (0..count-1) */
2296struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2297 unsigned int ctl_id)
2298{
2299 struct pvr2_ctrl *cptr;
2300 unsigned int idx;
2301 int i;
2302
2303 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002304 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002305 cptr = hdw->controls + idx;
2306 i = cptr->info->internal_id;
2307 if (i && (i == ctl_id)) return cptr;
2308 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002309 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002310}
2311
2312
Mike Iselya761f432006-06-25 20:04:44 -03002313/* Given a V4L ID, retrieve the control structure associated with it. */
Mike Iselyd8554972006-06-26 20:58:46 -03002314struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2315{
2316 struct pvr2_ctrl *cptr;
2317 unsigned int idx;
2318 int i;
2319
2320 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002321 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002322 cptr = hdw->controls + idx;
2323 i = cptr->info->v4l_id;
2324 if (i && (i == ctl_id)) return cptr;
2325 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002326 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002327}
2328
2329
Mike Iselya761f432006-06-25 20:04:44 -03002330/* Given a V4L ID for its immediate predecessor, retrieve the control
2331 structure associated with it. */
2332struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2333 unsigned int ctl_id)
2334{
2335 struct pvr2_ctrl *cptr,*cp2;
2336 unsigned int idx;
2337 int i;
2338
2339 /* This could be made a lot more efficient, but for now... */
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002340 cp2 = NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002341 for (idx = 0; idx < hdw->control_cnt; idx++) {
2342 cptr = hdw->controls + idx;
2343 i = cptr->info->v4l_id;
2344 if (!i) continue;
2345 if (i <= ctl_id) continue;
2346 if (cp2 && (cp2->info->v4l_id < i)) continue;
2347 cp2 = cptr;
2348 }
2349 return cp2;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002350 return NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002351}
2352
2353
Mike Iselyd8554972006-06-26 20:58:46 -03002354static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2355{
2356 switch (tp) {
2357 case pvr2_ctl_int: return "integer";
2358 case pvr2_ctl_enum: return "enum";
Mike Isely33213962006-06-25 20:04:40 -03002359 case pvr2_ctl_bool: return "boolean";
Mike Iselyd8554972006-06-26 20:58:46 -03002360 case pvr2_ctl_bitmask: return "bitmask";
2361 }
2362 return "";
2363}
2364
2365
2366/* Commit all control changes made up to this point. Subsystems can be
2367 indirectly affected by these changes. For a given set of things being
2368 committed, we'll clear the affected subsystem bits and then once we're
2369 done committing everything we'll make a request to restore the subsystem
2370 state(s) back to their previous value before this function was called.
2371 Thus we can automatically reconfigure affected pieces of the driver as
2372 controls are changed. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002373static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002374{
2375 unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
2376 unsigned long stale_subsys_mask = 0;
2377 unsigned int idx;
2378 struct pvr2_ctrl *cptr;
2379 int value;
2380 int commit_flag = 0;
2381 char buf[100];
2382 unsigned int bcnt,ccnt;
2383
Mike Iselyc05c0462006-06-25 20:04:25 -03002384 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002385 cptr = hdw->controls + idx;
2386 if (cptr->info->is_dirty == 0) continue;
2387 if (!cptr->info->is_dirty(cptr)) continue;
Mike Iselyfe23a282007-01-20 00:10:55 -03002388 commit_flag = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002389
Mike Iselyfe23a282007-01-20 00:10:55 -03002390 if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002391 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2392 cptr->info->name);
2393 value = 0;
2394 cptr->info->get_value(cptr,&value);
2395 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2396 buf+bcnt,
2397 sizeof(buf)-bcnt,&ccnt);
2398 bcnt += ccnt;
2399 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2400 get_ctrl_typename(cptr->info->type));
2401 pvr2_trace(PVR2_TRACE_CTL,
2402 "/*--TRACE_COMMIT--*/ %.*s",
2403 bcnt,buf);
2404 }
2405
2406 if (!commit_flag) {
2407 /* Nothing has changed */
2408 return 0;
2409 }
2410
2411 /* When video standard changes, reset the hres and vres values -
2412 but if the user has pending changes there, then let the changes
2413 take priority. */
2414 if (hdw->std_dirty) {
2415 /* Rewrite the vertical resolution to be appropriate to the
2416 video standard that has been selected. */
2417 int nvres;
2418 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2419 nvres = 480;
2420 } else {
2421 nvres = 576;
2422 }
2423 if (nvres != hdw->res_ver_val) {
2424 hdw->res_ver_val = nvres;
2425 hdw->res_ver_dirty = !0;
2426 }
Mike Iselyd8554972006-06-26 20:58:46 -03002427 }
2428
2429 if (hdw->std_dirty ||
Mike Isely434449f2006-08-08 09:10:06 -03002430 hdw->enc_stale ||
2431 hdw->srate_dirty ||
2432 hdw->res_ver_dirty ||
2433 hdw->res_hor_dirty ||
Mike Iselyb46cfa82006-06-25 20:04:53 -03002434 0) {
Mike Iselyd8554972006-06-26 20:58:46 -03002435 /* If any of this changes, then the encoder needs to be
2436 reconfigured, and we need to reset the stream. */
2437 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
Mike Iselyd8554972006-06-26 20:58:46 -03002438 }
2439
Pantelis Koukousoulas275b2e22006-12-27 23:05:19 -03002440 if (hdw->input_dirty) {
2441 /* pk: If input changes to or from radio, then the encoder
2442 needs to be restarted (for ENC_MUTE_VIDEO to work) */
2443 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
2444 }
2445
2446
Mike Iselyb30d2442006-06-25 20:05:01 -03002447 if (hdw->srate_dirty) {
2448 /* Write new sample rate into control structure since
2449 * the master copy is stale. We must track srate
2450 * separate from the mpeg control structure because
2451 * other logic also uses this value. */
2452 struct v4l2_ext_controls cs;
2453 struct v4l2_ext_control c1;
2454 memset(&cs,0,sizeof(cs));
2455 memset(&c1,0,sizeof(c1));
2456 cs.controls = &c1;
2457 cs.count = 1;
2458 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2459 c1.value = hdw->srate_val;
2460 cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS);
2461 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002462
Mike Iselyd8554972006-06-26 20:58:46 -03002463 /* Scan i2c core at this point - before we clear all the dirty
2464 bits. Various parts of the i2c core will notice dirty bits as
2465 appropriate and arrange to broadcast or directly send updates to
2466 the client drivers in order to keep everything in sync */
2467 pvr2_i2c_core_check_stale(hdw);
2468
Mike Iselyc05c0462006-06-25 20:04:25 -03002469 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002470 cptr = hdw->controls + idx;
2471 if (!cptr->info->clear_dirty) continue;
2472 cptr->info->clear_dirty(cptr);
2473 }
2474
2475 /* Now execute i2c core update */
2476 pvr2_i2c_core_sync(hdw);
2477
2478 pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
2479 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
2480
2481 return 0;
2482}
2483
2484
2485int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2486{
2487 LOCK_TAKE(hdw->big_lock); do {
2488 pvr2_hdw_commit_ctl_internal(hdw);
2489 } while (0); LOCK_GIVE(hdw->big_lock);
2490 return 0;
2491}
2492
2493
2494void pvr2_hdw_poll(struct pvr2_hdw *hdw)
2495{
2496 LOCK_TAKE(hdw->big_lock); do {
2497 pvr2_i2c_core_sync(hdw);
2498 } while (0); LOCK_GIVE(hdw->big_lock);
2499}
2500
2501
2502void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
2503 void (*func)(void *),
2504 void *data)
2505{
2506 LOCK_TAKE(hdw->big_lock); do {
2507 hdw->poll_trigger_func = func;
2508 hdw->poll_trigger_data = data;
2509 } while (0); LOCK_GIVE(hdw->big_lock);
2510}
2511
2512
2513void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
2514{
2515 if (hdw->poll_trigger_func) {
2516 hdw->poll_trigger_func(hdw->poll_trigger_data);
2517 }
2518}
2519
Mike Iselyd8554972006-06-26 20:58:46 -03002520/* Return name for this driver instance */
2521const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2522{
2523 return hdw->name;
2524}
2525
2526
Mike Iselyd8554972006-06-26 20:58:46 -03002527int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2528{
2529 int result;
2530 LOCK_TAKE(hdw->ctl_lock); do {
2531 hdw->cmd_buffer[0] = 0x0b;
2532 result = pvr2_send_request(hdw,
2533 hdw->cmd_buffer,1,
2534 hdw->cmd_buffer,1);
2535 if (result < 0) break;
2536 result = (hdw->cmd_buffer[0] != 0);
2537 } while(0); LOCK_GIVE(hdw->ctl_lock);
2538 return result;
2539}
2540
2541
Mike Isely18103c572007-01-20 00:09:47 -03002542/* Execute poll of tuner status */
2543void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002544{
Mike Iselyd8554972006-06-26 20:58:46 -03002545 LOCK_TAKE(hdw->big_lock); do {
Mike Isely18103c572007-01-20 00:09:47 -03002546 pvr2_i2c_core_status_poll(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002547 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely18103c572007-01-20 00:09:47 -03002548}
2549
2550
2551/* Return information about the tuner */
2552int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
2553{
2554 LOCK_TAKE(hdw->big_lock); do {
2555 if (hdw->tuner_signal_stale) {
2556 pvr2_i2c_core_status_poll(hdw);
2557 }
2558 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
2559 } while (0); LOCK_GIVE(hdw->big_lock);
2560 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002561}
2562
2563
2564/* Get handle to video output stream */
2565struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2566{
2567 return hp->vid_stream;
2568}
2569
2570
2571void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2572{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002573 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002574 LOCK_TAKE(hdw->big_lock); do {
2575 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002576 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002577 pvr2_i2c_core_check_stale(hdw);
2578 hdw->log_requested = 0;
2579 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002580 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002581 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely4f1a3e52006-06-25 20:04:31 -03002582 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002583 } while (0); LOCK_GIVE(hdw->big_lock);
2584}
2585
2586void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
2587{
2588 int ret;
2589 u16 address;
2590 unsigned int pipe;
2591 LOCK_TAKE(hdw->big_lock); do {
2592 if ((hdw->fw_buffer == 0) == !enable_flag) break;
2593
2594 if (!enable_flag) {
2595 pvr2_trace(PVR2_TRACE_FIRMWARE,
2596 "Cleaning up after CPU firmware fetch");
2597 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002598 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002599 hdw->fw_size = 0;
2600 /* Now release the CPU. It will disconnect and
2601 reconnect later. */
2602 pvr2_hdw_cpureset_assert(hdw,0);
2603 break;
2604 }
2605
2606 pvr2_trace(PVR2_TRACE_FIRMWARE,
2607 "Preparing to suck out CPU firmware");
2608 hdw->fw_size = 0x2000;
2609 hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL);
2610 if (!hdw->fw_buffer) {
2611 hdw->fw_size = 0;
2612 break;
2613 }
2614
2615 memset(hdw->fw_buffer,0,hdw->fw_size);
2616
2617 /* We have to hold the CPU during firmware upload. */
2618 pvr2_hdw_cpureset_assert(hdw,1);
2619
2620 /* download the firmware from address 0000-1fff in 2048
2621 (=0x800) bytes chunk. */
2622
2623 pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
2624 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2625 for(address = 0; address < hdw->fw_size; address += 0x800) {
2626 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
2627 address,0,
2628 hdw->fw_buffer+address,0x800,HZ);
2629 if (ret < 0) break;
2630 }
2631
2632 pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
2633
2634 } while (0); LOCK_GIVE(hdw->big_lock);
2635}
2636
2637
2638/* Return true if we're in a mode for retrieval CPU firmware */
2639int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2640{
2641 return hdw->fw_buffer != 0;
2642}
2643
2644
2645int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2646 char *buf,unsigned int cnt)
2647{
2648 int ret = -EINVAL;
2649 LOCK_TAKE(hdw->big_lock); do {
2650 if (!buf) break;
2651 if (!cnt) break;
2652
2653 if (!hdw->fw_buffer) {
2654 ret = -EIO;
2655 break;
2656 }
2657
2658 if (offs >= hdw->fw_size) {
2659 pvr2_trace(PVR2_TRACE_FIRMWARE,
2660 "Read firmware data offs=%d EOF",
2661 offs);
2662 ret = 0;
2663 break;
2664 }
2665
2666 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2667
2668 memcpy(buf,hdw->fw_buffer+offs,cnt);
2669
2670 pvr2_trace(PVR2_TRACE_FIRMWARE,
2671 "Read firmware data offs=%d cnt=%d",
2672 offs,cnt);
2673 ret = cnt;
2674 } while (0); LOCK_GIVE(hdw->big_lock);
2675
2676 return ret;
2677}
2678
2679
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002680int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002681 enum pvr2_v4l_type index)
Mike Iselyd8554972006-06-26 20:58:46 -03002682{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002683 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002684 case pvr2_v4l_type_video: return hdw->v4l_minor_number_video;
2685 case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi;
2686 case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002687 default: return -1;
2688 }
Mike Iselyd8554972006-06-26 20:58:46 -03002689}
2690
2691
Pantelis Koukousoulas2fdf3d92006-12-27 23:07:58 -03002692/* Store a v4l minor device number */
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002693void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002694 enum pvr2_v4l_type index,int v)
Mike Iselyd8554972006-06-26 20:58:46 -03002695{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002696 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002697 case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
2698 case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
2699 case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002700 default: break;
2701 }
Mike Iselyd8554972006-06-26 20:58:46 -03002702}
2703
2704
David Howells7d12e782006-10-05 14:55:46 +01002705static void pvr2_ctl_write_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002706{
2707 struct pvr2_hdw *hdw = urb->context;
2708 hdw->ctl_write_pend_flag = 0;
2709 if (hdw->ctl_read_pend_flag) return;
2710 complete(&hdw->ctl_done);
2711}
2712
2713
David Howells7d12e782006-10-05 14:55:46 +01002714static void pvr2_ctl_read_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002715{
2716 struct pvr2_hdw *hdw = urb->context;
2717 hdw->ctl_read_pend_flag = 0;
2718 if (hdw->ctl_write_pend_flag) return;
2719 complete(&hdw->ctl_done);
2720}
2721
2722
2723static void pvr2_ctl_timeout(unsigned long data)
2724{
2725 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2726 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2727 hdw->ctl_timeout_flag = !0;
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002728 if (hdw->ctl_write_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002729 usb_unlink_urb(hdw->ctl_write_urb);
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002730 if (hdw->ctl_read_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002731 usb_unlink_urb(hdw->ctl_read_urb);
Mike Iselyd8554972006-06-26 20:58:46 -03002732 }
2733}
2734
2735
Mike Iselye61b6fc2006-07-18 22:42:18 -03002736/* Issue a command and get a response from the device. This extended
2737 version includes a probe flag (which if set means that device errors
2738 should not be logged or treated as fatal) and a timeout in jiffies.
2739 This can be used to non-lethally probe the health of endpoint 1. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002740static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2741 unsigned int timeout,int probe_fl,
2742 void *write_data,unsigned int write_len,
2743 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002744{
2745 unsigned int idx;
2746 int status = 0;
2747 struct timer_list timer;
2748 if (!hdw->ctl_lock_held) {
2749 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2750 "Attempted to execute control transfer"
2751 " without lock!!");
2752 return -EDEADLK;
2753 }
2754 if ((!hdw->flag_ok) && !probe_fl) {
2755 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2756 "Attempted to execute control transfer"
2757 " when device not ok");
2758 return -EIO;
2759 }
2760 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2761 if (!probe_fl) {
2762 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2763 "Attempted to execute control transfer"
2764 " when USB is disconnected");
2765 }
2766 return -ENOTTY;
2767 }
2768
2769 /* Ensure that we have sane parameters */
2770 if (!write_data) write_len = 0;
2771 if (!read_data) read_len = 0;
2772 if (write_len > PVR2_CTL_BUFFSIZE) {
2773 pvr2_trace(
2774 PVR2_TRACE_ERROR_LEGS,
2775 "Attempted to execute %d byte"
2776 " control-write transfer (limit=%d)",
2777 write_len,PVR2_CTL_BUFFSIZE);
2778 return -EINVAL;
2779 }
2780 if (read_len > PVR2_CTL_BUFFSIZE) {
2781 pvr2_trace(
2782 PVR2_TRACE_ERROR_LEGS,
2783 "Attempted to execute %d byte"
2784 " control-read transfer (limit=%d)",
2785 write_len,PVR2_CTL_BUFFSIZE);
2786 return -EINVAL;
2787 }
2788 if ((!write_len) && (!read_len)) {
2789 pvr2_trace(
2790 PVR2_TRACE_ERROR_LEGS,
2791 "Attempted to execute null control transfer?");
2792 return -EINVAL;
2793 }
2794
2795
2796 hdw->cmd_debug_state = 1;
2797 if (write_len) {
2798 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2799 } else {
2800 hdw->cmd_debug_code = 0;
2801 }
2802 hdw->cmd_debug_write_len = write_len;
2803 hdw->cmd_debug_read_len = read_len;
2804
2805 /* Initialize common stuff */
2806 init_completion(&hdw->ctl_done);
2807 hdw->ctl_timeout_flag = 0;
2808 hdw->ctl_write_pend_flag = 0;
2809 hdw->ctl_read_pend_flag = 0;
2810 init_timer(&timer);
2811 timer.expires = jiffies + timeout;
2812 timer.data = (unsigned long)hdw;
2813 timer.function = pvr2_ctl_timeout;
2814
2815 if (write_len) {
2816 hdw->cmd_debug_state = 2;
2817 /* Transfer write data to internal buffer */
2818 for (idx = 0; idx < write_len; idx++) {
2819 hdw->ctl_write_buffer[idx] =
2820 ((unsigned char *)write_data)[idx];
2821 }
2822 /* Initiate a write request */
2823 usb_fill_bulk_urb(hdw->ctl_write_urb,
2824 hdw->usb_dev,
2825 usb_sndbulkpipe(hdw->usb_dev,
2826 PVR2_CTL_WRITE_ENDPOINT),
2827 hdw->ctl_write_buffer,
2828 write_len,
2829 pvr2_ctl_write_complete,
2830 hdw);
2831 hdw->ctl_write_urb->actual_length = 0;
2832 hdw->ctl_write_pend_flag = !0;
2833 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2834 if (status < 0) {
2835 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2836 "Failed to submit write-control"
2837 " URB status=%d",status);
2838 hdw->ctl_write_pend_flag = 0;
2839 goto done;
2840 }
2841 }
2842
2843 if (read_len) {
2844 hdw->cmd_debug_state = 3;
2845 memset(hdw->ctl_read_buffer,0x43,read_len);
2846 /* Initiate a read request */
2847 usb_fill_bulk_urb(hdw->ctl_read_urb,
2848 hdw->usb_dev,
2849 usb_rcvbulkpipe(hdw->usb_dev,
2850 PVR2_CTL_READ_ENDPOINT),
2851 hdw->ctl_read_buffer,
2852 read_len,
2853 pvr2_ctl_read_complete,
2854 hdw);
2855 hdw->ctl_read_urb->actual_length = 0;
2856 hdw->ctl_read_pend_flag = !0;
2857 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
2858 if (status < 0) {
2859 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2860 "Failed to submit read-control"
2861 " URB status=%d",status);
2862 hdw->ctl_read_pend_flag = 0;
2863 goto done;
2864 }
2865 }
2866
2867 /* Start timer */
2868 add_timer(&timer);
2869
2870 /* Now wait for all I/O to complete */
2871 hdw->cmd_debug_state = 4;
2872 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2873 wait_for_completion(&hdw->ctl_done);
2874 }
2875 hdw->cmd_debug_state = 5;
2876
2877 /* Stop timer */
2878 del_timer_sync(&timer);
2879
2880 hdw->cmd_debug_state = 6;
2881 status = 0;
2882
2883 if (hdw->ctl_timeout_flag) {
2884 status = -ETIMEDOUT;
2885 if (!probe_fl) {
2886 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2887 "Timed out control-write");
2888 }
2889 goto done;
2890 }
2891
2892 if (write_len) {
2893 /* Validate results of write request */
2894 if ((hdw->ctl_write_urb->status != 0) &&
2895 (hdw->ctl_write_urb->status != -ENOENT) &&
2896 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
2897 (hdw->ctl_write_urb->status != -ECONNRESET)) {
2898 /* USB subsystem is reporting some kind of failure
2899 on the write */
2900 status = hdw->ctl_write_urb->status;
2901 if (!probe_fl) {
2902 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2903 "control-write URB failure,"
2904 " status=%d",
2905 status);
2906 }
2907 goto done;
2908 }
2909 if (hdw->ctl_write_urb->actual_length < write_len) {
2910 /* Failed to write enough data */
2911 status = -EIO;
2912 if (!probe_fl) {
2913 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2914 "control-write URB short,"
2915 " expected=%d got=%d",
2916 write_len,
2917 hdw->ctl_write_urb->actual_length);
2918 }
2919 goto done;
2920 }
2921 }
2922 if (read_len) {
2923 /* Validate results of read request */
2924 if ((hdw->ctl_read_urb->status != 0) &&
2925 (hdw->ctl_read_urb->status != -ENOENT) &&
2926 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
2927 (hdw->ctl_read_urb->status != -ECONNRESET)) {
2928 /* USB subsystem is reporting some kind of failure
2929 on the read */
2930 status = hdw->ctl_read_urb->status;
2931 if (!probe_fl) {
2932 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2933 "control-read URB failure,"
2934 " status=%d",
2935 status);
2936 }
2937 goto done;
2938 }
2939 if (hdw->ctl_read_urb->actual_length < read_len) {
2940 /* Failed to read enough data */
2941 status = -EIO;
2942 if (!probe_fl) {
2943 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2944 "control-read URB short,"
2945 " expected=%d got=%d",
2946 read_len,
2947 hdw->ctl_read_urb->actual_length);
2948 }
2949 goto done;
2950 }
2951 /* Transfer retrieved data out from internal buffer */
2952 for (idx = 0; idx < read_len; idx++) {
2953 ((unsigned char *)read_data)[idx] =
2954 hdw->ctl_read_buffer[idx];
2955 }
2956 }
2957
2958 done:
2959
2960 hdw->cmd_debug_state = 0;
2961 if ((status < 0) && (!probe_fl)) {
2962 pvr2_hdw_render_useless_unlocked(hdw);
2963 }
2964 return status;
2965}
2966
2967
2968int pvr2_send_request(struct pvr2_hdw *hdw,
2969 void *write_data,unsigned int write_len,
2970 void *read_data,unsigned int read_len)
2971{
2972 return pvr2_send_request_ex(hdw,HZ*4,0,
2973 write_data,write_len,
2974 read_data,read_len);
2975}
2976
2977int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
2978{
2979 int ret;
2980
2981 LOCK_TAKE(hdw->ctl_lock);
2982
2983 hdw->cmd_buffer[0] = 0x04; /* write register prefix */
2984 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
2985 hdw->cmd_buffer[5] = 0;
2986 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2987 hdw->cmd_buffer[7] = reg & 0xff;
2988
2989
2990 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
2991
2992 LOCK_GIVE(hdw->ctl_lock);
2993
2994 return ret;
2995}
2996
2997
Adrian Bunk07e337e2006-06-30 11:30:20 -03002998static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03002999{
3000 int ret = 0;
3001
3002 LOCK_TAKE(hdw->ctl_lock);
3003
3004 hdw->cmd_buffer[0] = 0x05; /* read register prefix */
3005 hdw->cmd_buffer[1] = 0;
3006 hdw->cmd_buffer[2] = 0;
3007 hdw->cmd_buffer[3] = 0;
3008 hdw->cmd_buffer[4] = 0;
3009 hdw->cmd_buffer[5] = 0;
3010 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3011 hdw->cmd_buffer[7] = reg & 0xff;
3012
3013 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
3014 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
3015
3016 LOCK_GIVE(hdw->ctl_lock);
3017
3018 return ret;
3019}
3020
3021
Adrian Bunk07e337e2006-06-30 11:30:20 -03003022static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03003023{
3024 int ret;
3025
3026 LOCK_TAKE(hdw->ctl_lock);
3027
3028 hdw->cmd_buffer[0] = (data >> 8) & 0xff;
3029 hdw->cmd_buffer[1] = data & 0xff;
3030
3031 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
3032
3033 LOCK_GIVE(hdw->ctl_lock);
3034
3035 return ret;
3036}
3037
3038
Adrian Bunk07e337e2006-06-30 11:30:20 -03003039static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03003040{
3041 int ret;
3042
3043 LOCK_TAKE(hdw->ctl_lock);
3044
3045 hdw->cmd_buffer[0] = data;
3046
3047 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
3048
3049 LOCK_GIVE(hdw->ctl_lock);
3050
3051 return ret;
3052}
3053
3054
Adrian Bunk07e337e2006-06-30 11:30:20 -03003055static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003056{
3057 if (!hdw->flag_ok) return;
3058 pvr2_trace(PVR2_TRACE_INIT,"render_useless");
3059 hdw->flag_ok = 0;
3060 if (hdw->vid_stream) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003061 pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003062 }
3063 hdw->flag_streaming_enabled = 0;
3064 hdw->subsys_enabled_mask = 0;
3065}
3066
3067
3068void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
3069{
3070 LOCK_TAKE(hdw->ctl_lock);
3071 pvr2_hdw_render_useless_unlocked(hdw);
3072 LOCK_GIVE(hdw->ctl_lock);
3073}
3074
3075
3076void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
3077{
3078 int ret;
3079 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003080 ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -03003081 if (ret == 1) {
3082 ret = usb_reset_device(hdw->usb_dev);
3083 usb_unlock_device(hdw->usb_dev);
3084 } else {
3085 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3086 "Failed to lock USB device ret=%d",ret);
3087 }
3088 if (init_pause_msec) {
3089 pvr2_trace(PVR2_TRACE_INFO,
3090 "Waiting %u msec for hardware to settle",
3091 init_pause_msec);
3092 msleep(init_pause_msec);
3093 }
3094
3095}
3096
3097
3098void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
3099{
3100 char da[1];
3101 unsigned int pipe;
3102 int ret;
3103
3104 if (!hdw->usb_dev) return;
3105
3106 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
3107
3108 da[0] = val ? 0x01 : 0x00;
3109
3110 /* Write the CPUCS register on the 8051. The lsb of the register
3111 is the reset bit; a 1 asserts reset while a 0 clears it. */
3112 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
3113 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
3114 if (ret < 0) {
3115 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3116 "cpureset_assert(%d) error=%d",val,ret);
3117 pvr2_hdw_render_useless(hdw);
3118 }
3119}
3120
3121
3122int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
3123{
3124 int status;
3125 LOCK_TAKE(hdw->ctl_lock); do {
3126 pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
3127 hdw->flag_ok = !0;
3128 hdw->cmd_buffer[0] = 0xdd;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003129 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003130 } while (0); LOCK_GIVE(hdw->ctl_lock);
3131 return status;
3132}
3133
3134
3135int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
3136{
3137 int status;
3138 LOCK_TAKE(hdw->ctl_lock); do {
3139 pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
3140 hdw->cmd_buffer[0] = 0xde;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003141 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003142 } while (0); LOCK_GIVE(hdw->ctl_lock);
3143 return status;
3144}
3145
3146
3147int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
3148{
3149 if (!hdw->decoder_ctrl) {
3150 pvr2_trace(PVR2_TRACE_INIT,
3151 "Unable to reset decoder: nothing attached");
3152 return -ENOTTY;
3153 }
3154
3155 if (!hdw->decoder_ctrl->force_reset) {
3156 pvr2_trace(PVR2_TRACE_INIT,
3157 "Unable to reset decoder: not implemented");
3158 return -ENOTTY;
3159 }
3160
3161 pvr2_trace(PVR2_TRACE_INIT,
3162 "Requesting decoder reset");
3163 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
3164 return 0;
3165}
3166
3167
Mike Iselye61b6fc2006-07-18 22:42:18 -03003168/* Stop / start video stream transport */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003169static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03003170{
3171 int status;
3172 LOCK_TAKE(hdw->ctl_lock); do {
3173 hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003174 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003175 } while (0); LOCK_GIVE(hdw->ctl_lock);
3176 if (!status) {
3177 hdw->subsys_enabled_mask =
3178 ((hdw->subsys_enabled_mask &
3179 ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
3180 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
3181 }
3182 return status;
3183}
3184
3185
3186void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
3187 struct pvr2_hdw_debug_info *ptr)
3188{
3189 ptr->big_lock_held = hdw->big_lock_held;
3190 ptr->ctl_lock_held = hdw->ctl_lock_held;
3191 ptr->flag_ok = hdw->flag_ok;
3192 ptr->flag_disconnected = hdw->flag_disconnected;
3193 ptr->flag_init_ok = hdw->flag_init_ok;
3194 ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
3195 ptr->subsys_flags = hdw->subsys_enabled_mask;
3196 ptr->cmd_debug_state = hdw->cmd_debug_state;
3197 ptr->cmd_code = hdw->cmd_debug_code;
3198 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
3199 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
3200 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
3201 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
3202 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
3203 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
3204 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
3205}
3206
3207
3208int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
3209{
3210 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
3211}
3212
3213
3214int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
3215{
3216 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
3217}
3218
3219
3220int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
3221{
3222 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
3223}
3224
3225
3226int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
3227{
3228 u32 cval,nval;
3229 int ret;
3230 if (~msk) {
3231 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
3232 if (ret) return ret;
3233 nval = (cval & ~msk) | (val & msk);
3234 pvr2_trace(PVR2_TRACE_GPIO,
3235 "GPIO direction changing 0x%x:0x%x"
3236 " from 0x%x to 0x%x",
3237 msk,val,cval,nval);
3238 } else {
3239 nval = val;
3240 pvr2_trace(PVR2_TRACE_GPIO,
3241 "GPIO direction changing to 0x%x",nval);
3242 }
3243 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
3244}
3245
3246
3247int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
3248{
3249 u32 cval,nval;
3250 int ret;
3251 if (~msk) {
3252 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
3253 if (ret) return ret;
3254 nval = (cval & ~msk) | (val & msk);
3255 pvr2_trace(PVR2_TRACE_GPIO,
3256 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
3257 msk,val,cval,nval);
3258 } else {
3259 nval = val;
3260 pvr2_trace(PVR2_TRACE_GPIO,
3261 "GPIO output changing to 0x%x",nval);
3262 }
3263 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
3264}
3265
3266
Mike Iselye61b6fc2006-07-18 22:42:18 -03003267/* Find I2C address of eeprom */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003268static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003269{
3270 int result;
3271 LOCK_TAKE(hdw->ctl_lock); do {
3272 hdw->cmd_buffer[0] = 0xeb;
3273 result = pvr2_send_request(hdw,
3274 hdw->cmd_buffer,1,
3275 hdw->cmd_buffer,1);
3276 if (result < 0) break;
3277 result = hdw->cmd_buffer[0];
3278 } while(0); LOCK_GIVE(hdw->ctl_lock);
3279 return result;
3280}
3281
3282
Mike Isely32ffa9a2006-09-23 22:26:52 -03003283int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
3284 u32 chip_id,unsigned long reg_id,
3285 int setFl,u32 *val_ptr)
3286{
3287#ifdef CONFIG_VIDEO_ADV_DEBUG
3288 struct list_head *item;
3289 struct pvr2_i2c_client *cp;
3290 struct v4l2_register req;
Mike Isely6d988162006-09-28 17:53:49 -03003291 int stat = 0;
3292 int okFl = 0;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003293
3294 req.i2c_id = chip_id;
3295 req.reg = reg_id;
3296 if (setFl) req.val = *val_ptr;
3297 mutex_lock(&hdw->i2c_list_lock); do {
3298 list_for_each(item,&hdw->i2c_clients) {
3299 cp = list_entry(item,struct pvr2_i2c_client,list);
3300 if (cp->client->driver->id != chip_id) continue;
3301 stat = pvr2_i2c_client_cmd(
3302 cp,(setFl ? VIDIOC_INT_S_REGISTER :
3303 VIDIOC_INT_G_REGISTER),&req);
3304 if (!setFl) *val_ptr = req.val;
Mike Isely6d988162006-09-28 17:53:49 -03003305 okFl = !0;
3306 break;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003307 }
3308 } while (0); mutex_unlock(&hdw->i2c_list_lock);
Mike Isely6d988162006-09-28 17:53:49 -03003309 if (okFl) {
3310 return stat;
3311 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03003312 return -EINVAL;
3313#else
3314 return -ENOSYS;
3315#endif
3316}
3317
3318
Mike Iselyd8554972006-06-26 20:58:46 -03003319/*
3320 Stuff for Emacs to see, in order to encourage consistent editing style:
3321 *** Local Variables: ***
3322 *** mode: c ***
3323 *** fill-column: 75 ***
3324 *** tab-width: 8 ***
3325 *** c-basic-offset: 8 ***
3326 *** End: ***
3327 */