blob: 9916cf32494d9843570eebc69ae050419c958c00 [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);
Mike Iselyd8554972006-06-26 20:58:46 -0300274
275static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
276{
277 struct pvr2_hdw *hdw = cptr->hdw;
278 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
279 *vp = hdw->freqTable[hdw->freqProgSlot-1];
280 } else {
281 *vp = 0;
282 }
283 return 0;
284}
285
286static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
287{
288 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300289 unsigned int slotId = hdw->freqProgSlot;
290 if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) {
291 hdw->freqTable[slotId-1] = v;
292 /* Handle side effects correctly - if we're tuned to this
293 slot, then forgot the slot id relation since the stored
294 frequency has been changed. */
295 if (hdw->freqSelector) {
296 if (hdw->freqSlotRadio == slotId) {
297 hdw->freqSlotRadio = 0;
298 }
299 } else {
300 if (hdw->freqSlotTelevision == slotId) {
301 hdw->freqSlotTelevision = 0;
302 }
303 }
Mike Iselyd8554972006-06-26 20:58:46 -0300304 }
305 return 0;
306}
307
308static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
309{
310 *vp = cptr->hdw->freqProgSlot;
311 return 0;
312}
313
314static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
315{
316 struct pvr2_hdw *hdw = cptr->hdw;
317 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
318 hdw->freqProgSlot = v;
319 }
320 return 0;
321}
322
323static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
324{
Mike Isely1bde0282006-12-27 23:30:13 -0300325 struct pvr2_hdw *hdw = cptr->hdw;
326 *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision;
Mike Iselyd8554972006-06-26 20:58:46 -0300327 return 0;
328}
329
Mike Isely1bde0282006-12-27 23:30:13 -0300330static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId)
Mike Iselyd8554972006-06-26 20:58:46 -0300331{
332 unsigned freq = 0;
333 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300334 if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0;
335 if (slotId > 0) {
336 freq = hdw->freqTable[slotId-1];
337 if (!freq) return 0;
338 pvr2_hdw_set_cur_freq(hdw,freq);
Mike Iselyd8554972006-06-26 20:58:46 -0300339 }
Mike Isely1bde0282006-12-27 23:30:13 -0300340 if (hdw->freqSelector) {
341 hdw->freqSlotRadio = slotId;
342 } else {
343 hdw->freqSlotTelevision = slotId;
Mike Iselyd8554972006-06-26 20:58:46 -0300344 }
345 return 0;
346}
347
348static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
349{
Mike Isely1bde0282006-12-27 23:30:13 -0300350 *vp = pvr2_hdw_get_cur_freq(cptr->hdw);
Mike Iselyd8554972006-06-26 20:58:46 -0300351 return 0;
352}
353
354static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
355{
356 return cptr->hdw->freqDirty != 0;
357}
358
359static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
360{
361 cptr->hdw->freqDirty = 0;
362}
363
364static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
365{
Mike Isely1bde0282006-12-27 23:30:13 -0300366 pvr2_hdw_set_cur_freq(cptr->hdw,v);
Mike Iselyd8554972006-06-26 20:58:46 -0300367 return 0;
368}
369
Mike Isely3ad9fc32006-09-02 22:37:52 -0300370static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
371{
372 /* Actual maximum depends on the video standard in effect. */
373 if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
374 *vp = 480;
375 } else {
376 *vp = 576;
377 }
378 return 0;
379}
380
381static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
382{
383 /* Actual minimum depends on device type. */
384 if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
385 *vp = 75;
386 } else {
387 *vp = 17;
388 }
389 return 0;
390}
391
Mike Isely1bde0282006-12-27 23:30:13 -0300392static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
393{
394 *vp = cptr->hdw->input_val;
395 return 0;
396}
397
398static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
399{
400 struct pvr2_hdw *hdw = cptr->hdw;
401
402 if (hdw->input_val != v) {
403 hdw->input_val = v;
404 hdw->input_dirty = !0;
405 }
406
407 /* Handle side effects - if we switch to a mode that needs the RF
408 tuner, then select the right frequency choice as well and mark
409 it dirty. */
410 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
411 hdw->freqSelector = 0;
412 hdw->freqDirty = !0;
413 } else if (hdw->input_val == PVR2_CVAL_INPUT_TV) {
414 hdw->freqSelector = 1;
415 hdw->freqDirty = !0;
416 }
417 return 0;
418}
419
420static int ctrl_isdirty_input(struct pvr2_ctrl *cptr)
421{
422 return cptr->hdw->input_dirty != 0;
423}
424
425static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr)
426{
427 cptr->hdw->input_dirty = 0;
428}
429
Mike Isely5549f542006-12-27 23:28:54 -0300430
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300431static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
432{
Mike Isely644afdb2007-01-20 00:19:23 -0300433 unsigned long fv;
434 struct pvr2_hdw *hdw = cptr->hdw;
435 if (hdw->tuner_signal_stale) {
436 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300437 }
Mike Isely644afdb2007-01-20 00:19:23 -0300438 fv = hdw->tuner_signal_info.rangehigh;
439 if (!fv) {
440 /* Safety fallback */
441 *vp = TV_MAX_FREQ;
442 return 0;
443 }
444 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
445 fv = (fv * 125) / 2;
446 } else {
447 fv = fv * 62500;
448 }
449 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300450 return 0;
451}
452
453static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
454{
Mike Isely644afdb2007-01-20 00:19:23 -0300455 unsigned long fv;
456 struct pvr2_hdw *hdw = cptr->hdw;
457 if (hdw->tuner_signal_stale) {
458 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300459 }
Mike Isely644afdb2007-01-20 00:19:23 -0300460 fv = hdw->tuner_signal_info.rangelow;
461 if (!fv) {
462 /* Safety fallback */
463 *vp = TV_MIN_FREQ;
464 return 0;
465 }
466 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
467 fv = (fv * 125) / 2;
468 } else {
469 fv = fv * 62500;
470 }
471 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300472 return 0;
473}
474
Mike Iselyb30d2442006-06-25 20:05:01 -0300475static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
476{
477 return cptr->hdw->enc_stale != 0;
478}
479
480static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
481{
482 cptr->hdw->enc_stale = 0;
483}
484
485static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
486{
487 int ret;
488 struct v4l2_ext_controls cs;
489 struct v4l2_ext_control c1;
490 memset(&cs,0,sizeof(cs));
491 memset(&c1,0,sizeof(c1));
492 cs.controls = &c1;
493 cs.count = 1;
494 c1.id = cptr->info->v4l_id;
495 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
496 VIDIOC_G_EXT_CTRLS);
497 if (ret) return ret;
498 *vp = c1.value;
499 return 0;
500}
501
502static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
503{
504 int ret;
505 struct v4l2_ext_controls cs;
506 struct v4l2_ext_control c1;
507 memset(&cs,0,sizeof(cs));
508 memset(&c1,0,sizeof(c1));
509 cs.controls = &c1;
510 cs.count = 1;
511 c1.id = cptr->info->v4l_id;
512 c1.value = v;
513 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
514 VIDIOC_S_EXT_CTRLS);
515 if (ret) return ret;
516 cptr->hdw->enc_stale = !0;
517 return 0;
518}
519
520static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
521{
522 struct v4l2_queryctrl qctrl;
523 struct pvr2_ctl_info *info;
524 qctrl.id = cptr->info->v4l_id;
525 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
526 /* Strip out the const so we can adjust a function pointer. It's
527 OK to do this here because we know this is a dynamically created
528 control, so the underlying storage for the info pointer is (a)
529 private to us, and (b) not in read-only storage. Either we do
530 this or we significantly complicate the underlying control
531 implementation. */
532 info = (struct pvr2_ctl_info *)(cptr->info);
533 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
534 if (info->set_value) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300535 info->set_value = NULL;
Mike Iselyb30d2442006-06-25 20:05:01 -0300536 }
537 } else {
538 if (!(info->set_value)) {
539 info->set_value = ctrl_cx2341x_set;
540 }
541 }
542 return qctrl.flags;
543}
544
Mike Iselyd8554972006-06-26 20:58:46 -0300545static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
546{
547 *vp = cptr->hdw->flag_streaming_enabled;
548 return 0;
549}
550
551static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
552{
553 int result = pvr2_hdw_is_hsm(cptr->hdw);
554 *vp = PVR2_CVAL_HSM_FULL;
555 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
556 if (result) *vp = PVR2_CVAL_HSM_HIGH;
557 return 0;
558}
559
560static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
561{
562 *vp = cptr->hdw->std_mask_avail;
563 return 0;
564}
565
566static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
567{
568 struct pvr2_hdw *hdw = cptr->hdw;
569 v4l2_std_id ns;
570 ns = hdw->std_mask_avail;
571 ns = (ns & ~m) | (v & m);
572 if (ns == hdw->std_mask_avail) return 0;
573 hdw->std_mask_avail = ns;
574 pvr2_hdw_internal_set_std_avail(hdw);
575 pvr2_hdw_internal_find_stdenum(hdw);
576 return 0;
577}
578
579static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
580 char *bufPtr,unsigned int bufSize,
581 unsigned int *len)
582{
583 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
584 return 0;
585}
586
587static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
588 const char *bufPtr,unsigned int bufSize,
589 int *mskp,int *valp)
590{
591 int ret;
592 v4l2_std_id id;
593 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
594 if (ret < 0) return ret;
595 if (mskp) *mskp = id;
596 if (valp) *valp = id;
597 return 0;
598}
599
600static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
601{
602 *vp = cptr->hdw->std_mask_cur;
603 return 0;
604}
605
606static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
607{
608 struct pvr2_hdw *hdw = cptr->hdw;
609 v4l2_std_id ns;
610 ns = hdw->std_mask_cur;
611 ns = (ns & ~m) | (v & m);
612 if (ns == hdw->std_mask_cur) return 0;
613 hdw->std_mask_cur = ns;
614 hdw->std_dirty = !0;
615 pvr2_hdw_internal_find_stdenum(hdw);
616 return 0;
617}
618
619static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
620{
621 return cptr->hdw->std_dirty != 0;
622}
623
624static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
625{
626 cptr->hdw->std_dirty = 0;
627}
628
629static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
630{
Mike Isely18103c52007-01-20 00:09:47 -0300631 struct pvr2_hdw *hdw = cptr->hdw;
632 pvr2_i2c_core_status_poll(hdw);
633 *vp = hdw->tuner_signal_info.signal;
634 return 0;
635}
636
637static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
638{
639 int val = 0;
640 unsigned int subchan;
641 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely644afdb2007-01-20 00:19:23 -0300642 pvr2_i2c_core_status_poll(hdw);
Mike Isely18103c52007-01-20 00:09:47 -0300643 subchan = hdw->tuner_signal_info.rxsubchans;
644 if (subchan & V4L2_TUNER_SUB_MONO) {
645 val |= (1 << V4L2_TUNER_MODE_MONO);
646 }
647 if (subchan & V4L2_TUNER_SUB_STEREO) {
648 val |= (1 << V4L2_TUNER_MODE_STEREO);
649 }
650 if (subchan & V4L2_TUNER_SUB_LANG1) {
651 val |= (1 << V4L2_TUNER_MODE_LANG1);
652 }
653 if (subchan & V4L2_TUNER_SUB_LANG2) {
654 val |= (1 << V4L2_TUNER_MODE_LANG2);
655 }
656 *vp = val;
Mike Iselyd8554972006-06-26 20:58:46 -0300657 return 0;
658}
659
660static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp)
661{
662 *vp = cptr->hdw->subsys_enabled_mask;
663 return 0;
664}
665
666static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v)
667{
668 pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v);
669 return 0;
670}
671
672static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp)
673{
674 *vp = cptr->hdw->subsys_stream_mask;
675 return 0;
676}
677
678static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v)
679{
680 pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v);
681 return 0;
682}
683
684static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
685{
686 struct pvr2_hdw *hdw = cptr->hdw;
687 if (v < 0) return -EINVAL;
688 if (v > hdw->std_enum_cnt) return -EINVAL;
689 hdw->std_enum_cur = v;
690 if (!v) return 0;
691 v--;
692 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
693 hdw->std_mask_cur = hdw->std_defs[v].id;
694 hdw->std_dirty = !0;
695 return 0;
696}
697
698
699static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
700{
701 *vp = cptr->hdw->std_enum_cur;
702 return 0;
703}
704
705
706static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
707{
708 return cptr->hdw->std_dirty != 0;
709}
710
711
712static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
713{
714 cptr->hdw->std_dirty = 0;
715}
716
717
718#define DEFINT(vmin,vmax) \
719 .type = pvr2_ctl_int, \
720 .def.type_int.min_value = vmin, \
721 .def.type_int.max_value = vmax
722
723#define DEFENUM(tab) \
724 .type = pvr2_ctl_enum, \
Mike Isely27c7b712007-01-20 00:39:17 -0300725 .def.type_enum.count = ARRAY_SIZE(tab), \
Mike Iselyd8554972006-06-26 20:58:46 -0300726 .def.type_enum.value_names = tab
727
Mike Isely33213962006-06-25 20:04:40 -0300728#define DEFBOOL \
729 .type = pvr2_ctl_bool
730
Mike Iselyd8554972006-06-26 20:58:46 -0300731#define DEFMASK(msk,tab) \
732 .type = pvr2_ctl_bitmask, \
733 .def.type_bitmask.valid_bits = msk, \
734 .def.type_bitmask.bit_names = tab
735
736#define DEFREF(vname) \
737 .set_value = ctrl_set_##vname, \
738 .get_value = ctrl_get_##vname, \
739 .is_dirty = ctrl_isdirty_##vname, \
740 .clear_dirty = ctrl_cleardirty_##vname
741
742
743#define VCREATE_FUNCS(vname) \
744static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
745{*vp = cptr->hdw->vname##_val; return 0;} \
746static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
747{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
748static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
749{return cptr->hdw->vname##_dirty != 0;} \
750static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
751{cptr->hdw->vname##_dirty = 0;}
752
753VCREATE_FUNCS(brightness)
754VCREATE_FUNCS(contrast)
755VCREATE_FUNCS(saturation)
756VCREATE_FUNCS(hue)
757VCREATE_FUNCS(volume)
758VCREATE_FUNCS(balance)
759VCREATE_FUNCS(bass)
760VCREATE_FUNCS(treble)
761VCREATE_FUNCS(mute)
Mike Iselyc05c0462006-06-25 20:04:25 -0300762VCREATE_FUNCS(audiomode)
763VCREATE_FUNCS(res_hor)
764VCREATE_FUNCS(res_ver)
Mike Iselyd8554972006-06-26 20:58:46 -0300765VCREATE_FUNCS(srate)
Mike Iselyd8554972006-06-26 20:58:46 -0300766
Mike Iselyd8554972006-06-26 20:58:46 -0300767/* Table definition of all controls which can be manipulated */
768static const struct pvr2_ctl_info control_defs[] = {
769 {
770 .v4l_id = V4L2_CID_BRIGHTNESS,
771 .desc = "Brightness",
772 .name = "brightness",
773 .default_value = 128,
774 DEFREF(brightness),
775 DEFINT(0,255),
776 },{
777 .v4l_id = V4L2_CID_CONTRAST,
778 .desc = "Contrast",
779 .name = "contrast",
780 .default_value = 68,
781 DEFREF(contrast),
782 DEFINT(0,127),
783 },{
784 .v4l_id = V4L2_CID_SATURATION,
785 .desc = "Saturation",
786 .name = "saturation",
787 .default_value = 64,
788 DEFREF(saturation),
789 DEFINT(0,127),
790 },{
791 .v4l_id = V4L2_CID_HUE,
792 .desc = "Hue",
793 .name = "hue",
794 .default_value = 0,
795 DEFREF(hue),
796 DEFINT(-128,127),
797 },{
798 .v4l_id = V4L2_CID_AUDIO_VOLUME,
799 .desc = "Volume",
800 .name = "volume",
Mike Isely139eecf2006-12-27 23:36:33 -0300801 .default_value = 62000,
Mike Iselyd8554972006-06-26 20:58:46 -0300802 DEFREF(volume),
803 DEFINT(0,65535),
804 },{
805 .v4l_id = V4L2_CID_AUDIO_BALANCE,
806 .desc = "Balance",
807 .name = "balance",
808 .default_value = 0,
809 DEFREF(balance),
810 DEFINT(-32768,32767),
811 },{
812 .v4l_id = V4L2_CID_AUDIO_BASS,
813 .desc = "Bass",
814 .name = "bass",
815 .default_value = 0,
816 DEFREF(bass),
817 DEFINT(-32768,32767),
818 },{
819 .v4l_id = V4L2_CID_AUDIO_TREBLE,
820 .desc = "Treble",
821 .name = "treble",
822 .default_value = 0,
823 DEFREF(treble),
824 DEFINT(-32768,32767),
825 },{
826 .v4l_id = V4L2_CID_AUDIO_MUTE,
827 .desc = "Mute",
828 .name = "mute",
829 .default_value = 0,
830 DEFREF(mute),
Mike Isely33213962006-06-25 20:04:40 -0300831 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300832 },{
Mike Iselyc05c0462006-06-25 20:04:25 -0300833 .desc = "Video Source",
834 .name = "input",
835 .internal_id = PVR2_CID_INPUT,
836 .default_value = PVR2_CVAL_INPUT_TV,
837 DEFREF(input),
838 DEFENUM(control_values_input),
839 },{
840 .desc = "Audio Mode",
841 .name = "audio_mode",
842 .internal_id = PVR2_CID_AUDIOMODE,
843 .default_value = V4L2_TUNER_MODE_STEREO,
844 DEFREF(audiomode),
845 DEFENUM(control_values_audiomode),
846 },{
847 .desc = "Horizontal capture resolution",
848 .name = "resolution_hor",
849 .internal_id = PVR2_CID_HRES,
850 .default_value = 720,
851 DEFREF(res_hor),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300852 DEFINT(19,720),
Mike Iselyc05c0462006-06-25 20:04:25 -0300853 },{
854 .desc = "Vertical capture resolution",
855 .name = "resolution_ver",
856 .internal_id = PVR2_CID_VRES,
857 .default_value = 480,
858 DEFREF(res_ver),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300859 DEFINT(17,576),
860 /* Hook in check for video standard and adjust maximum
861 depending on the standard. */
862 .get_max_value = ctrl_vres_max_get,
863 .get_min_value = ctrl_vres_min_get,
Mike Iselyc05c0462006-06-25 20:04:25 -0300864 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300865 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
Mike Isely434449f2006-08-08 09:10:06 -0300866 .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
867 .desc = "Audio Sampling Frequency",
Mike Iselyd8554972006-06-26 20:58:46 -0300868 .name = "srate",
Mike Iselyd8554972006-06-26 20:58:46 -0300869 DEFREF(srate),
870 DEFENUM(control_values_srate),
871 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300872 .desc = "Tuner Frequency (Hz)",
873 .name = "frequency",
874 .internal_id = PVR2_CID_FREQUENCY,
Mike Isely1bde0282006-12-27 23:30:13 -0300875 .default_value = 0,
Mike Iselyd8554972006-06-26 20:58:46 -0300876 .set_value = ctrl_freq_set,
877 .get_value = ctrl_freq_get,
878 .is_dirty = ctrl_freq_is_dirty,
879 .clear_dirty = ctrl_freq_clear_dirty,
Mike Isely644afdb2007-01-20 00:19:23 -0300880 DEFINT(0,0),
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300881 /* Hook in check for input value (tv/radio) and adjust
882 max/min values accordingly */
883 .get_max_value = ctrl_freq_max_get,
884 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300885 },{
886 .desc = "Channel",
887 .name = "channel",
888 .set_value = ctrl_channel_set,
889 .get_value = ctrl_channel_get,
890 DEFINT(0,FREQTABLE_SIZE),
891 },{
892 .desc = "Channel Program Frequency",
893 .name = "freq_table_value",
894 .set_value = ctrl_channelfreq_set,
895 .get_value = ctrl_channelfreq_get,
Mike Isely644afdb2007-01-20 00:19:23 -0300896 DEFINT(0,0),
Mike Isely1bde0282006-12-27 23:30:13 -0300897 /* Hook in check for input value (tv/radio) and adjust
898 max/min values accordingly */
Mike Isely1bde0282006-12-27 23:30:13 -0300899 .get_max_value = ctrl_freq_max_get,
900 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300901 },{
902 .desc = "Channel Program ID",
903 .name = "freq_table_channel",
904 .set_value = ctrl_channelprog_set,
905 .get_value = ctrl_channelprog_get,
906 DEFINT(0,FREQTABLE_SIZE),
907 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300908 .desc = "Streaming Enabled",
909 .name = "streaming_enabled",
910 .get_value = ctrl_streamingenabled_get,
Mike Isely33213962006-06-25 20:04:40 -0300911 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300912 },{
913 .desc = "USB Speed",
914 .name = "usb_speed",
915 .get_value = ctrl_hsm_get,
916 DEFENUM(control_values_hsm),
917 },{
918 .desc = "Signal Present",
919 .name = "signal_present",
920 .get_value = ctrl_signal_get,
Mike Isely18103c52007-01-20 00:09:47 -0300921 DEFINT(0,65535),
922 },{
923 .desc = "Audio Modes Present",
924 .name = "audio_modes_present",
925 .get_value = ctrl_audio_modes_present_get,
926 /* For this type we "borrow" the V4L2_TUNER_MODE enum from
927 v4l. Nothing outside of this module cares about this,
928 but I reuse it in order to also reuse the
929 control_values_audiomode string table. */
930 DEFMASK(((1 << V4L2_TUNER_MODE_MONO)|
931 (1 << V4L2_TUNER_MODE_STEREO)|
932 (1 << V4L2_TUNER_MODE_LANG1)|
933 (1 << V4L2_TUNER_MODE_LANG2)),
934 control_values_audiomode),
Mike Iselyd8554972006-06-26 20:58:46 -0300935 },{
936 .desc = "Video Standards Available Mask",
937 .name = "video_standard_mask_available",
938 .internal_id = PVR2_CID_STDAVAIL,
939 .skip_init = !0,
940 .get_value = ctrl_stdavail_get,
941 .set_value = ctrl_stdavail_set,
942 .val_to_sym = ctrl_std_val_to_sym,
943 .sym_to_val = ctrl_std_sym_to_val,
944 .type = pvr2_ctl_bitmask,
945 },{
946 .desc = "Video Standards In Use Mask",
947 .name = "video_standard_mask_active",
948 .internal_id = PVR2_CID_STDCUR,
949 .skip_init = !0,
950 .get_value = ctrl_stdcur_get,
951 .set_value = ctrl_stdcur_set,
952 .is_dirty = ctrl_stdcur_is_dirty,
953 .clear_dirty = ctrl_stdcur_clear_dirty,
954 .val_to_sym = ctrl_std_val_to_sym,
955 .sym_to_val = ctrl_std_sym_to_val,
956 .type = pvr2_ctl_bitmask,
957 },{
958 .desc = "Subsystem enabled mask",
959 .name = "debug_subsys_mask",
960 .skip_init = !0,
961 .get_value = ctrl_subsys_get,
962 .set_value = ctrl_subsys_set,
963 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
964 },{
965 .desc = "Subsystem stream mask",
966 .name = "debug_subsys_stream_mask",
967 .skip_init = !0,
968 .get_value = ctrl_subsys_stream_get,
969 .set_value = ctrl_subsys_stream_set,
970 DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem),
971 },{
972 .desc = "Video Standard Name",
973 .name = "video_standard",
974 .internal_id = PVR2_CID_STDENUM,
975 .skip_init = !0,
976 .get_value = ctrl_stdenumcur_get,
977 .set_value = ctrl_stdenumcur_set,
978 .is_dirty = ctrl_stdenumcur_is_dirty,
979 .clear_dirty = ctrl_stdenumcur_clear_dirty,
980 .type = pvr2_ctl_enum,
981 }
982};
983
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -0300984#define CTRLDEF_COUNT ARRAY_SIZE(control_defs)
Mike Iselyd8554972006-06-26 20:58:46 -0300985
986
987const char *pvr2_config_get_name(enum pvr2_config cfg)
988{
989 switch (cfg) {
990 case pvr2_config_empty: return "empty";
991 case pvr2_config_mpeg: return "mpeg";
992 case pvr2_config_vbi: return "vbi";
Mike Isely16eb40d2006-12-30 18:27:32 -0300993 case pvr2_config_pcm: return "pcm";
994 case pvr2_config_rawvideo: return "raw video";
Mike Iselyd8554972006-06-26 20:58:46 -0300995 }
996 return "<unknown>";
997}
998
999
1000struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
1001{
1002 return hdw->usb_dev;
1003}
1004
1005
1006unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
1007{
1008 return hdw->serial_number;
1009}
1010
Mike Isely1bde0282006-12-27 23:30:13 -03001011unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
1012{
1013 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
1014}
1015
1016/* Set the currently tuned frequency and account for all possible
1017 driver-core side effects of this action. */
1018void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val)
1019{
Mike Isely7c74e572007-01-20 00:15:41 -03001020 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
Mike Isely1bde0282006-12-27 23:30:13 -03001021 if (hdw->freqSelector) {
1022 /* Swing over to radio frequency selection */
1023 hdw->freqSelector = 0;
1024 hdw->freqDirty = !0;
1025 }
Mike Isely1bde0282006-12-27 23:30:13 -03001026 if (hdw->freqValRadio != val) {
1027 hdw->freqValRadio = val;
1028 hdw->freqSlotRadio = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001029 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001030 }
Mike Isely7c74e572007-01-20 00:15:41 -03001031 } else {
Mike Isely1bde0282006-12-27 23:30:13 -03001032 if (!(hdw->freqSelector)) {
1033 /* Swing over to television frequency selection */
1034 hdw->freqSelector = 1;
1035 hdw->freqDirty = !0;
1036 }
Mike Isely1bde0282006-12-27 23:30:13 -03001037 if (hdw->freqValTelevision != val) {
1038 hdw->freqValTelevision = val;
1039 hdw->freqSlotTelevision = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001040 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001041 }
Mike Isely1bde0282006-12-27 23:30:13 -03001042 }
1043}
1044
Mike Iselyd8554972006-06-26 20:58:46 -03001045int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
1046{
1047 return hdw->unit_number;
1048}
1049
1050
1051/* Attempt to locate one of the given set of files. Messages are logged
1052 appropriate to what has been found. The return value will be 0 or
1053 greater on success (it will be the index of the file name found) and
1054 fw_entry will be filled in. Otherwise a negative error is returned on
1055 failure. If the return value is -ENOENT then no viable firmware file
1056 could be located. */
1057static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
1058 const struct firmware **fw_entry,
1059 const char *fwtypename,
1060 unsigned int fwcount,
1061 const char *fwnames[])
1062{
1063 unsigned int idx;
1064 int ret = -EINVAL;
1065 for (idx = 0; idx < fwcount; idx++) {
1066 ret = request_firmware(fw_entry,
1067 fwnames[idx],
1068 &hdw->usb_dev->dev);
1069 if (!ret) {
1070 trace_firmware("Located %s firmware: %s;"
1071 " uploading...",
1072 fwtypename,
1073 fwnames[idx]);
1074 return idx;
1075 }
1076 if (ret == -ENOENT) continue;
1077 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1078 "request_firmware fatal error with code=%d",ret);
1079 return ret;
1080 }
1081 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1082 "***WARNING***"
1083 " Device %s firmware"
1084 " seems to be missing.",
1085 fwtypename);
1086 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1087 "Did you install the pvrusb2 firmware files"
1088 " in their proper location?");
1089 if (fwcount == 1) {
1090 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1091 "request_firmware unable to locate %s file %s",
1092 fwtypename,fwnames[0]);
1093 } else {
1094 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1095 "request_firmware unable to locate"
1096 " one of the following %s files:",
1097 fwtypename);
1098 for (idx = 0; idx < fwcount; idx++) {
1099 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1100 "request_firmware: Failed to find %s",
1101 fwnames[idx]);
1102 }
1103 }
1104 return ret;
1105}
1106
1107
1108/*
1109 * pvr2_upload_firmware1().
1110 *
1111 * Send the 8051 firmware to the device. After the upload, arrange for
1112 * device to re-enumerate.
1113 *
1114 * NOTE : the pointer to the firmware data given by request_firmware()
1115 * is not suitable for an usb transaction.
1116 *
1117 */
Adrian Bunk07e337e2006-06-30 11:30:20 -03001118static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001119{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001120 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001121 void *fw_ptr;
1122 unsigned int pipe;
1123 int ret;
1124 u16 address;
1125 static const char *fw_files_29xxx[] = {
1126 "v4l-pvrusb2-29xxx-01.fw",
1127 };
Mike Iselyd8554972006-06-26 20:58:46 -03001128 static const char *fw_files_24xxx[] = {
1129 "v4l-pvrusb2-24xxx-01.fw",
1130 };
Mike Iselyd8554972006-06-26 20:58:46 -03001131 static const struct pvr2_string_table fw_file_defs[] = {
1132 [PVR2_HDW_TYPE_29XXX] = {
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001133 fw_files_29xxx, ARRAY_SIZE(fw_files_29xxx)
Mike Iselyd8554972006-06-26 20:58:46 -03001134 },
Mike Iselyd8554972006-06-26 20:58:46 -03001135 [PVR2_HDW_TYPE_24XXX] = {
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001136 fw_files_24xxx, ARRAY_SIZE(fw_files_24xxx)
Mike Iselyd8554972006-06-26 20:58:46 -03001137 },
Mike Iselyd8554972006-06-26 20:58:46 -03001138 };
1139 hdw->fw1_state = FW1_STATE_FAILED; // default result
1140
1141 trace_firmware("pvr2_upload_firmware1");
1142
1143 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
1144 fw_file_defs[hdw->hdw_type].cnt,
1145 fw_file_defs[hdw->hdw_type].lst);
1146 if (ret < 0) {
1147 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
1148 return ret;
1149 }
1150
1151 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
1152 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
1153
1154 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
1155
1156 if (fw_entry->size != 0x2000){
1157 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
1158 release_firmware(fw_entry);
1159 return -ENOMEM;
1160 }
1161
1162 fw_ptr = kmalloc(0x800, GFP_KERNEL);
1163 if (fw_ptr == NULL){
1164 release_firmware(fw_entry);
1165 return -ENOMEM;
1166 }
1167
1168 /* We have to hold the CPU during firmware upload. */
1169 pvr2_hdw_cpureset_assert(hdw,1);
1170
1171 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
1172 chunk. */
1173
1174 ret = 0;
1175 for(address = 0; address < fw_entry->size; address += 0x800) {
1176 memcpy(fw_ptr, fw_entry->data + address, 0x800);
1177 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
1178 0, fw_ptr, 0x800, HZ);
1179 }
1180
1181 trace_firmware("Upload done, releasing device's CPU");
1182
1183 /* Now release the CPU. It will disconnect and reconnect later. */
1184 pvr2_hdw_cpureset_assert(hdw,0);
1185
1186 kfree(fw_ptr);
1187 release_firmware(fw_entry);
1188
1189 trace_firmware("Upload done (%d bytes sent)",ret);
1190
1191 /* We should have written 8192 bytes */
1192 if (ret == 8192) {
1193 hdw->fw1_state = FW1_STATE_RELOAD;
1194 return 0;
1195 }
1196
1197 return -EIO;
1198}
1199
1200
1201/*
1202 * pvr2_upload_firmware2()
1203 *
1204 * This uploads encoder firmware on endpoint 2.
1205 *
1206 */
1207
1208int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
1209{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001210 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001211 void *fw_ptr;
Mike Isely90060d32007-02-08 02:02:53 -03001212 unsigned int pipe, fw_len, fw_done, bcnt, icnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001213 int actual_length;
1214 int ret = 0;
1215 int fwidx;
1216 static const char *fw_files[] = {
1217 CX2341X_FIRM_ENC_FILENAME,
1218 };
1219
1220 trace_firmware("pvr2_upload_firmware2");
1221
1222 ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001223 ARRAY_SIZE(fw_files), fw_files);
Mike Iselyd8554972006-06-26 20:58:46 -03001224 if (ret < 0) return ret;
1225 fwidx = ret;
1226 ret = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001227 /* Since we're about to completely reinitialize the encoder,
1228 invalidate our cached copy of its configuration state. Next
1229 time we configure the encoder, then we'll fully configure it. */
1230 hdw->enc_cur_valid = 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001231
1232 /* First prepare firmware loading */
1233 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
1234 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
1235 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1236 ret |= pvr2_hdw_cmd_deep_reset(hdw);
1237 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
1238 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
1239 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1240 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
1241 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
1242 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
1243 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
1244 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
1245 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
1246 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
1247 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
1248 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
Mike Isely567d7112007-01-28 15:38:55 -03001249 LOCK_TAKE(hdw->ctl_lock); do {
1250 hdw->cmd_buffer[0] = FX2CMD_FWPOST1;
Al Viro89952d12007-03-14 09:17:59 +00001251 ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Isely567d7112007-01-28 15:38:55 -03001252 hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
1253 hdw->cmd_buffer[1] = 0;
Al Viro89952d12007-03-14 09:17:59 +00001254 ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
Mike Isely567d7112007-01-28 15:38:55 -03001255 } while (0); LOCK_GIVE(hdw->ctl_lock);
Mike Iselyd8554972006-06-26 20:58:46 -03001256
1257 if (ret) {
1258 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1259 "firmware2 upload prep failed, ret=%d",ret);
1260 release_firmware(fw_entry);
1261 return ret;
1262 }
1263
1264 /* Now send firmware */
1265
1266 fw_len = fw_entry->size;
1267
Mike Isely90060d32007-02-08 02:02:53 -03001268 if (fw_len % sizeof(u32)) {
Mike Iselyd8554972006-06-26 20:58:46 -03001269 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1270 "size of %s firmware"
Mike Isely48dc30a2007-03-03 10:13:05 -02001271 " must be a multiple of %zu bytes",
Mike Isely90060d32007-02-08 02:02:53 -03001272 fw_files[fwidx],sizeof(u32));
Mike Iselyd8554972006-06-26 20:58:46 -03001273 release_firmware(fw_entry);
1274 return -1;
1275 }
1276
1277 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1278 if (fw_ptr == NULL){
1279 release_firmware(fw_entry);
1280 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1281 "failed to allocate memory for firmware2 upload");
1282 return -ENOMEM;
1283 }
1284
1285 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1286
Mike Isely90060d32007-02-08 02:02:53 -03001287 fw_done = 0;
1288 for (fw_done = 0; fw_done < fw_len;) {
1289 bcnt = fw_len - fw_done;
1290 if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE;
1291 memcpy(fw_ptr, fw_entry->data + fw_done, bcnt);
1292 /* Usbsnoop log shows that we must swap bytes... */
1293 for (icnt = 0; icnt < bcnt/4 ; icnt++)
1294 ((u32 *)fw_ptr)[icnt] =
1295 ___swab32(((u32 *)fw_ptr)[icnt]);
Mike Iselyd8554972006-06-26 20:58:46 -03001296
Mike Isely90060d32007-02-08 02:02:53 -03001297 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001298 &actual_length, HZ);
Mike Isely90060d32007-02-08 02:02:53 -03001299 ret |= (actual_length != bcnt);
1300 if (ret) break;
1301 fw_done += bcnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001302 }
1303
1304 trace_firmware("upload of %s : %i / %i ",
1305 fw_files[fwidx],fw_done,fw_len);
1306
1307 kfree(fw_ptr);
1308 release_firmware(fw_entry);
1309
1310 if (ret) {
1311 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1312 "firmware2 upload transfer failure");
1313 return ret;
1314 }
1315
1316 /* Finish upload */
1317
1318 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1319 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
Mike Isely567d7112007-01-28 15:38:55 -03001320 LOCK_TAKE(hdw->ctl_lock); do {
1321 hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
1322 hdw->cmd_buffer[1] = 0;
Al Viro89952d12007-03-14 09:17:59 +00001323 ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
Mike Isely567d7112007-01-28 15:38:55 -03001324 } while (0); LOCK_GIVE(hdw->ctl_lock);
Mike Iselyd8554972006-06-26 20:58:46 -03001325
1326 if (ret) {
1327 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1328 "firmware2 upload post-proc failure");
1329 } else {
1330 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
1331 }
1332 return ret;
1333}
1334
1335
1336#define FIRMWARE_RECOVERY_BITS \
1337 ((1<<PVR2_SUBSYS_B_ENC_CFG) | \
1338 (1<<PVR2_SUBSYS_B_ENC_RUN) | \
1339 (1<<PVR2_SUBSYS_B_ENC_FIRMWARE) | \
1340 (1<<PVR2_SUBSYS_B_USBSTREAM_RUN))
1341
1342/*
1343
1344 This single function is key to pretty much everything. The pvrusb2
1345 device can logically be viewed as a series of subsystems which can be
1346 stopped / started or unconfigured / configured. To get things streaming,
1347 one must configure everything and start everything, but there may be
1348 various reasons over time to deconfigure something or stop something.
1349 This function handles all of this activity. Everything EVERYWHERE that
1350 must affect a subsystem eventually comes here to do the work.
1351
1352 The current state of all subsystems is represented by a single bit mask,
1353 known as subsys_enabled_mask. The bit positions are defined by the
1354 PVR2_SUBSYS_xxxx macros, with one subsystem per bit position. At any
1355 time the set of configured or active subsystems can be queried just by
1356 looking at that mask. To change bits in that mask, this function here
1357 must be called. The "msk" argument indicates which bit positions to
1358 change, and the "val" argument defines the new values for the positions
1359 defined by "msk".
1360
1361 There is a priority ordering of starting / stopping things, and for
1362 multiple requested changes, this function implements that ordering.
1363 (Thus we will act on a request to load encoder firmware before we
1364 configure the encoder.) In addition to priority ordering, there is a
1365 recovery strategy implemented here. If a particular step fails and we
1366 detect that failure, this function will clear the affected subsystem bits
1367 and restart. Thus we have a means for recovering from a dead encoder:
1368 Clear all bits that correspond to subsystems that we need to restart /
1369 reconfigure and start over.
1370
1371*/
Adrian Bunk07e337e2006-06-30 11:30:20 -03001372static void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw,
1373 unsigned long msk,
1374 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001375{
1376 unsigned long nmsk;
1377 unsigned long vmsk;
1378 int ret;
1379 unsigned int tryCount = 0;
1380
1381 if (!hdw->flag_ok) return;
1382
1383 msk &= PVR2_SUBSYS_ALL;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001384 nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk);
1385 nmsk &= PVR2_SUBSYS_ALL;
Mike Iselyd8554972006-06-26 20:58:46 -03001386
1387 for (;;) {
1388 tryCount++;
Mike Iselyeb8e0ee2006-06-25 20:04:47 -03001389 if (!((nmsk ^ hdw->subsys_enabled_mask) &
1390 PVR2_SUBSYS_ALL)) break;
Mike Iselyd8554972006-06-26 20:58:46 -03001391 if (tryCount > 4) {
1392 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1393 "Too many retries when configuring device;"
1394 " giving up");
1395 pvr2_hdw_render_useless(hdw);
1396 break;
1397 }
1398 if (tryCount > 1) {
1399 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1400 "Retrying device reconfiguration");
1401 }
1402 pvr2_trace(PVR2_TRACE_INIT,
1403 "subsys mask changing 0x%lx:0x%lx"
1404 " from 0x%lx to 0x%lx",
1405 msk,val,hdw->subsys_enabled_mask,nmsk);
1406
1407 vmsk = (nmsk ^ hdw->subsys_enabled_mask) &
1408 hdw->subsys_enabled_mask;
1409 if (vmsk) {
1410 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1411 pvr2_trace(PVR2_TRACE_CTL,
1412 "/*---TRACE_CTL----*/"
1413 " pvr2_encoder_stop");
1414 ret = pvr2_encoder_stop(hdw);
1415 if (ret) {
1416 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1417 "Error recovery initiated");
1418 hdw->subsys_enabled_mask &=
1419 ~FIRMWARE_RECOVERY_BITS;
1420 continue;
1421 }
1422 }
1423 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1424 pvr2_trace(PVR2_TRACE_CTL,
1425 "/*---TRACE_CTL----*/"
1426 " pvr2_hdw_cmd_usbstream(0)");
1427 pvr2_hdw_cmd_usbstream(hdw,0);
1428 }
1429 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1430 pvr2_trace(PVR2_TRACE_CTL,
1431 "/*---TRACE_CTL----*/"
1432 " decoder disable");
1433 if (hdw->decoder_ctrl) {
1434 hdw->decoder_ctrl->enable(
1435 hdw->decoder_ctrl->ctxt,0);
1436 } else {
1437 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1438 "WARNING:"
1439 " No decoder present");
1440 }
1441 hdw->subsys_enabled_mask &=
1442 ~(1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1443 }
1444 if (vmsk & PVR2_SUBSYS_CFG_ALL) {
1445 hdw->subsys_enabled_mask &=
1446 ~(vmsk & PVR2_SUBSYS_CFG_ALL);
1447 }
1448 }
1449 vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk;
1450 if (vmsk) {
1451 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_FIRMWARE)) {
1452 pvr2_trace(PVR2_TRACE_CTL,
1453 "/*---TRACE_CTL----*/"
1454 " pvr2_upload_firmware2");
1455 ret = pvr2_upload_firmware2(hdw);
1456 if (ret) {
1457 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1458 "Failure uploading encoder"
1459 " firmware");
1460 pvr2_hdw_render_useless(hdw);
1461 break;
1462 }
1463 }
1464 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_CFG)) {
1465 pvr2_trace(PVR2_TRACE_CTL,
1466 "/*---TRACE_CTL----*/"
1467 " pvr2_encoder_configure");
1468 ret = pvr2_encoder_configure(hdw);
1469 if (ret) {
1470 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1471 "Error recovery initiated");
1472 hdw->subsys_enabled_mask &=
1473 ~FIRMWARE_RECOVERY_BITS;
1474 continue;
1475 }
1476 }
1477 if (vmsk & (1<<PVR2_SUBSYS_B_DIGITIZER_RUN)) {
1478 pvr2_trace(PVR2_TRACE_CTL,
1479 "/*---TRACE_CTL----*/"
1480 " decoder enable");
1481 if (hdw->decoder_ctrl) {
1482 hdw->decoder_ctrl->enable(
1483 hdw->decoder_ctrl->ctxt,!0);
1484 } else {
1485 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1486 "WARNING:"
1487 " No decoder present");
1488 }
1489 hdw->subsys_enabled_mask |=
1490 (1<<PVR2_SUBSYS_B_DIGITIZER_RUN);
1491 }
1492 if (vmsk & (1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) {
1493 pvr2_trace(PVR2_TRACE_CTL,
1494 "/*---TRACE_CTL----*/"
1495 " pvr2_hdw_cmd_usbstream(1)");
1496 pvr2_hdw_cmd_usbstream(hdw,!0);
1497 }
1498 if (vmsk & (1<<PVR2_SUBSYS_B_ENC_RUN)) {
1499 pvr2_trace(PVR2_TRACE_CTL,
1500 "/*---TRACE_CTL----*/"
1501 " pvr2_encoder_start");
1502 ret = pvr2_encoder_start(hdw);
1503 if (ret) {
1504 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1505 "Error recovery initiated");
1506 hdw->subsys_enabled_mask &=
1507 ~FIRMWARE_RECOVERY_BITS;
1508 continue;
1509 }
1510 }
1511 }
1512 }
1513}
1514
1515
1516void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw,
1517 unsigned long msk,unsigned long val)
1518{
1519 LOCK_TAKE(hdw->big_lock); do {
1520 pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val);
1521 } while (0); LOCK_GIVE(hdw->big_lock);
1522}
1523
1524
Mike Iselyd8554972006-06-26 20:58:46 -03001525unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw)
1526{
1527 return hdw->subsys_enabled_mask;
1528}
1529
1530
1531unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw)
1532{
1533 return hdw->subsys_stream_mask;
1534}
1535
1536
Adrian Bunk07e337e2006-06-30 11:30:20 -03001537static void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw,
1538 unsigned long msk,
1539 unsigned long val)
Mike Iselyd8554972006-06-26 20:58:46 -03001540{
1541 unsigned long val2;
1542 msk &= PVR2_SUBSYS_ALL;
1543 val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk));
1544 pvr2_trace(PVR2_TRACE_INIT,
1545 "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx",
1546 msk,val,hdw->subsys_stream_mask,val2);
1547 hdw->subsys_stream_mask = val2;
1548}
1549
1550
1551void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
1552 unsigned long msk,
1553 unsigned long val)
1554{
1555 LOCK_TAKE(hdw->big_lock); do {
1556 pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val);
1557 } while (0); LOCK_GIVE(hdw->big_lock);
1558}
1559
1560
Adrian Bunk07e337e2006-06-30 11:30:20 -03001561static int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl)
Mike Iselyd8554972006-06-26 20:58:46 -03001562{
1563 if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0;
1564 if (enableFl) {
1565 pvr2_trace(PVR2_TRACE_START_STOP,
1566 "/*--TRACE_STREAM--*/ enable");
1567 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0);
1568 } else {
1569 pvr2_trace(PVR2_TRACE_START_STOP,
1570 "/*--TRACE_STREAM--*/ disable");
1571 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1572 }
1573 if (!hdw->flag_ok) return -EIO;
1574 hdw->flag_streaming_enabled = enableFl != 0;
1575 return 0;
1576}
1577
1578
1579int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1580{
1581 return hdw->flag_streaming_enabled != 0;
1582}
1583
1584
1585int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1586{
1587 int ret;
1588 LOCK_TAKE(hdw->big_lock); do {
1589 ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag);
1590 } while (0); LOCK_GIVE(hdw->big_lock);
1591 return ret;
1592}
1593
1594
Adrian Bunk07e337e2006-06-30 11:30:20 -03001595static int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw,
1596 enum pvr2_config config)
Mike Iselyd8554972006-06-26 20:58:46 -03001597{
1598 unsigned long sm = hdw->subsys_enabled_mask;
1599 if (!hdw->flag_ok) return -EIO;
1600 pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0);
1601 hdw->config = config;
1602 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm);
1603 return 0;
1604}
1605
1606
1607int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1608{
1609 int ret;
1610 if (!hdw->flag_ok) return -EIO;
1611 LOCK_TAKE(hdw->big_lock);
1612 ret = pvr2_hdw_set_stream_type_no_lock(hdw,config);
1613 LOCK_GIVE(hdw->big_lock);
1614 return ret;
1615}
1616
1617
1618static int get_default_tuner_type(struct pvr2_hdw *hdw)
1619{
1620 int unit_number = hdw->unit_number;
1621 int tp = -1;
1622 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1623 tp = tuner[unit_number];
1624 }
1625 if (tp < 0) return -EINVAL;
1626 hdw->tuner_type = tp;
1627 return 0;
1628}
1629
1630
1631static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1632{
1633 int unit_number = hdw->unit_number;
1634 int tp = 0;
1635 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1636 tp = video_std[unit_number];
1637 }
1638 return tp;
1639}
1640
1641
1642static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1643{
1644 int unit_number = hdw->unit_number;
1645 int tp = 0;
1646 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1647 tp = tolerance[unit_number];
1648 }
1649 return tp;
1650}
1651
1652
1653static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1654{
1655 /* Try a harmless request to fetch the eeprom's address over
1656 endpoint 1. See what happens. Only the full FX2 image can
1657 respond to this. If this probe fails then likely the FX2
1658 firmware needs be loaded. */
1659 int result;
1660 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03001661 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03001662 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1663 hdw->cmd_buffer,1,
1664 hdw->cmd_buffer,1);
1665 if (result < 0) break;
1666 } while(0); LOCK_GIVE(hdw->ctl_lock);
1667 if (result) {
1668 pvr2_trace(PVR2_TRACE_INIT,
1669 "Probe of device endpoint 1 result status %d",
1670 result);
1671 } else {
1672 pvr2_trace(PVR2_TRACE_INIT,
1673 "Probe of device endpoint 1 succeeded");
1674 }
1675 return result == 0;
1676}
1677
1678static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1679{
1680 char buf[40];
1681 unsigned int bcnt;
1682 v4l2_std_id std1,std2;
1683
1684 std1 = get_default_standard(hdw);
1685
1686 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
1687 pvr2_trace(PVR2_TRACE_INIT,
1688 "Supported video standard(s) reported by eeprom: %.*s",
1689 bcnt,buf);
1690
1691 hdw->std_mask_avail = hdw->std_mask_eeprom;
1692
1693 std2 = std1 & ~hdw->std_mask_avail;
1694 if (std2) {
1695 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
1696 pvr2_trace(PVR2_TRACE_INIT,
1697 "Expanding supported video standards"
1698 " to include: %.*s",
1699 bcnt,buf);
1700 hdw->std_mask_avail |= std2;
1701 }
1702
1703 pvr2_hdw_internal_set_std_avail(hdw);
1704
1705 if (std1) {
1706 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
1707 pvr2_trace(PVR2_TRACE_INIT,
1708 "Initial video standard forced to %.*s",
1709 bcnt,buf);
1710 hdw->std_mask_cur = std1;
1711 hdw->std_dirty = !0;
1712 pvr2_hdw_internal_find_stdenum(hdw);
1713 return;
1714 }
1715
1716 if (hdw->std_enum_cnt > 1) {
1717 // Autoselect the first listed standard
1718 hdw->std_enum_cur = 1;
1719 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1720 hdw->std_dirty = !0;
1721 pvr2_trace(PVR2_TRACE_INIT,
1722 "Initial video standard auto-selected to %s",
1723 hdw->std_defs[hdw->std_enum_cur-1].name);
1724 return;
1725 }
1726
Mike Isely0885ba12006-06-25 21:30:47 -03001727 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
Mike Iselyd8554972006-06-26 20:58:46 -03001728 "Unable to select a viable initial video standard");
1729}
1730
1731
1732static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1733{
1734 int ret;
1735 unsigned int idx;
1736 struct pvr2_ctrl *cptr;
1737 int reloadFl = 0;
1738 if (!reloadFl) {
1739 reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1740 == 0);
1741 if (reloadFl) {
1742 pvr2_trace(PVR2_TRACE_INIT,
1743 "USB endpoint config looks strange"
1744 "; possibly firmware needs to be loaded");
1745 }
1746 }
1747 if (!reloadFl) {
1748 reloadFl = !pvr2_hdw_check_firmware(hdw);
1749 if (reloadFl) {
1750 pvr2_trace(PVR2_TRACE_INIT,
1751 "Check for FX2 firmware failed"
1752 "; possibly firmware needs to be loaded");
1753 }
1754 }
1755 if (reloadFl) {
1756 if (pvr2_upload_firmware1(hdw) != 0) {
1757 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1758 "Failure uploading firmware1");
1759 }
1760 return;
1761 }
1762 hdw->fw1_state = FW1_STATE_OK;
1763
1764 if (initusbreset) {
1765 pvr2_hdw_device_reset(hdw);
1766 }
1767 if (!pvr2_hdw_dev_ok(hdw)) return;
1768
1769 for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) {
1770 request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]);
1771 }
1772
1773 pvr2_hdw_cmd_powerup(hdw);
1774 if (!pvr2_hdw_dev_ok(hdw)) return;
1775
1776 if (pvr2_upload_firmware2(hdw)){
1777 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
1778 pvr2_hdw_render_useless(hdw);
1779 return;
1780 }
1781
1782 // This step MUST happen after the earlier powerup step.
1783 pvr2_i2c_core_init(hdw);
1784 if (!pvr2_hdw_dev_ok(hdw)) return;
1785
Mike Iselyc05c0462006-06-25 20:04:25 -03001786 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001787 cptr = hdw->controls + idx;
1788 if (cptr->info->skip_init) continue;
1789 if (!cptr->info->set_value) continue;
1790 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1791 }
1792
Mike Isely1bde0282006-12-27 23:30:13 -03001793 /* Set up special default values for the television and radio
1794 frequencies here. It's not really important what these defaults
1795 are, but I set them to something usable in the Chicago area just
1796 to make driver testing a little easier. */
1797
1798 /* US Broadcast channel 7 (175.25 MHz) */
1799 hdw->freqValTelevision = 175250000L;
1800 /* 104.3 MHz, a usable FM station for my area */
1801 hdw->freqValRadio = 104300000L;
1802
Mike Iselyd8554972006-06-26 20:58:46 -03001803 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1804 // thread-safe against the normal pvr2_send_request() mechanism.
1805 // (We should make it thread safe).
1806
1807 ret = pvr2_hdw_get_eeprom_addr(hdw);
1808 if (!pvr2_hdw_dev_ok(hdw)) return;
1809 if (ret < 0) {
1810 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1811 "Unable to determine location of eeprom, skipping");
1812 } else {
1813 hdw->eeprom_addr = ret;
1814 pvr2_eeprom_analyze(hdw);
1815 if (!pvr2_hdw_dev_ok(hdw)) return;
1816 }
1817
1818 pvr2_hdw_setup_std(hdw);
1819
1820 if (!get_default_tuner_type(hdw)) {
1821 pvr2_trace(PVR2_TRACE_INIT,
1822 "pvr2_hdw_setup: Tuner type overridden to %d",
1823 hdw->tuner_type);
1824 }
1825
1826 hdw->tuner_updated = !0;
1827 pvr2_i2c_core_check_stale(hdw);
1828 hdw->tuner_updated = 0;
1829
1830 if (!pvr2_hdw_dev_ok(hdw)) return;
1831
1832 pvr2_hdw_commit_ctl_internal(hdw);
1833 if (!pvr2_hdw_dev_ok(hdw)) return;
1834
1835 hdw->vid_stream = pvr2_stream_create();
1836 if (!pvr2_hdw_dev_ok(hdw)) return;
1837 pvr2_trace(PVR2_TRACE_INIT,
1838 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1839 if (hdw->vid_stream) {
1840 idx = get_default_error_tolerance(hdw);
1841 if (idx) {
1842 pvr2_trace(PVR2_TRACE_INIT,
1843 "pvr2_hdw_setup: video stream %p"
1844 " setting tolerance %u",
1845 hdw->vid_stream,idx);
1846 }
1847 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1848 PVR2_VID_ENDPOINT,idx);
1849 }
1850
1851 if (!pvr2_hdw_dev_ok(hdw)) return;
1852
1853 /* Make sure everything is up to date */
1854 pvr2_i2c_core_sync(hdw);
1855
1856 if (!pvr2_hdw_dev_ok(hdw)) return;
1857
1858 hdw->flag_init_ok = !0;
1859}
1860
1861
1862int pvr2_hdw_setup(struct pvr2_hdw *hdw)
1863{
1864 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
1865 LOCK_TAKE(hdw->big_lock); do {
1866 pvr2_hdw_setup_low(hdw);
1867 pvr2_trace(PVR2_TRACE_INIT,
1868 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
1869 hdw,hdw->flag_ok,hdw->flag_init_ok);
1870 if (pvr2_hdw_dev_ok(hdw)) {
1871 if (pvr2_hdw_init_ok(hdw)) {
1872 pvr2_trace(
1873 PVR2_TRACE_INFO,
1874 "Device initialization"
1875 " completed successfully.");
1876 break;
1877 }
1878 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1879 pvr2_trace(
1880 PVR2_TRACE_INFO,
1881 "Device microcontroller firmware"
1882 " (re)loaded; it should now reset"
1883 " and reconnect.");
1884 break;
1885 }
1886 pvr2_trace(
1887 PVR2_TRACE_ERROR_LEGS,
1888 "Device initialization was not successful.");
1889 if (hdw->fw1_state == FW1_STATE_MISSING) {
1890 pvr2_trace(
1891 PVR2_TRACE_ERROR_LEGS,
1892 "Giving up since device"
1893 " microcontroller firmware"
1894 " appears to be missing.");
1895 break;
1896 }
1897 }
1898 if (procreload) {
1899 pvr2_trace(
1900 PVR2_TRACE_ERROR_LEGS,
1901 "Attempting pvrusb2 recovery by reloading"
1902 " primary firmware.");
1903 pvr2_trace(
1904 PVR2_TRACE_ERROR_LEGS,
1905 "If this works, device should disconnect"
1906 " and reconnect in a sane state.");
1907 hdw->fw1_state = FW1_STATE_UNKNOWN;
1908 pvr2_upload_firmware1(hdw);
1909 } else {
1910 pvr2_trace(
1911 PVR2_TRACE_ERROR_LEGS,
1912 "***WARNING*** pvrusb2 device hardware"
1913 " appears to be jammed"
1914 " and I can't clear it.");
1915 pvr2_trace(
1916 PVR2_TRACE_ERROR_LEGS,
1917 "You might need to power cycle"
1918 " the pvrusb2 device"
1919 " in order to recover.");
1920 }
1921 } while (0); LOCK_GIVE(hdw->big_lock);
1922 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
1923 return hdw->flag_init_ok;
1924}
1925
1926
1927/* Create and return a structure for interacting with the underlying
1928 hardware */
1929struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1930 const struct usb_device_id *devid)
1931{
1932 unsigned int idx,cnt1,cnt2;
1933 struct pvr2_hdw *hdw;
1934 unsigned int hdw_type;
1935 int valid_std_mask;
1936 struct pvr2_ctrl *cptr;
1937 __u8 ifnum;
Mike Iselyb30d2442006-06-25 20:05:01 -03001938 struct v4l2_queryctrl qctrl;
1939 struct pvr2_ctl_info *ciptr;
Mike Iselyd8554972006-06-26 20:58:46 -03001940
1941 hdw_type = devid - pvr2_device_table;
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001942 if (hdw_type >= ARRAY_SIZE(pvr2_device_names)) {
Mike Iselyd8554972006-06-26 20:58:46 -03001943 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1944 "Bogus device type of %u reported",hdw_type);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001945 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001946 }
1947
Mike Iselyca545f72007-01-20 00:37:11 -03001948 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -03001949 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
1950 hdw,pvr2_device_names[hdw_type]);
1951 if (!hdw) goto fail;
Mike Isely18103c52007-01-20 00:09:47 -03001952 hdw->tuner_signal_stale = !0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001953 cx2341x_fill_defaults(&hdw->enc_ctl_state);
Mike Iselyd8554972006-06-26 20:58:46 -03001954
Mike Iselyc05c0462006-06-25 20:04:25 -03001955 hdw->control_cnt = CTRLDEF_COUNT;
Mike Iselyb30d2442006-06-25 20:05:01 -03001956 hdw->control_cnt += MPEGDEF_COUNT;
Mike Iselyca545f72007-01-20 00:37:11 -03001957 hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001958 GFP_KERNEL);
1959 if (!hdw->controls) goto fail;
Mike Iselyd8554972006-06-26 20:58:46 -03001960 hdw->hdw_type = hdw_type;
Mike Iselyc05c0462006-06-25 20:04:25 -03001961 for (idx = 0; idx < hdw->control_cnt; idx++) {
1962 cptr = hdw->controls + idx;
1963 cptr->hdw = hdw;
1964 }
Mike Iselyd8554972006-06-26 20:58:46 -03001965 for (idx = 0; idx < 32; idx++) {
1966 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1967 }
Mike Iselyc05c0462006-06-25 20:04:25 -03001968 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001969 cptr = hdw->controls + idx;
Mike Iselyd8554972006-06-26 20:58:46 -03001970 cptr->info = control_defs+idx;
1971 }
Mike Iselyb30d2442006-06-25 20:05:01 -03001972 /* Define and configure additional controls from cx2341x module. */
Mike Iselyca545f72007-01-20 00:37:11 -03001973 hdw->mpeg_ctrl_info = kzalloc(
Mike Iselyb30d2442006-06-25 20:05:01 -03001974 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
1975 if (!hdw->mpeg_ctrl_info) goto fail;
Mike Iselyb30d2442006-06-25 20:05:01 -03001976 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
1977 cptr = hdw->controls + idx + CTRLDEF_COUNT;
1978 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
1979 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
1980 ciptr->name = mpeg_ids[idx].strid;
1981 ciptr->v4l_id = mpeg_ids[idx].id;
1982 ciptr->skip_init = !0;
1983 ciptr->get_value = ctrl_cx2341x_get;
1984 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
1985 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
1986 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
1987 qctrl.id = ciptr->v4l_id;
1988 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
1989 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
1990 ciptr->set_value = ctrl_cx2341x_set;
1991 }
1992 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
1993 PVR2_CTLD_INFO_DESC_SIZE);
1994 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
1995 ciptr->default_value = qctrl.default_value;
1996 switch (qctrl.type) {
1997 default:
1998 case V4L2_CTRL_TYPE_INTEGER:
1999 ciptr->type = pvr2_ctl_int;
2000 ciptr->def.type_int.min_value = qctrl.minimum;
2001 ciptr->def.type_int.max_value = qctrl.maximum;
2002 break;
2003 case V4L2_CTRL_TYPE_BOOLEAN:
2004 ciptr->type = pvr2_ctl_bool;
2005 break;
2006 case V4L2_CTRL_TYPE_MENU:
2007 ciptr->type = pvr2_ctl_enum;
2008 ciptr->def.type_enum.value_names =
2009 cx2341x_ctrl_get_menu(ciptr->v4l_id);
2010 for (cnt1 = 0;
2011 ciptr->def.type_enum.value_names[cnt1] != NULL;
2012 cnt1++) { }
2013 ciptr->def.type_enum.count = cnt1;
2014 break;
2015 }
2016 cptr->info = ciptr;
2017 }
Mike Iselyd8554972006-06-26 20:58:46 -03002018
2019 // Initialize video standard enum dynamic control
2020 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
2021 if (cptr) {
2022 memcpy(&hdw->std_info_enum,cptr->info,
2023 sizeof(hdw->std_info_enum));
2024 cptr->info = &hdw->std_info_enum;
2025
2026 }
2027 // Initialize control data regarding video standard masks
2028 valid_std_mask = pvr2_std_get_usable();
2029 for (idx = 0; idx < 32; idx++) {
2030 if (!(valid_std_mask & (1 << idx))) continue;
2031 cnt1 = pvr2_std_id_to_str(
2032 hdw->std_mask_names[idx],
2033 sizeof(hdw->std_mask_names[idx])-1,
2034 1 << idx);
2035 hdw->std_mask_names[idx][cnt1] = 0;
2036 }
2037 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
2038 if (cptr) {
2039 memcpy(&hdw->std_info_avail,cptr->info,
2040 sizeof(hdw->std_info_avail));
2041 cptr->info = &hdw->std_info_avail;
2042 hdw->std_info_avail.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 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
2048 if (cptr) {
2049 memcpy(&hdw->std_info_cur,cptr->info,
2050 sizeof(hdw->std_info_cur));
2051 cptr->info = &hdw->std_info_cur;
2052 hdw->std_info_cur.def.type_bitmask.bit_names =
2053 hdw->std_mask_ptrs;
2054 hdw->std_info_avail.def.type_bitmask.valid_bits =
2055 valid_std_mask;
2056 }
2057
2058 hdw->eeprom_addr = -1;
2059 hdw->unit_number = -1;
Mike Isely80793842006-12-27 23:12:28 -03002060 hdw->v4l_minor_number_video = -1;
2061 hdw->v4l_minor_number_vbi = -1;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002062 hdw->v4l_minor_number_radio = -1;
Mike Iselyd8554972006-06-26 20:58:46 -03002063 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2064 if (!hdw->ctl_write_buffer) goto fail;
2065 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2066 if (!hdw->ctl_read_buffer) goto fail;
2067 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
2068 if (!hdw->ctl_write_urb) goto fail;
2069 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
2070 if (!hdw->ctl_read_urb) goto fail;
2071
2072 down(&pvr2_unit_sem); do {
2073 for (idx = 0; idx < PVR_NUM; idx++) {
2074 if (unit_pointers[idx]) continue;
2075 hdw->unit_number = idx;
2076 unit_pointers[idx] = hdw;
2077 break;
2078 }
2079 } while (0); up(&pvr2_unit_sem);
2080
2081 cnt1 = 0;
2082 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
2083 cnt1 += cnt2;
2084 if (hdw->unit_number >= 0) {
2085 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
2086 ('a' + hdw->unit_number));
2087 cnt1 += cnt2;
2088 }
2089 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
2090 hdw->name[cnt1] = 0;
2091
2092 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
2093 hdw->unit_number,hdw->name);
2094
2095 hdw->tuner_type = -1;
2096 hdw->flag_ok = !0;
2097 /* Initialize the mask of subsystems that we will shut down when we
2098 stop streaming. */
2099 hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
2100 hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
2101
2102 pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
2103 hdw->subsys_stream_mask);
2104
2105 hdw->usb_intf = intf;
2106 hdw->usb_dev = interface_to_usbdev(intf);
2107
2108 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2109 usb_set_interface(hdw->usb_dev,ifnum,0);
2110
2111 mutex_init(&hdw->ctl_lock_mutex);
2112 mutex_init(&hdw->big_lock_mutex);
2113
2114 return hdw;
2115 fail:
2116 if (hdw) {
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002117 usb_free_urb(hdw->ctl_read_urb);
2118 usb_free_urb(hdw->ctl_write_urb);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002119 kfree(hdw->ctl_read_buffer);
2120 kfree(hdw->ctl_write_buffer);
2121 kfree(hdw->controls);
2122 kfree(hdw->mpeg_ctrl_info);
Mike Iselyd8554972006-06-26 20:58:46 -03002123 kfree(hdw);
2124 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002125 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002126}
2127
2128
2129/* Remove _all_ associations between this driver and the underlying USB
2130 layer. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002131static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002132{
2133 if (hdw->flag_disconnected) return;
2134 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
2135 if (hdw->ctl_read_urb) {
2136 usb_kill_urb(hdw->ctl_read_urb);
2137 usb_free_urb(hdw->ctl_read_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002138 hdw->ctl_read_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002139 }
2140 if (hdw->ctl_write_urb) {
2141 usb_kill_urb(hdw->ctl_write_urb);
2142 usb_free_urb(hdw->ctl_write_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002143 hdw->ctl_write_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002144 }
2145 if (hdw->ctl_read_buffer) {
2146 kfree(hdw->ctl_read_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002147 hdw->ctl_read_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002148 }
2149 if (hdw->ctl_write_buffer) {
2150 kfree(hdw->ctl_write_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002151 hdw->ctl_write_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002152 }
2153 pvr2_hdw_render_useless_unlocked(hdw);
2154 hdw->flag_disconnected = !0;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002155 hdw->usb_dev = NULL;
2156 hdw->usb_intf = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002157}
2158
2159
2160/* Destroy hardware interaction structure */
2161void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2162{
2163 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
2164 if (hdw->fw_buffer) {
2165 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002166 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002167 }
2168 if (hdw->vid_stream) {
2169 pvr2_stream_destroy(hdw->vid_stream);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002170 hdw->vid_stream = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002171 }
Mike Iselyd8554972006-06-26 20:58:46 -03002172 if (hdw->decoder_ctrl) {
2173 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2174 }
2175 pvr2_i2c_core_done(hdw);
2176 pvr2_hdw_remove_usb_stuff(hdw);
2177 down(&pvr2_unit_sem); do {
2178 if ((hdw->unit_number >= 0) &&
2179 (hdw->unit_number < PVR_NUM) &&
2180 (unit_pointers[hdw->unit_number] == hdw)) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002181 unit_pointers[hdw->unit_number] = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002182 }
2183 } while (0); up(&pvr2_unit_sem);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002184 kfree(hdw->controls);
2185 kfree(hdw->mpeg_ctrl_info);
2186 kfree(hdw->std_defs);
2187 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002188 kfree(hdw);
2189}
2190
2191
2192int pvr2_hdw_init_ok(struct pvr2_hdw *hdw)
2193{
2194 return hdw->flag_init_ok;
2195}
2196
2197
2198int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2199{
2200 return (hdw && hdw->flag_ok);
2201}
2202
2203
2204/* Called when hardware has been unplugged */
2205void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2206{
2207 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2208 LOCK_TAKE(hdw->big_lock);
2209 LOCK_TAKE(hdw->ctl_lock);
2210 pvr2_hdw_remove_usb_stuff(hdw);
2211 LOCK_GIVE(hdw->ctl_lock);
2212 LOCK_GIVE(hdw->big_lock);
2213}
2214
2215
2216// Attempt to autoselect an appropriate value for std_enum_cur given
2217// whatever is currently in std_mask_cur
Adrian Bunk07e337e2006-06-30 11:30:20 -03002218static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002219{
2220 unsigned int idx;
2221 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2222 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2223 hdw->std_enum_cur = idx;
2224 return;
2225 }
2226 }
2227 hdw->std_enum_cur = 0;
2228}
2229
2230
2231// Calculate correct set of enumerated standards based on currently known
2232// set of available standards bits.
Adrian Bunk07e337e2006-06-30 11:30:20 -03002233static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002234{
2235 struct v4l2_standard *newstd;
2236 unsigned int std_cnt;
2237 unsigned int idx;
2238
2239 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2240
2241 if (hdw->std_defs) {
2242 kfree(hdw->std_defs);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002243 hdw->std_defs = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002244 }
2245 hdw->std_enum_cnt = 0;
2246 if (hdw->std_enum_names) {
2247 kfree(hdw->std_enum_names);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002248 hdw->std_enum_names = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002249 }
2250
2251 if (!std_cnt) {
2252 pvr2_trace(
2253 PVR2_TRACE_ERROR_LEGS,
2254 "WARNING: Failed to identify any viable standards");
2255 }
2256 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2257 hdw->std_enum_names[0] = "none";
2258 for (idx = 0; idx < std_cnt; idx++) {
2259 hdw->std_enum_names[idx+1] =
2260 newstd[idx].name;
2261 }
2262 // Set up the dynamic control for this standard
2263 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2264 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2265 hdw->std_defs = newstd;
2266 hdw->std_enum_cnt = std_cnt+1;
2267 hdw->std_enum_cur = 0;
2268 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2269}
2270
2271
2272int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2273 struct v4l2_standard *std,
2274 unsigned int idx)
2275{
2276 int ret = -EINVAL;
2277 if (!idx) return ret;
2278 LOCK_TAKE(hdw->big_lock); do {
2279 if (idx >= hdw->std_enum_cnt) break;
2280 idx--;
2281 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2282 ret = 0;
2283 } while (0); LOCK_GIVE(hdw->big_lock);
2284 return ret;
2285}
2286
2287
2288/* Get the number of defined controls */
2289unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2290{
Mike Iselyc05c0462006-06-25 20:04:25 -03002291 return hdw->control_cnt;
Mike Iselyd8554972006-06-26 20:58:46 -03002292}
2293
2294
2295/* Retrieve a control handle given its index (0..count-1) */
2296struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2297 unsigned int idx)
2298{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002299 if (idx >= hdw->control_cnt) return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002300 return hdw->controls + idx;
2301}
2302
2303
2304/* Retrieve a control handle given its index (0..count-1) */
2305struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2306 unsigned int ctl_id)
2307{
2308 struct pvr2_ctrl *cptr;
2309 unsigned int idx;
2310 int i;
2311
2312 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002313 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002314 cptr = hdw->controls + idx;
2315 i = cptr->info->internal_id;
2316 if (i && (i == ctl_id)) return cptr;
2317 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002318 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002319}
2320
2321
Mike Iselya761f432006-06-25 20:04:44 -03002322/* Given a V4L ID, retrieve the control structure associated with it. */
Mike Iselyd8554972006-06-26 20:58:46 -03002323struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2324{
2325 struct pvr2_ctrl *cptr;
2326 unsigned int idx;
2327 int i;
2328
2329 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002330 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002331 cptr = hdw->controls + idx;
2332 i = cptr->info->v4l_id;
2333 if (i && (i == ctl_id)) return cptr;
2334 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002335 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002336}
2337
2338
Mike Iselya761f432006-06-25 20:04:44 -03002339/* Given a V4L ID for its immediate predecessor, retrieve the control
2340 structure associated with it. */
2341struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2342 unsigned int ctl_id)
2343{
2344 struct pvr2_ctrl *cptr,*cp2;
2345 unsigned int idx;
2346 int i;
2347
2348 /* This could be made a lot more efficient, but for now... */
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002349 cp2 = NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002350 for (idx = 0; idx < hdw->control_cnt; idx++) {
2351 cptr = hdw->controls + idx;
2352 i = cptr->info->v4l_id;
2353 if (!i) continue;
2354 if (i <= ctl_id) continue;
2355 if (cp2 && (cp2->info->v4l_id < i)) continue;
2356 cp2 = cptr;
2357 }
2358 return cp2;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002359 return NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002360}
2361
2362
Mike Iselyd8554972006-06-26 20:58:46 -03002363static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2364{
2365 switch (tp) {
2366 case pvr2_ctl_int: return "integer";
2367 case pvr2_ctl_enum: return "enum";
Mike Isely33213962006-06-25 20:04:40 -03002368 case pvr2_ctl_bool: return "boolean";
Mike Iselyd8554972006-06-26 20:58:46 -03002369 case pvr2_ctl_bitmask: return "bitmask";
2370 }
2371 return "";
2372}
2373
2374
2375/* Commit all control changes made up to this point. Subsystems can be
2376 indirectly affected by these changes. For a given set of things being
2377 committed, we'll clear the affected subsystem bits and then once we're
2378 done committing everything we'll make a request to restore the subsystem
2379 state(s) back to their previous value before this function was called.
2380 Thus we can automatically reconfigure affected pieces of the driver as
2381 controls are changed. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002382static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002383{
2384 unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
2385 unsigned long stale_subsys_mask = 0;
2386 unsigned int idx;
2387 struct pvr2_ctrl *cptr;
2388 int value;
2389 int commit_flag = 0;
2390 char buf[100];
2391 unsigned int bcnt,ccnt;
2392
Mike Iselyc05c0462006-06-25 20:04:25 -03002393 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002394 cptr = hdw->controls + idx;
2395 if (cptr->info->is_dirty == 0) continue;
2396 if (!cptr->info->is_dirty(cptr)) continue;
Mike Iselyfe23a282007-01-20 00:10:55 -03002397 commit_flag = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002398
Mike Iselyfe23a282007-01-20 00:10:55 -03002399 if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002400 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2401 cptr->info->name);
2402 value = 0;
2403 cptr->info->get_value(cptr,&value);
2404 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2405 buf+bcnt,
2406 sizeof(buf)-bcnt,&ccnt);
2407 bcnt += ccnt;
2408 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2409 get_ctrl_typename(cptr->info->type));
2410 pvr2_trace(PVR2_TRACE_CTL,
2411 "/*--TRACE_COMMIT--*/ %.*s",
2412 bcnt,buf);
2413 }
2414
2415 if (!commit_flag) {
2416 /* Nothing has changed */
2417 return 0;
2418 }
2419
2420 /* When video standard changes, reset the hres and vres values -
2421 but if the user has pending changes there, then let the changes
2422 take priority. */
2423 if (hdw->std_dirty) {
2424 /* Rewrite the vertical resolution to be appropriate to the
2425 video standard that has been selected. */
2426 int nvres;
2427 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2428 nvres = 480;
2429 } else {
2430 nvres = 576;
2431 }
2432 if (nvres != hdw->res_ver_val) {
2433 hdw->res_ver_val = nvres;
2434 hdw->res_ver_dirty = !0;
2435 }
Mike Iselyd8554972006-06-26 20:58:46 -03002436 }
2437
2438 if (hdw->std_dirty ||
Mike Isely434449f2006-08-08 09:10:06 -03002439 hdw->enc_stale ||
2440 hdw->srate_dirty ||
2441 hdw->res_ver_dirty ||
2442 hdw->res_hor_dirty ||
Mike Iselyb46cfa82006-06-25 20:04:53 -03002443 0) {
Mike Iselyd8554972006-06-26 20:58:46 -03002444 /* If any of this changes, then the encoder needs to be
2445 reconfigured, and we need to reset the stream. */
2446 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
Mike Iselyd8554972006-06-26 20:58:46 -03002447 }
2448
Pantelis Koukousoulas275b2e22006-12-27 23:05:19 -03002449 if (hdw->input_dirty) {
2450 /* pk: If input changes to or from radio, then the encoder
2451 needs to be restarted (for ENC_MUTE_VIDEO to work) */
2452 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
2453 }
2454
2455
Mike Iselyb30d2442006-06-25 20:05:01 -03002456 if (hdw->srate_dirty) {
2457 /* Write new sample rate into control structure since
2458 * the master copy is stale. We must track srate
2459 * separate from the mpeg control structure because
2460 * other logic also uses this value. */
2461 struct v4l2_ext_controls cs;
2462 struct v4l2_ext_control c1;
2463 memset(&cs,0,sizeof(cs));
2464 memset(&c1,0,sizeof(c1));
2465 cs.controls = &c1;
2466 cs.count = 1;
2467 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2468 c1.value = hdw->srate_val;
2469 cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS);
2470 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002471
Mike Iselyd8554972006-06-26 20:58:46 -03002472 /* Scan i2c core at this point - before we clear all the dirty
2473 bits. Various parts of the i2c core will notice dirty bits as
2474 appropriate and arrange to broadcast or directly send updates to
2475 the client drivers in order to keep everything in sync */
2476 pvr2_i2c_core_check_stale(hdw);
2477
Mike Iselyc05c0462006-06-25 20:04:25 -03002478 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002479 cptr = hdw->controls + idx;
2480 if (!cptr->info->clear_dirty) continue;
2481 cptr->info->clear_dirty(cptr);
2482 }
2483
2484 /* Now execute i2c core update */
2485 pvr2_i2c_core_sync(hdw);
2486
2487 pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
2488 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
2489
2490 return 0;
2491}
2492
2493
2494int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2495{
2496 LOCK_TAKE(hdw->big_lock); do {
2497 pvr2_hdw_commit_ctl_internal(hdw);
2498 } while (0); LOCK_GIVE(hdw->big_lock);
2499 return 0;
2500}
2501
2502
2503void pvr2_hdw_poll(struct pvr2_hdw *hdw)
2504{
2505 LOCK_TAKE(hdw->big_lock); do {
2506 pvr2_i2c_core_sync(hdw);
2507 } while (0); LOCK_GIVE(hdw->big_lock);
2508}
2509
2510
2511void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
2512 void (*func)(void *),
2513 void *data)
2514{
2515 LOCK_TAKE(hdw->big_lock); do {
2516 hdw->poll_trigger_func = func;
2517 hdw->poll_trigger_data = data;
2518 } while (0); LOCK_GIVE(hdw->big_lock);
2519}
2520
2521
2522void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
2523{
2524 if (hdw->poll_trigger_func) {
2525 hdw->poll_trigger_func(hdw->poll_trigger_data);
2526 }
2527}
2528
Mike Iselyd8554972006-06-26 20:58:46 -03002529/* Return name for this driver instance */
2530const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2531{
2532 return hdw->name;
2533}
2534
2535
Mike Iselyd8554972006-06-26 20:58:46 -03002536int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2537{
2538 int result;
2539 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03002540 hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED;
Mike Iselyd8554972006-06-26 20:58:46 -03002541 result = pvr2_send_request(hdw,
2542 hdw->cmd_buffer,1,
2543 hdw->cmd_buffer,1);
2544 if (result < 0) break;
2545 result = (hdw->cmd_buffer[0] != 0);
2546 } while(0); LOCK_GIVE(hdw->ctl_lock);
2547 return result;
2548}
2549
2550
Mike Isely18103c52007-01-20 00:09:47 -03002551/* Execute poll of tuner status */
2552void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002553{
Mike Iselyd8554972006-06-26 20:58:46 -03002554 LOCK_TAKE(hdw->big_lock); do {
Mike Isely18103c52007-01-20 00:09:47 -03002555 pvr2_i2c_core_status_poll(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002556 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely18103c52007-01-20 00:09:47 -03002557}
2558
2559
2560/* Return information about the tuner */
2561int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
2562{
2563 LOCK_TAKE(hdw->big_lock); do {
2564 if (hdw->tuner_signal_stale) {
2565 pvr2_i2c_core_status_poll(hdw);
2566 }
2567 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
2568 } while (0); LOCK_GIVE(hdw->big_lock);
2569 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002570}
2571
2572
2573/* Get handle to video output stream */
2574struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2575{
2576 return hp->vid_stream;
2577}
2578
2579
2580void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2581{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002582 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002583 LOCK_TAKE(hdw->big_lock); do {
2584 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002585 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002586 pvr2_i2c_core_check_stale(hdw);
2587 hdw->log_requested = 0;
2588 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002589 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002590 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely4f1a3e52006-06-25 20:04:31 -03002591 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002592 } while (0); LOCK_GIVE(hdw->big_lock);
2593}
2594
2595void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
2596{
2597 int ret;
2598 u16 address;
2599 unsigned int pipe;
2600 LOCK_TAKE(hdw->big_lock); do {
2601 if ((hdw->fw_buffer == 0) == !enable_flag) break;
2602
2603 if (!enable_flag) {
2604 pvr2_trace(PVR2_TRACE_FIRMWARE,
2605 "Cleaning up after CPU firmware fetch");
2606 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002607 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002608 hdw->fw_size = 0;
2609 /* Now release the CPU. It will disconnect and
2610 reconnect later. */
2611 pvr2_hdw_cpureset_assert(hdw,0);
2612 break;
2613 }
2614
2615 pvr2_trace(PVR2_TRACE_FIRMWARE,
2616 "Preparing to suck out CPU firmware");
2617 hdw->fw_size = 0x2000;
Mike Iselyca545f72007-01-20 00:37:11 -03002618 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -03002619 if (!hdw->fw_buffer) {
2620 hdw->fw_size = 0;
2621 break;
2622 }
2623
Mike Iselyd8554972006-06-26 20:58:46 -03002624 /* We have to hold the CPU during firmware upload. */
2625 pvr2_hdw_cpureset_assert(hdw,1);
2626
2627 /* download the firmware from address 0000-1fff in 2048
2628 (=0x800) bytes chunk. */
2629
2630 pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
2631 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2632 for(address = 0; address < hdw->fw_size; address += 0x800) {
2633 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
2634 address,0,
2635 hdw->fw_buffer+address,0x800,HZ);
2636 if (ret < 0) break;
2637 }
2638
2639 pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
2640
2641 } while (0); LOCK_GIVE(hdw->big_lock);
2642}
2643
2644
2645/* Return true if we're in a mode for retrieval CPU firmware */
2646int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2647{
2648 return hdw->fw_buffer != 0;
2649}
2650
2651
2652int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2653 char *buf,unsigned int cnt)
2654{
2655 int ret = -EINVAL;
2656 LOCK_TAKE(hdw->big_lock); do {
2657 if (!buf) break;
2658 if (!cnt) break;
2659
2660 if (!hdw->fw_buffer) {
2661 ret = -EIO;
2662 break;
2663 }
2664
2665 if (offs >= hdw->fw_size) {
2666 pvr2_trace(PVR2_TRACE_FIRMWARE,
2667 "Read firmware data offs=%d EOF",
2668 offs);
2669 ret = 0;
2670 break;
2671 }
2672
2673 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2674
2675 memcpy(buf,hdw->fw_buffer+offs,cnt);
2676
2677 pvr2_trace(PVR2_TRACE_FIRMWARE,
2678 "Read firmware data offs=%d cnt=%d",
2679 offs,cnt);
2680 ret = cnt;
2681 } while (0); LOCK_GIVE(hdw->big_lock);
2682
2683 return ret;
2684}
2685
2686
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002687int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002688 enum pvr2_v4l_type index)
Mike Iselyd8554972006-06-26 20:58:46 -03002689{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002690 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002691 case pvr2_v4l_type_video: return hdw->v4l_minor_number_video;
2692 case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi;
2693 case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002694 default: return -1;
2695 }
Mike Iselyd8554972006-06-26 20:58:46 -03002696}
2697
2698
Pantelis Koukousoulas2fdf3d92006-12-27 23:07:58 -03002699/* Store a v4l minor device number */
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002700void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002701 enum pvr2_v4l_type index,int v)
Mike Iselyd8554972006-06-26 20:58:46 -03002702{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002703 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002704 case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
2705 case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
2706 case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002707 default: break;
2708 }
Mike Iselyd8554972006-06-26 20:58:46 -03002709}
2710
2711
David Howells7d12e782006-10-05 14:55:46 +01002712static void pvr2_ctl_write_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002713{
2714 struct pvr2_hdw *hdw = urb->context;
2715 hdw->ctl_write_pend_flag = 0;
2716 if (hdw->ctl_read_pend_flag) return;
2717 complete(&hdw->ctl_done);
2718}
2719
2720
David Howells7d12e782006-10-05 14:55:46 +01002721static void pvr2_ctl_read_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002722{
2723 struct pvr2_hdw *hdw = urb->context;
2724 hdw->ctl_read_pend_flag = 0;
2725 if (hdw->ctl_write_pend_flag) return;
2726 complete(&hdw->ctl_done);
2727}
2728
2729
2730static void pvr2_ctl_timeout(unsigned long data)
2731{
2732 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2733 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2734 hdw->ctl_timeout_flag = !0;
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002735 if (hdw->ctl_write_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002736 usb_unlink_urb(hdw->ctl_write_urb);
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002737 if (hdw->ctl_read_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002738 usb_unlink_urb(hdw->ctl_read_urb);
Mike Iselyd8554972006-06-26 20:58:46 -03002739 }
2740}
2741
2742
Mike Iselye61b6fc2006-07-18 22:42:18 -03002743/* Issue a command and get a response from the device. This extended
2744 version includes a probe flag (which if set means that device errors
2745 should not be logged or treated as fatal) and a timeout in jiffies.
2746 This can be used to non-lethally probe the health of endpoint 1. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002747static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2748 unsigned int timeout,int probe_fl,
2749 void *write_data,unsigned int write_len,
2750 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002751{
2752 unsigned int idx;
2753 int status = 0;
2754 struct timer_list timer;
2755 if (!hdw->ctl_lock_held) {
2756 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2757 "Attempted to execute control transfer"
2758 " without lock!!");
2759 return -EDEADLK;
2760 }
2761 if ((!hdw->flag_ok) && !probe_fl) {
2762 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2763 "Attempted to execute control transfer"
2764 " when device not ok");
2765 return -EIO;
2766 }
2767 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2768 if (!probe_fl) {
2769 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2770 "Attempted to execute control transfer"
2771 " when USB is disconnected");
2772 }
2773 return -ENOTTY;
2774 }
2775
2776 /* Ensure that we have sane parameters */
2777 if (!write_data) write_len = 0;
2778 if (!read_data) read_len = 0;
2779 if (write_len > PVR2_CTL_BUFFSIZE) {
2780 pvr2_trace(
2781 PVR2_TRACE_ERROR_LEGS,
2782 "Attempted to execute %d byte"
2783 " control-write transfer (limit=%d)",
2784 write_len,PVR2_CTL_BUFFSIZE);
2785 return -EINVAL;
2786 }
2787 if (read_len > PVR2_CTL_BUFFSIZE) {
2788 pvr2_trace(
2789 PVR2_TRACE_ERROR_LEGS,
2790 "Attempted to execute %d byte"
2791 " control-read transfer (limit=%d)",
2792 write_len,PVR2_CTL_BUFFSIZE);
2793 return -EINVAL;
2794 }
2795 if ((!write_len) && (!read_len)) {
2796 pvr2_trace(
2797 PVR2_TRACE_ERROR_LEGS,
2798 "Attempted to execute null control transfer?");
2799 return -EINVAL;
2800 }
2801
2802
2803 hdw->cmd_debug_state = 1;
2804 if (write_len) {
2805 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2806 } else {
2807 hdw->cmd_debug_code = 0;
2808 }
2809 hdw->cmd_debug_write_len = write_len;
2810 hdw->cmd_debug_read_len = read_len;
2811
2812 /* Initialize common stuff */
2813 init_completion(&hdw->ctl_done);
2814 hdw->ctl_timeout_flag = 0;
2815 hdw->ctl_write_pend_flag = 0;
2816 hdw->ctl_read_pend_flag = 0;
2817 init_timer(&timer);
2818 timer.expires = jiffies + timeout;
2819 timer.data = (unsigned long)hdw;
2820 timer.function = pvr2_ctl_timeout;
2821
2822 if (write_len) {
2823 hdw->cmd_debug_state = 2;
2824 /* Transfer write data to internal buffer */
2825 for (idx = 0; idx < write_len; idx++) {
2826 hdw->ctl_write_buffer[idx] =
2827 ((unsigned char *)write_data)[idx];
2828 }
2829 /* Initiate a write request */
2830 usb_fill_bulk_urb(hdw->ctl_write_urb,
2831 hdw->usb_dev,
2832 usb_sndbulkpipe(hdw->usb_dev,
2833 PVR2_CTL_WRITE_ENDPOINT),
2834 hdw->ctl_write_buffer,
2835 write_len,
2836 pvr2_ctl_write_complete,
2837 hdw);
2838 hdw->ctl_write_urb->actual_length = 0;
2839 hdw->ctl_write_pend_flag = !0;
2840 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2841 if (status < 0) {
2842 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2843 "Failed to submit write-control"
2844 " URB status=%d",status);
2845 hdw->ctl_write_pend_flag = 0;
2846 goto done;
2847 }
2848 }
2849
2850 if (read_len) {
2851 hdw->cmd_debug_state = 3;
2852 memset(hdw->ctl_read_buffer,0x43,read_len);
2853 /* Initiate a read request */
2854 usb_fill_bulk_urb(hdw->ctl_read_urb,
2855 hdw->usb_dev,
2856 usb_rcvbulkpipe(hdw->usb_dev,
2857 PVR2_CTL_READ_ENDPOINT),
2858 hdw->ctl_read_buffer,
2859 read_len,
2860 pvr2_ctl_read_complete,
2861 hdw);
2862 hdw->ctl_read_urb->actual_length = 0;
2863 hdw->ctl_read_pend_flag = !0;
2864 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
2865 if (status < 0) {
2866 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2867 "Failed to submit read-control"
2868 " URB status=%d",status);
2869 hdw->ctl_read_pend_flag = 0;
2870 goto done;
2871 }
2872 }
2873
2874 /* Start timer */
2875 add_timer(&timer);
2876
2877 /* Now wait for all I/O to complete */
2878 hdw->cmd_debug_state = 4;
2879 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2880 wait_for_completion(&hdw->ctl_done);
2881 }
2882 hdw->cmd_debug_state = 5;
2883
2884 /* Stop timer */
2885 del_timer_sync(&timer);
2886
2887 hdw->cmd_debug_state = 6;
2888 status = 0;
2889
2890 if (hdw->ctl_timeout_flag) {
2891 status = -ETIMEDOUT;
2892 if (!probe_fl) {
2893 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2894 "Timed out control-write");
2895 }
2896 goto done;
2897 }
2898
2899 if (write_len) {
2900 /* Validate results of write request */
2901 if ((hdw->ctl_write_urb->status != 0) &&
2902 (hdw->ctl_write_urb->status != -ENOENT) &&
2903 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
2904 (hdw->ctl_write_urb->status != -ECONNRESET)) {
2905 /* USB subsystem is reporting some kind of failure
2906 on the write */
2907 status = hdw->ctl_write_urb->status;
2908 if (!probe_fl) {
2909 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2910 "control-write URB failure,"
2911 " status=%d",
2912 status);
2913 }
2914 goto done;
2915 }
2916 if (hdw->ctl_write_urb->actual_length < write_len) {
2917 /* Failed to write enough data */
2918 status = -EIO;
2919 if (!probe_fl) {
2920 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2921 "control-write URB short,"
2922 " expected=%d got=%d",
2923 write_len,
2924 hdw->ctl_write_urb->actual_length);
2925 }
2926 goto done;
2927 }
2928 }
2929 if (read_len) {
2930 /* Validate results of read request */
2931 if ((hdw->ctl_read_urb->status != 0) &&
2932 (hdw->ctl_read_urb->status != -ENOENT) &&
2933 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
2934 (hdw->ctl_read_urb->status != -ECONNRESET)) {
2935 /* USB subsystem is reporting some kind of failure
2936 on the read */
2937 status = hdw->ctl_read_urb->status;
2938 if (!probe_fl) {
2939 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2940 "control-read URB failure,"
2941 " status=%d",
2942 status);
2943 }
2944 goto done;
2945 }
2946 if (hdw->ctl_read_urb->actual_length < read_len) {
2947 /* Failed to read enough data */
2948 status = -EIO;
2949 if (!probe_fl) {
2950 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2951 "control-read URB short,"
2952 " expected=%d got=%d",
2953 read_len,
2954 hdw->ctl_read_urb->actual_length);
2955 }
2956 goto done;
2957 }
2958 /* Transfer retrieved data out from internal buffer */
2959 for (idx = 0; idx < read_len; idx++) {
2960 ((unsigned char *)read_data)[idx] =
2961 hdw->ctl_read_buffer[idx];
2962 }
2963 }
2964
2965 done:
2966
2967 hdw->cmd_debug_state = 0;
2968 if ((status < 0) && (!probe_fl)) {
2969 pvr2_hdw_render_useless_unlocked(hdw);
2970 }
2971 return status;
2972}
2973
2974
2975int pvr2_send_request(struct pvr2_hdw *hdw,
2976 void *write_data,unsigned int write_len,
2977 void *read_data,unsigned int read_len)
2978{
2979 return pvr2_send_request_ex(hdw,HZ*4,0,
2980 write_data,write_len,
2981 read_data,read_len);
2982}
2983
2984int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
2985{
2986 int ret;
2987
2988 LOCK_TAKE(hdw->ctl_lock);
2989
Michael Krufky8d364362007-01-22 02:17:55 -03002990 hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03002991 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
2992 hdw->cmd_buffer[5] = 0;
2993 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2994 hdw->cmd_buffer[7] = reg & 0xff;
2995
2996
2997 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
2998
2999 LOCK_GIVE(hdw->ctl_lock);
3000
3001 return ret;
3002}
3003
3004
Adrian Bunk07e337e2006-06-30 11:30:20 -03003005static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03003006{
3007 int ret = 0;
3008
3009 LOCK_TAKE(hdw->ctl_lock);
3010
Michael Krufky8d364362007-01-22 02:17:55 -03003011 hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03003012 hdw->cmd_buffer[1] = 0;
3013 hdw->cmd_buffer[2] = 0;
3014 hdw->cmd_buffer[3] = 0;
3015 hdw->cmd_buffer[4] = 0;
3016 hdw->cmd_buffer[5] = 0;
3017 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3018 hdw->cmd_buffer[7] = reg & 0xff;
3019
3020 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
3021 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
3022
3023 LOCK_GIVE(hdw->ctl_lock);
3024
3025 return ret;
3026}
3027
3028
Adrian Bunk07e337e2006-06-30 11:30:20 -03003029static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003030{
3031 if (!hdw->flag_ok) return;
3032 pvr2_trace(PVR2_TRACE_INIT,"render_useless");
3033 hdw->flag_ok = 0;
3034 if (hdw->vid_stream) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003035 pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003036 }
3037 hdw->flag_streaming_enabled = 0;
3038 hdw->subsys_enabled_mask = 0;
3039}
3040
3041
3042void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
3043{
3044 LOCK_TAKE(hdw->ctl_lock);
3045 pvr2_hdw_render_useless_unlocked(hdw);
3046 LOCK_GIVE(hdw->ctl_lock);
3047}
3048
3049
3050void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
3051{
3052 int ret;
3053 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003054 ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -03003055 if (ret == 1) {
3056 ret = usb_reset_device(hdw->usb_dev);
3057 usb_unlock_device(hdw->usb_dev);
3058 } else {
3059 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3060 "Failed to lock USB device ret=%d",ret);
3061 }
3062 if (init_pause_msec) {
3063 pvr2_trace(PVR2_TRACE_INFO,
3064 "Waiting %u msec for hardware to settle",
3065 init_pause_msec);
3066 msleep(init_pause_msec);
3067 }
3068
3069}
3070
3071
3072void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
3073{
3074 char da[1];
3075 unsigned int pipe;
3076 int ret;
3077
3078 if (!hdw->usb_dev) return;
3079
3080 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
3081
3082 da[0] = val ? 0x01 : 0x00;
3083
3084 /* Write the CPUCS register on the 8051. The lsb of the register
3085 is the reset bit; a 1 asserts reset while a 0 clears it. */
3086 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
3087 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
3088 if (ret < 0) {
3089 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3090 "cpureset_assert(%d) error=%d",val,ret);
3091 pvr2_hdw_render_useless(hdw);
3092 }
3093}
3094
3095
3096int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
3097{
3098 int status;
3099 LOCK_TAKE(hdw->ctl_lock); do {
3100 pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
3101 hdw->flag_ok = !0;
Michael Krufky8d364362007-01-22 02:17:55 -03003102 hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003103 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003104 } while (0); LOCK_GIVE(hdw->ctl_lock);
3105 return status;
3106}
3107
3108
3109int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
3110{
3111 int status;
3112 LOCK_TAKE(hdw->ctl_lock); do {
3113 pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
Michael Krufky8d364362007-01-22 02:17:55 -03003114 hdw->cmd_buffer[0] = FX2CMD_POWER_ON;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003115 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003116 } while (0); LOCK_GIVE(hdw->ctl_lock);
3117 return status;
3118}
3119
3120
3121int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
3122{
3123 if (!hdw->decoder_ctrl) {
3124 pvr2_trace(PVR2_TRACE_INIT,
3125 "Unable to reset decoder: nothing attached");
3126 return -ENOTTY;
3127 }
3128
3129 if (!hdw->decoder_ctrl->force_reset) {
3130 pvr2_trace(PVR2_TRACE_INIT,
3131 "Unable to reset decoder: not implemented");
3132 return -ENOTTY;
3133 }
3134
3135 pvr2_trace(PVR2_TRACE_INIT,
3136 "Requesting decoder reset");
3137 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
3138 return 0;
3139}
3140
3141
Mike Iselye61b6fc2006-07-18 22:42:18 -03003142/* Stop / start video stream transport */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003143static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03003144{
3145 int status;
3146 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03003147 hdw->cmd_buffer[0] =
3148 (runFl ? FX2CMD_STREAMING_ON : FX2CMD_STREAMING_OFF);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003149 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003150 } while (0); LOCK_GIVE(hdw->ctl_lock);
3151 if (!status) {
3152 hdw->subsys_enabled_mask =
3153 ((hdw->subsys_enabled_mask &
3154 ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
3155 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
3156 }
3157 return status;
3158}
3159
3160
3161void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
3162 struct pvr2_hdw_debug_info *ptr)
3163{
3164 ptr->big_lock_held = hdw->big_lock_held;
3165 ptr->ctl_lock_held = hdw->ctl_lock_held;
3166 ptr->flag_ok = hdw->flag_ok;
3167 ptr->flag_disconnected = hdw->flag_disconnected;
3168 ptr->flag_init_ok = hdw->flag_init_ok;
3169 ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
3170 ptr->subsys_flags = hdw->subsys_enabled_mask;
3171 ptr->cmd_debug_state = hdw->cmd_debug_state;
3172 ptr->cmd_code = hdw->cmd_debug_code;
3173 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
3174 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
3175 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
3176 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
3177 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
3178 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
3179 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
3180}
3181
3182
3183int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
3184{
3185 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
3186}
3187
3188
3189int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
3190{
3191 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
3192}
3193
3194
3195int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
3196{
3197 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
3198}
3199
3200
3201int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
3202{
3203 u32 cval,nval;
3204 int ret;
3205 if (~msk) {
3206 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
3207 if (ret) return ret;
3208 nval = (cval & ~msk) | (val & msk);
3209 pvr2_trace(PVR2_TRACE_GPIO,
3210 "GPIO direction changing 0x%x:0x%x"
3211 " from 0x%x to 0x%x",
3212 msk,val,cval,nval);
3213 } else {
3214 nval = val;
3215 pvr2_trace(PVR2_TRACE_GPIO,
3216 "GPIO direction changing to 0x%x",nval);
3217 }
3218 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
3219}
3220
3221
3222int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
3223{
3224 u32 cval,nval;
3225 int ret;
3226 if (~msk) {
3227 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
3228 if (ret) return ret;
3229 nval = (cval & ~msk) | (val & msk);
3230 pvr2_trace(PVR2_TRACE_GPIO,
3231 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
3232 msk,val,cval,nval);
3233 } else {
3234 nval = val;
3235 pvr2_trace(PVR2_TRACE_GPIO,
3236 "GPIO output changing to 0x%x",nval);
3237 }
3238 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
3239}
3240
3241
Mike Iselye61b6fc2006-07-18 22:42:18 -03003242/* Find I2C address of eeprom */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003243static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003244{
3245 int result;
3246 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03003247 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03003248 result = pvr2_send_request(hdw,
3249 hdw->cmd_buffer,1,
3250 hdw->cmd_buffer,1);
3251 if (result < 0) break;
3252 result = hdw->cmd_buffer[0];
3253 } while(0); LOCK_GIVE(hdw->ctl_lock);
3254 return result;
3255}
3256
3257
Mike Isely32ffa9a2006-09-23 22:26:52 -03003258int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
Hans Verkuilf3d092b2007-02-23 20:55:14 -03003259 u32 match_type, u32 match_chip, u64 reg_id,
3260 int setFl,u64 *val_ptr)
Mike Isely32ffa9a2006-09-23 22:26:52 -03003261{
3262#ifdef CONFIG_VIDEO_ADV_DEBUG
3263 struct list_head *item;
3264 struct pvr2_i2c_client *cp;
3265 struct v4l2_register req;
Mike Isely6d988162006-09-28 17:53:49 -03003266 int stat = 0;
3267 int okFl = 0;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003268
Mike Isely201f5c92007-01-28 16:08:36 -03003269 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
3270
Hans Verkuilf3d092b2007-02-23 20:55:14 -03003271 req.match_type = match_type;
3272 req.match_chip = match_chip;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003273 req.reg = reg_id;
3274 if (setFl) req.val = *val_ptr;
3275 mutex_lock(&hdw->i2c_list_lock); do {
3276 list_for_each(item,&hdw->i2c_clients) {
3277 cp = list_entry(item,struct pvr2_i2c_client,list);
Hans Verkuilf3d092b2007-02-23 20:55:14 -03003278 if (!v4l2_chip_match_i2c_client(cp->client, req.match_type, req.match_chip)) {
3279 continue;
3280 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03003281 stat = pvr2_i2c_client_cmd(
Trent Piepho52ebc762007-01-23 22:38:13 -03003282 cp,(setFl ? VIDIOC_DBG_S_REGISTER :
3283 VIDIOC_DBG_G_REGISTER),&req);
Mike Isely32ffa9a2006-09-23 22:26:52 -03003284 if (!setFl) *val_ptr = req.val;
Mike Isely6d988162006-09-28 17:53:49 -03003285 okFl = !0;
3286 break;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003287 }
3288 } while (0); mutex_unlock(&hdw->i2c_list_lock);
Mike Isely6d988162006-09-28 17:53:49 -03003289 if (okFl) {
3290 return stat;
3291 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03003292 return -EINVAL;
3293#else
3294 return -ENOSYS;
3295#endif
3296}
3297
3298
Mike Iselyd8554972006-06-26 20:58:46 -03003299/*
3300 Stuff for Emacs to see, in order to encourage consistent editing style:
3301 *** Local Variables: ***
3302 *** mode: c ***
3303 *** fill-column: 75 ***
3304 *** tab-width: 8 ***
3305 *** c-basic-offset: 8 ***
3306 *** End: ***
3307 */