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