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