blob: 2a350755bd30d58e7979a6806110225dfeeca071 [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, \
Mike Isely27c7b712007-01-20 00:39:17 -0300726 .def.type_enum.count = ARRAY_SIZE(tab), \
Mike Iselyd8554972006-06-26 20:58:46 -0300727 .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
Mike Iselyca545f72007-01-20 00:37:11 -03001937 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -03001938 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
1939 hdw,pvr2_device_names[hdw_type]);
1940 if (!hdw) goto fail;
Mike Isely18103c572007-01-20 00:09:47 -03001941 hdw->tuner_signal_stale = !0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001942 cx2341x_fill_defaults(&hdw->enc_ctl_state);
Mike Iselyd8554972006-06-26 20:58:46 -03001943
Mike Iselyc05c0462006-06-25 20:04:25 -03001944 hdw->control_cnt = CTRLDEF_COUNT;
Mike Iselyb30d2442006-06-25 20:05:01 -03001945 hdw->control_cnt += MPEGDEF_COUNT;
Mike Iselyca545f72007-01-20 00:37:11 -03001946 hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001947 GFP_KERNEL);
1948 if (!hdw->controls) goto fail;
Mike Iselyd8554972006-06-26 20:58:46 -03001949 hdw->hdw_type = hdw_type;
Mike Iselyc05c0462006-06-25 20:04:25 -03001950 for (idx = 0; idx < hdw->control_cnt; idx++) {
1951 cptr = hdw->controls + idx;
1952 cptr->hdw = hdw;
1953 }
Mike Iselyd8554972006-06-26 20:58:46 -03001954 for (idx = 0; idx < 32; idx++) {
1955 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1956 }
Mike Iselyc05c0462006-06-25 20:04:25 -03001957 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001958 cptr = hdw->controls + idx;
Mike Iselyd8554972006-06-26 20:58:46 -03001959 cptr->info = control_defs+idx;
1960 }
Mike Iselyb30d2442006-06-25 20:05:01 -03001961 /* Define and configure additional controls from cx2341x module. */
Mike Iselyca545f72007-01-20 00:37:11 -03001962 hdw->mpeg_ctrl_info = kzalloc(
Mike Iselyb30d2442006-06-25 20:05:01 -03001963 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
1964 if (!hdw->mpeg_ctrl_info) goto fail;
Mike Iselyb30d2442006-06-25 20:05:01 -03001965 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
1966 cptr = hdw->controls + idx + CTRLDEF_COUNT;
1967 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
1968 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
1969 ciptr->name = mpeg_ids[idx].strid;
1970 ciptr->v4l_id = mpeg_ids[idx].id;
1971 ciptr->skip_init = !0;
1972 ciptr->get_value = ctrl_cx2341x_get;
1973 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
1974 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
1975 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
1976 qctrl.id = ciptr->v4l_id;
1977 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
1978 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
1979 ciptr->set_value = ctrl_cx2341x_set;
1980 }
1981 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
1982 PVR2_CTLD_INFO_DESC_SIZE);
1983 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
1984 ciptr->default_value = qctrl.default_value;
1985 switch (qctrl.type) {
1986 default:
1987 case V4L2_CTRL_TYPE_INTEGER:
1988 ciptr->type = pvr2_ctl_int;
1989 ciptr->def.type_int.min_value = qctrl.minimum;
1990 ciptr->def.type_int.max_value = qctrl.maximum;
1991 break;
1992 case V4L2_CTRL_TYPE_BOOLEAN:
1993 ciptr->type = pvr2_ctl_bool;
1994 break;
1995 case V4L2_CTRL_TYPE_MENU:
1996 ciptr->type = pvr2_ctl_enum;
1997 ciptr->def.type_enum.value_names =
1998 cx2341x_ctrl_get_menu(ciptr->v4l_id);
1999 for (cnt1 = 0;
2000 ciptr->def.type_enum.value_names[cnt1] != NULL;
2001 cnt1++) { }
2002 ciptr->def.type_enum.count = cnt1;
2003 break;
2004 }
2005 cptr->info = ciptr;
2006 }
Mike Iselyd8554972006-06-26 20:58:46 -03002007
2008 // Initialize video standard enum dynamic control
2009 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
2010 if (cptr) {
2011 memcpy(&hdw->std_info_enum,cptr->info,
2012 sizeof(hdw->std_info_enum));
2013 cptr->info = &hdw->std_info_enum;
2014
2015 }
2016 // Initialize control data regarding video standard masks
2017 valid_std_mask = pvr2_std_get_usable();
2018 for (idx = 0; idx < 32; idx++) {
2019 if (!(valid_std_mask & (1 << idx))) continue;
2020 cnt1 = pvr2_std_id_to_str(
2021 hdw->std_mask_names[idx],
2022 sizeof(hdw->std_mask_names[idx])-1,
2023 1 << idx);
2024 hdw->std_mask_names[idx][cnt1] = 0;
2025 }
2026 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
2027 if (cptr) {
2028 memcpy(&hdw->std_info_avail,cptr->info,
2029 sizeof(hdw->std_info_avail));
2030 cptr->info = &hdw->std_info_avail;
2031 hdw->std_info_avail.def.type_bitmask.bit_names =
2032 hdw->std_mask_ptrs;
2033 hdw->std_info_avail.def.type_bitmask.valid_bits =
2034 valid_std_mask;
2035 }
2036 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
2037 if (cptr) {
2038 memcpy(&hdw->std_info_cur,cptr->info,
2039 sizeof(hdw->std_info_cur));
2040 cptr->info = &hdw->std_info_cur;
2041 hdw->std_info_cur.def.type_bitmask.bit_names =
2042 hdw->std_mask_ptrs;
2043 hdw->std_info_avail.def.type_bitmask.valid_bits =
2044 valid_std_mask;
2045 }
2046
2047 hdw->eeprom_addr = -1;
2048 hdw->unit_number = -1;
Mike Isely80793842006-12-27 23:12:28 -03002049 hdw->v4l_minor_number_video = -1;
2050 hdw->v4l_minor_number_vbi = -1;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002051 hdw->v4l_minor_number_radio = -1;
Mike Iselyd8554972006-06-26 20:58:46 -03002052 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2053 if (!hdw->ctl_write_buffer) goto fail;
2054 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2055 if (!hdw->ctl_read_buffer) goto fail;
2056 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
2057 if (!hdw->ctl_write_urb) goto fail;
2058 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
2059 if (!hdw->ctl_read_urb) goto fail;
2060
2061 down(&pvr2_unit_sem); do {
2062 for (idx = 0; idx < PVR_NUM; idx++) {
2063 if (unit_pointers[idx]) continue;
2064 hdw->unit_number = idx;
2065 unit_pointers[idx] = hdw;
2066 break;
2067 }
2068 } while (0); up(&pvr2_unit_sem);
2069
2070 cnt1 = 0;
2071 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
2072 cnt1 += cnt2;
2073 if (hdw->unit_number >= 0) {
2074 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
2075 ('a' + hdw->unit_number));
2076 cnt1 += cnt2;
2077 }
2078 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
2079 hdw->name[cnt1] = 0;
2080
2081 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
2082 hdw->unit_number,hdw->name);
2083
2084 hdw->tuner_type = -1;
2085 hdw->flag_ok = !0;
2086 /* Initialize the mask of subsystems that we will shut down when we
2087 stop streaming. */
2088 hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL;
2089 hdw->subsys_stream_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
2090
2091 pvr2_trace(PVR2_TRACE_INIT,"subsys_stream_mask: 0x%lx",
2092 hdw->subsys_stream_mask);
2093
2094 hdw->usb_intf = intf;
2095 hdw->usb_dev = interface_to_usbdev(intf);
2096
2097 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2098 usb_set_interface(hdw->usb_dev,ifnum,0);
2099
2100 mutex_init(&hdw->ctl_lock_mutex);
2101 mutex_init(&hdw->big_lock_mutex);
2102
2103 return hdw;
2104 fail:
2105 if (hdw) {
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002106 usb_free_urb(hdw->ctl_read_urb);
2107 usb_free_urb(hdw->ctl_write_urb);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002108 kfree(hdw->ctl_read_buffer);
2109 kfree(hdw->ctl_write_buffer);
2110 kfree(hdw->controls);
2111 kfree(hdw->mpeg_ctrl_info);
Mike Iselyd8554972006-06-26 20:58:46 -03002112 kfree(hdw);
2113 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002114 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002115}
2116
2117
2118/* Remove _all_ associations between this driver and the underlying USB
2119 layer. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002120static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002121{
2122 if (hdw->flag_disconnected) return;
2123 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
2124 if (hdw->ctl_read_urb) {
2125 usb_kill_urb(hdw->ctl_read_urb);
2126 usb_free_urb(hdw->ctl_read_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002127 hdw->ctl_read_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002128 }
2129 if (hdw->ctl_write_urb) {
2130 usb_kill_urb(hdw->ctl_write_urb);
2131 usb_free_urb(hdw->ctl_write_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002132 hdw->ctl_write_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002133 }
2134 if (hdw->ctl_read_buffer) {
2135 kfree(hdw->ctl_read_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002136 hdw->ctl_read_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002137 }
2138 if (hdw->ctl_write_buffer) {
2139 kfree(hdw->ctl_write_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002140 hdw->ctl_write_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002141 }
2142 pvr2_hdw_render_useless_unlocked(hdw);
2143 hdw->flag_disconnected = !0;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002144 hdw->usb_dev = NULL;
2145 hdw->usb_intf = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002146}
2147
2148
2149/* Destroy hardware interaction structure */
2150void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2151{
2152 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
2153 if (hdw->fw_buffer) {
2154 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002155 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002156 }
2157 if (hdw->vid_stream) {
2158 pvr2_stream_destroy(hdw->vid_stream);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002159 hdw->vid_stream = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002160 }
Mike Iselyd8554972006-06-26 20:58:46 -03002161 if (hdw->decoder_ctrl) {
2162 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2163 }
2164 pvr2_i2c_core_done(hdw);
2165 pvr2_hdw_remove_usb_stuff(hdw);
2166 down(&pvr2_unit_sem); do {
2167 if ((hdw->unit_number >= 0) &&
2168 (hdw->unit_number < PVR_NUM) &&
2169 (unit_pointers[hdw->unit_number] == hdw)) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002170 unit_pointers[hdw->unit_number] = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002171 }
2172 } while (0); up(&pvr2_unit_sem);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002173 kfree(hdw->controls);
2174 kfree(hdw->mpeg_ctrl_info);
2175 kfree(hdw->std_defs);
2176 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002177 kfree(hdw);
2178}
2179
2180
2181int pvr2_hdw_init_ok(struct pvr2_hdw *hdw)
2182{
2183 return hdw->flag_init_ok;
2184}
2185
2186
2187int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2188{
2189 return (hdw && hdw->flag_ok);
2190}
2191
2192
2193/* Called when hardware has been unplugged */
2194void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2195{
2196 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2197 LOCK_TAKE(hdw->big_lock);
2198 LOCK_TAKE(hdw->ctl_lock);
2199 pvr2_hdw_remove_usb_stuff(hdw);
2200 LOCK_GIVE(hdw->ctl_lock);
2201 LOCK_GIVE(hdw->big_lock);
2202}
2203
2204
2205// Attempt to autoselect an appropriate value for std_enum_cur given
2206// whatever is currently in std_mask_cur
Adrian Bunk07e337e2006-06-30 11:30:20 -03002207static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002208{
2209 unsigned int idx;
2210 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2211 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2212 hdw->std_enum_cur = idx;
2213 return;
2214 }
2215 }
2216 hdw->std_enum_cur = 0;
2217}
2218
2219
2220// Calculate correct set of enumerated standards based on currently known
2221// set of available standards bits.
Adrian Bunk07e337e2006-06-30 11:30:20 -03002222static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002223{
2224 struct v4l2_standard *newstd;
2225 unsigned int std_cnt;
2226 unsigned int idx;
2227
2228 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2229
2230 if (hdw->std_defs) {
2231 kfree(hdw->std_defs);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002232 hdw->std_defs = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002233 }
2234 hdw->std_enum_cnt = 0;
2235 if (hdw->std_enum_names) {
2236 kfree(hdw->std_enum_names);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002237 hdw->std_enum_names = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002238 }
2239
2240 if (!std_cnt) {
2241 pvr2_trace(
2242 PVR2_TRACE_ERROR_LEGS,
2243 "WARNING: Failed to identify any viable standards");
2244 }
2245 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2246 hdw->std_enum_names[0] = "none";
2247 for (idx = 0; idx < std_cnt; idx++) {
2248 hdw->std_enum_names[idx+1] =
2249 newstd[idx].name;
2250 }
2251 // Set up the dynamic control for this standard
2252 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2253 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2254 hdw->std_defs = newstd;
2255 hdw->std_enum_cnt = std_cnt+1;
2256 hdw->std_enum_cur = 0;
2257 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2258}
2259
2260
2261int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2262 struct v4l2_standard *std,
2263 unsigned int idx)
2264{
2265 int ret = -EINVAL;
2266 if (!idx) return ret;
2267 LOCK_TAKE(hdw->big_lock); do {
2268 if (idx >= hdw->std_enum_cnt) break;
2269 idx--;
2270 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2271 ret = 0;
2272 } while (0); LOCK_GIVE(hdw->big_lock);
2273 return ret;
2274}
2275
2276
2277/* Get the number of defined controls */
2278unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2279{
Mike Iselyc05c0462006-06-25 20:04:25 -03002280 return hdw->control_cnt;
Mike Iselyd8554972006-06-26 20:58:46 -03002281}
2282
2283
2284/* Retrieve a control handle given its index (0..count-1) */
2285struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2286 unsigned int idx)
2287{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002288 if (idx >= hdw->control_cnt) return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002289 return hdw->controls + idx;
2290}
2291
2292
2293/* Retrieve a control handle given its index (0..count-1) */
2294struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2295 unsigned int ctl_id)
2296{
2297 struct pvr2_ctrl *cptr;
2298 unsigned int idx;
2299 int i;
2300
2301 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002302 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002303 cptr = hdw->controls + idx;
2304 i = cptr->info->internal_id;
2305 if (i && (i == ctl_id)) return cptr;
2306 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002307 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002308}
2309
2310
Mike Iselya761f432006-06-25 20:04:44 -03002311/* Given a V4L ID, retrieve the control structure associated with it. */
Mike Iselyd8554972006-06-26 20:58:46 -03002312struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2313{
2314 struct pvr2_ctrl *cptr;
2315 unsigned int idx;
2316 int i;
2317
2318 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002319 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002320 cptr = hdw->controls + idx;
2321 i = cptr->info->v4l_id;
2322 if (i && (i == ctl_id)) return cptr;
2323 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002324 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002325}
2326
2327
Mike Iselya761f432006-06-25 20:04:44 -03002328/* Given a V4L ID for its immediate predecessor, retrieve the control
2329 structure associated with it. */
2330struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2331 unsigned int ctl_id)
2332{
2333 struct pvr2_ctrl *cptr,*cp2;
2334 unsigned int idx;
2335 int i;
2336
2337 /* This could be made a lot more efficient, but for now... */
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002338 cp2 = NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002339 for (idx = 0; idx < hdw->control_cnt; idx++) {
2340 cptr = hdw->controls + idx;
2341 i = cptr->info->v4l_id;
2342 if (!i) continue;
2343 if (i <= ctl_id) continue;
2344 if (cp2 && (cp2->info->v4l_id < i)) continue;
2345 cp2 = cptr;
2346 }
2347 return cp2;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002348 return NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002349}
2350
2351
Mike Iselyd8554972006-06-26 20:58:46 -03002352static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2353{
2354 switch (tp) {
2355 case pvr2_ctl_int: return "integer";
2356 case pvr2_ctl_enum: return "enum";
Mike Isely33213962006-06-25 20:04:40 -03002357 case pvr2_ctl_bool: return "boolean";
Mike Iselyd8554972006-06-26 20:58:46 -03002358 case pvr2_ctl_bitmask: return "bitmask";
2359 }
2360 return "";
2361}
2362
2363
2364/* Commit all control changes made up to this point. Subsystems can be
2365 indirectly affected by these changes. For a given set of things being
2366 committed, we'll clear the affected subsystem bits and then once we're
2367 done committing everything we'll make a request to restore the subsystem
2368 state(s) back to their previous value before this function was called.
2369 Thus we can automatically reconfigure affected pieces of the driver as
2370 controls are changed. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002371static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002372{
2373 unsigned long saved_subsys_mask = hdw->subsys_enabled_mask;
2374 unsigned long stale_subsys_mask = 0;
2375 unsigned int idx;
2376 struct pvr2_ctrl *cptr;
2377 int value;
2378 int commit_flag = 0;
2379 char buf[100];
2380 unsigned int bcnt,ccnt;
2381
Mike Iselyc05c0462006-06-25 20:04:25 -03002382 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002383 cptr = hdw->controls + idx;
2384 if (cptr->info->is_dirty == 0) continue;
2385 if (!cptr->info->is_dirty(cptr)) continue;
Mike Iselyfe23a282007-01-20 00:10:55 -03002386 commit_flag = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002387
Mike Iselyfe23a282007-01-20 00:10:55 -03002388 if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002389 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2390 cptr->info->name);
2391 value = 0;
2392 cptr->info->get_value(cptr,&value);
2393 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2394 buf+bcnt,
2395 sizeof(buf)-bcnt,&ccnt);
2396 bcnt += ccnt;
2397 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2398 get_ctrl_typename(cptr->info->type));
2399 pvr2_trace(PVR2_TRACE_CTL,
2400 "/*--TRACE_COMMIT--*/ %.*s",
2401 bcnt,buf);
2402 }
2403
2404 if (!commit_flag) {
2405 /* Nothing has changed */
2406 return 0;
2407 }
2408
2409 /* When video standard changes, reset the hres and vres values -
2410 but if the user has pending changes there, then let the changes
2411 take priority. */
2412 if (hdw->std_dirty) {
2413 /* Rewrite the vertical resolution to be appropriate to the
2414 video standard that has been selected. */
2415 int nvres;
2416 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2417 nvres = 480;
2418 } else {
2419 nvres = 576;
2420 }
2421 if (nvres != hdw->res_ver_val) {
2422 hdw->res_ver_val = nvres;
2423 hdw->res_ver_dirty = !0;
2424 }
Mike Iselyd8554972006-06-26 20:58:46 -03002425 }
2426
2427 if (hdw->std_dirty ||
Mike Isely434449f2006-08-08 09:10:06 -03002428 hdw->enc_stale ||
2429 hdw->srate_dirty ||
2430 hdw->res_ver_dirty ||
2431 hdw->res_hor_dirty ||
Mike Iselyb46cfa82006-06-25 20:04:53 -03002432 0) {
Mike Iselyd8554972006-06-26 20:58:46 -03002433 /* If any of this changes, then the encoder needs to be
2434 reconfigured, and we need to reset the stream. */
2435 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
Mike Iselyd8554972006-06-26 20:58:46 -03002436 }
2437
Pantelis Koukousoulas275b2e22006-12-27 23:05:19 -03002438 if (hdw->input_dirty) {
2439 /* pk: If input changes to or from radio, then the encoder
2440 needs to be restarted (for ENC_MUTE_VIDEO to work) */
2441 stale_subsys_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
2442 }
2443
2444
Mike Iselyb30d2442006-06-25 20:05:01 -03002445 if (hdw->srate_dirty) {
2446 /* Write new sample rate into control structure since
2447 * the master copy is stale. We must track srate
2448 * separate from the mpeg control structure because
2449 * other logic also uses this value. */
2450 struct v4l2_ext_controls cs;
2451 struct v4l2_ext_control c1;
2452 memset(&cs,0,sizeof(cs));
2453 memset(&c1,0,sizeof(c1));
2454 cs.controls = &c1;
2455 cs.count = 1;
2456 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2457 c1.value = hdw->srate_val;
2458 cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS);
2459 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002460
Mike Iselyd8554972006-06-26 20:58:46 -03002461 /* Scan i2c core at this point - before we clear all the dirty
2462 bits. Various parts of the i2c core will notice dirty bits as
2463 appropriate and arrange to broadcast or directly send updates to
2464 the client drivers in order to keep everything in sync */
2465 pvr2_i2c_core_check_stale(hdw);
2466
Mike Iselyc05c0462006-06-25 20:04:25 -03002467 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002468 cptr = hdw->controls + idx;
2469 if (!cptr->info->clear_dirty) continue;
2470 cptr->info->clear_dirty(cptr);
2471 }
2472
2473 /* Now execute i2c core update */
2474 pvr2_i2c_core_sync(hdw);
2475
2476 pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0);
2477 pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask);
2478
2479 return 0;
2480}
2481
2482
2483int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2484{
2485 LOCK_TAKE(hdw->big_lock); do {
2486 pvr2_hdw_commit_ctl_internal(hdw);
2487 } while (0); LOCK_GIVE(hdw->big_lock);
2488 return 0;
2489}
2490
2491
2492void pvr2_hdw_poll(struct pvr2_hdw *hdw)
2493{
2494 LOCK_TAKE(hdw->big_lock); do {
2495 pvr2_i2c_core_sync(hdw);
2496 } while (0); LOCK_GIVE(hdw->big_lock);
2497}
2498
2499
2500void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw,
2501 void (*func)(void *),
2502 void *data)
2503{
2504 LOCK_TAKE(hdw->big_lock); do {
2505 hdw->poll_trigger_func = func;
2506 hdw->poll_trigger_data = data;
2507 } while (0); LOCK_GIVE(hdw->big_lock);
2508}
2509
2510
2511void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw)
2512{
2513 if (hdw->poll_trigger_func) {
2514 hdw->poll_trigger_func(hdw->poll_trigger_data);
2515 }
2516}
2517
Mike Iselyd8554972006-06-26 20:58:46 -03002518/* Return name for this driver instance */
2519const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2520{
2521 return hdw->name;
2522}
2523
2524
Mike Iselyd8554972006-06-26 20:58:46 -03002525int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2526{
2527 int result;
2528 LOCK_TAKE(hdw->ctl_lock); do {
2529 hdw->cmd_buffer[0] = 0x0b;
2530 result = pvr2_send_request(hdw,
2531 hdw->cmd_buffer,1,
2532 hdw->cmd_buffer,1);
2533 if (result < 0) break;
2534 result = (hdw->cmd_buffer[0] != 0);
2535 } while(0); LOCK_GIVE(hdw->ctl_lock);
2536 return result;
2537}
2538
2539
Mike Isely18103c572007-01-20 00:09:47 -03002540/* Execute poll of tuner status */
2541void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002542{
Mike Iselyd8554972006-06-26 20:58:46 -03002543 LOCK_TAKE(hdw->big_lock); do {
Mike Isely18103c572007-01-20 00:09:47 -03002544 pvr2_i2c_core_status_poll(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002545 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely18103c572007-01-20 00:09:47 -03002546}
2547
2548
2549/* Return information about the tuner */
2550int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
2551{
2552 LOCK_TAKE(hdw->big_lock); do {
2553 if (hdw->tuner_signal_stale) {
2554 pvr2_i2c_core_status_poll(hdw);
2555 }
2556 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
2557 } while (0); LOCK_GIVE(hdw->big_lock);
2558 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002559}
2560
2561
2562/* Get handle to video output stream */
2563struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2564{
2565 return hp->vid_stream;
2566}
2567
2568
2569void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2570{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002571 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002572 LOCK_TAKE(hdw->big_lock); do {
2573 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002574 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002575 pvr2_i2c_core_check_stale(hdw);
2576 hdw->log_requested = 0;
2577 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002578 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002579 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely4f1a3e52006-06-25 20:04:31 -03002580 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002581 } while (0); LOCK_GIVE(hdw->big_lock);
2582}
2583
2584void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
2585{
2586 int ret;
2587 u16 address;
2588 unsigned int pipe;
2589 LOCK_TAKE(hdw->big_lock); do {
2590 if ((hdw->fw_buffer == 0) == !enable_flag) break;
2591
2592 if (!enable_flag) {
2593 pvr2_trace(PVR2_TRACE_FIRMWARE,
2594 "Cleaning up after CPU firmware fetch");
2595 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002596 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002597 hdw->fw_size = 0;
2598 /* Now release the CPU. It will disconnect and
2599 reconnect later. */
2600 pvr2_hdw_cpureset_assert(hdw,0);
2601 break;
2602 }
2603
2604 pvr2_trace(PVR2_TRACE_FIRMWARE,
2605 "Preparing to suck out CPU firmware");
2606 hdw->fw_size = 0x2000;
Mike Iselyca545f72007-01-20 00:37:11 -03002607 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -03002608 if (!hdw->fw_buffer) {
2609 hdw->fw_size = 0;
2610 break;
2611 }
2612
Mike Iselyd8554972006-06-26 20:58:46 -03002613 /* We have to hold the CPU during firmware upload. */
2614 pvr2_hdw_cpureset_assert(hdw,1);
2615
2616 /* download the firmware from address 0000-1fff in 2048
2617 (=0x800) bytes chunk. */
2618
2619 pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
2620 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2621 for(address = 0; address < hdw->fw_size; address += 0x800) {
2622 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
2623 address,0,
2624 hdw->fw_buffer+address,0x800,HZ);
2625 if (ret < 0) break;
2626 }
2627
2628 pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
2629
2630 } while (0); LOCK_GIVE(hdw->big_lock);
2631}
2632
2633
2634/* Return true if we're in a mode for retrieval CPU firmware */
2635int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2636{
2637 return hdw->fw_buffer != 0;
2638}
2639
2640
2641int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2642 char *buf,unsigned int cnt)
2643{
2644 int ret = -EINVAL;
2645 LOCK_TAKE(hdw->big_lock); do {
2646 if (!buf) break;
2647 if (!cnt) break;
2648
2649 if (!hdw->fw_buffer) {
2650 ret = -EIO;
2651 break;
2652 }
2653
2654 if (offs >= hdw->fw_size) {
2655 pvr2_trace(PVR2_TRACE_FIRMWARE,
2656 "Read firmware data offs=%d EOF",
2657 offs);
2658 ret = 0;
2659 break;
2660 }
2661
2662 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2663
2664 memcpy(buf,hdw->fw_buffer+offs,cnt);
2665
2666 pvr2_trace(PVR2_TRACE_FIRMWARE,
2667 "Read firmware data offs=%d cnt=%d",
2668 offs,cnt);
2669 ret = cnt;
2670 } while (0); LOCK_GIVE(hdw->big_lock);
2671
2672 return ret;
2673}
2674
2675
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002676int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002677 enum pvr2_v4l_type index)
Mike Iselyd8554972006-06-26 20:58:46 -03002678{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002679 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002680 case pvr2_v4l_type_video: return hdw->v4l_minor_number_video;
2681 case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi;
2682 case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002683 default: return -1;
2684 }
Mike Iselyd8554972006-06-26 20:58:46 -03002685}
2686
2687
Pantelis Koukousoulas2fdf3d92006-12-27 23:07:58 -03002688/* Store a v4l minor device number */
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002689void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002690 enum pvr2_v4l_type index,int v)
Mike Iselyd8554972006-06-26 20:58:46 -03002691{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002692 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002693 case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
2694 case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
2695 case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002696 default: break;
2697 }
Mike Iselyd8554972006-06-26 20:58:46 -03002698}
2699
2700
David Howells7d12e782006-10-05 14:55:46 +01002701static void pvr2_ctl_write_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002702{
2703 struct pvr2_hdw *hdw = urb->context;
2704 hdw->ctl_write_pend_flag = 0;
2705 if (hdw->ctl_read_pend_flag) return;
2706 complete(&hdw->ctl_done);
2707}
2708
2709
David Howells7d12e782006-10-05 14:55:46 +01002710static void pvr2_ctl_read_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002711{
2712 struct pvr2_hdw *hdw = urb->context;
2713 hdw->ctl_read_pend_flag = 0;
2714 if (hdw->ctl_write_pend_flag) return;
2715 complete(&hdw->ctl_done);
2716}
2717
2718
2719static void pvr2_ctl_timeout(unsigned long data)
2720{
2721 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2722 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2723 hdw->ctl_timeout_flag = !0;
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002724 if (hdw->ctl_write_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002725 usb_unlink_urb(hdw->ctl_write_urb);
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002726 if (hdw->ctl_read_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002727 usb_unlink_urb(hdw->ctl_read_urb);
Mike Iselyd8554972006-06-26 20:58:46 -03002728 }
2729}
2730
2731
Mike Iselye61b6fc2006-07-18 22:42:18 -03002732/* Issue a command and get a response from the device. This extended
2733 version includes a probe flag (which if set means that device errors
2734 should not be logged or treated as fatal) and a timeout in jiffies.
2735 This can be used to non-lethally probe the health of endpoint 1. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002736static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2737 unsigned int timeout,int probe_fl,
2738 void *write_data,unsigned int write_len,
2739 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002740{
2741 unsigned int idx;
2742 int status = 0;
2743 struct timer_list timer;
2744 if (!hdw->ctl_lock_held) {
2745 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2746 "Attempted to execute control transfer"
2747 " without lock!!");
2748 return -EDEADLK;
2749 }
2750 if ((!hdw->flag_ok) && !probe_fl) {
2751 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2752 "Attempted to execute control transfer"
2753 " when device not ok");
2754 return -EIO;
2755 }
2756 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2757 if (!probe_fl) {
2758 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2759 "Attempted to execute control transfer"
2760 " when USB is disconnected");
2761 }
2762 return -ENOTTY;
2763 }
2764
2765 /* Ensure that we have sane parameters */
2766 if (!write_data) write_len = 0;
2767 if (!read_data) read_len = 0;
2768 if (write_len > PVR2_CTL_BUFFSIZE) {
2769 pvr2_trace(
2770 PVR2_TRACE_ERROR_LEGS,
2771 "Attempted to execute %d byte"
2772 " control-write transfer (limit=%d)",
2773 write_len,PVR2_CTL_BUFFSIZE);
2774 return -EINVAL;
2775 }
2776 if (read_len > PVR2_CTL_BUFFSIZE) {
2777 pvr2_trace(
2778 PVR2_TRACE_ERROR_LEGS,
2779 "Attempted to execute %d byte"
2780 " control-read transfer (limit=%d)",
2781 write_len,PVR2_CTL_BUFFSIZE);
2782 return -EINVAL;
2783 }
2784 if ((!write_len) && (!read_len)) {
2785 pvr2_trace(
2786 PVR2_TRACE_ERROR_LEGS,
2787 "Attempted to execute null control transfer?");
2788 return -EINVAL;
2789 }
2790
2791
2792 hdw->cmd_debug_state = 1;
2793 if (write_len) {
2794 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2795 } else {
2796 hdw->cmd_debug_code = 0;
2797 }
2798 hdw->cmd_debug_write_len = write_len;
2799 hdw->cmd_debug_read_len = read_len;
2800
2801 /* Initialize common stuff */
2802 init_completion(&hdw->ctl_done);
2803 hdw->ctl_timeout_flag = 0;
2804 hdw->ctl_write_pend_flag = 0;
2805 hdw->ctl_read_pend_flag = 0;
2806 init_timer(&timer);
2807 timer.expires = jiffies + timeout;
2808 timer.data = (unsigned long)hdw;
2809 timer.function = pvr2_ctl_timeout;
2810
2811 if (write_len) {
2812 hdw->cmd_debug_state = 2;
2813 /* Transfer write data to internal buffer */
2814 for (idx = 0; idx < write_len; idx++) {
2815 hdw->ctl_write_buffer[idx] =
2816 ((unsigned char *)write_data)[idx];
2817 }
2818 /* Initiate a write request */
2819 usb_fill_bulk_urb(hdw->ctl_write_urb,
2820 hdw->usb_dev,
2821 usb_sndbulkpipe(hdw->usb_dev,
2822 PVR2_CTL_WRITE_ENDPOINT),
2823 hdw->ctl_write_buffer,
2824 write_len,
2825 pvr2_ctl_write_complete,
2826 hdw);
2827 hdw->ctl_write_urb->actual_length = 0;
2828 hdw->ctl_write_pend_flag = !0;
2829 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2830 if (status < 0) {
2831 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2832 "Failed to submit write-control"
2833 " URB status=%d",status);
2834 hdw->ctl_write_pend_flag = 0;
2835 goto done;
2836 }
2837 }
2838
2839 if (read_len) {
2840 hdw->cmd_debug_state = 3;
2841 memset(hdw->ctl_read_buffer,0x43,read_len);
2842 /* Initiate a read request */
2843 usb_fill_bulk_urb(hdw->ctl_read_urb,
2844 hdw->usb_dev,
2845 usb_rcvbulkpipe(hdw->usb_dev,
2846 PVR2_CTL_READ_ENDPOINT),
2847 hdw->ctl_read_buffer,
2848 read_len,
2849 pvr2_ctl_read_complete,
2850 hdw);
2851 hdw->ctl_read_urb->actual_length = 0;
2852 hdw->ctl_read_pend_flag = !0;
2853 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
2854 if (status < 0) {
2855 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2856 "Failed to submit read-control"
2857 " URB status=%d",status);
2858 hdw->ctl_read_pend_flag = 0;
2859 goto done;
2860 }
2861 }
2862
2863 /* Start timer */
2864 add_timer(&timer);
2865
2866 /* Now wait for all I/O to complete */
2867 hdw->cmd_debug_state = 4;
2868 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2869 wait_for_completion(&hdw->ctl_done);
2870 }
2871 hdw->cmd_debug_state = 5;
2872
2873 /* Stop timer */
2874 del_timer_sync(&timer);
2875
2876 hdw->cmd_debug_state = 6;
2877 status = 0;
2878
2879 if (hdw->ctl_timeout_flag) {
2880 status = -ETIMEDOUT;
2881 if (!probe_fl) {
2882 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2883 "Timed out control-write");
2884 }
2885 goto done;
2886 }
2887
2888 if (write_len) {
2889 /* Validate results of write request */
2890 if ((hdw->ctl_write_urb->status != 0) &&
2891 (hdw->ctl_write_urb->status != -ENOENT) &&
2892 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
2893 (hdw->ctl_write_urb->status != -ECONNRESET)) {
2894 /* USB subsystem is reporting some kind of failure
2895 on the write */
2896 status = hdw->ctl_write_urb->status;
2897 if (!probe_fl) {
2898 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2899 "control-write URB failure,"
2900 " status=%d",
2901 status);
2902 }
2903 goto done;
2904 }
2905 if (hdw->ctl_write_urb->actual_length < write_len) {
2906 /* Failed to write enough data */
2907 status = -EIO;
2908 if (!probe_fl) {
2909 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2910 "control-write URB short,"
2911 " expected=%d got=%d",
2912 write_len,
2913 hdw->ctl_write_urb->actual_length);
2914 }
2915 goto done;
2916 }
2917 }
2918 if (read_len) {
2919 /* Validate results of read request */
2920 if ((hdw->ctl_read_urb->status != 0) &&
2921 (hdw->ctl_read_urb->status != -ENOENT) &&
2922 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
2923 (hdw->ctl_read_urb->status != -ECONNRESET)) {
2924 /* USB subsystem is reporting some kind of failure
2925 on the read */
2926 status = hdw->ctl_read_urb->status;
2927 if (!probe_fl) {
2928 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2929 "control-read URB failure,"
2930 " status=%d",
2931 status);
2932 }
2933 goto done;
2934 }
2935 if (hdw->ctl_read_urb->actual_length < read_len) {
2936 /* Failed to read enough data */
2937 status = -EIO;
2938 if (!probe_fl) {
2939 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2940 "control-read URB short,"
2941 " expected=%d got=%d",
2942 read_len,
2943 hdw->ctl_read_urb->actual_length);
2944 }
2945 goto done;
2946 }
2947 /* Transfer retrieved data out from internal buffer */
2948 for (idx = 0; idx < read_len; idx++) {
2949 ((unsigned char *)read_data)[idx] =
2950 hdw->ctl_read_buffer[idx];
2951 }
2952 }
2953
2954 done:
2955
2956 hdw->cmd_debug_state = 0;
2957 if ((status < 0) && (!probe_fl)) {
2958 pvr2_hdw_render_useless_unlocked(hdw);
2959 }
2960 return status;
2961}
2962
2963
2964int pvr2_send_request(struct pvr2_hdw *hdw,
2965 void *write_data,unsigned int write_len,
2966 void *read_data,unsigned int read_len)
2967{
2968 return pvr2_send_request_ex(hdw,HZ*4,0,
2969 write_data,write_len,
2970 read_data,read_len);
2971}
2972
2973int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
2974{
2975 int ret;
2976
2977 LOCK_TAKE(hdw->ctl_lock);
2978
2979 hdw->cmd_buffer[0] = 0x04; /* write register prefix */
2980 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
2981 hdw->cmd_buffer[5] = 0;
2982 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
2983 hdw->cmd_buffer[7] = reg & 0xff;
2984
2985
2986 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
2987
2988 LOCK_GIVE(hdw->ctl_lock);
2989
2990 return ret;
2991}
2992
2993
Adrian Bunk07e337e2006-06-30 11:30:20 -03002994static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03002995{
2996 int ret = 0;
2997
2998 LOCK_TAKE(hdw->ctl_lock);
2999
3000 hdw->cmd_buffer[0] = 0x05; /* read register prefix */
3001 hdw->cmd_buffer[1] = 0;
3002 hdw->cmd_buffer[2] = 0;
3003 hdw->cmd_buffer[3] = 0;
3004 hdw->cmd_buffer[4] = 0;
3005 hdw->cmd_buffer[5] = 0;
3006 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3007 hdw->cmd_buffer[7] = reg & 0xff;
3008
3009 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
3010 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
3011
3012 LOCK_GIVE(hdw->ctl_lock);
3013
3014 return ret;
3015}
3016
3017
Adrian Bunk07e337e2006-06-30 11:30:20 -03003018static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03003019{
3020 int ret;
3021
3022 LOCK_TAKE(hdw->ctl_lock);
3023
3024 hdw->cmd_buffer[0] = (data >> 8) & 0xff;
3025 hdw->cmd_buffer[1] = data & 0xff;
3026
3027 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
3028
3029 LOCK_GIVE(hdw->ctl_lock);
3030
3031 return ret;
3032}
3033
3034
Adrian Bunk07e337e2006-06-30 11:30:20 -03003035static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
Mike Iselyd8554972006-06-26 20:58:46 -03003036{
3037 int ret;
3038
3039 LOCK_TAKE(hdw->ctl_lock);
3040
3041 hdw->cmd_buffer[0] = data;
3042
3043 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
3044
3045 LOCK_GIVE(hdw->ctl_lock);
3046
3047 return ret;
3048}
3049
3050
Adrian Bunk07e337e2006-06-30 11:30:20 -03003051static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003052{
3053 if (!hdw->flag_ok) return;
3054 pvr2_trace(PVR2_TRACE_INIT,"render_useless");
3055 hdw->flag_ok = 0;
3056 if (hdw->vid_stream) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003057 pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003058 }
3059 hdw->flag_streaming_enabled = 0;
3060 hdw->subsys_enabled_mask = 0;
3061}
3062
3063
3064void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
3065{
3066 LOCK_TAKE(hdw->ctl_lock);
3067 pvr2_hdw_render_useless_unlocked(hdw);
3068 LOCK_GIVE(hdw->ctl_lock);
3069}
3070
3071
3072void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
3073{
3074 int ret;
3075 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003076 ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -03003077 if (ret == 1) {
3078 ret = usb_reset_device(hdw->usb_dev);
3079 usb_unlock_device(hdw->usb_dev);
3080 } else {
3081 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3082 "Failed to lock USB device ret=%d",ret);
3083 }
3084 if (init_pause_msec) {
3085 pvr2_trace(PVR2_TRACE_INFO,
3086 "Waiting %u msec for hardware to settle",
3087 init_pause_msec);
3088 msleep(init_pause_msec);
3089 }
3090
3091}
3092
3093
3094void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
3095{
3096 char da[1];
3097 unsigned int pipe;
3098 int ret;
3099
3100 if (!hdw->usb_dev) return;
3101
3102 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
3103
3104 da[0] = val ? 0x01 : 0x00;
3105
3106 /* Write the CPUCS register on the 8051. The lsb of the register
3107 is the reset bit; a 1 asserts reset while a 0 clears it. */
3108 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
3109 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
3110 if (ret < 0) {
3111 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3112 "cpureset_assert(%d) error=%d",val,ret);
3113 pvr2_hdw_render_useless(hdw);
3114 }
3115}
3116
3117
3118int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
3119{
3120 int status;
3121 LOCK_TAKE(hdw->ctl_lock); do {
3122 pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
3123 hdw->flag_ok = !0;
3124 hdw->cmd_buffer[0] = 0xdd;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003125 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003126 } while (0); LOCK_GIVE(hdw->ctl_lock);
3127 return status;
3128}
3129
3130
3131int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
3132{
3133 int status;
3134 LOCK_TAKE(hdw->ctl_lock); do {
3135 pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
3136 hdw->cmd_buffer[0] = 0xde;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003137 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003138 } while (0); LOCK_GIVE(hdw->ctl_lock);
3139 return status;
3140}
3141
3142
3143int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
3144{
3145 if (!hdw->decoder_ctrl) {
3146 pvr2_trace(PVR2_TRACE_INIT,
3147 "Unable to reset decoder: nothing attached");
3148 return -ENOTTY;
3149 }
3150
3151 if (!hdw->decoder_ctrl->force_reset) {
3152 pvr2_trace(PVR2_TRACE_INIT,
3153 "Unable to reset decoder: not implemented");
3154 return -ENOTTY;
3155 }
3156
3157 pvr2_trace(PVR2_TRACE_INIT,
3158 "Requesting decoder reset");
3159 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
3160 return 0;
3161}
3162
3163
Mike Iselye61b6fc2006-07-18 22:42:18 -03003164/* Stop / start video stream transport */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003165static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03003166{
3167 int status;
3168 LOCK_TAKE(hdw->ctl_lock); do {
3169 hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003170 status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003171 } while (0); LOCK_GIVE(hdw->ctl_lock);
3172 if (!status) {
3173 hdw->subsys_enabled_mask =
3174 ((hdw->subsys_enabled_mask &
3175 ~(1<<PVR2_SUBSYS_B_USBSTREAM_RUN)) |
3176 (runFl ? (1<<PVR2_SUBSYS_B_USBSTREAM_RUN) : 0));
3177 }
3178 return status;
3179}
3180
3181
3182void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw,
3183 struct pvr2_hdw_debug_info *ptr)
3184{
3185 ptr->big_lock_held = hdw->big_lock_held;
3186 ptr->ctl_lock_held = hdw->ctl_lock_held;
3187 ptr->flag_ok = hdw->flag_ok;
3188 ptr->flag_disconnected = hdw->flag_disconnected;
3189 ptr->flag_init_ok = hdw->flag_init_ok;
3190 ptr->flag_streaming_enabled = hdw->flag_streaming_enabled;
3191 ptr->subsys_flags = hdw->subsys_enabled_mask;
3192 ptr->cmd_debug_state = hdw->cmd_debug_state;
3193 ptr->cmd_code = hdw->cmd_debug_code;
3194 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
3195 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
3196 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
3197 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
3198 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
3199 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
3200 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
3201}
3202
3203
3204int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
3205{
3206 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
3207}
3208
3209
3210int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
3211{
3212 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
3213}
3214
3215
3216int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
3217{
3218 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
3219}
3220
3221
3222int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
3223{
3224 u32 cval,nval;
3225 int ret;
3226 if (~msk) {
3227 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
3228 if (ret) return ret;
3229 nval = (cval & ~msk) | (val & msk);
3230 pvr2_trace(PVR2_TRACE_GPIO,
3231 "GPIO direction changing 0x%x:0x%x"
3232 " from 0x%x to 0x%x",
3233 msk,val,cval,nval);
3234 } else {
3235 nval = val;
3236 pvr2_trace(PVR2_TRACE_GPIO,
3237 "GPIO direction changing to 0x%x",nval);
3238 }
3239 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
3240}
3241
3242
3243int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
3244{
3245 u32 cval,nval;
3246 int ret;
3247 if (~msk) {
3248 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
3249 if (ret) return ret;
3250 nval = (cval & ~msk) | (val & msk);
3251 pvr2_trace(PVR2_TRACE_GPIO,
3252 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
3253 msk,val,cval,nval);
3254 } else {
3255 nval = val;
3256 pvr2_trace(PVR2_TRACE_GPIO,
3257 "GPIO output changing to 0x%x",nval);
3258 }
3259 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
3260}
3261
3262
Mike Iselye61b6fc2006-07-18 22:42:18 -03003263/* Find I2C address of eeprom */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003264static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003265{
3266 int result;
3267 LOCK_TAKE(hdw->ctl_lock); do {
3268 hdw->cmd_buffer[0] = 0xeb;
3269 result = pvr2_send_request(hdw,
3270 hdw->cmd_buffer,1,
3271 hdw->cmd_buffer,1);
3272 if (result < 0) break;
3273 result = hdw->cmd_buffer[0];
3274 } while(0); LOCK_GIVE(hdw->ctl_lock);
3275 return result;
3276}
3277
3278
Mike Isely32ffa9a2006-09-23 22:26:52 -03003279int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
Trent Piepho52ebc762007-01-23 22:38:13 -03003280 u32 chip_id, u32 reg_id,
Mike Isely32ffa9a2006-09-23 22:26:52 -03003281 int setFl,u32 *val_ptr)
3282{
3283#ifdef CONFIG_VIDEO_ADV_DEBUG
3284 struct list_head *item;
3285 struct pvr2_i2c_client *cp;
3286 struct v4l2_register req;
Mike Isely6d988162006-09-28 17:53:49 -03003287 int stat = 0;
3288 int okFl = 0;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003289
3290 req.i2c_id = chip_id;
3291 req.reg = reg_id;
3292 if (setFl) req.val = *val_ptr;
3293 mutex_lock(&hdw->i2c_list_lock); do {
3294 list_for_each(item,&hdw->i2c_clients) {
3295 cp = list_entry(item,struct pvr2_i2c_client,list);
3296 if (cp->client->driver->id != chip_id) continue;
3297 stat = pvr2_i2c_client_cmd(
Trent Piepho52ebc762007-01-23 22:38:13 -03003298 cp,(setFl ? VIDIOC_DBG_S_REGISTER :
3299 VIDIOC_DBG_G_REGISTER),&req);
Mike Isely32ffa9a2006-09-23 22:26:52 -03003300 if (!setFl) *val_ptr = req.val;
Mike Isely6d988162006-09-28 17:53:49 -03003301 okFl = !0;
3302 break;
Mike Isely32ffa9a2006-09-23 22:26:52 -03003303 }
3304 } while (0); mutex_unlock(&hdw->i2c_list_lock);
Mike Isely6d988162006-09-28 17:53:49 -03003305 if (okFl) {
3306 return stat;
3307 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03003308 return -EINVAL;
3309#else
3310 return -ENOSYS;
3311#endif
3312}
3313
3314
Mike Iselyd8554972006-06-26 20:58:46 -03003315/*
3316 Stuff for Emacs to see, in order to encourage consistent editing style:
3317 *** Local Variables: ***
3318 *** mode: c ***
3319 *** fill-column: 75 ***
3320 *** tab-width: 8 ***
3321 *** c-basic-offset: 8 ***
3322 *** End: ***
3323 */