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