blob: 584716e0c1713c93b38914420aa20f180bf3c914 [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 Iselyd8554972006-06-26 20:58:46 -030028#include "pvrusb2.h"
29#include "pvrusb2-std.h"
30#include "pvrusb2-util.h"
31#include "pvrusb2-hdw.h"
32#include "pvrusb2-i2c-core.h"
33#include "pvrusb2-tuner.h"
34#include "pvrusb2-eeprom.h"
35#include "pvrusb2-hdw-internal.h"
36#include "pvrusb2-encoder.h"
37#include "pvrusb2-debug.h"
Michael Krufky8d364362007-01-22 02:17:55 -030038#include "pvrusb2-fx2-cmd.h"
Mike Iselyd8554972006-06-26 20:58:46 -030039
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 Iselya0fd1cb2006-06-30 11:35:28 -030043static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -030044static DEFINE_MUTEX(pvr2_unit_mtx);
Mike Iselyd8554972006-06-26 20:58:46 -030045
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030046static int ctlchg;
Mike Iselyd8554972006-06-26 20:58:46 -030047static int initusbreset = 1;
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030048static int procreload;
Mike Iselyd8554972006-06-26 20:58:46 -030049static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
50static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
51static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 };
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030052static int init_pause_msec;
Mike Iselyd8554972006-06-26 20:58:46 -030053
54module_param(ctlchg, int, S_IRUGO|S_IWUSR);
55MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value");
56module_param(init_pause_msec, int, S_IRUGO|S_IWUSR);
57MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay");
58module_param(initusbreset, int, S_IRUGO|S_IWUSR);
59MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe");
60module_param(procreload, int, S_IRUGO|S_IWUSR);
61MODULE_PARM_DESC(procreload,
62 "Attempt init failure recovery with firmware reload");
63module_param_array(tuner, int, NULL, 0444);
64MODULE_PARM_DESC(tuner,"specify installed tuner type");
65module_param_array(video_std, int, NULL, 0444);
66MODULE_PARM_DESC(video_std,"specify initial video standard");
67module_param_array(tolerance, int, NULL, 0444);
68MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
69
Michael Krufky5a4f5da62008-05-11 16:37:50 -030070/* US Broadcast channel 7 (175.25 MHz) */
71static int default_tv_freq = 175250000L;
72/* 104.3 MHz, a usable FM station for my area */
73static int default_radio_freq = 104300000L;
74
75module_param_named(tv_freq, default_tv_freq, int, 0444);
76MODULE_PARM_DESC(tv_freq, "specify initial television frequency");
77module_param_named(radio_freq, default_radio_freq, int, 0444);
78MODULE_PARM_DESC(radio_freq, "specify initial radio frequency");
79
Mike Iselyd8554972006-06-26 20:58:46 -030080#define PVR2_CTL_WRITE_ENDPOINT 0x01
81#define PVR2_CTL_READ_ENDPOINT 0x81
82
83#define PVR2_GPIO_IN 0x9008
84#define PVR2_GPIO_OUT 0x900c
85#define PVR2_GPIO_DIR 0x9020
86
87#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
88
89#define PVR2_FIRMWARE_ENDPOINT 0x02
90
91/* size of a firmware chunk */
92#define FIRMWARE_CHUNK_SIZE 0x2000
93
Mike Iselyb30d2442006-06-25 20:05:01 -030094/* Define the list of additional controls we'll dynamically construct based
95 on query of the cx2341x module. */
96struct pvr2_mpeg_ids {
97 const char *strid;
98 int id;
99};
100static const struct pvr2_mpeg_ids mpeg_ids[] = {
101 {
102 .strid = "audio_layer",
103 .id = V4L2_CID_MPEG_AUDIO_ENCODING,
104 },{
105 .strid = "audio_bitrate",
106 .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE,
107 },{
108 /* Already using audio_mode elsewhere :-( */
109 .strid = "mpeg_audio_mode",
110 .id = V4L2_CID_MPEG_AUDIO_MODE,
111 },{
112 .strid = "mpeg_audio_mode_extension",
113 .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
114 },{
115 .strid = "audio_emphasis",
116 .id = V4L2_CID_MPEG_AUDIO_EMPHASIS,
117 },{
118 .strid = "audio_crc",
119 .id = V4L2_CID_MPEG_AUDIO_CRC,
120 },{
121 .strid = "video_aspect",
122 .id = V4L2_CID_MPEG_VIDEO_ASPECT,
123 },{
124 .strid = "video_b_frames",
125 .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
126 },{
127 .strid = "video_gop_size",
128 .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
129 },{
130 .strid = "video_gop_closure",
131 .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
132 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300133 .strid = "video_bitrate_mode",
134 .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
135 },{
136 .strid = "video_bitrate",
137 .id = V4L2_CID_MPEG_VIDEO_BITRATE,
138 },{
139 .strid = "video_bitrate_peak",
140 .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
141 },{
142 .strid = "video_temporal_decimation",
143 .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
144 },{
145 .strid = "stream_type",
146 .id = V4L2_CID_MPEG_STREAM_TYPE,
147 },{
148 .strid = "video_spatial_filter_mode",
149 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
150 },{
151 .strid = "video_spatial_filter",
152 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
153 },{
154 .strid = "video_luma_spatial_filter_type",
155 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
156 },{
157 .strid = "video_chroma_spatial_filter_type",
158 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
159 },{
160 .strid = "video_temporal_filter_mode",
161 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
162 },{
163 .strid = "video_temporal_filter",
164 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
165 },{
166 .strid = "video_median_filter_type",
167 .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
168 },{
169 .strid = "video_luma_median_filter_top",
170 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
171 },{
172 .strid = "video_luma_median_filter_bottom",
173 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
174 },{
175 .strid = "video_chroma_median_filter_top",
176 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
177 },{
178 .strid = "video_chroma_median_filter_bottom",
179 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
180 }
181};
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -0300182#define MPEGDEF_COUNT ARRAY_SIZE(mpeg_ids)
Mike Iselyc05c0462006-06-25 20:04:25 -0300183
Mike Iselyd8554972006-06-26 20:58:46 -0300184
Mike Isely434449f2006-08-08 09:10:06 -0300185static const char *control_values_srate[] = {
186 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100] = "44.1 kHz",
187 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000] = "48 kHz",
188 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000] = "32 kHz",
189};
Mike Iselyd8554972006-06-26 20:58:46 -0300190
Mike Iselyd8554972006-06-26 20:58:46 -0300191
192
193static const char *control_values_input[] = {
194 [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
Mike Isely29bf5b12008-04-22 14:45:37 -0300195 [PVR2_CVAL_INPUT_DTV] = "dtv",
Mike Iselyd8554972006-06-26 20:58:46 -0300196 [PVR2_CVAL_INPUT_RADIO] = "radio",
197 [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
198 [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
199};
200
201
202static const char *control_values_audiomode[] = {
203 [V4L2_TUNER_MODE_MONO] = "Mono",
204 [V4L2_TUNER_MODE_STEREO] = "Stereo",
205 [V4L2_TUNER_MODE_LANG1] = "Lang1",
206 [V4L2_TUNER_MODE_LANG2] = "Lang2",
207 [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
208};
209
210
211static const char *control_values_hsm[] = {
212 [PVR2_CVAL_HSM_FAIL] = "Fail",
213 [PVR2_CVAL_HSM_HIGH] = "High",
214 [PVR2_CVAL_HSM_FULL] = "Full",
215};
216
217
Mike Isely681c7392007-11-26 01:48:52 -0300218static const char *pvr2_state_names[] = {
219 [PVR2_STATE_NONE] = "none",
220 [PVR2_STATE_DEAD] = "dead",
221 [PVR2_STATE_COLD] = "cold",
222 [PVR2_STATE_WARM] = "warm",
223 [PVR2_STATE_ERROR] = "error",
224 [PVR2_STATE_READY] = "ready",
225 [PVR2_STATE_RUN] = "run",
Mike Iselyd8554972006-06-26 20:58:46 -0300226};
227
Mike Isely681c7392007-11-26 01:48:52 -0300228
Mike Isely694dca2b2008-03-28 05:42:10 -0300229struct pvr2_fx2cmd_descdef {
Mike Isely1c9d10d2008-03-28 05:38:54 -0300230 unsigned char id;
231 unsigned char *desc;
232};
233
Mike Isely694dca2b2008-03-28 05:42:10 -0300234static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
Mike Isely1c9d10d2008-03-28 05:38:54 -0300235 {FX2CMD_MEM_WRITE_DWORD, "write encoder dword"},
236 {FX2CMD_MEM_READ_DWORD, "read encoder dword"},
237 {FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"},
238 {FX2CMD_REG_WRITE, "write encoder register"},
239 {FX2CMD_REG_READ, "read encoder register"},
240 {FX2CMD_MEMSEL, "encoder memsel"},
241 {FX2CMD_I2C_WRITE, "i2c write"},
242 {FX2CMD_I2C_READ, "i2c read"},
243 {FX2CMD_GET_USB_SPEED, "get USB speed"},
244 {FX2CMD_STREAMING_ON, "stream on"},
245 {FX2CMD_STREAMING_OFF, "stream off"},
246 {FX2CMD_FWPOST1, "fwpost1"},
247 {FX2CMD_POWER_OFF, "power off"},
248 {FX2CMD_POWER_ON, "power on"},
249 {FX2CMD_DEEP_RESET, "deep reset"},
250 {FX2CMD_GET_EEPROM_ADDR, "get rom addr"},
251 {FX2CMD_GET_IR_CODE, "get IR code"},
252 {FX2CMD_HCW_DEMOD_RESETIN, "hcw demod resetin"},
253 {FX2CMD_HCW_DTV_STREAMING_ON, "hcw dtv stream on"},
254 {FX2CMD_HCW_DTV_STREAMING_OFF, "hcw dtv stream off"},
255 {FX2CMD_ONAIR_DTV_STREAMING_ON, "onair dtv stream on"},
256 {FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
257 {FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
258 {FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
259};
260
261
Mike Isely1cb03b72008-04-21 03:47:43 -0300262static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v);
Mike Isely681c7392007-11-26 01:48:52 -0300263static void pvr2_hdw_state_sched(struct pvr2_hdw *);
264static int pvr2_hdw_state_eval(struct pvr2_hdw *);
Mike Isely1bde0282006-12-27 23:30:13 -0300265static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
Mike Isely681c7392007-11-26 01:48:52 -0300266static void pvr2_hdw_worker_i2c(struct work_struct *work);
267static void pvr2_hdw_worker_poll(struct work_struct *work);
Mike Isely681c7392007-11-26 01:48:52 -0300268static int pvr2_hdw_wait(struct pvr2_hdw *,int state);
269static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *);
270static void pvr2_hdw_state_log_state(struct pvr2_hdw *);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300271static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
Mike Isely681c7392007-11-26 01:48:52 -0300272static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300273static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300274static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
275static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
Mike Isely681c7392007-11-26 01:48:52 -0300276static void pvr2_hdw_quiescent_timeout(unsigned long);
277static void pvr2_hdw_encoder_wait_timeout(unsigned long);
Mike Iselyd913d632008-04-06 04:04:35 -0300278static void pvr2_hdw_encoder_run_timeout(unsigned long);
Mike Isely1c9d10d2008-03-28 05:38:54 -0300279static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300280static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
281 unsigned int timeout,int probe_fl,
282 void *write_data,unsigned int write_len,
283 void *read_data,unsigned int read_len);
Mike Iselyd8554972006-06-26 20:58:46 -0300284
Mike Isely681c7392007-11-26 01:48:52 -0300285
286static void trace_stbit(const char *name,int val)
287{
288 pvr2_trace(PVR2_TRACE_STBITS,
289 "State bit %s <-- %s",
290 name,(val ? "true" : "false"));
291}
292
Mike Iselyd8554972006-06-26 20:58:46 -0300293static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
294{
295 struct pvr2_hdw *hdw = cptr->hdw;
296 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
297 *vp = hdw->freqTable[hdw->freqProgSlot-1];
298 } else {
299 *vp = 0;
300 }
301 return 0;
302}
303
304static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
305{
306 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300307 unsigned int slotId = hdw->freqProgSlot;
308 if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) {
309 hdw->freqTable[slotId-1] = v;
310 /* Handle side effects correctly - if we're tuned to this
311 slot, then forgot the slot id relation since the stored
312 frequency has been changed. */
313 if (hdw->freqSelector) {
314 if (hdw->freqSlotRadio == slotId) {
315 hdw->freqSlotRadio = 0;
316 }
317 } else {
318 if (hdw->freqSlotTelevision == slotId) {
319 hdw->freqSlotTelevision = 0;
320 }
321 }
Mike Iselyd8554972006-06-26 20:58:46 -0300322 }
323 return 0;
324}
325
326static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
327{
328 *vp = cptr->hdw->freqProgSlot;
329 return 0;
330}
331
332static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
333{
334 struct pvr2_hdw *hdw = cptr->hdw;
335 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
336 hdw->freqProgSlot = v;
337 }
338 return 0;
339}
340
341static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
342{
Mike Isely1bde0282006-12-27 23:30:13 -0300343 struct pvr2_hdw *hdw = cptr->hdw;
344 *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision;
Mike Iselyd8554972006-06-26 20:58:46 -0300345 return 0;
346}
347
Mike Isely1bde0282006-12-27 23:30:13 -0300348static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId)
Mike Iselyd8554972006-06-26 20:58:46 -0300349{
350 unsigned freq = 0;
351 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300352 if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0;
353 if (slotId > 0) {
354 freq = hdw->freqTable[slotId-1];
355 if (!freq) return 0;
356 pvr2_hdw_set_cur_freq(hdw,freq);
Mike Iselyd8554972006-06-26 20:58:46 -0300357 }
Mike Isely1bde0282006-12-27 23:30:13 -0300358 if (hdw->freqSelector) {
359 hdw->freqSlotRadio = slotId;
360 } else {
361 hdw->freqSlotTelevision = slotId;
Mike Iselyd8554972006-06-26 20:58:46 -0300362 }
363 return 0;
364}
365
366static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
367{
Mike Isely1bde0282006-12-27 23:30:13 -0300368 *vp = pvr2_hdw_get_cur_freq(cptr->hdw);
Mike Iselyd8554972006-06-26 20:58:46 -0300369 return 0;
370}
371
372static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
373{
374 return cptr->hdw->freqDirty != 0;
375}
376
377static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
378{
379 cptr->hdw->freqDirty = 0;
380}
381
382static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
383{
Mike Isely1bde0282006-12-27 23:30:13 -0300384 pvr2_hdw_set_cur_freq(cptr->hdw,v);
Mike Iselyd8554972006-06-26 20:58:46 -0300385 return 0;
386}
387
Mike Isely3ad9fc32006-09-02 22:37:52 -0300388static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
389{
390 /* Actual maximum depends on the video standard in effect. */
391 if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
392 *vp = 480;
393 } else {
394 *vp = 576;
395 }
396 return 0;
397}
398
399static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
400{
Mike Isely989eb152007-11-26 01:53:12 -0300401 /* Actual minimum depends on device digitizer type. */
402 if (cptr->hdw->hdw_desc->flag_has_cx25840) {
Mike Isely3ad9fc32006-09-02 22:37:52 -0300403 *vp = 75;
404 } else {
405 *vp = 17;
406 }
407 return 0;
408}
409
Mike Isely1bde0282006-12-27 23:30:13 -0300410static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
411{
412 *vp = cptr->hdw->input_val;
413 return 0;
414}
415
Mike Isely29bf5b12008-04-22 14:45:37 -0300416static int ctrl_check_input(struct pvr2_ctrl *cptr,int v)
417{
Mike Isely1cb03b72008-04-21 03:47:43 -0300418 return ((1 << v) & cptr->hdw->input_allowed_mask) != 0;
Mike Isely29bf5b12008-04-22 14:45:37 -0300419}
420
Mike Isely1bde0282006-12-27 23:30:13 -0300421static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
422{
Mike Isely1cb03b72008-04-21 03:47:43 -0300423 return pvr2_hdw_set_input(cptr->hdw,v);
Mike Isely1bde0282006-12-27 23:30:13 -0300424}
425
426static int ctrl_isdirty_input(struct pvr2_ctrl *cptr)
427{
428 return cptr->hdw->input_dirty != 0;
429}
430
431static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr)
432{
433 cptr->hdw->input_dirty = 0;
434}
435
Mike Isely5549f542006-12-27 23:28:54 -0300436
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300437static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
438{
Mike Isely644afdb2007-01-20 00:19:23 -0300439 unsigned long fv;
440 struct pvr2_hdw *hdw = cptr->hdw;
441 if (hdw->tuner_signal_stale) {
442 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300443 }
Mike Isely644afdb2007-01-20 00:19:23 -0300444 fv = hdw->tuner_signal_info.rangehigh;
445 if (!fv) {
446 /* Safety fallback */
447 *vp = TV_MAX_FREQ;
448 return 0;
449 }
450 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
451 fv = (fv * 125) / 2;
452 } else {
453 fv = fv * 62500;
454 }
455 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300456 return 0;
457}
458
459static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
460{
Mike Isely644afdb2007-01-20 00:19:23 -0300461 unsigned long fv;
462 struct pvr2_hdw *hdw = cptr->hdw;
463 if (hdw->tuner_signal_stale) {
464 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300465 }
Mike Isely644afdb2007-01-20 00:19:23 -0300466 fv = hdw->tuner_signal_info.rangelow;
467 if (!fv) {
468 /* Safety fallback */
469 *vp = TV_MIN_FREQ;
470 return 0;
471 }
472 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
473 fv = (fv * 125) / 2;
474 } else {
475 fv = fv * 62500;
476 }
477 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300478 return 0;
479}
480
Mike Iselyb30d2442006-06-25 20:05:01 -0300481static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
482{
483 return cptr->hdw->enc_stale != 0;
484}
485
486static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
487{
488 cptr->hdw->enc_stale = 0;
Mike Isely681c7392007-11-26 01:48:52 -0300489 cptr->hdw->enc_unsafe_stale = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -0300490}
491
492static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
493{
494 int ret;
495 struct v4l2_ext_controls cs;
496 struct v4l2_ext_control c1;
497 memset(&cs,0,sizeof(cs));
498 memset(&c1,0,sizeof(c1));
499 cs.controls = &c1;
500 cs.count = 1;
501 c1.id = cptr->info->v4l_id;
Hans Verkuil01f1e442007-08-21 18:32:42 -0300502 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs,
Mike Iselyb30d2442006-06-25 20:05:01 -0300503 VIDIOC_G_EXT_CTRLS);
504 if (ret) return ret;
505 *vp = c1.value;
506 return 0;
507}
508
509static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
510{
511 int ret;
Mike Isely681c7392007-11-26 01:48:52 -0300512 struct pvr2_hdw *hdw = cptr->hdw;
Mike Iselyb30d2442006-06-25 20:05:01 -0300513 struct v4l2_ext_controls cs;
514 struct v4l2_ext_control c1;
515 memset(&cs,0,sizeof(cs));
516 memset(&c1,0,sizeof(c1));
517 cs.controls = &c1;
518 cs.count = 1;
519 c1.id = cptr->info->v4l_id;
520 c1.value = v;
Mike Isely681c7392007-11-26 01:48:52 -0300521 ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
522 hdw->state_encoder_run, &cs,
Mike Iselyb30d2442006-06-25 20:05:01 -0300523 VIDIOC_S_EXT_CTRLS);
Mike Isely681c7392007-11-26 01:48:52 -0300524 if (ret == -EBUSY) {
525 /* Oops. cx2341x is telling us it's not safe to change
526 this control while we're capturing. Make a note of this
527 fact so that the pipeline will be stopped the next time
528 controls are committed. Then go on ahead and store this
529 change anyway. */
530 ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
531 0, &cs,
532 VIDIOC_S_EXT_CTRLS);
533 if (!ret) hdw->enc_unsafe_stale = !0;
534 }
Mike Iselyb30d2442006-06-25 20:05:01 -0300535 if (ret) return ret;
Mike Isely681c7392007-11-26 01:48:52 -0300536 hdw->enc_stale = !0;
Mike Iselyb30d2442006-06-25 20:05:01 -0300537 return 0;
538}
539
540static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
541{
542 struct v4l2_queryctrl qctrl;
543 struct pvr2_ctl_info *info;
544 qctrl.id = cptr->info->v4l_id;
545 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
546 /* Strip out the const so we can adjust a function pointer. It's
547 OK to do this here because we know this is a dynamically created
548 control, so the underlying storage for the info pointer is (a)
549 private to us, and (b) not in read-only storage. Either we do
550 this or we significantly complicate the underlying control
551 implementation. */
552 info = (struct pvr2_ctl_info *)(cptr->info);
553 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
554 if (info->set_value) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300555 info->set_value = NULL;
Mike Iselyb30d2442006-06-25 20:05:01 -0300556 }
557 } else {
558 if (!(info->set_value)) {
559 info->set_value = ctrl_cx2341x_set;
560 }
561 }
562 return qctrl.flags;
563}
564
Mike Iselyd8554972006-06-26 20:58:46 -0300565static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
566{
Mike Isely681c7392007-11-26 01:48:52 -0300567 *vp = cptr->hdw->state_pipeline_req;
568 return 0;
569}
570
571static int ctrl_masterstate_get(struct pvr2_ctrl *cptr,int *vp)
572{
573 *vp = cptr->hdw->master_state;
Mike Iselyd8554972006-06-26 20:58:46 -0300574 return 0;
575}
576
577static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
578{
579 int result = pvr2_hdw_is_hsm(cptr->hdw);
580 *vp = PVR2_CVAL_HSM_FULL;
581 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
582 if (result) *vp = PVR2_CVAL_HSM_HIGH;
583 return 0;
584}
585
586static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
587{
588 *vp = cptr->hdw->std_mask_avail;
589 return 0;
590}
591
592static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
593{
594 struct pvr2_hdw *hdw = cptr->hdw;
595 v4l2_std_id ns;
596 ns = hdw->std_mask_avail;
597 ns = (ns & ~m) | (v & m);
598 if (ns == hdw->std_mask_avail) return 0;
599 hdw->std_mask_avail = ns;
600 pvr2_hdw_internal_set_std_avail(hdw);
601 pvr2_hdw_internal_find_stdenum(hdw);
602 return 0;
603}
604
605static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
606 char *bufPtr,unsigned int bufSize,
607 unsigned int *len)
608{
609 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
610 return 0;
611}
612
613static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
614 const char *bufPtr,unsigned int bufSize,
615 int *mskp,int *valp)
616{
617 int ret;
618 v4l2_std_id id;
619 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
620 if (ret < 0) return ret;
621 if (mskp) *mskp = id;
622 if (valp) *valp = id;
623 return 0;
624}
625
626static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
627{
628 *vp = cptr->hdw->std_mask_cur;
629 return 0;
630}
631
632static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
633{
634 struct pvr2_hdw *hdw = cptr->hdw;
635 v4l2_std_id ns;
636 ns = hdw->std_mask_cur;
637 ns = (ns & ~m) | (v & m);
638 if (ns == hdw->std_mask_cur) return 0;
639 hdw->std_mask_cur = ns;
640 hdw->std_dirty = !0;
641 pvr2_hdw_internal_find_stdenum(hdw);
642 return 0;
643}
644
645static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
646{
647 return cptr->hdw->std_dirty != 0;
648}
649
650static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
651{
652 cptr->hdw->std_dirty = 0;
653}
654
655static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
656{
Mike Isely18103c572007-01-20 00:09:47 -0300657 struct pvr2_hdw *hdw = cptr->hdw;
658 pvr2_i2c_core_status_poll(hdw);
659 *vp = hdw->tuner_signal_info.signal;
660 return 0;
661}
662
663static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
664{
665 int val = 0;
666 unsigned int subchan;
667 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely644afdb2007-01-20 00:19:23 -0300668 pvr2_i2c_core_status_poll(hdw);
Mike Isely18103c572007-01-20 00:09:47 -0300669 subchan = hdw->tuner_signal_info.rxsubchans;
670 if (subchan & V4L2_TUNER_SUB_MONO) {
671 val |= (1 << V4L2_TUNER_MODE_MONO);
672 }
673 if (subchan & V4L2_TUNER_SUB_STEREO) {
674 val |= (1 << V4L2_TUNER_MODE_STEREO);
675 }
676 if (subchan & V4L2_TUNER_SUB_LANG1) {
677 val |= (1 << V4L2_TUNER_MODE_LANG1);
678 }
679 if (subchan & V4L2_TUNER_SUB_LANG2) {
680 val |= (1 << V4L2_TUNER_MODE_LANG2);
681 }
682 *vp = val;
Mike Iselyd8554972006-06-26 20:58:46 -0300683 return 0;
684}
685
Mike Iselyd8554972006-06-26 20:58:46 -0300686
687static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
688{
689 struct pvr2_hdw *hdw = cptr->hdw;
690 if (v < 0) return -EINVAL;
691 if (v > hdw->std_enum_cnt) return -EINVAL;
692 hdw->std_enum_cur = v;
693 if (!v) return 0;
694 v--;
695 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
696 hdw->std_mask_cur = hdw->std_defs[v].id;
697 hdw->std_dirty = !0;
698 return 0;
699}
700
701
702static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
703{
704 *vp = cptr->hdw->std_enum_cur;
705 return 0;
706}
707
708
709static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
710{
711 return cptr->hdw->std_dirty != 0;
712}
713
714
715static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
716{
717 cptr->hdw->std_dirty = 0;
718}
719
720
721#define DEFINT(vmin,vmax) \
722 .type = pvr2_ctl_int, \
723 .def.type_int.min_value = vmin, \
724 .def.type_int.max_value = vmax
725
726#define DEFENUM(tab) \
727 .type = pvr2_ctl_enum, \
Mike Isely27c7b712007-01-20 00:39:17 -0300728 .def.type_enum.count = ARRAY_SIZE(tab), \
Mike Iselyd8554972006-06-26 20:58:46 -0300729 .def.type_enum.value_names = tab
730
Mike Isely33213962006-06-25 20:04:40 -0300731#define DEFBOOL \
732 .type = pvr2_ctl_bool
733
Mike Iselyd8554972006-06-26 20:58:46 -0300734#define DEFMASK(msk,tab) \
735 .type = pvr2_ctl_bitmask, \
736 .def.type_bitmask.valid_bits = msk, \
737 .def.type_bitmask.bit_names = tab
738
739#define DEFREF(vname) \
740 .set_value = ctrl_set_##vname, \
741 .get_value = ctrl_get_##vname, \
742 .is_dirty = ctrl_isdirty_##vname, \
743 .clear_dirty = ctrl_cleardirty_##vname
744
745
746#define VCREATE_FUNCS(vname) \
747static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
748{*vp = cptr->hdw->vname##_val; return 0;} \
749static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
750{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
751static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
752{return cptr->hdw->vname##_dirty != 0;} \
753static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
754{cptr->hdw->vname##_dirty = 0;}
755
756VCREATE_FUNCS(brightness)
757VCREATE_FUNCS(contrast)
758VCREATE_FUNCS(saturation)
759VCREATE_FUNCS(hue)
760VCREATE_FUNCS(volume)
761VCREATE_FUNCS(balance)
762VCREATE_FUNCS(bass)
763VCREATE_FUNCS(treble)
764VCREATE_FUNCS(mute)
Mike Iselyc05c0462006-06-25 20:04:25 -0300765VCREATE_FUNCS(audiomode)
766VCREATE_FUNCS(res_hor)
767VCREATE_FUNCS(res_ver)
Mike Iselyd8554972006-06-26 20:58:46 -0300768VCREATE_FUNCS(srate)
Mike Iselyd8554972006-06-26 20:58:46 -0300769
Mike Iselyd8554972006-06-26 20:58:46 -0300770/* Table definition of all controls which can be manipulated */
771static const struct pvr2_ctl_info control_defs[] = {
772 {
773 .v4l_id = V4L2_CID_BRIGHTNESS,
774 .desc = "Brightness",
775 .name = "brightness",
776 .default_value = 128,
777 DEFREF(brightness),
778 DEFINT(0,255),
779 },{
780 .v4l_id = V4L2_CID_CONTRAST,
781 .desc = "Contrast",
782 .name = "contrast",
783 .default_value = 68,
784 DEFREF(contrast),
785 DEFINT(0,127),
786 },{
787 .v4l_id = V4L2_CID_SATURATION,
788 .desc = "Saturation",
789 .name = "saturation",
790 .default_value = 64,
791 DEFREF(saturation),
792 DEFINT(0,127),
793 },{
794 .v4l_id = V4L2_CID_HUE,
795 .desc = "Hue",
796 .name = "hue",
797 .default_value = 0,
798 DEFREF(hue),
799 DEFINT(-128,127),
800 },{
801 .v4l_id = V4L2_CID_AUDIO_VOLUME,
802 .desc = "Volume",
803 .name = "volume",
Mike Isely139eecf2006-12-27 23:36:33 -0300804 .default_value = 62000,
Mike Iselyd8554972006-06-26 20:58:46 -0300805 DEFREF(volume),
806 DEFINT(0,65535),
807 },{
808 .v4l_id = V4L2_CID_AUDIO_BALANCE,
809 .desc = "Balance",
810 .name = "balance",
811 .default_value = 0,
812 DEFREF(balance),
813 DEFINT(-32768,32767),
814 },{
815 .v4l_id = V4L2_CID_AUDIO_BASS,
816 .desc = "Bass",
817 .name = "bass",
818 .default_value = 0,
819 DEFREF(bass),
820 DEFINT(-32768,32767),
821 },{
822 .v4l_id = V4L2_CID_AUDIO_TREBLE,
823 .desc = "Treble",
824 .name = "treble",
825 .default_value = 0,
826 DEFREF(treble),
827 DEFINT(-32768,32767),
828 },{
829 .v4l_id = V4L2_CID_AUDIO_MUTE,
830 .desc = "Mute",
831 .name = "mute",
832 .default_value = 0,
833 DEFREF(mute),
Mike Isely33213962006-06-25 20:04:40 -0300834 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300835 },{
Mike Iselyc05c0462006-06-25 20:04:25 -0300836 .desc = "Video Source",
837 .name = "input",
838 .internal_id = PVR2_CID_INPUT,
839 .default_value = PVR2_CVAL_INPUT_TV,
Mike Isely29bf5b12008-04-22 14:45:37 -0300840 .check_value = ctrl_check_input,
Mike Iselyc05c0462006-06-25 20:04:25 -0300841 DEFREF(input),
842 DEFENUM(control_values_input),
843 },{
844 .desc = "Audio Mode",
845 .name = "audio_mode",
846 .internal_id = PVR2_CID_AUDIOMODE,
847 .default_value = V4L2_TUNER_MODE_STEREO,
848 DEFREF(audiomode),
849 DEFENUM(control_values_audiomode),
850 },{
851 .desc = "Horizontal capture resolution",
852 .name = "resolution_hor",
853 .internal_id = PVR2_CID_HRES,
854 .default_value = 720,
855 DEFREF(res_hor),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300856 DEFINT(19,720),
Mike Iselyc05c0462006-06-25 20:04:25 -0300857 },{
858 .desc = "Vertical capture resolution",
859 .name = "resolution_ver",
860 .internal_id = PVR2_CID_VRES,
861 .default_value = 480,
862 DEFREF(res_ver),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300863 DEFINT(17,576),
864 /* Hook in check for video standard and adjust maximum
865 depending on the standard. */
866 .get_max_value = ctrl_vres_max_get,
867 .get_min_value = ctrl_vres_min_get,
Mike Iselyc05c0462006-06-25 20:04:25 -0300868 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300869 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
Mike Isely434449f2006-08-08 09:10:06 -0300870 .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
871 .desc = "Audio Sampling Frequency",
Mike Iselyd8554972006-06-26 20:58:46 -0300872 .name = "srate",
Mike Iselyd8554972006-06-26 20:58:46 -0300873 DEFREF(srate),
874 DEFENUM(control_values_srate),
875 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300876 .desc = "Tuner Frequency (Hz)",
877 .name = "frequency",
878 .internal_id = PVR2_CID_FREQUENCY,
Mike Isely1bde0282006-12-27 23:30:13 -0300879 .default_value = 0,
Mike Iselyd8554972006-06-26 20:58:46 -0300880 .set_value = ctrl_freq_set,
881 .get_value = ctrl_freq_get,
882 .is_dirty = ctrl_freq_is_dirty,
883 .clear_dirty = ctrl_freq_clear_dirty,
Mike Isely644afdb2007-01-20 00:19:23 -0300884 DEFINT(0,0),
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300885 /* Hook in check for input value (tv/radio) and adjust
886 max/min values accordingly */
887 .get_max_value = ctrl_freq_max_get,
888 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300889 },{
890 .desc = "Channel",
891 .name = "channel",
892 .set_value = ctrl_channel_set,
893 .get_value = ctrl_channel_get,
894 DEFINT(0,FREQTABLE_SIZE),
895 },{
896 .desc = "Channel Program Frequency",
897 .name = "freq_table_value",
898 .set_value = ctrl_channelfreq_set,
899 .get_value = ctrl_channelfreq_get,
Mike Isely644afdb2007-01-20 00:19:23 -0300900 DEFINT(0,0),
Mike Isely1bde0282006-12-27 23:30:13 -0300901 /* Hook in check for input value (tv/radio) and adjust
902 max/min values accordingly */
Mike Isely1bde0282006-12-27 23:30:13 -0300903 .get_max_value = ctrl_freq_max_get,
904 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300905 },{
906 .desc = "Channel Program ID",
907 .name = "freq_table_channel",
908 .set_value = ctrl_channelprog_set,
909 .get_value = ctrl_channelprog_get,
910 DEFINT(0,FREQTABLE_SIZE),
911 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300912 .desc = "Streaming Enabled",
913 .name = "streaming_enabled",
914 .get_value = ctrl_streamingenabled_get,
Mike Isely33213962006-06-25 20:04:40 -0300915 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300916 },{
917 .desc = "USB Speed",
918 .name = "usb_speed",
919 .get_value = ctrl_hsm_get,
920 DEFENUM(control_values_hsm),
921 },{
Mike Isely681c7392007-11-26 01:48:52 -0300922 .desc = "Master State",
923 .name = "master_state",
924 .get_value = ctrl_masterstate_get,
925 DEFENUM(pvr2_state_names),
926 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300927 .desc = "Signal Present",
928 .name = "signal_present",
929 .get_value = ctrl_signal_get,
Mike Isely18103c572007-01-20 00:09:47 -0300930 DEFINT(0,65535),
931 },{
932 .desc = "Audio Modes Present",
933 .name = "audio_modes_present",
934 .get_value = ctrl_audio_modes_present_get,
935 /* For this type we "borrow" the V4L2_TUNER_MODE enum from
936 v4l. Nothing outside of this module cares about this,
937 but I reuse it in order to also reuse the
938 control_values_audiomode string table. */
939 DEFMASK(((1 << V4L2_TUNER_MODE_MONO)|
940 (1 << V4L2_TUNER_MODE_STEREO)|
941 (1 << V4L2_TUNER_MODE_LANG1)|
942 (1 << V4L2_TUNER_MODE_LANG2)),
943 control_values_audiomode),
Mike Iselyd8554972006-06-26 20:58:46 -0300944 },{
945 .desc = "Video Standards Available Mask",
946 .name = "video_standard_mask_available",
947 .internal_id = PVR2_CID_STDAVAIL,
948 .skip_init = !0,
949 .get_value = ctrl_stdavail_get,
950 .set_value = ctrl_stdavail_set,
951 .val_to_sym = ctrl_std_val_to_sym,
952 .sym_to_val = ctrl_std_sym_to_val,
953 .type = pvr2_ctl_bitmask,
954 },{
955 .desc = "Video Standards In Use Mask",
956 .name = "video_standard_mask_active",
957 .internal_id = PVR2_CID_STDCUR,
958 .skip_init = !0,
959 .get_value = ctrl_stdcur_get,
960 .set_value = ctrl_stdcur_set,
961 .is_dirty = ctrl_stdcur_is_dirty,
962 .clear_dirty = ctrl_stdcur_clear_dirty,
963 .val_to_sym = ctrl_std_val_to_sym,
964 .sym_to_val = ctrl_std_sym_to_val,
965 .type = pvr2_ctl_bitmask,
966 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300967 .desc = "Video Standard Name",
968 .name = "video_standard",
969 .internal_id = PVR2_CID_STDENUM,
970 .skip_init = !0,
971 .get_value = ctrl_stdenumcur_get,
972 .set_value = ctrl_stdenumcur_set,
973 .is_dirty = ctrl_stdenumcur_is_dirty,
974 .clear_dirty = ctrl_stdenumcur_clear_dirty,
975 .type = pvr2_ctl_enum,
976 }
977};
978
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -0300979#define CTRLDEF_COUNT ARRAY_SIZE(control_defs)
Mike Iselyd8554972006-06-26 20:58:46 -0300980
981
982const char *pvr2_config_get_name(enum pvr2_config cfg)
983{
984 switch (cfg) {
985 case pvr2_config_empty: return "empty";
986 case pvr2_config_mpeg: return "mpeg";
987 case pvr2_config_vbi: return "vbi";
Mike Isely16eb40d2006-12-30 18:27:32 -0300988 case pvr2_config_pcm: return "pcm";
989 case pvr2_config_rawvideo: return "raw video";
Mike Iselyd8554972006-06-26 20:58:46 -0300990 }
991 return "<unknown>";
992}
993
994
995struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
996{
997 return hdw->usb_dev;
998}
999
1000
1001unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
1002{
1003 return hdw->serial_number;
1004}
1005
Mike Isely31a18542007-04-08 01:11:47 -03001006
1007const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
1008{
1009 return hdw->bus_info;
1010}
1011
1012
Mike Isely1bde0282006-12-27 23:30:13 -03001013unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
1014{
1015 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
1016}
1017
1018/* Set the currently tuned frequency and account for all possible
1019 driver-core side effects of this action. */
Adrian Bunkf55a8712008-04-18 05:38:56 -03001020static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val)
Mike Isely1bde0282006-12-27 23:30:13 -03001021{
Mike Isely7c74e572007-01-20 00:15:41 -03001022 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
Mike Isely1bde0282006-12-27 23:30:13 -03001023 if (hdw->freqSelector) {
1024 /* Swing over to radio frequency selection */
1025 hdw->freqSelector = 0;
1026 hdw->freqDirty = !0;
1027 }
Mike Isely1bde0282006-12-27 23:30:13 -03001028 if (hdw->freqValRadio != val) {
1029 hdw->freqValRadio = val;
1030 hdw->freqSlotRadio = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001031 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001032 }
Mike Isely7c74e572007-01-20 00:15:41 -03001033 } else {
Mike Isely1bde0282006-12-27 23:30:13 -03001034 if (!(hdw->freqSelector)) {
1035 /* Swing over to television frequency selection */
1036 hdw->freqSelector = 1;
1037 hdw->freqDirty = !0;
1038 }
Mike Isely1bde0282006-12-27 23:30:13 -03001039 if (hdw->freqValTelevision != val) {
1040 hdw->freqValTelevision = val;
1041 hdw->freqSlotTelevision = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001042 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001043 }
Mike Isely1bde0282006-12-27 23:30:13 -03001044 }
1045}
1046
Mike Iselyd8554972006-06-26 20:58:46 -03001047int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
1048{
1049 return hdw->unit_number;
1050}
1051
1052
1053/* Attempt to locate one of the given set of files. Messages are logged
1054 appropriate to what has been found. The return value will be 0 or
1055 greater on success (it will be the index of the file name found) and
1056 fw_entry will be filled in. Otherwise a negative error is returned on
1057 failure. If the return value is -ENOENT then no viable firmware file
1058 could be located. */
1059static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
1060 const struct firmware **fw_entry,
1061 const char *fwtypename,
1062 unsigned int fwcount,
1063 const char *fwnames[])
1064{
1065 unsigned int idx;
1066 int ret = -EINVAL;
1067 for (idx = 0; idx < fwcount; idx++) {
1068 ret = request_firmware(fw_entry,
1069 fwnames[idx],
1070 &hdw->usb_dev->dev);
1071 if (!ret) {
1072 trace_firmware("Located %s firmware: %s;"
1073 " uploading...",
1074 fwtypename,
1075 fwnames[idx]);
1076 return idx;
1077 }
1078 if (ret == -ENOENT) continue;
1079 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1080 "request_firmware fatal error with code=%d",ret);
1081 return ret;
1082 }
1083 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1084 "***WARNING***"
1085 " Device %s firmware"
1086 " seems to be missing.",
1087 fwtypename);
1088 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1089 "Did you install the pvrusb2 firmware files"
1090 " in their proper location?");
1091 if (fwcount == 1) {
1092 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1093 "request_firmware unable to locate %s file %s",
1094 fwtypename,fwnames[0]);
1095 } else {
1096 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1097 "request_firmware unable to locate"
1098 " one of the following %s files:",
1099 fwtypename);
1100 for (idx = 0; idx < fwcount; idx++) {
1101 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1102 "request_firmware: Failed to find %s",
1103 fwnames[idx]);
1104 }
1105 }
1106 return ret;
1107}
1108
1109
1110/*
1111 * pvr2_upload_firmware1().
1112 *
1113 * Send the 8051 firmware to the device. After the upload, arrange for
1114 * device to re-enumerate.
1115 *
1116 * NOTE : the pointer to the firmware data given by request_firmware()
1117 * is not suitable for an usb transaction.
1118 *
1119 */
Adrian Bunk07e337e2006-06-30 11:30:20 -03001120static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001121{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001122 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001123 void *fw_ptr;
1124 unsigned int pipe;
1125 int ret;
1126 u16 address;
Mike Isely1d643a32007-09-08 22:18:50 -03001127
Mike Isely989eb152007-11-26 01:53:12 -03001128 if (!hdw->hdw_desc->fx2_firmware.cnt) {
Mike Isely1d643a32007-09-08 22:18:50 -03001129 hdw->fw1_state = FW1_STATE_OK;
Mike Isely56dcbfa2007-11-26 02:00:51 -03001130 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1131 "Connected device type defines"
1132 " no firmware to upload; ignoring firmware");
1133 return -ENOTTY;
Mike Isely1d643a32007-09-08 22:18:50 -03001134 }
1135
Mike Iselyd8554972006-06-26 20:58:46 -03001136 hdw->fw1_state = FW1_STATE_FAILED; // default result
1137
1138 trace_firmware("pvr2_upload_firmware1");
1139
1140 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
Mike Isely989eb152007-11-26 01:53:12 -03001141 hdw->hdw_desc->fx2_firmware.cnt,
1142 hdw->hdw_desc->fx2_firmware.lst);
Mike Iselyd8554972006-06-26 20:58:46 -03001143 if (ret < 0) {
1144 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
1145 return ret;
1146 }
1147
1148 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
1149 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
1150
1151 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
1152
1153 if (fw_entry->size != 0x2000){
1154 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
1155 release_firmware(fw_entry);
1156 return -ENOMEM;
1157 }
1158
1159 fw_ptr = kmalloc(0x800, GFP_KERNEL);
1160 if (fw_ptr == NULL){
1161 release_firmware(fw_entry);
1162 return -ENOMEM;
1163 }
1164
1165 /* We have to hold the CPU during firmware upload. */
1166 pvr2_hdw_cpureset_assert(hdw,1);
1167
1168 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
1169 chunk. */
1170
1171 ret = 0;
1172 for(address = 0; address < fw_entry->size; address += 0x800) {
1173 memcpy(fw_ptr, fw_entry->data + address, 0x800);
1174 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
1175 0, fw_ptr, 0x800, HZ);
1176 }
1177
1178 trace_firmware("Upload done, releasing device's CPU");
1179
1180 /* Now release the CPU. It will disconnect and reconnect later. */
1181 pvr2_hdw_cpureset_assert(hdw,0);
1182
1183 kfree(fw_ptr);
1184 release_firmware(fw_entry);
1185
1186 trace_firmware("Upload done (%d bytes sent)",ret);
1187
1188 /* We should have written 8192 bytes */
1189 if (ret == 8192) {
1190 hdw->fw1_state = FW1_STATE_RELOAD;
1191 return 0;
1192 }
1193
1194 return -EIO;
1195}
1196
1197
1198/*
1199 * pvr2_upload_firmware2()
1200 *
1201 * This uploads encoder firmware on endpoint 2.
1202 *
1203 */
1204
1205int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
1206{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001207 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001208 void *fw_ptr;
Mike Isely90060d32007-02-08 02:02:53 -03001209 unsigned int pipe, fw_len, fw_done, bcnt, icnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001210 int actual_length;
1211 int ret = 0;
1212 int fwidx;
1213 static const char *fw_files[] = {
1214 CX2341X_FIRM_ENC_FILENAME,
1215 };
1216
Mike Isely989eb152007-11-26 01:53:12 -03001217 if (hdw->hdw_desc->flag_skip_cx23416_firmware) {
Mike Isely1d643a32007-09-08 22:18:50 -03001218 return 0;
1219 }
1220
Mike Iselyd8554972006-06-26 20:58:46 -03001221 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
Mike Iselyd913d632008-04-06 04:04:35 -03001233 /* Encoder is about to be reset so note that as far as we're
1234 concerned now, the encoder has never been run. */
1235 del_timer_sync(&hdw->encoder_run_timer);
1236 if (hdw->state_encoder_runok) {
1237 hdw->state_encoder_runok = 0;
1238 trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
1239 }
1240
Mike Iselyd8554972006-06-26 20:58:46 -03001241 /* First prepare firmware loading */
1242 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
1243 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
1244 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1245 ret |= pvr2_hdw_cmd_deep_reset(hdw);
1246 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
1247 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
1248 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1249 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
1250 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
1251 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
1252 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
1253 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
1254 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
1255 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
1256 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
1257 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
Mike Isely1c9d10d2008-03-28 05:38:54 -03001258 ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_FWPOST1);
1259 ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
Mike Iselyd8554972006-06-26 20:58:46 -03001260
1261 if (ret) {
1262 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1263 "firmware2 upload prep failed, ret=%d",ret);
1264 release_firmware(fw_entry);
Mike Isely21684ba2008-04-21 03:49:33 -03001265 goto done;
Mike Iselyd8554972006-06-26 20:58:46 -03001266 }
1267
1268 /* Now send firmware */
1269
1270 fw_len = fw_entry->size;
1271
Mike Isely90060d32007-02-08 02:02:53 -03001272 if (fw_len % sizeof(u32)) {
Mike Iselyd8554972006-06-26 20:58:46 -03001273 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1274 "size of %s firmware"
Mike Isely48dc30a2007-03-03 10:13:05 -02001275 " must be a multiple of %zu bytes",
Mike Isely90060d32007-02-08 02:02:53 -03001276 fw_files[fwidx],sizeof(u32));
Mike Iselyd8554972006-06-26 20:58:46 -03001277 release_firmware(fw_entry);
Mike Isely21684ba2008-04-21 03:49:33 -03001278 ret = -EINVAL;
1279 goto done;
Mike Iselyd8554972006-06-26 20:58:46 -03001280 }
1281
1282 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1283 if (fw_ptr == NULL){
1284 release_firmware(fw_entry);
1285 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1286 "failed to allocate memory for firmware2 upload");
Mike Isely21684ba2008-04-21 03:49:33 -03001287 ret = -ENOMEM;
1288 goto done;
Mike Iselyd8554972006-06-26 20:58:46 -03001289 }
1290
1291 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1292
Mike Isely90060d32007-02-08 02:02:53 -03001293 fw_done = 0;
1294 for (fw_done = 0; fw_done < fw_len;) {
1295 bcnt = fw_len - fw_done;
1296 if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE;
1297 memcpy(fw_ptr, fw_entry->data + fw_done, bcnt);
1298 /* Usbsnoop log shows that we must swap bytes... */
1299 for (icnt = 0; icnt < bcnt/4 ; icnt++)
1300 ((u32 *)fw_ptr)[icnt] =
1301 ___swab32(((u32 *)fw_ptr)[icnt]);
Mike Iselyd8554972006-06-26 20:58:46 -03001302
Mike Isely90060d32007-02-08 02:02:53 -03001303 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001304 &actual_length, HZ);
Mike Isely90060d32007-02-08 02:02:53 -03001305 ret |= (actual_length != bcnt);
1306 if (ret) break;
1307 fw_done += bcnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001308 }
1309
1310 trace_firmware("upload of %s : %i / %i ",
1311 fw_files[fwidx],fw_done,fw_len);
1312
1313 kfree(fw_ptr);
1314 release_firmware(fw_entry);
1315
1316 if (ret) {
1317 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1318 "firmware2 upload transfer failure");
Mike Isely21684ba2008-04-21 03:49:33 -03001319 goto done;
Mike Iselyd8554972006-06-26 20:58:46 -03001320 }
1321
1322 /* Finish upload */
1323
1324 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1325 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
Mike Isely1c9d10d2008-03-28 05:38:54 -03001326 ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
Mike Iselyd8554972006-06-26 20:58:46 -03001327
1328 if (ret) {
1329 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1330 "firmware2 upload post-proc failure");
Mike Iselyd8554972006-06-26 20:58:46 -03001331 }
Mike Isely21684ba2008-04-21 03:49:33 -03001332
1333 done:
Mike Isely1df59f02008-04-21 03:50:39 -03001334 if (hdw->hdw_desc->signal_routing_scheme ==
1335 PVR2_ROUTING_SCHEME_GOTVIEW) {
1336 /* Ensure that GPIO 11 is set to output for GOTVIEW
1337 hardware. */
1338 pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0);
1339 }
Mike Iselyd8554972006-06-26 20:58:46 -03001340 return ret;
1341}
1342
1343
Mike Isely681c7392007-11-26 01:48:52 -03001344static const char *pvr2_get_state_name(unsigned int st)
Mike Iselyd8554972006-06-26 20:58:46 -03001345{
Mike Isely681c7392007-11-26 01:48:52 -03001346 if (st < ARRAY_SIZE(pvr2_state_names)) {
1347 return pvr2_state_names[st];
Mike Iselyd8554972006-06-26 20:58:46 -03001348 }
Mike Isely681c7392007-11-26 01:48:52 -03001349 return "???";
Mike Iselyd8554972006-06-26 20:58:46 -03001350}
1351
Mike Isely681c7392007-11-26 01:48:52 -03001352static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
Mike Iselyd8554972006-06-26 20:58:46 -03001353{
Mike Isely681c7392007-11-26 01:48:52 -03001354 if (!hdw->decoder_ctrl) {
1355 if (!hdw->flag_decoder_missed) {
1356 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1357 "WARNING: No decoder present");
1358 hdw->flag_decoder_missed = !0;
1359 trace_stbit("flag_decoder_missed",
1360 hdw->flag_decoder_missed);
1361 }
1362 return -EIO;
Mike Iselyd8554972006-06-26 20:58:46 -03001363 }
Mike Isely681c7392007-11-26 01:48:52 -03001364 hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt,enablefl);
Mike Iselyd8554972006-06-26 20:58:46 -03001365 return 0;
1366}
1367
1368
Mike Isely681c7392007-11-26 01:48:52 -03001369void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr)
1370{
1371 if (hdw->decoder_ctrl == ptr) return;
1372 hdw->decoder_ctrl = ptr;
1373 if (hdw->decoder_ctrl && hdw->flag_decoder_missed) {
1374 hdw->flag_decoder_missed = 0;
1375 trace_stbit("flag_decoder_missed",
1376 hdw->flag_decoder_missed);
1377 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1378 "Decoder has appeared");
1379 pvr2_hdw_state_sched(hdw);
1380 }
1381}
1382
1383
1384int pvr2_hdw_get_state(struct pvr2_hdw *hdw)
1385{
1386 return hdw->master_state;
1387}
1388
1389
1390static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *hdw)
1391{
1392 if (!hdw->flag_tripped) return 0;
1393 hdw->flag_tripped = 0;
1394 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1395 "Clearing driver error statuss");
1396 return !0;
1397}
1398
1399
1400int pvr2_hdw_untrip(struct pvr2_hdw *hdw)
1401{
1402 int fl;
1403 LOCK_TAKE(hdw->big_lock); do {
1404 fl = pvr2_hdw_untrip_unlocked(hdw);
1405 } while (0); LOCK_GIVE(hdw->big_lock);
1406 if (fl) pvr2_hdw_state_sched(hdw);
1407 return 0;
1408}
1409
1410
Mike Isely681c7392007-11-26 01:48:52 -03001411
1412
Mike Iselyd8554972006-06-26 20:58:46 -03001413int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1414{
Mike Isely681c7392007-11-26 01:48:52 -03001415 return hdw->state_pipeline_req != 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001416}
1417
1418
1419int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1420{
Mike Isely681c7392007-11-26 01:48:52 -03001421 int ret,st;
Mike Iselyd8554972006-06-26 20:58:46 -03001422 LOCK_TAKE(hdw->big_lock); do {
Mike Isely681c7392007-11-26 01:48:52 -03001423 pvr2_hdw_untrip_unlocked(hdw);
1424 if ((!enable_flag) != !(hdw->state_pipeline_req)) {
1425 hdw->state_pipeline_req = enable_flag != 0;
1426 pvr2_trace(PVR2_TRACE_START_STOP,
1427 "/*--TRACE_STREAM--*/ %s",
1428 enable_flag ? "enable" : "disable");
1429 }
1430 pvr2_hdw_state_sched(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001431 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely681c7392007-11-26 01:48:52 -03001432 if ((ret = pvr2_hdw_wait(hdw,0)) < 0) return ret;
1433 if (enable_flag) {
1434 while ((st = hdw->master_state) != PVR2_STATE_RUN) {
1435 if (st != PVR2_STATE_READY) return -EIO;
1436 if ((ret = pvr2_hdw_wait(hdw,st)) < 0) return ret;
1437 }
1438 }
Mike Iselyd8554972006-06-26 20:58:46 -03001439 return 0;
1440}
1441
1442
1443int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1444{
Mike Isely681c7392007-11-26 01:48:52 -03001445 int fl;
Mike Iselyd8554972006-06-26 20:58:46 -03001446 LOCK_TAKE(hdw->big_lock);
Mike Isely681c7392007-11-26 01:48:52 -03001447 if ((fl = (hdw->desired_stream_type != config)) != 0) {
1448 hdw->desired_stream_type = config;
1449 hdw->state_pipeline_config = 0;
1450 trace_stbit("state_pipeline_config",
1451 hdw->state_pipeline_config);
1452 pvr2_hdw_state_sched(hdw);
1453 }
Mike Iselyd8554972006-06-26 20:58:46 -03001454 LOCK_GIVE(hdw->big_lock);
Mike Isely681c7392007-11-26 01:48:52 -03001455 if (fl) return 0;
1456 return pvr2_hdw_wait(hdw,0);
Mike Iselyd8554972006-06-26 20:58:46 -03001457}
1458
1459
1460static int get_default_tuner_type(struct pvr2_hdw *hdw)
1461{
1462 int unit_number = hdw->unit_number;
1463 int tp = -1;
1464 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1465 tp = tuner[unit_number];
1466 }
1467 if (tp < 0) return -EINVAL;
1468 hdw->tuner_type = tp;
Mike Iselyaaf78842007-11-26 02:04:11 -03001469 hdw->tuner_updated = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03001470 return 0;
1471}
1472
1473
1474static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1475{
1476 int unit_number = hdw->unit_number;
1477 int tp = 0;
1478 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1479 tp = video_std[unit_number];
Mike Isely6a540252007-12-02 23:51:34 -03001480 if (tp) return tp;
Mike Iselyd8554972006-06-26 20:58:46 -03001481 }
Mike Isely6a540252007-12-02 23:51:34 -03001482 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001483}
1484
1485
1486static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1487{
1488 int unit_number = hdw->unit_number;
1489 int tp = 0;
1490 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1491 tp = tolerance[unit_number];
1492 }
1493 return tp;
1494}
1495
1496
1497static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1498{
1499 /* Try a harmless request to fetch the eeprom's address over
1500 endpoint 1. See what happens. Only the full FX2 image can
1501 respond to this. If this probe fails then likely the FX2
1502 firmware needs be loaded. */
1503 int result;
1504 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03001505 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03001506 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1507 hdw->cmd_buffer,1,
1508 hdw->cmd_buffer,1);
1509 if (result < 0) break;
1510 } while(0); LOCK_GIVE(hdw->ctl_lock);
1511 if (result) {
1512 pvr2_trace(PVR2_TRACE_INIT,
1513 "Probe of device endpoint 1 result status %d",
1514 result);
1515 } else {
1516 pvr2_trace(PVR2_TRACE_INIT,
1517 "Probe of device endpoint 1 succeeded");
1518 }
1519 return result == 0;
1520}
1521
Mike Isely9f66d4e2007-09-08 22:28:51 -03001522struct pvr2_std_hack {
1523 v4l2_std_id pat; /* Pattern to match */
1524 v4l2_std_id msk; /* Which bits we care about */
1525 v4l2_std_id std; /* What additional standards or default to set */
1526};
1527
1528/* This data structure labels specific combinations of standards from
1529 tveeprom that we'll try to recognize. If we recognize one, then assume
1530 a specified default standard to use. This is here because tveeprom only
1531 tells us about available standards not the intended default standard (if
1532 any) for the device in question. We guess the default based on what has
1533 been reported as available. Note that this is only for guessing a
1534 default - which can always be overridden explicitly - and if the user
1535 has otherwise named a default then that default will always be used in
1536 place of this table. */
Tobias Klauserebff0332008-04-22 14:45:45 -03001537static const struct pvr2_std_hack std_eeprom_maps[] = {
Mike Isely9f66d4e2007-09-08 22:28:51 -03001538 { /* PAL(B/G) */
1539 .pat = V4L2_STD_B|V4L2_STD_GH,
1540 .std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G,
1541 },
1542 { /* NTSC(M) */
1543 .pat = V4L2_STD_MN,
1544 .std = V4L2_STD_NTSC_M,
1545 },
1546 { /* PAL(I) */
1547 .pat = V4L2_STD_PAL_I,
1548 .std = V4L2_STD_PAL_I,
1549 },
1550 { /* SECAM(L/L') */
1551 .pat = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
1552 .std = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
1553 },
1554 { /* PAL(D/D1/K) */
1555 .pat = V4L2_STD_DK,
Roel Kluinea2562d2007-12-02 23:04:57 -03001556 .std = V4L2_STD_PAL_D|V4L2_STD_PAL_D1|V4L2_STD_PAL_K,
Mike Isely9f66d4e2007-09-08 22:28:51 -03001557 },
1558};
1559
Mike Iselyd8554972006-06-26 20:58:46 -03001560static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1561{
1562 char buf[40];
1563 unsigned int bcnt;
Mike Isely3d290bd2007-12-03 01:47:12 -03001564 v4l2_std_id std1,std2,std3;
Mike Iselyd8554972006-06-26 20:58:46 -03001565
1566 std1 = get_default_standard(hdw);
Mike Isely3d290bd2007-12-03 01:47:12 -03001567 std3 = std1 ? 0 : hdw->hdw_desc->default_std_mask;
Mike Iselyd8554972006-06-26 20:58:46 -03001568
1569 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
Mike Isely56585382007-09-08 22:32:12 -03001570 pvr2_trace(PVR2_TRACE_STD,
Mike Isely56dcbfa2007-11-26 02:00:51 -03001571 "Supported video standard(s) reported available"
1572 " in hardware: %.*s",
Mike Iselyd8554972006-06-26 20:58:46 -03001573 bcnt,buf);
1574
1575 hdw->std_mask_avail = hdw->std_mask_eeprom;
1576
Mike Isely3d290bd2007-12-03 01:47:12 -03001577 std2 = (std1|std3) & ~hdw->std_mask_avail;
Mike Iselyd8554972006-06-26 20:58:46 -03001578 if (std2) {
1579 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
Mike Isely56585382007-09-08 22:32:12 -03001580 pvr2_trace(PVR2_TRACE_STD,
Mike Iselyd8554972006-06-26 20:58:46 -03001581 "Expanding supported video standards"
1582 " to include: %.*s",
1583 bcnt,buf);
1584 hdw->std_mask_avail |= std2;
1585 }
1586
1587 pvr2_hdw_internal_set_std_avail(hdw);
1588
1589 if (std1) {
1590 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
Mike Isely56585382007-09-08 22:32:12 -03001591 pvr2_trace(PVR2_TRACE_STD,
Mike Iselyd8554972006-06-26 20:58:46 -03001592 "Initial video standard forced to %.*s",
1593 bcnt,buf);
1594 hdw->std_mask_cur = std1;
1595 hdw->std_dirty = !0;
1596 pvr2_hdw_internal_find_stdenum(hdw);
1597 return;
1598 }
Mike Isely3d290bd2007-12-03 01:47:12 -03001599 if (std3) {
1600 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std3);
1601 pvr2_trace(PVR2_TRACE_STD,
1602 "Initial video standard"
1603 " (determined by device type): %.*s",bcnt,buf);
1604 hdw->std_mask_cur = std3;
1605 hdw->std_dirty = !0;
1606 pvr2_hdw_internal_find_stdenum(hdw);
1607 return;
1608 }
Mike Iselyd8554972006-06-26 20:58:46 -03001609
Mike Isely9f66d4e2007-09-08 22:28:51 -03001610 {
1611 unsigned int idx;
1612 for (idx = 0; idx < ARRAY_SIZE(std_eeprom_maps); idx++) {
1613 if (std_eeprom_maps[idx].msk ?
1614 ((std_eeprom_maps[idx].pat ^
1615 hdw->std_mask_eeprom) &
1616 std_eeprom_maps[idx].msk) :
1617 (std_eeprom_maps[idx].pat !=
1618 hdw->std_mask_eeprom)) continue;
1619 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),
1620 std_eeprom_maps[idx].std);
Mike Isely56585382007-09-08 22:32:12 -03001621 pvr2_trace(PVR2_TRACE_STD,
Mike Isely9f66d4e2007-09-08 22:28:51 -03001622 "Initial video standard guessed as %.*s",
1623 bcnt,buf);
1624 hdw->std_mask_cur = std_eeprom_maps[idx].std;
1625 hdw->std_dirty = !0;
1626 pvr2_hdw_internal_find_stdenum(hdw);
1627 return;
1628 }
1629 }
1630
Mike Iselyd8554972006-06-26 20:58:46 -03001631 if (hdw->std_enum_cnt > 1) {
1632 // Autoselect the first listed standard
1633 hdw->std_enum_cur = 1;
1634 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1635 hdw->std_dirty = !0;
Mike Isely56585382007-09-08 22:32:12 -03001636 pvr2_trace(PVR2_TRACE_STD,
Mike Iselyd8554972006-06-26 20:58:46 -03001637 "Initial video standard auto-selected to %s",
1638 hdw->std_defs[hdw->std_enum_cur-1].name);
1639 return;
1640 }
1641
Mike Isely0885ba12006-06-25 21:30:47 -03001642 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
Mike Iselyd8554972006-06-26 20:58:46 -03001643 "Unable to select a viable initial video standard");
1644}
1645
1646
1647static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1648{
1649 int ret;
1650 unsigned int idx;
1651 struct pvr2_ctrl *cptr;
1652 int reloadFl = 0;
Mike Isely989eb152007-11-26 01:53:12 -03001653 if (hdw->hdw_desc->fx2_firmware.cnt) {
Mike Isely1d643a32007-09-08 22:18:50 -03001654 if (!reloadFl) {
1655 reloadFl =
1656 (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1657 == 0);
1658 if (reloadFl) {
1659 pvr2_trace(PVR2_TRACE_INIT,
1660 "USB endpoint config looks strange"
1661 "; possibly firmware needs to be"
1662 " loaded");
1663 }
1664 }
1665 if (!reloadFl) {
1666 reloadFl = !pvr2_hdw_check_firmware(hdw);
1667 if (reloadFl) {
1668 pvr2_trace(PVR2_TRACE_INIT,
1669 "Check for FX2 firmware failed"
1670 "; possibly firmware needs to be"
1671 " loaded");
1672 }
1673 }
Mike Iselyd8554972006-06-26 20:58:46 -03001674 if (reloadFl) {
Mike Isely1d643a32007-09-08 22:18:50 -03001675 if (pvr2_upload_firmware1(hdw) != 0) {
1676 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1677 "Failure uploading firmware1");
1678 }
1679 return;
Mike Iselyd8554972006-06-26 20:58:46 -03001680 }
1681 }
Mike Iselyd8554972006-06-26 20:58:46 -03001682 hdw->fw1_state = FW1_STATE_OK;
1683
1684 if (initusbreset) {
1685 pvr2_hdw_device_reset(hdw);
1686 }
1687 if (!pvr2_hdw_dev_ok(hdw)) return;
1688
Mike Isely989eb152007-11-26 01:53:12 -03001689 for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
1690 request_module(hdw->hdw_desc->client_modules.lst[idx]);
Mike Iselyd8554972006-06-26 20:58:46 -03001691 }
1692
Mike Isely989eb152007-11-26 01:53:12 -03001693 if (!hdw->hdw_desc->flag_no_powerup) {
Mike Isely1d643a32007-09-08 22:18:50 -03001694 pvr2_hdw_cmd_powerup(hdw);
1695 if (!pvr2_hdw_dev_ok(hdw)) return;
Mike Iselyd8554972006-06-26 20:58:46 -03001696 }
1697
1698 // This step MUST happen after the earlier powerup step.
1699 pvr2_i2c_core_init(hdw);
1700 if (!pvr2_hdw_dev_ok(hdw)) return;
1701
Mike Iselyc05c0462006-06-25 20:04:25 -03001702 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001703 cptr = hdw->controls + idx;
1704 if (cptr->info->skip_init) continue;
1705 if (!cptr->info->set_value) continue;
1706 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1707 }
1708
Mike Isely1bde0282006-12-27 23:30:13 -03001709 /* Set up special default values for the television and radio
1710 frequencies here. It's not really important what these defaults
1711 are, but I set them to something usable in the Chicago area just
1712 to make driver testing a little easier. */
1713
Michael Krufky5a4f5da62008-05-11 16:37:50 -03001714 hdw->freqValTelevision = default_tv_freq;
1715 hdw->freqValRadio = default_radio_freq;
Mike Isely1bde0282006-12-27 23:30:13 -03001716
Mike Iselyd8554972006-06-26 20:58:46 -03001717 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1718 // thread-safe against the normal pvr2_send_request() mechanism.
1719 // (We should make it thread safe).
1720
Mike Iselyaaf78842007-11-26 02:04:11 -03001721 if (hdw->hdw_desc->flag_has_hauppauge_rom) {
1722 ret = pvr2_hdw_get_eeprom_addr(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001723 if (!pvr2_hdw_dev_ok(hdw)) return;
Mike Iselyaaf78842007-11-26 02:04:11 -03001724 if (ret < 0) {
1725 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1726 "Unable to determine location of eeprom,"
1727 " skipping");
1728 } else {
1729 hdw->eeprom_addr = ret;
1730 pvr2_eeprom_analyze(hdw);
1731 if (!pvr2_hdw_dev_ok(hdw)) return;
1732 }
1733 } else {
1734 hdw->tuner_type = hdw->hdw_desc->default_tuner_type;
1735 hdw->tuner_updated = !0;
1736 hdw->std_mask_eeprom = V4L2_STD_ALL;
Mike Iselyd8554972006-06-26 20:58:46 -03001737 }
1738
1739 pvr2_hdw_setup_std(hdw);
1740
1741 if (!get_default_tuner_type(hdw)) {
1742 pvr2_trace(PVR2_TRACE_INIT,
1743 "pvr2_hdw_setup: Tuner type overridden to %d",
1744 hdw->tuner_type);
1745 }
1746
Mike Iselyd8554972006-06-26 20:58:46 -03001747 pvr2_i2c_core_check_stale(hdw);
1748 hdw->tuner_updated = 0;
1749
1750 if (!pvr2_hdw_dev_ok(hdw)) return;
1751
Mike Isely1df59f02008-04-21 03:50:39 -03001752 if (hdw->hdw_desc->signal_routing_scheme ==
1753 PVR2_ROUTING_SCHEME_GOTVIEW) {
1754 /* Ensure that GPIO 11 is set to output for GOTVIEW
1755 hardware. */
1756 pvr2_hdw_gpio_chg_dir(hdw,(1 << 11),~0);
1757 }
1758
Mike Isely681c7392007-11-26 01:48:52 -03001759 pvr2_hdw_commit_setup(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001760
1761 hdw->vid_stream = pvr2_stream_create();
1762 if (!pvr2_hdw_dev_ok(hdw)) return;
1763 pvr2_trace(PVR2_TRACE_INIT,
1764 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1765 if (hdw->vid_stream) {
1766 idx = get_default_error_tolerance(hdw);
1767 if (idx) {
1768 pvr2_trace(PVR2_TRACE_INIT,
1769 "pvr2_hdw_setup: video stream %p"
1770 " setting tolerance %u",
1771 hdw->vid_stream,idx);
1772 }
1773 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1774 PVR2_VID_ENDPOINT,idx);
1775 }
1776
1777 if (!pvr2_hdw_dev_ok(hdw)) return;
1778
Mike Iselyd8554972006-06-26 20:58:46 -03001779 hdw->flag_init_ok = !0;
Mike Isely681c7392007-11-26 01:48:52 -03001780
1781 pvr2_hdw_state_sched(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001782}
1783
1784
Mike Isely681c7392007-11-26 01:48:52 -03001785/* Set up the structure and attempt to put the device into a usable state.
1786 This can be a time-consuming operation, which is why it is not done
1787 internally as part of the create() step. */
1788static void pvr2_hdw_setup(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001789{
1790 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
Mike Isely681c7392007-11-26 01:48:52 -03001791 do {
Mike Iselyd8554972006-06-26 20:58:46 -03001792 pvr2_hdw_setup_low(hdw);
1793 pvr2_trace(PVR2_TRACE_INIT,
1794 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
Mike Isely681c7392007-11-26 01:48:52 -03001795 hdw,pvr2_hdw_dev_ok(hdw),hdw->flag_init_ok);
Mike Iselyd8554972006-06-26 20:58:46 -03001796 if (pvr2_hdw_dev_ok(hdw)) {
Mike Isely681c7392007-11-26 01:48:52 -03001797 if (hdw->flag_init_ok) {
Mike Iselyd8554972006-06-26 20:58:46 -03001798 pvr2_trace(
1799 PVR2_TRACE_INFO,
1800 "Device initialization"
1801 " completed successfully.");
1802 break;
1803 }
1804 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1805 pvr2_trace(
1806 PVR2_TRACE_INFO,
1807 "Device microcontroller firmware"
1808 " (re)loaded; it should now reset"
1809 " and reconnect.");
1810 break;
1811 }
1812 pvr2_trace(
1813 PVR2_TRACE_ERROR_LEGS,
1814 "Device initialization was not successful.");
1815 if (hdw->fw1_state == FW1_STATE_MISSING) {
1816 pvr2_trace(
1817 PVR2_TRACE_ERROR_LEGS,
1818 "Giving up since device"
1819 " microcontroller firmware"
1820 " appears to be missing.");
1821 break;
1822 }
1823 }
1824 if (procreload) {
1825 pvr2_trace(
1826 PVR2_TRACE_ERROR_LEGS,
1827 "Attempting pvrusb2 recovery by reloading"
1828 " primary firmware.");
1829 pvr2_trace(
1830 PVR2_TRACE_ERROR_LEGS,
1831 "If this works, device should disconnect"
1832 " and reconnect in a sane state.");
1833 hdw->fw1_state = FW1_STATE_UNKNOWN;
1834 pvr2_upload_firmware1(hdw);
1835 } else {
1836 pvr2_trace(
1837 PVR2_TRACE_ERROR_LEGS,
1838 "***WARNING*** pvrusb2 device hardware"
1839 " appears to be jammed"
1840 " and I can't clear it.");
1841 pvr2_trace(
1842 PVR2_TRACE_ERROR_LEGS,
1843 "You might need to power cycle"
1844 " the pvrusb2 device"
1845 " in order to recover.");
1846 }
Mike Isely681c7392007-11-26 01:48:52 -03001847 } while (0);
Mike Iselyd8554972006-06-26 20:58:46 -03001848 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001849}
1850
1851
Mike Iselyc4a8828d2008-04-22 14:45:44 -03001852/* Perform second stage initialization. Set callback pointer first so that
1853 we can avoid a possible initialization race (if the kernel thread runs
1854 before the callback has been set). */
Mike Isely794b1602008-04-22 14:45:45 -03001855int pvr2_hdw_initialize(struct pvr2_hdw *hdw,
1856 void (*callback_func)(void *),
1857 void *callback_data)
Mike Iselyc4a8828d2008-04-22 14:45:44 -03001858{
1859 LOCK_TAKE(hdw->big_lock); do {
Mike Isely97f26ff2008-04-07 02:22:43 -03001860 if (hdw->flag_disconnected) {
1861 /* Handle a race here: If we're already
1862 disconnected by this point, then give up. If we
1863 get past this then we'll remain connected for
1864 the duration of initialization since the entire
1865 initialization sequence is now protected by the
1866 big_lock. */
1867 break;
1868 }
Mike Iselyc4a8828d2008-04-22 14:45:44 -03001869 hdw->state_data = callback_data;
1870 hdw->state_func = callback_func;
Mike Isely97f26ff2008-04-07 02:22:43 -03001871 pvr2_hdw_setup(hdw);
Mike Iselyc4a8828d2008-04-22 14:45:44 -03001872 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely794b1602008-04-22 14:45:45 -03001873 return hdw->flag_init_ok;
Mike Iselyc4a8828d2008-04-22 14:45:44 -03001874}
1875
1876
1877/* Create, set up, and return a structure for interacting with the
1878 underlying hardware. */
Mike Iselyd8554972006-06-26 20:58:46 -03001879struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1880 const struct usb_device_id *devid)
1881{
Mike Isely7fb20fa2008-04-22 14:45:37 -03001882 unsigned int idx,cnt1,cnt2,m;
Mike Iselyd8554972006-06-26 20:58:46 -03001883 struct pvr2_hdw *hdw;
Mike Iselyd8554972006-06-26 20:58:46 -03001884 int valid_std_mask;
1885 struct pvr2_ctrl *cptr;
Mike Isely989eb152007-11-26 01:53:12 -03001886 const struct pvr2_device_desc *hdw_desc;
Mike Iselyd8554972006-06-26 20:58:46 -03001887 __u8 ifnum;
Mike Iselyb30d2442006-06-25 20:05:01 -03001888 struct v4l2_queryctrl qctrl;
1889 struct pvr2_ctl_info *ciptr;
Mike Iselyd8554972006-06-26 20:58:46 -03001890
Mike Iselyd130fa82007-12-08 17:20:06 -03001891 hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info);
Mike Iselyd8554972006-06-26 20:58:46 -03001892
Mike Iselyca545f72007-01-20 00:37:11 -03001893 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -03001894 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
Mike Isely989eb152007-11-26 01:53:12 -03001895 hdw,hdw_desc->description);
Mike Iselyd8554972006-06-26 20:58:46 -03001896 if (!hdw) goto fail;
Mike Isely681c7392007-11-26 01:48:52 -03001897
1898 init_timer(&hdw->quiescent_timer);
1899 hdw->quiescent_timer.data = (unsigned long)hdw;
1900 hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout;
1901
1902 init_timer(&hdw->encoder_wait_timer);
1903 hdw->encoder_wait_timer.data = (unsigned long)hdw;
1904 hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout;
1905
Mike Iselyd913d632008-04-06 04:04:35 -03001906 init_timer(&hdw->encoder_run_timer);
1907 hdw->encoder_run_timer.data = (unsigned long)hdw;
1908 hdw->encoder_run_timer.function = pvr2_hdw_encoder_run_timeout;
1909
Mike Isely681c7392007-11-26 01:48:52 -03001910 hdw->master_state = PVR2_STATE_DEAD;
1911
1912 init_waitqueue_head(&hdw->state_wait_data);
1913
Mike Isely18103c572007-01-20 00:09:47 -03001914 hdw->tuner_signal_stale = !0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001915 cx2341x_fill_defaults(&hdw->enc_ctl_state);
Mike Iselyd8554972006-06-26 20:58:46 -03001916
Mike Isely7fb20fa2008-04-22 14:45:37 -03001917 /* Calculate which inputs are OK */
1918 m = 0;
1919 if (hdw_desc->flag_has_analogtuner) m |= 1 << PVR2_CVAL_INPUT_TV;
Mike Iselye8f5bac2008-04-22 14:45:40 -03001920 if (hdw_desc->digital_control_scheme != PVR2_DIGITAL_SCHEME_NONE) {
1921 m |= 1 << PVR2_CVAL_INPUT_DTV;
1922 }
Mike Isely7fb20fa2008-04-22 14:45:37 -03001923 if (hdw_desc->flag_has_svideo) m |= 1 << PVR2_CVAL_INPUT_SVIDEO;
1924 if (hdw_desc->flag_has_composite) m |= 1 << PVR2_CVAL_INPUT_COMPOSITE;
1925 if (hdw_desc->flag_has_fmradio) m |= 1 << PVR2_CVAL_INPUT_RADIO;
1926 hdw->input_avail_mask = m;
Mike Isely1cb03b72008-04-21 03:47:43 -03001927 hdw->input_allowed_mask = hdw->input_avail_mask;
Mike Isely7fb20fa2008-04-22 14:45:37 -03001928
Mike Isely62433e32008-04-22 14:45:40 -03001929 /* If not a hybrid device, pathway_state never changes. So
1930 initialize it here to what it should forever be. */
1931 if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_DTV))) {
1932 hdw->pathway_state = PVR2_PATHWAY_ANALOG;
1933 } else if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_TV))) {
1934 hdw->pathway_state = PVR2_PATHWAY_DIGITAL;
1935 }
1936
Mike Iselyc05c0462006-06-25 20:04:25 -03001937 hdw->control_cnt = CTRLDEF_COUNT;
Mike Iselyb30d2442006-06-25 20:05:01 -03001938 hdw->control_cnt += MPEGDEF_COUNT;
Mike Iselyca545f72007-01-20 00:37:11 -03001939 hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001940 GFP_KERNEL);
1941 if (!hdw->controls) goto fail;
Mike Isely989eb152007-11-26 01:53:12 -03001942 hdw->hdw_desc = hdw_desc;
Mike Iselyc05c0462006-06-25 20:04:25 -03001943 for (idx = 0; idx < hdw->control_cnt; idx++) {
1944 cptr = hdw->controls + idx;
1945 cptr->hdw = hdw;
1946 }
Mike Iselyd8554972006-06-26 20:58:46 -03001947 for (idx = 0; idx < 32; idx++) {
1948 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1949 }
Mike Iselyc05c0462006-06-25 20:04:25 -03001950 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001951 cptr = hdw->controls + idx;
Mike Iselyd8554972006-06-26 20:58:46 -03001952 cptr->info = control_defs+idx;
1953 }
Mike Iselydbc40a02008-04-22 14:45:39 -03001954
1955 /* Ensure that default input choice is a valid one. */
1956 m = hdw->input_avail_mask;
1957 if (m) for (idx = 0; idx < (sizeof(m) << 3); idx++) {
1958 if (!((1 << idx) & m)) continue;
1959 hdw->input_val = idx;
1960 break;
1961 }
1962
Mike Iselyb30d2442006-06-25 20:05:01 -03001963 /* Define and configure additional controls from cx2341x module. */
Mike Iselyca545f72007-01-20 00:37:11 -03001964 hdw->mpeg_ctrl_info = kzalloc(
Mike Iselyb30d2442006-06-25 20:05:01 -03001965 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
1966 if (!hdw->mpeg_ctrl_info) goto fail;
Mike Iselyb30d2442006-06-25 20:05:01 -03001967 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
1968 cptr = hdw->controls + idx + CTRLDEF_COUNT;
1969 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
1970 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
1971 ciptr->name = mpeg_ids[idx].strid;
1972 ciptr->v4l_id = mpeg_ids[idx].id;
1973 ciptr->skip_init = !0;
1974 ciptr->get_value = ctrl_cx2341x_get;
1975 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
1976 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
1977 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
1978 qctrl.id = ciptr->v4l_id;
1979 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
1980 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
1981 ciptr->set_value = ctrl_cx2341x_set;
1982 }
1983 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
1984 PVR2_CTLD_INFO_DESC_SIZE);
1985 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
1986 ciptr->default_value = qctrl.default_value;
1987 switch (qctrl.type) {
1988 default:
1989 case V4L2_CTRL_TYPE_INTEGER:
1990 ciptr->type = pvr2_ctl_int;
1991 ciptr->def.type_int.min_value = qctrl.minimum;
1992 ciptr->def.type_int.max_value = qctrl.maximum;
1993 break;
1994 case V4L2_CTRL_TYPE_BOOLEAN:
1995 ciptr->type = pvr2_ctl_bool;
1996 break;
1997 case V4L2_CTRL_TYPE_MENU:
1998 ciptr->type = pvr2_ctl_enum;
1999 ciptr->def.type_enum.value_names =
2000 cx2341x_ctrl_get_menu(ciptr->v4l_id);
2001 for (cnt1 = 0;
2002 ciptr->def.type_enum.value_names[cnt1] != NULL;
2003 cnt1++) { }
2004 ciptr->def.type_enum.count = cnt1;
2005 break;
2006 }
2007 cptr->info = ciptr;
2008 }
Mike Iselyd8554972006-06-26 20:58:46 -03002009
2010 // Initialize video standard enum dynamic control
2011 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
2012 if (cptr) {
2013 memcpy(&hdw->std_info_enum,cptr->info,
2014 sizeof(hdw->std_info_enum));
2015 cptr->info = &hdw->std_info_enum;
2016
2017 }
2018 // Initialize control data regarding video standard masks
2019 valid_std_mask = pvr2_std_get_usable();
2020 for (idx = 0; idx < 32; idx++) {
2021 if (!(valid_std_mask & (1 << idx))) continue;
2022 cnt1 = pvr2_std_id_to_str(
2023 hdw->std_mask_names[idx],
2024 sizeof(hdw->std_mask_names[idx])-1,
2025 1 << idx);
2026 hdw->std_mask_names[idx][cnt1] = 0;
2027 }
2028 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
2029 if (cptr) {
2030 memcpy(&hdw->std_info_avail,cptr->info,
2031 sizeof(hdw->std_info_avail));
2032 cptr->info = &hdw->std_info_avail;
2033 hdw->std_info_avail.def.type_bitmask.bit_names =
2034 hdw->std_mask_ptrs;
2035 hdw->std_info_avail.def.type_bitmask.valid_bits =
2036 valid_std_mask;
2037 }
2038 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
2039 if (cptr) {
2040 memcpy(&hdw->std_info_cur,cptr->info,
2041 sizeof(hdw->std_info_cur));
2042 cptr->info = &hdw->std_info_cur;
2043 hdw->std_info_cur.def.type_bitmask.bit_names =
2044 hdw->std_mask_ptrs;
2045 hdw->std_info_avail.def.type_bitmask.valid_bits =
2046 valid_std_mask;
2047 }
2048
2049 hdw->eeprom_addr = -1;
2050 hdw->unit_number = -1;
Mike Isely80793842006-12-27 23:12:28 -03002051 hdw->v4l_minor_number_video = -1;
2052 hdw->v4l_minor_number_vbi = -1;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002053 hdw->v4l_minor_number_radio = -1;
Mike Iselyd8554972006-06-26 20:58:46 -03002054 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2055 if (!hdw->ctl_write_buffer) goto fail;
2056 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2057 if (!hdw->ctl_read_buffer) goto fail;
2058 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
2059 if (!hdw->ctl_write_urb) goto fail;
2060 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
2061 if (!hdw->ctl_read_urb) goto fail;
2062
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002063 mutex_lock(&pvr2_unit_mtx); do {
Mike Iselyd8554972006-06-26 20:58:46 -03002064 for (idx = 0; idx < PVR_NUM; idx++) {
2065 if (unit_pointers[idx]) continue;
2066 hdw->unit_number = idx;
2067 unit_pointers[idx] = hdw;
2068 break;
2069 }
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002070 } while (0); mutex_unlock(&pvr2_unit_mtx);
Mike Iselyd8554972006-06-26 20:58:46 -03002071
2072 cnt1 = 0;
2073 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
2074 cnt1 += cnt2;
2075 if (hdw->unit_number >= 0) {
2076 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
2077 ('a' + hdw->unit_number));
2078 cnt1 += cnt2;
2079 }
2080 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
2081 hdw->name[cnt1] = 0;
2082
Mike Isely681c7392007-11-26 01:48:52 -03002083 hdw->workqueue = create_singlethread_workqueue(hdw->name);
2084 INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll);
2085 INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c);
Mike Isely681c7392007-11-26 01:48:52 -03002086
Mike Iselyd8554972006-06-26 20:58:46 -03002087 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
2088 hdw->unit_number,hdw->name);
2089
2090 hdw->tuner_type = -1;
2091 hdw->flag_ok = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002092
2093 hdw->usb_intf = intf;
2094 hdw->usb_dev = interface_to_usbdev(intf);
2095
Mike Isely31a18542007-04-08 01:11:47 -03002096 scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
2097 "usb %s address %d",
2098 hdw->usb_dev->dev.bus_id,
2099 hdw->usb_dev->devnum);
2100
Mike Iselyd8554972006-06-26 20:58:46 -03002101 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2102 usb_set_interface(hdw->usb_dev,ifnum,0);
2103
2104 mutex_init(&hdw->ctl_lock_mutex);
2105 mutex_init(&hdw->big_lock_mutex);
2106
2107 return hdw;
2108 fail:
2109 if (hdw) {
Mike Isely681c7392007-11-26 01:48:52 -03002110 del_timer_sync(&hdw->quiescent_timer);
Mike Iselyd913d632008-04-06 04:04:35 -03002111 del_timer_sync(&hdw->encoder_run_timer);
Mike Isely681c7392007-11-26 01:48:52 -03002112 del_timer_sync(&hdw->encoder_wait_timer);
2113 if (hdw->workqueue) {
2114 flush_workqueue(hdw->workqueue);
2115 destroy_workqueue(hdw->workqueue);
2116 hdw->workqueue = NULL;
2117 }
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002118 usb_free_urb(hdw->ctl_read_urb);
2119 usb_free_urb(hdw->ctl_write_urb);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002120 kfree(hdw->ctl_read_buffer);
2121 kfree(hdw->ctl_write_buffer);
2122 kfree(hdw->controls);
2123 kfree(hdw->mpeg_ctrl_info);
Mike Isely681c7392007-11-26 01:48:52 -03002124 kfree(hdw->std_defs);
2125 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002126 kfree(hdw);
2127 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002128 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002129}
2130
2131
2132/* Remove _all_ associations between this driver and the underlying USB
2133 layer. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002134static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002135{
2136 if (hdw->flag_disconnected) return;
2137 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
2138 if (hdw->ctl_read_urb) {
2139 usb_kill_urb(hdw->ctl_read_urb);
2140 usb_free_urb(hdw->ctl_read_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002141 hdw->ctl_read_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002142 }
2143 if (hdw->ctl_write_urb) {
2144 usb_kill_urb(hdw->ctl_write_urb);
2145 usb_free_urb(hdw->ctl_write_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002146 hdw->ctl_write_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002147 }
2148 if (hdw->ctl_read_buffer) {
2149 kfree(hdw->ctl_read_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002150 hdw->ctl_read_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002151 }
2152 if (hdw->ctl_write_buffer) {
2153 kfree(hdw->ctl_write_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002154 hdw->ctl_write_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002155 }
Mike Iselyd8554972006-06-26 20:58:46 -03002156 hdw->flag_disconnected = !0;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002157 hdw->usb_dev = NULL;
2158 hdw->usb_intf = NULL;
Mike Isely681c7392007-11-26 01:48:52 -03002159 pvr2_hdw_render_useless(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002160}
2161
2162
2163/* Destroy hardware interaction structure */
2164void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2165{
Mike Isely401c27c2007-09-08 22:11:46 -03002166 if (!hdw) return;
Mike Iselyd8554972006-06-26 20:58:46 -03002167 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
Mike Isely681c7392007-11-26 01:48:52 -03002168 if (hdw->workqueue) {
2169 flush_workqueue(hdw->workqueue);
2170 destroy_workqueue(hdw->workqueue);
2171 hdw->workqueue = NULL;
2172 }
Mike Isely8f591002008-04-22 14:45:45 -03002173 del_timer_sync(&hdw->quiescent_timer);
Mike Iselyd913d632008-04-06 04:04:35 -03002174 del_timer_sync(&hdw->encoder_run_timer);
Mike Isely8f591002008-04-22 14:45:45 -03002175 del_timer_sync(&hdw->encoder_wait_timer);
Mike Iselyd8554972006-06-26 20:58:46 -03002176 if (hdw->fw_buffer) {
2177 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002178 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002179 }
2180 if (hdw->vid_stream) {
2181 pvr2_stream_destroy(hdw->vid_stream);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002182 hdw->vid_stream = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002183 }
Mike Iselyd8554972006-06-26 20:58:46 -03002184 if (hdw->decoder_ctrl) {
2185 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2186 }
2187 pvr2_i2c_core_done(hdw);
2188 pvr2_hdw_remove_usb_stuff(hdw);
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002189 mutex_lock(&pvr2_unit_mtx); do {
Mike Iselyd8554972006-06-26 20:58:46 -03002190 if ((hdw->unit_number >= 0) &&
2191 (hdw->unit_number < PVR_NUM) &&
2192 (unit_pointers[hdw->unit_number] == hdw)) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002193 unit_pointers[hdw->unit_number] = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002194 }
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002195 } while (0); mutex_unlock(&pvr2_unit_mtx);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002196 kfree(hdw->controls);
2197 kfree(hdw->mpeg_ctrl_info);
2198 kfree(hdw->std_defs);
2199 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002200 kfree(hdw);
2201}
2202
2203
Mike Iselyd8554972006-06-26 20:58:46 -03002204int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2205{
2206 return (hdw && hdw->flag_ok);
2207}
2208
2209
2210/* Called when hardware has been unplugged */
2211void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2212{
2213 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2214 LOCK_TAKE(hdw->big_lock);
2215 LOCK_TAKE(hdw->ctl_lock);
2216 pvr2_hdw_remove_usb_stuff(hdw);
2217 LOCK_GIVE(hdw->ctl_lock);
2218 LOCK_GIVE(hdw->big_lock);
2219}
2220
2221
2222// Attempt to autoselect an appropriate value for std_enum_cur given
2223// whatever is currently in std_mask_cur
Adrian Bunk07e337e2006-06-30 11:30:20 -03002224static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002225{
2226 unsigned int idx;
2227 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2228 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2229 hdw->std_enum_cur = idx;
2230 return;
2231 }
2232 }
2233 hdw->std_enum_cur = 0;
2234}
2235
2236
2237// Calculate correct set of enumerated standards based on currently known
2238// set of available standards bits.
Adrian Bunk07e337e2006-06-30 11:30:20 -03002239static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002240{
2241 struct v4l2_standard *newstd;
2242 unsigned int std_cnt;
2243 unsigned int idx;
2244
2245 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2246
2247 if (hdw->std_defs) {
2248 kfree(hdw->std_defs);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002249 hdw->std_defs = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002250 }
2251 hdw->std_enum_cnt = 0;
2252 if (hdw->std_enum_names) {
2253 kfree(hdw->std_enum_names);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002254 hdw->std_enum_names = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002255 }
2256
2257 if (!std_cnt) {
2258 pvr2_trace(
2259 PVR2_TRACE_ERROR_LEGS,
2260 "WARNING: Failed to identify any viable standards");
2261 }
2262 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2263 hdw->std_enum_names[0] = "none";
2264 for (idx = 0; idx < std_cnt; idx++) {
2265 hdw->std_enum_names[idx+1] =
2266 newstd[idx].name;
2267 }
2268 // Set up the dynamic control for this standard
2269 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2270 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2271 hdw->std_defs = newstd;
2272 hdw->std_enum_cnt = std_cnt+1;
2273 hdw->std_enum_cur = 0;
2274 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2275}
2276
2277
2278int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2279 struct v4l2_standard *std,
2280 unsigned int idx)
2281{
2282 int ret = -EINVAL;
2283 if (!idx) return ret;
2284 LOCK_TAKE(hdw->big_lock); do {
2285 if (idx >= hdw->std_enum_cnt) break;
2286 idx--;
2287 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2288 ret = 0;
2289 } while (0); LOCK_GIVE(hdw->big_lock);
2290 return ret;
2291}
2292
2293
2294/* Get the number of defined controls */
2295unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2296{
Mike Iselyc05c0462006-06-25 20:04:25 -03002297 return hdw->control_cnt;
Mike Iselyd8554972006-06-26 20:58:46 -03002298}
2299
2300
2301/* Retrieve a control handle given its index (0..count-1) */
2302struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2303 unsigned int idx)
2304{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002305 if (idx >= hdw->control_cnt) return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002306 return hdw->controls + idx;
2307}
2308
2309
2310/* Retrieve a control handle given its index (0..count-1) */
2311struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2312 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->internal_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, retrieve the control structure associated with it. */
Mike Iselyd8554972006-06-26 20:58:46 -03002329struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2330{
2331 struct pvr2_ctrl *cptr;
2332 unsigned int idx;
2333 int i;
2334
2335 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002336 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002337 cptr = hdw->controls + idx;
2338 i = cptr->info->v4l_id;
2339 if (i && (i == ctl_id)) return cptr;
2340 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002341 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002342}
2343
2344
Mike Iselya761f432006-06-25 20:04:44 -03002345/* Given a V4L ID for its immediate predecessor, retrieve the control
2346 structure associated with it. */
2347struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2348 unsigned int ctl_id)
2349{
2350 struct pvr2_ctrl *cptr,*cp2;
2351 unsigned int idx;
2352 int i;
2353
2354 /* This could be made a lot more efficient, but for now... */
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002355 cp2 = NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002356 for (idx = 0; idx < hdw->control_cnt; idx++) {
2357 cptr = hdw->controls + idx;
2358 i = cptr->info->v4l_id;
2359 if (!i) continue;
2360 if (i <= ctl_id) continue;
2361 if (cp2 && (cp2->info->v4l_id < i)) continue;
2362 cp2 = cptr;
2363 }
2364 return cp2;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002365 return NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002366}
2367
2368
Mike Iselyd8554972006-06-26 20:58:46 -03002369static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2370{
2371 switch (tp) {
2372 case pvr2_ctl_int: return "integer";
2373 case pvr2_ctl_enum: return "enum";
Mike Isely33213962006-06-25 20:04:40 -03002374 case pvr2_ctl_bool: return "boolean";
Mike Iselyd8554972006-06-26 20:58:46 -03002375 case pvr2_ctl_bitmask: return "bitmask";
2376 }
2377 return "";
2378}
2379
2380
Mike Isely681c7392007-11-26 01:48:52 -03002381/* Figure out if we need to commit control changes. If so, mark internal
2382 state flags to indicate this fact and return true. Otherwise do nothing
2383 else and return false. */
2384static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002385{
Mike Iselyd8554972006-06-26 20:58:46 -03002386 unsigned int idx;
2387 struct pvr2_ctrl *cptr;
2388 int value;
2389 int commit_flag = 0;
2390 char buf[100];
2391 unsigned int bcnt,ccnt;
2392
Mike Iselyc05c0462006-06-25 20:04:25 -03002393 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002394 cptr = hdw->controls + idx;
Al Viro5fa12472008-03-29 03:07:38 +00002395 if (!cptr->info->is_dirty) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002396 if (!cptr->info->is_dirty(cptr)) continue;
Mike Iselyfe23a282007-01-20 00:10:55 -03002397 commit_flag = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002398
Mike Iselyfe23a282007-01-20 00:10:55 -03002399 if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002400 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2401 cptr->info->name);
2402 value = 0;
2403 cptr->info->get_value(cptr,&value);
2404 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2405 buf+bcnt,
2406 sizeof(buf)-bcnt,&ccnt);
2407 bcnt += ccnt;
2408 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2409 get_ctrl_typename(cptr->info->type));
2410 pvr2_trace(PVR2_TRACE_CTL,
2411 "/*--TRACE_COMMIT--*/ %.*s",
2412 bcnt,buf);
2413 }
2414
2415 if (!commit_flag) {
2416 /* Nothing has changed */
2417 return 0;
2418 }
2419
Mike Isely681c7392007-11-26 01:48:52 -03002420 hdw->state_pipeline_config = 0;
2421 trace_stbit("state_pipeline_config",hdw->state_pipeline_config);
2422 pvr2_hdw_state_sched(hdw);
2423
2424 return !0;
2425}
2426
2427
2428/* Perform all operations needed to commit all control changes. This must
2429 be performed in synchronization with the pipeline state and is thus
2430 expected to be called as part of the driver's worker thread. Return
2431 true if commit successful, otherwise return false to indicate that
2432 commit isn't possible at this time. */
2433static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
2434{
2435 unsigned int idx;
2436 struct pvr2_ctrl *cptr;
2437 int disruptive_change;
2438
Mike Iselyd8554972006-06-26 20:58:46 -03002439 /* When video standard changes, reset the hres and vres values -
2440 but if the user has pending changes there, then let the changes
2441 take priority. */
2442 if (hdw->std_dirty) {
2443 /* Rewrite the vertical resolution to be appropriate to the
2444 video standard that has been selected. */
2445 int nvres;
2446 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2447 nvres = 480;
2448 } else {
2449 nvres = 576;
2450 }
2451 if (nvres != hdw->res_ver_val) {
2452 hdw->res_ver_val = nvres;
2453 hdw->res_ver_dirty = !0;
2454 }
Mike Iselyd8554972006-06-26 20:58:46 -03002455 }
2456
Mike Isely38d9a2c2008-03-28 05:30:48 -03002457 if (hdw->input_dirty && hdw->state_pathway_ok &&
Mike Isely62433e32008-04-22 14:45:40 -03002458 (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ?
2459 PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) !=
2460 hdw->pathway_state)) {
2461 /* Change of mode being asked for... */
2462 hdw->state_pathway_ok = 0;
Mike Iselye9db1ff2008-04-22 14:45:41 -03002463 trace_stbit("state_pathway_ok",hdw->state_pathway_ok);
Mike Isely62433e32008-04-22 14:45:40 -03002464 }
2465 if (!hdw->state_pathway_ok) {
2466 /* Can't commit anything until pathway is ok. */
2467 return 0;
2468 }
Mike Isely681c7392007-11-26 01:48:52 -03002469 /* If any of the below has changed, then we can't do the update
2470 while the pipeline is running. Pipeline must be paused first
2471 and decoder -> encoder connection be made quiescent before we
2472 can proceed. */
2473 disruptive_change =
2474 (hdw->std_dirty ||
2475 hdw->enc_unsafe_stale ||
2476 hdw->srate_dirty ||
2477 hdw->res_ver_dirty ||
2478 hdw->res_hor_dirty ||
2479 hdw->input_dirty ||
2480 (hdw->active_stream_type != hdw->desired_stream_type));
2481 if (disruptive_change && !hdw->state_pipeline_idle) {
2482 /* Pipeline is not idle; we can't proceed. Arrange to
2483 cause pipeline to stop so that we can try this again
2484 later.... */
2485 hdw->state_pipeline_pause = !0;
2486 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002487 }
2488
Mike Iselyb30d2442006-06-25 20:05:01 -03002489 if (hdw->srate_dirty) {
2490 /* Write new sample rate into control structure since
2491 * the master copy is stale. We must track srate
2492 * separate from the mpeg control structure because
2493 * other logic also uses this value. */
2494 struct v4l2_ext_controls cs;
2495 struct v4l2_ext_control c1;
2496 memset(&cs,0,sizeof(cs));
2497 memset(&c1,0,sizeof(c1));
2498 cs.controls = &c1;
2499 cs.count = 1;
2500 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2501 c1.value = hdw->srate_val;
Hans Verkuil01f1e442007-08-21 18:32:42 -03002502 cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
Mike Iselyb30d2442006-06-25 20:05:01 -03002503 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002504
Mike Iselyd8554972006-06-26 20:58:46 -03002505 /* Scan i2c core at this point - before we clear all the dirty
2506 bits. Various parts of the i2c core will notice dirty bits as
2507 appropriate and arrange to broadcast or directly send updates to
2508 the client drivers in order to keep everything in sync */
2509 pvr2_i2c_core_check_stale(hdw);
2510
Mike Iselyc05c0462006-06-25 20:04:25 -03002511 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002512 cptr = hdw->controls + idx;
2513 if (!cptr->info->clear_dirty) continue;
2514 cptr->info->clear_dirty(cptr);
2515 }
2516
Mike Isely681c7392007-11-26 01:48:52 -03002517 if (hdw->active_stream_type != hdw->desired_stream_type) {
2518 /* Handle any side effects of stream config here */
2519 hdw->active_stream_type = hdw->desired_stream_type;
2520 }
2521
Mike Isely1df59f02008-04-21 03:50:39 -03002522 if (hdw->hdw_desc->signal_routing_scheme ==
2523 PVR2_ROUTING_SCHEME_GOTVIEW) {
2524 u32 b;
2525 /* Handle GOTVIEW audio switching */
2526 pvr2_hdw_gpio_get_out(hdw,&b);
2527 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
2528 /* Set GPIO 11 */
2529 pvr2_hdw_gpio_chg_out(hdw,(1 << 11),~0);
2530 } else {
2531 /* Clear GPIO 11 */
2532 pvr2_hdw_gpio_chg_out(hdw,(1 << 11),0);
2533 }
2534 }
2535
Mike Iselyd8554972006-06-26 20:58:46 -03002536 /* Now execute i2c core update */
2537 pvr2_i2c_core_sync(hdw);
2538
Mike Isely62433e32008-04-22 14:45:40 -03002539 if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
2540 hdw->state_encoder_run) {
2541 /* If encoder isn't running or it can't be touched, then
2542 this will get worked out later when we start the
2543 encoder. */
Mike Isely681c7392007-11-26 01:48:52 -03002544 if (pvr2_encoder_adjust(hdw) < 0) return !0;
2545 }
Mike Iselyd8554972006-06-26 20:58:46 -03002546
Mike Isely681c7392007-11-26 01:48:52 -03002547 hdw->state_pipeline_config = !0;
2548 trace_stbit("state_pipeline_config",hdw->state_pipeline_config);
2549 return !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002550}
2551
2552
2553int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2554{
Mike Isely681c7392007-11-26 01:48:52 -03002555 int fl;
2556 LOCK_TAKE(hdw->big_lock);
2557 fl = pvr2_hdw_commit_setup(hdw);
2558 LOCK_GIVE(hdw->big_lock);
2559 if (!fl) return 0;
2560 return pvr2_hdw_wait(hdw,0);
Mike Iselyd8554972006-06-26 20:58:46 -03002561}
2562
2563
Mike Isely681c7392007-11-26 01:48:52 -03002564static void pvr2_hdw_worker_i2c(struct work_struct *work)
Mike Iselyd8554972006-06-26 20:58:46 -03002565{
Mike Isely681c7392007-11-26 01:48:52 -03002566 struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync);
Mike Iselyd8554972006-06-26 20:58:46 -03002567 LOCK_TAKE(hdw->big_lock); do {
2568 pvr2_i2c_core_sync(hdw);
2569 } while (0); LOCK_GIVE(hdw->big_lock);
2570}
2571
2572
Mike Isely681c7392007-11-26 01:48:52 -03002573static void pvr2_hdw_worker_poll(struct work_struct *work)
Mike Iselyd8554972006-06-26 20:58:46 -03002574{
Mike Isely681c7392007-11-26 01:48:52 -03002575 int fl = 0;
2576 struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,workpoll);
Mike Iselyd8554972006-06-26 20:58:46 -03002577 LOCK_TAKE(hdw->big_lock); do {
Mike Isely681c7392007-11-26 01:48:52 -03002578 fl = pvr2_hdw_state_eval(hdw);
2579 } while (0); LOCK_GIVE(hdw->big_lock);
2580 if (fl && hdw->state_func) {
2581 hdw->state_func(hdw->state_data);
2582 }
2583}
2584
2585
Mike Isely681c7392007-11-26 01:48:52 -03002586static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state)
Mike Iselyd8554972006-06-26 20:58:46 -03002587{
Mike Isely681c7392007-11-26 01:48:52 -03002588 return wait_event_interruptible(
2589 hdw->state_wait_data,
2590 (hdw->state_stale == 0) &&
2591 (!state || (hdw->master_state != state)));
Mike Iselyd8554972006-06-26 20:58:46 -03002592}
2593
Mike Isely681c7392007-11-26 01:48:52 -03002594
Mike Iselyd8554972006-06-26 20:58:46 -03002595/* Return name for this driver instance */
2596const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2597{
2598 return hdw->name;
2599}
2600
2601
Mike Isely78a47102007-11-26 01:58:20 -03002602const char *pvr2_hdw_get_desc(struct pvr2_hdw *hdw)
2603{
2604 return hdw->hdw_desc->description;
2605}
2606
2607
2608const char *pvr2_hdw_get_type(struct pvr2_hdw *hdw)
2609{
2610 return hdw->hdw_desc->shortname;
2611}
2612
2613
Mike Iselyd8554972006-06-26 20:58:46 -03002614int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2615{
2616 int result;
2617 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03002618 hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED;
Mike Iselyd8554972006-06-26 20:58:46 -03002619 result = pvr2_send_request(hdw,
2620 hdw->cmd_buffer,1,
2621 hdw->cmd_buffer,1);
2622 if (result < 0) break;
2623 result = (hdw->cmd_buffer[0] != 0);
2624 } while(0); LOCK_GIVE(hdw->ctl_lock);
2625 return result;
2626}
2627
2628
Mike Isely18103c572007-01-20 00:09:47 -03002629/* Execute poll of tuner status */
2630void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002631{
Mike Iselyd8554972006-06-26 20:58:46 -03002632 LOCK_TAKE(hdw->big_lock); do {
Mike Isely18103c572007-01-20 00:09:47 -03002633 pvr2_i2c_core_status_poll(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002634 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely18103c572007-01-20 00:09:47 -03002635}
2636
2637
2638/* Return information about the tuner */
2639int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
2640{
2641 LOCK_TAKE(hdw->big_lock); do {
2642 if (hdw->tuner_signal_stale) {
2643 pvr2_i2c_core_status_poll(hdw);
2644 }
2645 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
2646 } while (0); LOCK_GIVE(hdw->big_lock);
2647 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002648}
2649
2650
2651/* Get handle to video output stream */
2652struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2653{
2654 return hp->vid_stream;
2655}
2656
2657
2658void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2659{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002660 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002661 LOCK_TAKE(hdw->big_lock); do {
2662 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002663 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002664 pvr2_i2c_core_check_stale(hdw);
2665 hdw->log_requested = 0;
2666 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002667 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002668 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely681c7392007-11-26 01:48:52 -03002669 pvr2_hdw_state_log_state(hdw);
Mike Isely4f1a3e52006-06-25 20:04:31 -03002670 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002671 } while (0); LOCK_GIVE(hdw->big_lock);
2672}
2673
Mike Isely4db666c2007-09-08 22:16:27 -03002674
2675/* Grab EEPROM contents, needed for direct method. */
2676#define EEPROM_SIZE 8192
2677#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
2678static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw)
2679{
2680 struct i2c_msg msg[2];
2681 u8 *eeprom;
2682 u8 iadd[2];
2683 u8 addr;
2684 u16 eepromSize;
2685 unsigned int offs;
2686 int ret;
2687 int mode16 = 0;
2688 unsigned pcnt,tcnt;
2689 eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
2690 if (!eeprom) {
2691 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2692 "Failed to allocate memory"
2693 " required to read eeprom");
2694 return NULL;
2695 }
2696
2697 trace_eeprom("Value for eeprom addr from controller was 0x%x",
2698 hdw->eeprom_addr);
2699 addr = hdw->eeprom_addr;
2700 /* Seems that if the high bit is set, then the *real* eeprom
2701 address is shifted right now bit position (noticed this in
2702 newer PVR USB2 hardware) */
2703 if (addr & 0x80) addr >>= 1;
2704
2705 /* FX2 documentation states that a 16bit-addressed eeprom is
2706 expected if the I2C address is an odd number (yeah, this is
2707 strange but it's what they do) */
2708 mode16 = (addr & 1);
2709 eepromSize = (mode16 ? EEPROM_SIZE : 256);
2710 trace_eeprom("Examining %d byte eeprom at location 0x%x"
2711 " using %d bit addressing",eepromSize,addr,
2712 mode16 ? 16 : 8);
2713
2714 msg[0].addr = addr;
2715 msg[0].flags = 0;
2716 msg[0].len = mode16 ? 2 : 1;
2717 msg[0].buf = iadd;
2718 msg[1].addr = addr;
2719 msg[1].flags = I2C_M_RD;
2720
2721 /* We have to do the actual eeprom data fetch ourselves, because
2722 (1) we're only fetching part of the eeprom, and (2) if we were
2723 getting the whole thing our I2C driver can't grab it in one
2724 pass - which is what tveeprom is otherwise going to attempt */
2725 memset(eeprom,0,EEPROM_SIZE);
2726 for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
2727 pcnt = 16;
2728 if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
2729 offs = tcnt + (eepromSize - EEPROM_SIZE);
2730 if (mode16) {
2731 iadd[0] = offs >> 8;
2732 iadd[1] = offs;
2733 } else {
2734 iadd[0] = offs;
2735 }
2736 msg[1].len = pcnt;
2737 msg[1].buf = eeprom+tcnt;
2738 if ((ret = i2c_transfer(&hdw->i2c_adap,
2739 msg,ARRAY_SIZE(msg))) != 2) {
2740 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2741 "eeprom fetch set offs err=%d",ret);
2742 kfree(eeprom);
2743 return NULL;
2744 }
2745 }
2746 return eeprom;
2747}
2748
2749
2750void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
2751 int prom_flag,
2752 int enable_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002753{
2754 int ret;
2755 u16 address;
2756 unsigned int pipe;
2757 LOCK_TAKE(hdw->big_lock); do {
Al Viro5fa12472008-03-29 03:07:38 +00002758 if ((hdw->fw_buffer == NULL) == !enable_flag) break;
Mike Iselyd8554972006-06-26 20:58:46 -03002759
2760 if (!enable_flag) {
2761 pvr2_trace(PVR2_TRACE_FIRMWARE,
2762 "Cleaning up after CPU firmware fetch");
2763 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002764 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002765 hdw->fw_size = 0;
Mike Isely4db666c2007-09-08 22:16:27 -03002766 if (hdw->fw_cpu_flag) {
2767 /* Now release the CPU. It will disconnect
2768 and reconnect later. */
2769 pvr2_hdw_cpureset_assert(hdw,0);
2770 }
Mike Iselyd8554972006-06-26 20:58:46 -03002771 break;
2772 }
2773
Mike Isely4db666c2007-09-08 22:16:27 -03002774 hdw->fw_cpu_flag = (prom_flag == 0);
2775 if (hdw->fw_cpu_flag) {
2776 pvr2_trace(PVR2_TRACE_FIRMWARE,
2777 "Preparing to suck out CPU firmware");
2778 hdw->fw_size = 0x2000;
2779 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
2780 if (!hdw->fw_buffer) {
2781 hdw->fw_size = 0;
2782 break;
2783 }
2784
2785 /* We have to hold the CPU during firmware upload. */
2786 pvr2_hdw_cpureset_assert(hdw,1);
2787
2788 /* download the firmware from address 0000-1fff in 2048
2789 (=0x800) bytes chunk. */
2790
2791 pvr2_trace(PVR2_TRACE_FIRMWARE,
2792 "Grabbing CPU firmware");
2793 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2794 for(address = 0; address < hdw->fw_size;
2795 address += 0x800) {
2796 ret = usb_control_msg(hdw->usb_dev,pipe,
2797 0xa0,0xc0,
2798 address,0,
2799 hdw->fw_buffer+address,
2800 0x800,HZ);
2801 if (ret < 0) break;
2802 }
2803
2804 pvr2_trace(PVR2_TRACE_FIRMWARE,
2805 "Done grabbing CPU firmware");
2806 } else {
2807 pvr2_trace(PVR2_TRACE_FIRMWARE,
2808 "Sucking down EEPROM contents");
2809 hdw->fw_buffer = pvr2_full_eeprom_fetch(hdw);
2810 if (!hdw->fw_buffer) {
2811 pvr2_trace(PVR2_TRACE_FIRMWARE,
2812 "EEPROM content suck failed.");
2813 break;
2814 }
2815 hdw->fw_size = EEPROM_SIZE;
2816 pvr2_trace(PVR2_TRACE_FIRMWARE,
2817 "Done sucking down EEPROM contents");
Mike Iselyd8554972006-06-26 20:58:46 -03002818 }
2819
Mike Iselyd8554972006-06-26 20:58:46 -03002820 } while (0); LOCK_GIVE(hdw->big_lock);
2821}
2822
2823
2824/* Return true if we're in a mode for retrieval CPU firmware */
2825int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2826{
Al Viro5fa12472008-03-29 03:07:38 +00002827 return hdw->fw_buffer != NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002828}
2829
2830
2831int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2832 char *buf,unsigned int cnt)
2833{
2834 int ret = -EINVAL;
2835 LOCK_TAKE(hdw->big_lock); do {
2836 if (!buf) break;
2837 if (!cnt) break;
2838
2839 if (!hdw->fw_buffer) {
2840 ret = -EIO;
2841 break;
2842 }
2843
2844 if (offs >= hdw->fw_size) {
2845 pvr2_trace(PVR2_TRACE_FIRMWARE,
2846 "Read firmware data offs=%d EOF",
2847 offs);
2848 ret = 0;
2849 break;
2850 }
2851
2852 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2853
2854 memcpy(buf,hdw->fw_buffer+offs,cnt);
2855
2856 pvr2_trace(PVR2_TRACE_FIRMWARE,
2857 "Read firmware data offs=%d cnt=%d",
2858 offs,cnt);
2859 ret = cnt;
2860 } while (0); LOCK_GIVE(hdw->big_lock);
2861
2862 return ret;
2863}
2864
2865
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002866int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002867 enum pvr2_v4l_type index)
Mike Iselyd8554972006-06-26 20:58:46 -03002868{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002869 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002870 case pvr2_v4l_type_video: return hdw->v4l_minor_number_video;
2871 case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi;
2872 case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002873 default: return -1;
2874 }
Mike Iselyd8554972006-06-26 20:58:46 -03002875}
2876
2877
Pantelis Koukousoulas2fdf3d92006-12-27 23:07:58 -03002878/* Store a v4l minor device number */
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002879void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002880 enum pvr2_v4l_type index,int v)
Mike Iselyd8554972006-06-26 20:58:46 -03002881{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002882 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002883 case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
2884 case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
2885 case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002886 default: break;
2887 }
Mike Iselyd8554972006-06-26 20:58:46 -03002888}
2889
2890
David Howells7d12e782006-10-05 14:55:46 +01002891static void pvr2_ctl_write_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002892{
2893 struct pvr2_hdw *hdw = urb->context;
2894 hdw->ctl_write_pend_flag = 0;
2895 if (hdw->ctl_read_pend_flag) return;
2896 complete(&hdw->ctl_done);
2897}
2898
2899
David Howells7d12e782006-10-05 14:55:46 +01002900static void pvr2_ctl_read_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002901{
2902 struct pvr2_hdw *hdw = urb->context;
2903 hdw->ctl_read_pend_flag = 0;
2904 if (hdw->ctl_write_pend_flag) return;
2905 complete(&hdw->ctl_done);
2906}
2907
2908
2909static void pvr2_ctl_timeout(unsigned long data)
2910{
2911 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2912 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2913 hdw->ctl_timeout_flag = !0;
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002914 if (hdw->ctl_write_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002915 usb_unlink_urb(hdw->ctl_write_urb);
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002916 if (hdw->ctl_read_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002917 usb_unlink_urb(hdw->ctl_read_urb);
Mike Iselyd8554972006-06-26 20:58:46 -03002918 }
2919}
2920
2921
Mike Iselye61b6fc2006-07-18 22:42:18 -03002922/* Issue a command and get a response from the device. This extended
2923 version includes a probe flag (which if set means that device errors
2924 should not be logged or treated as fatal) and a timeout in jiffies.
2925 This can be used to non-lethally probe the health of endpoint 1. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002926static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2927 unsigned int timeout,int probe_fl,
2928 void *write_data,unsigned int write_len,
2929 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002930{
2931 unsigned int idx;
2932 int status = 0;
2933 struct timer_list timer;
2934 if (!hdw->ctl_lock_held) {
2935 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2936 "Attempted to execute control transfer"
2937 " without lock!!");
2938 return -EDEADLK;
2939 }
Mike Isely681c7392007-11-26 01:48:52 -03002940 if (!hdw->flag_ok && !probe_fl) {
Mike Iselyd8554972006-06-26 20:58:46 -03002941 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2942 "Attempted to execute control transfer"
2943 " when device not ok");
2944 return -EIO;
2945 }
2946 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2947 if (!probe_fl) {
2948 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2949 "Attempted to execute control transfer"
2950 " when USB is disconnected");
2951 }
2952 return -ENOTTY;
2953 }
2954
2955 /* Ensure that we have sane parameters */
2956 if (!write_data) write_len = 0;
2957 if (!read_data) read_len = 0;
2958 if (write_len > PVR2_CTL_BUFFSIZE) {
2959 pvr2_trace(
2960 PVR2_TRACE_ERROR_LEGS,
2961 "Attempted to execute %d byte"
2962 " control-write transfer (limit=%d)",
2963 write_len,PVR2_CTL_BUFFSIZE);
2964 return -EINVAL;
2965 }
2966 if (read_len > PVR2_CTL_BUFFSIZE) {
2967 pvr2_trace(
2968 PVR2_TRACE_ERROR_LEGS,
2969 "Attempted to execute %d byte"
2970 " control-read transfer (limit=%d)",
2971 write_len,PVR2_CTL_BUFFSIZE);
2972 return -EINVAL;
2973 }
2974 if ((!write_len) && (!read_len)) {
2975 pvr2_trace(
2976 PVR2_TRACE_ERROR_LEGS,
2977 "Attempted to execute null control transfer?");
2978 return -EINVAL;
2979 }
2980
2981
2982 hdw->cmd_debug_state = 1;
2983 if (write_len) {
2984 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2985 } else {
2986 hdw->cmd_debug_code = 0;
2987 }
2988 hdw->cmd_debug_write_len = write_len;
2989 hdw->cmd_debug_read_len = read_len;
2990
2991 /* Initialize common stuff */
2992 init_completion(&hdw->ctl_done);
2993 hdw->ctl_timeout_flag = 0;
2994 hdw->ctl_write_pend_flag = 0;
2995 hdw->ctl_read_pend_flag = 0;
2996 init_timer(&timer);
2997 timer.expires = jiffies + timeout;
2998 timer.data = (unsigned long)hdw;
2999 timer.function = pvr2_ctl_timeout;
3000
3001 if (write_len) {
3002 hdw->cmd_debug_state = 2;
3003 /* Transfer write data to internal buffer */
3004 for (idx = 0; idx < write_len; idx++) {
3005 hdw->ctl_write_buffer[idx] =
3006 ((unsigned char *)write_data)[idx];
3007 }
3008 /* Initiate a write request */
3009 usb_fill_bulk_urb(hdw->ctl_write_urb,
3010 hdw->usb_dev,
3011 usb_sndbulkpipe(hdw->usb_dev,
3012 PVR2_CTL_WRITE_ENDPOINT),
3013 hdw->ctl_write_buffer,
3014 write_len,
3015 pvr2_ctl_write_complete,
3016 hdw);
3017 hdw->ctl_write_urb->actual_length = 0;
3018 hdw->ctl_write_pend_flag = !0;
3019 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
3020 if (status < 0) {
3021 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3022 "Failed to submit write-control"
3023 " URB status=%d",status);
3024 hdw->ctl_write_pend_flag = 0;
3025 goto done;
3026 }
3027 }
3028
3029 if (read_len) {
3030 hdw->cmd_debug_state = 3;
3031 memset(hdw->ctl_read_buffer,0x43,read_len);
3032 /* Initiate a read request */
3033 usb_fill_bulk_urb(hdw->ctl_read_urb,
3034 hdw->usb_dev,
3035 usb_rcvbulkpipe(hdw->usb_dev,
3036 PVR2_CTL_READ_ENDPOINT),
3037 hdw->ctl_read_buffer,
3038 read_len,
3039 pvr2_ctl_read_complete,
3040 hdw);
3041 hdw->ctl_read_urb->actual_length = 0;
3042 hdw->ctl_read_pend_flag = !0;
3043 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
3044 if (status < 0) {
3045 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3046 "Failed to submit read-control"
3047 " URB status=%d",status);
3048 hdw->ctl_read_pend_flag = 0;
3049 goto done;
3050 }
3051 }
3052
3053 /* Start timer */
3054 add_timer(&timer);
3055
3056 /* Now wait for all I/O to complete */
3057 hdw->cmd_debug_state = 4;
3058 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
3059 wait_for_completion(&hdw->ctl_done);
3060 }
3061 hdw->cmd_debug_state = 5;
3062
3063 /* Stop timer */
3064 del_timer_sync(&timer);
3065
3066 hdw->cmd_debug_state = 6;
3067 status = 0;
3068
3069 if (hdw->ctl_timeout_flag) {
3070 status = -ETIMEDOUT;
3071 if (!probe_fl) {
3072 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3073 "Timed out control-write");
3074 }
3075 goto done;
3076 }
3077
3078 if (write_len) {
3079 /* Validate results of write request */
3080 if ((hdw->ctl_write_urb->status != 0) &&
3081 (hdw->ctl_write_urb->status != -ENOENT) &&
3082 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
3083 (hdw->ctl_write_urb->status != -ECONNRESET)) {
3084 /* USB subsystem is reporting some kind of failure
3085 on the write */
3086 status = hdw->ctl_write_urb->status;
3087 if (!probe_fl) {
3088 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3089 "control-write URB failure,"
3090 " status=%d",
3091 status);
3092 }
3093 goto done;
3094 }
3095 if (hdw->ctl_write_urb->actual_length < write_len) {
3096 /* Failed to write enough data */
3097 status = -EIO;
3098 if (!probe_fl) {
3099 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3100 "control-write URB short,"
3101 " expected=%d got=%d",
3102 write_len,
3103 hdw->ctl_write_urb->actual_length);
3104 }
3105 goto done;
3106 }
3107 }
3108 if (read_len) {
3109 /* Validate results of read request */
3110 if ((hdw->ctl_read_urb->status != 0) &&
3111 (hdw->ctl_read_urb->status != -ENOENT) &&
3112 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
3113 (hdw->ctl_read_urb->status != -ECONNRESET)) {
3114 /* USB subsystem is reporting some kind of failure
3115 on the read */
3116 status = hdw->ctl_read_urb->status;
3117 if (!probe_fl) {
3118 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3119 "control-read URB failure,"
3120 " status=%d",
3121 status);
3122 }
3123 goto done;
3124 }
3125 if (hdw->ctl_read_urb->actual_length < read_len) {
3126 /* Failed to read enough data */
3127 status = -EIO;
3128 if (!probe_fl) {
3129 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3130 "control-read URB short,"
3131 " expected=%d got=%d",
3132 read_len,
3133 hdw->ctl_read_urb->actual_length);
3134 }
3135 goto done;
3136 }
3137 /* Transfer retrieved data out from internal buffer */
3138 for (idx = 0; idx < read_len; idx++) {
3139 ((unsigned char *)read_data)[idx] =
3140 hdw->ctl_read_buffer[idx];
3141 }
3142 }
3143
3144 done:
3145
3146 hdw->cmd_debug_state = 0;
3147 if ((status < 0) && (!probe_fl)) {
Mike Isely681c7392007-11-26 01:48:52 -03003148 pvr2_hdw_render_useless(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03003149 }
3150 return status;
3151}
3152
3153
3154int pvr2_send_request(struct pvr2_hdw *hdw,
3155 void *write_data,unsigned int write_len,
3156 void *read_data,unsigned int read_len)
3157{
3158 return pvr2_send_request_ex(hdw,HZ*4,0,
3159 write_data,write_len,
3160 read_data,read_len);
3161}
3162
Mike Isely1c9d10d2008-03-28 05:38:54 -03003163
3164static int pvr2_issue_simple_cmd(struct pvr2_hdw *hdw,u32 cmdcode)
3165{
3166 int ret;
3167 unsigned int cnt = 1;
3168 unsigned int args = 0;
3169 LOCK_TAKE(hdw->ctl_lock);
3170 hdw->cmd_buffer[0] = cmdcode & 0xffu;
3171 args = (cmdcode >> 8) & 0xffu;
3172 args = (args > 2) ? 2 : args;
3173 if (args) {
3174 cnt += args;
3175 hdw->cmd_buffer[1] = (cmdcode >> 16) & 0xffu;
3176 if (args > 1) {
3177 hdw->cmd_buffer[2] = (cmdcode >> 24) & 0xffu;
3178 }
3179 }
3180 if (pvrusb2_debug & PVR2_TRACE_INIT) {
3181 unsigned int idx;
3182 unsigned int ccnt,bcnt;
3183 char tbuf[50];
3184 cmdcode &= 0xffu;
3185 bcnt = 0;
3186 ccnt = scnprintf(tbuf+bcnt,
3187 sizeof(tbuf)-bcnt,
3188 "Sending FX2 command 0x%x",cmdcode);
3189 bcnt += ccnt;
3190 for (idx = 0; idx < ARRAY_SIZE(pvr2_fx2cmd_desc); idx++) {
3191 if (pvr2_fx2cmd_desc[idx].id == cmdcode) {
3192 ccnt = scnprintf(tbuf+bcnt,
3193 sizeof(tbuf)-bcnt,
3194 " \"%s\"",
3195 pvr2_fx2cmd_desc[idx].desc);
3196 bcnt += ccnt;
3197 break;
3198 }
3199 }
3200 if (args) {
3201 ccnt = scnprintf(tbuf+bcnt,
3202 sizeof(tbuf)-bcnt,
3203 " (%u",hdw->cmd_buffer[1]);
3204 bcnt += ccnt;
3205 if (args > 1) {
3206 ccnt = scnprintf(tbuf+bcnt,
3207 sizeof(tbuf)-bcnt,
3208 ",%u",hdw->cmd_buffer[2]);
3209 bcnt += ccnt;
3210 }
3211 ccnt = scnprintf(tbuf+bcnt,
3212 sizeof(tbuf)-bcnt,
3213 ")");
3214 bcnt += ccnt;
3215 }
3216 pvr2_trace(PVR2_TRACE_INIT,"%.*s",bcnt,tbuf);
3217 }
3218 ret = pvr2_send_request(hdw,hdw->cmd_buffer,cnt,NULL,0);
3219 LOCK_GIVE(hdw->ctl_lock);
3220 return ret;
3221}
3222
3223
Mike Iselyd8554972006-06-26 20:58:46 -03003224int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
3225{
3226 int ret;
3227
3228 LOCK_TAKE(hdw->ctl_lock);
3229
Michael Krufky8d364362007-01-22 02:17:55 -03003230 hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03003231 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
3232 hdw->cmd_buffer[5] = 0;
3233 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3234 hdw->cmd_buffer[7] = reg & 0xff;
3235
3236
3237 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
3238
3239 LOCK_GIVE(hdw->ctl_lock);
3240
3241 return ret;
3242}
3243
3244
Adrian Bunk07e337e2006-06-30 11:30:20 -03003245static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03003246{
3247 int ret = 0;
3248
3249 LOCK_TAKE(hdw->ctl_lock);
3250
Michael Krufky8d364362007-01-22 02:17:55 -03003251 hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03003252 hdw->cmd_buffer[1] = 0;
3253 hdw->cmd_buffer[2] = 0;
3254 hdw->cmd_buffer[3] = 0;
3255 hdw->cmd_buffer[4] = 0;
3256 hdw->cmd_buffer[5] = 0;
3257 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3258 hdw->cmd_buffer[7] = reg & 0xff;
3259
3260 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
3261 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
3262
3263 LOCK_GIVE(hdw->ctl_lock);
3264
3265 return ret;
3266}
3267
3268
Mike Isely681c7392007-11-26 01:48:52 -03003269void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003270{
3271 if (!hdw->flag_ok) return;
Mike Isely681c7392007-11-26 01:48:52 -03003272 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3273 "Device being rendered inoperable");
Mike Iselyd8554972006-06-26 20:58:46 -03003274 if (hdw->vid_stream) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003275 pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003276 }
Mike Isely681c7392007-11-26 01:48:52 -03003277 hdw->flag_ok = 0;
3278 trace_stbit("flag_ok",hdw->flag_ok);
3279 pvr2_hdw_state_sched(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03003280}
3281
3282
3283void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
3284{
3285 int ret;
3286 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003287 ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -03003288 if (ret == 1) {
3289 ret = usb_reset_device(hdw->usb_dev);
3290 usb_unlock_device(hdw->usb_dev);
3291 } else {
3292 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3293 "Failed to lock USB device ret=%d",ret);
3294 }
3295 if (init_pause_msec) {
3296 pvr2_trace(PVR2_TRACE_INFO,
3297 "Waiting %u msec for hardware to settle",
3298 init_pause_msec);
3299 msleep(init_pause_msec);
3300 }
3301
3302}
3303
3304
3305void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
3306{
3307 char da[1];
3308 unsigned int pipe;
3309 int ret;
3310
3311 if (!hdw->usb_dev) return;
3312
3313 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
3314
3315 da[0] = val ? 0x01 : 0x00;
3316
3317 /* Write the CPUCS register on the 8051. The lsb of the register
3318 is the reset bit; a 1 asserts reset while a 0 clears it. */
3319 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
3320 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
3321 if (ret < 0) {
3322 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3323 "cpureset_assert(%d) error=%d",val,ret);
3324 pvr2_hdw_render_useless(hdw);
3325 }
3326}
3327
3328
3329int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
3330{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003331 return pvr2_issue_simple_cmd(hdw,FX2CMD_DEEP_RESET);
Mike Iselyd8554972006-06-26 20:58:46 -03003332}
3333
3334
Michael Krufkye1edb192008-04-22 14:45:39 -03003335int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
3336{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003337 return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_ON);
Michael Krufkye1edb192008-04-22 14:45:39 -03003338}
3339
Mike Isely1c9d10d2008-03-28 05:38:54 -03003340
Michael Krufkye1edb192008-04-22 14:45:39 -03003341int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw)
3342{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003343 return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_OFF);
Michael Krufkye1edb192008-04-22 14:45:39 -03003344}
3345
Mike Iselyd8554972006-06-26 20:58:46 -03003346
3347int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
3348{
3349 if (!hdw->decoder_ctrl) {
3350 pvr2_trace(PVR2_TRACE_INIT,
3351 "Unable to reset decoder: nothing attached");
3352 return -ENOTTY;
3353 }
3354
3355 if (!hdw->decoder_ctrl->force_reset) {
3356 pvr2_trace(PVR2_TRACE_INIT,
3357 "Unable to reset decoder: not implemented");
3358 return -ENOTTY;
3359 }
3360
3361 pvr2_trace(PVR2_TRACE_INIT,
3362 "Requesting decoder reset");
3363 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
3364 return 0;
3365}
3366
3367
Mike Isely62433e32008-04-22 14:45:40 -03003368static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
Mike Isely84147f32008-04-22 14:45:40 -03003369{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003370 hdw->flag_ok = !0;
3371 return pvr2_issue_simple_cmd(hdw,
3372 FX2CMD_HCW_DEMOD_RESETIN |
3373 (1 << 8) |
3374 ((onoff ? 1 : 0) << 16));
Mike Isely84147f32008-04-22 14:45:40 -03003375}
3376
Mike Isely84147f32008-04-22 14:45:40 -03003377
Mike Isely62433e32008-04-22 14:45:40 -03003378static int pvr2_hdw_cmd_onair_fe_power_ctrl(struct pvr2_hdw *hdw, int onoff)
Mike Isely84147f32008-04-22 14:45:40 -03003379{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003380 hdw->flag_ok = !0;
3381 return pvr2_issue_simple_cmd(hdw,(onoff ?
3382 FX2CMD_ONAIR_DTV_POWER_ON :
3383 FX2CMD_ONAIR_DTV_POWER_OFF));
Mike Isely84147f32008-04-22 14:45:40 -03003384}
3385
Mike Isely62433e32008-04-22 14:45:40 -03003386
3387static int pvr2_hdw_cmd_onair_digital_path_ctrl(struct pvr2_hdw *hdw,
3388 int onoff)
Mike Isely84147f32008-04-22 14:45:40 -03003389{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003390 return pvr2_issue_simple_cmd(hdw,(onoff ?
3391 FX2CMD_ONAIR_DTV_STREAMING_ON :
3392 FX2CMD_ONAIR_DTV_STREAMING_OFF));
Mike Isely84147f32008-04-22 14:45:40 -03003393}
3394
Mike Isely62433e32008-04-22 14:45:40 -03003395
3396static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl)
3397{
3398 int cmode;
3399 /* Compare digital/analog desired setting with current setting. If
3400 they don't match, fix it... */
3401 cmode = (digitalFl ? PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG);
3402 if (cmode == hdw->pathway_state) {
3403 /* They match; nothing to do */
3404 return;
3405 }
3406
3407 switch (hdw->hdw_desc->digital_control_scheme) {
3408 case PVR2_DIGITAL_SCHEME_HAUPPAUGE:
3409 pvr2_hdw_cmd_hcw_demod_reset(hdw,digitalFl);
3410 if (cmode == PVR2_PATHWAY_ANALOG) {
3411 /* If moving to analog mode, also force the decoder
3412 to reset. If no decoder is attached, then it's
3413 ok to ignore this because if/when the decoder
3414 attaches, it will reset itself at that time. */
3415 pvr2_hdw_cmd_decoder_reset(hdw);
3416 }
3417 break;
3418 case PVR2_DIGITAL_SCHEME_ONAIR:
3419 /* Supposedly we should always have the power on whether in
3420 digital or analog mode. But for now do what appears to
3421 work... */
Mike Iselybb0c2fe2008-03-28 05:41:19 -03003422 pvr2_hdw_cmd_onair_fe_power_ctrl(hdw,digitalFl);
Mike Isely62433e32008-04-22 14:45:40 -03003423 break;
3424 default: break;
3425 }
3426
Mike Isely1b9c18c2008-04-22 14:45:41 -03003427 pvr2_hdw_untrip_unlocked(hdw);
Mike Isely62433e32008-04-22 14:45:40 -03003428 hdw->pathway_state = cmode;
3429}
3430
3431
Adrian Bunke9b59f62008-05-10 04:35:24 -03003432static void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff)
Mike Iselyc55a97d2008-04-22 14:45:41 -03003433{
3434 /* change some GPIO data
3435 *
3436 * note: bit d7 of dir appears to control the LED,
3437 * so we shut it off here.
3438 *
Mike Iselyc55a97d2008-04-22 14:45:41 -03003439 */
Mike Isely40381cb2008-04-22 14:45:42 -03003440 if (onoff) {
Mike Iselyc55a97d2008-04-22 14:45:41 -03003441 pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000481);
Mike Isely40381cb2008-04-22 14:45:42 -03003442 } else {
Mike Iselyc55a97d2008-04-22 14:45:41 -03003443 pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000401);
Mike Isely40381cb2008-04-22 14:45:42 -03003444 }
Mike Iselyc55a97d2008-04-22 14:45:41 -03003445 pvr2_hdw_gpio_chg_out(hdw, 0xffffffff, 0x00000000);
Mike Isely40381cb2008-04-22 14:45:42 -03003446}
Mike Iselyc55a97d2008-04-22 14:45:41 -03003447
Mike Isely40381cb2008-04-22 14:45:42 -03003448
3449typedef void (*led_method_func)(struct pvr2_hdw *,int);
3450
3451static led_method_func led_methods[] = {
3452 [PVR2_LED_SCHEME_HAUPPAUGE] = pvr2_led_ctrl_hauppauge,
3453};
3454
3455
3456/* Toggle LED */
3457static void pvr2_led_ctrl(struct pvr2_hdw *hdw,int onoff)
3458{
3459 unsigned int scheme_id;
3460 led_method_func fp;
3461
3462 if ((!onoff) == (!hdw->led_on)) return;
3463
3464 hdw->led_on = onoff != 0;
3465
3466 scheme_id = hdw->hdw_desc->led_scheme;
3467 if (scheme_id < ARRAY_SIZE(led_methods)) {
3468 fp = led_methods[scheme_id];
3469 } else {
3470 fp = NULL;
3471 }
3472
3473 if (fp) (*fp)(hdw,onoff);
Mike Iselyc55a97d2008-04-22 14:45:41 -03003474}
3475
3476
Mike Iselye61b6fc2006-07-18 22:42:18 -03003477/* Stop / start video stream transport */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003478static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03003479{
Mike Iselybb0c2fe2008-03-28 05:41:19 -03003480 int ret;
3481
3482 /* If we're in analog mode, then just issue the usual analog
3483 command. */
3484 if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
3485 return pvr2_issue_simple_cmd(hdw,
3486 (runFl ?
3487 FX2CMD_STREAMING_ON :
3488 FX2CMD_STREAMING_OFF));
3489 /*Note: Not reached */
Mike Isely62433e32008-04-22 14:45:40 -03003490 }
Mike Iselybb0c2fe2008-03-28 05:41:19 -03003491
3492 if (hdw->pathway_state != PVR2_PATHWAY_DIGITAL) {
3493 /* Whoops, we don't know what mode we're in... */
3494 return -EINVAL;
3495 }
3496
3497 /* To get here we have to be in digital mode. The mechanism here
3498 is unfortunately different for different vendors. So we switch
3499 on the device's digital scheme attribute in order to figure out
3500 what to do. */
3501 switch (hdw->hdw_desc->digital_control_scheme) {
3502 case PVR2_DIGITAL_SCHEME_HAUPPAUGE:
3503 return pvr2_issue_simple_cmd(hdw,
3504 (runFl ?
3505 FX2CMD_HCW_DTV_STREAMING_ON :
3506 FX2CMD_HCW_DTV_STREAMING_OFF));
3507 case PVR2_DIGITAL_SCHEME_ONAIR:
3508 ret = pvr2_issue_simple_cmd(hdw,
3509 (runFl ?
3510 FX2CMD_STREAMING_ON :
3511 FX2CMD_STREAMING_OFF));
3512 if (ret) return ret;
3513 return pvr2_hdw_cmd_onair_digital_path_ctrl(hdw,runFl);
3514 default:
3515 return -EINVAL;
3516 }
Mike Iselyd8554972006-06-26 20:58:46 -03003517}
3518
3519
Mike Isely62433e32008-04-22 14:45:40 -03003520/* Evaluate whether or not state_pathway_ok can change */
3521static int state_eval_pathway_ok(struct pvr2_hdw *hdw)
3522{
3523 if (hdw->state_pathway_ok) {
3524 /* Nothing to do if pathway is already ok */
3525 return 0;
3526 }
3527 if (!hdw->state_pipeline_idle) {
3528 /* Not allowed to change anything if pipeline is not idle */
3529 return 0;
3530 }
3531 pvr2_hdw_cmd_modeswitch(hdw,hdw->input_val == PVR2_CVAL_INPUT_DTV);
3532 hdw->state_pathway_ok = !0;
Mike Iselye9db1ff2008-04-22 14:45:41 -03003533 trace_stbit("state_pathway_ok",hdw->state_pathway_ok);
Mike Isely62433e32008-04-22 14:45:40 -03003534 return !0;
3535}
3536
3537
Mike Isely681c7392007-11-26 01:48:52 -03003538/* Evaluate whether or not state_encoder_ok can change */
3539static int state_eval_encoder_ok(struct pvr2_hdw *hdw)
3540{
3541 if (hdw->state_encoder_ok) return 0;
3542 if (hdw->flag_tripped) return 0;
3543 if (hdw->state_encoder_run) return 0;
3544 if (hdw->state_encoder_config) return 0;
3545 if (hdw->state_decoder_run) return 0;
3546 if (hdw->state_usbstream_run) return 0;
Mike Isely72998b72008-04-03 04:51:19 -03003547 if (hdw->pathway_state == PVR2_PATHWAY_DIGITAL) {
3548 if (!hdw->hdw_desc->flag_digital_requires_cx23416) return 0;
3549 } else if (hdw->pathway_state != PVR2_PATHWAY_ANALOG) {
3550 return 0;
3551 }
3552
Mike Isely681c7392007-11-26 01:48:52 -03003553 if (pvr2_upload_firmware2(hdw) < 0) {
3554 hdw->flag_tripped = !0;
3555 trace_stbit("flag_tripped",hdw->flag_tripped);
3556 return !0;
3557 }
3558 hdw->state_encoder_ok = !0;
3559 trace_stbit("state_encoder_ok",hdw->state_encoder_ok);
3560 return !0;
3561}
3562
3563
3564/* Evaluate whether or not state_encoder_config can change */
3565static int state_eval_encoder_config(struct pvr2_hdw *hdw)
3566{
3567 if (hdw->state_encoder_config) {
3568 if (hdw->state_encoder_ok) {
3569 if (hdw->state_pipeline_req &&
3570 !hdw->state_pipeline_pause) return 0;
3571 }
3572 hdw->state_encoder_config = 0;
3573 hdw->state_encoder_waitok = 0;
3574 trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
3575 /* paranoia - solve race if timer just completed */
3576 del_timer_sync(&hdw->encoder_wait_timer);
3577 } else {
Mike Isely62433e32008-04-22 14:45:40 -03003578 if (!hdw->state_pathway_ok ||
3579 (hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
3580 !hdw->state_encoder_ok ||
Mike Isely681c7392007-11-26 01:48:52 -03003581 !hdw->state_pipeline_idle ||
3582 hdw->state_pipeline_pause ||
3583 !hdw->state_pipeline_req ||
3584 !hdw->state_pipeline_config) {
3585 /* We must reset the enforced wait interval if
3586 anything has happened that might have disturbed
3587 the encoder. This should be a rare case. */
3588 if (timer_pending(&hdw->encoder_wait_timer)) {
3589 del_timer_sync(&hdw->encoder_wait_timer);
3590 }
3591 if (hdw->state_encoder_waitok) {
3592 /* Must clear the state - therefore we did
3593 something to a state bit and must also
3594 return true. */
3595 hdw->state_encoder_waitok = 0;
3596 trace_stbit("state_encoder_waitok",
3597 hdw->state_encoder_waitok);
3598 return !0;
3599 }
3600 return 0;
3601 }
3602 if (!hdw->state_encoder_waitok) {
3603 if (!timer_pending(&hdw->encoder_wait_timer)) {
3604 /* waitok flag wasn't set and timer isn't
3605 running. Check flag once more to avoid
3606 a race then start the timer. This is
3607 the point when we measure out a minimal
3608 quiet interval before doing something to
3609 the encoder. */
3610 if (!hdw->state_encoder_waitok) {
3611 hdw->encoder_wait_timer.expires =
3612 jiffies + (HZ*50/1000);
3613 add_timer(&hdw->encoder_wait_timer);
3614 }
3615 }
3616 /* We can't continue until we know we have been
3617 quiet for the interval measured by this
3618 timer. */
3619 return 0;
3620 }
3621 pvr2_encoder_configure(hdw);
3622 if (hdw->state_encoder_ok) hdw->state_encoder_config = !0;
3623 }
3624 trace_stbit("state_encoder_config",hdw->state_encoder_config);
3625 return !0;
3626}
3627
3628
Mike Iselyd913d632008-04-06 04:04:35 -03003629/* Return true if the encoder should not be running. */
3630static int state_check_disable_encoder_run(struct pvr2_hdw *hdw)
3631{
3632 if (!hdw->state_encoder_ok) {
3633 /* Encoder isn't healthy at the moment, so stop it. */
3634 return !0;
3635 }
3636 if (!hdw->state_pathway_ok) {
3637 /* Mode is not understood at the moment (i.e. it wants to
3638 change), so encoder must be stopped. */
3639 return !0;
3640 }
3641
3642 switch (hdw->pathway_state) {
3643 case PVR2_PATHWAY_ANALOG:
3644 if (!hdw->state_decoder_run) {
3645 /* We're in analog mode and the decoder is not
3646 running; thus the encoder should be stopped as
3647 well. */
3648 return !0;
3649 }
3650 break;
3651 case PVR2_PATHWAY_DIGITAL:
3652 if (hdw->state_encoder_runok) {
3653 /* This is a funny case. We're in digital mode so
3654 really the encoder should be stopped. However
3655 if it really is running, only kill it after
3656 runok has been set. This gives a chance for the
3657 onair quirk to function (encoder must run
3658 briefly first, at least once, before onair
3659 digital streaming can work). */
3660 return !0;
3661 }
3662 break;
3663 default:
3664 /* Unknown mode; so encoder should be stopped. */
3665 return !0;
3666 }
3667
3668 /* If we get here, we haven't found a reason to stop the
3669 encoder. */
3670 return 0;
3671}
3672
3673
3674/* Return true if the encoder should be running. */
3675static int state_check_enable_encoder_run(struct pvr2_hdw *hdw)
3676{
3677 if (!hdw->state_encoder_ok) {
3678 /* Don't run the encoder if it isn't healthy... */
3679 return 0;
3680 }
3681 if (!hdw->state_pathway_ok) {
3682 /* Don't run the encoder if we don't (yet) know what mode
3683 we need to be in... */
3684 return 0;
3685 }
3686
3687 switch (hdw->pathway_state) {
3688 case PVR2_PATHWAY_ANALOG:
3689 if (hdw->state_decoder_run) {
3690 /* In analog mode, if the decoder is running, then
3691 run the encoder. */
3692 return !0;
3693 }
3694 break;
3695 case PVR2_PATHWAY_DIGITAL:
3696 if ((hdw->hdw_desc->digital_control_scheme ==
3697 PVR2_DIGITAL_SCHEME_ONAIR) &&
3698 !hdw->state_encoder_runok) {
3699 /* This is a quirk. OnAir hardware won't stream
3700 digital until the encoder has been run at least
3701 once, for a minimal period of time (empiricially
3702 measured to be 1/4 second). So if we're on
3703 OnAir hardware and the encoder has never been
3704 run at all, then start the encoder. Normal
3705 state machine logic in the driver will
3706 automatically handle the remaining bits. */
3707 return !0;
3708 }
3709 break;
3710 default:
3711 /* For completeness (unknown mode; encoder won't run ever) */
3712 break;
3713 }
3714 /* If we get here, then we haven't found any reason to run the
3715 encoder, so don't run it. */
3716 return 0;
3717}
3718
3719
Mike Isely681c7392007-11-26 01:48:52 -03003720/* Evaluate whether or not state_encoder_run can change */
3721static int state_eval_encoder_run(struct pvr2_hdw *hdw)
3722{
3723 if (hdw->state_encoder_run) {
Mike Iselyd913d632008-04-06 04:04:35 -03003724 if (!state_check_disable_encoder_run(hdw)) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003725 if (hdw->state_encoder_ok) {
Mike Iselyd913d632008-04-06 04:04:35 -03003726 del_timer_sync(&hdw->encoder_run_timer);
Mike Isely681c7392007-11-26 01:48:52 -03003727 if (pvr2_encoder_stop(hdw) < 0) return !0;
3728 }
3729 hdw->state_encoder_run = 0;
3730 } else {
Mike Iselyd913d632008-04-06 04:04:35 -03003731 if (!state_check_enable_encoder_run(hdw)) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003732 if (pvr2_encoder_start(hdw) < 0) return !0;
3733 hdw->state_encoder_run = !0;
Mike Iselyd913d632008-04-06 04:04:35 -03003734 if (!hdw->state_encoder_runok) {
3735 hdw->encoder_run_timer.expires =
3736 jiffies + (HZ*250/1000);
3737 add_timer(&hdw->encoder_run_timer);
3738 }
Mike Isely681c7392007-11-26 01:48:52 -03003739 }
3740 trace_stbit("state_encoder_run",hdw->state_encoder_run);
3741 return !0;
3742}
3743
3744
3745/* Timeout function for quiescent timer. */
3746static void pvr2_hdw_quiescent_timeout(unsigned long data)
3747{
3748 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
3749 hdw->state_decoder_quiescent = !0;
3750 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
3751 hdw->state_stale = !0;
3752 queue_work(hdw->workqueue,&hdw->workpoll);
3753}
3754
3755
3756/* Timeout function for encoder wait timer. */
3757static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
3758{
3759 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
3760 hdw->state_encoder_waitok = !0;
3761 trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
3762 hdw->state_stale = !0;
3763 queue_work(hdw->workqueue,&hdw->workpoll);
3764}
3765
3766
Mike Iselyd913d632008-04-06 04:04:35 -03003767/* Timeout function for encoder run timer. */
3768static void pvr2_hdw_encoder_run_timeout(unsigned long data)
3769{
3770 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
3771 if (!hdw->state_encoder_runok) {
3772 hdw->state_encoder_runok = !0;
3773 trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
3774 hdw->state_stale = !0;
3775 queue_work(hdw->workqueue,&hdw->workpoll);
3776 }
3777}
3778
3779
Mike Isely681c7392007-11-26 01:48:52 -03003780/* Evaluate whether or not state_decoder_run can change */
3781static int state_eval_decoder_run(struct pvr2_hdw *hdw)
3782{
3783 if (hdw->state_decoder_run) {
3784 if (hdw->state_encoder_ok) {
3785 if (hdw->state_pipeline_req &&
Mike Isely62433e32008-04-22 14:45:40 -03003786 !hdw->state_pipeline_pause &&
3787 hdw->state_pathway_ok) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003788 }
3789 if (!hdw->flag_decoder_missed) {
3790 pvr2_decoder_enable(hdw,0);
3791 }
3792 hdw->state_decoder_quiescent = 0;
3793 hdw->state_decoder_run = 0;
3794 /* paranoia - solve race if timer just completed */
3795 del_timer_sync(&hdw->quiescent_timer);
3796 } else {
3797 if (!hdw->state_decoder_quiescent) {
3798 if (!timer_pending(&hdw->quiescent_timer)) {
3799 /* We don't do something about the
3800 quiescent timer until right here because
3801 we also want to catch cases where the
3802 decoder was already not running (like
3803 after initialization) as opposed to
3804 knowing that we had just stopped it.
3805 The second flag check is here to cover a
3806 race - the timer could have run and set
3807 this flag just after the previous check
3808 but before we did the pending check. */
3809 if (!hdw->state_decoder_quiescent) {
3810 hdw->quiescent_timer.expires =
3811 jiffies + (HZ*50/1000);
3812 add_timer(&hdw->quiescent_timer);
3813 }
3814 }
3815 /* Don't allow decoder to start again until it has
3816 been quiesced first. This little detail should
3817 hopefully further stabilize the encoder. */
3818 return 0;
3819 }
Mike Isely62433e32008-04-22 14:45:40 -03003820 if (!hdw->state_pathway_ok ||
3821 (hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
3822 !hdw->state_pipeline_req ||
Mike Isely681c7392007-11-26 01:48:52 -03003823 hdw->state_pipeline_pause ||
3824 !hdw->state_pipeline_config ||
3825 !hdw->state_encoder_config ||
3826 !hdw->state_encoder_ok) return 0;
3827 del_timer_sync(&hdw->quiescent_timer);
3828 if (hdw->flag_decoder_missed) return 0;
3829 if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
3830 hdw->state_decoder_quiescent = 0;
3831 hdw->state_decoder_run = !0;
3832 }
3833 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
3834 trace_stbit("state_decoder_run",hdw->state_decoder_run);
3835 return !0;
3836}
3837
3838
3839/* Evaluate whether or not state_usbstream_run can change */
3840static int state_eval_usbstream_run(struct pvr2_hdw *hdw)
3841{
3842 if (hdw->state_usbstream_run) {
Mike Isely72998b72008-04-03 04:51:19 -03003843 int fl = !0;
Mike Isely62433e32008-04-22 14:45:40 -03003844 if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
Mike Isely72998b72008-04-03 04:51:19 -03003845 fl = (hdw->state_encoder_ok &&
3846 hdw->state_encoder_run);
3847 } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
3848 (hdw->hdw_desc->flag_digital_requires_cx23416)) {
3849 fl = hdw->state_encoder_ok;
3850 }
3851 if (fl &&
3852 hdw->state_pipeline_req &&
3853 !hdw->state_pipeline_pause &&
3854 hdw->state_pathway_ok) {
3855 return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003856 }
3857 pvr2_hdw_cmd_usbstream(hdw,0);
3858 hdw->state_usbstream_run = 0;
3859 } else {
Mike Isely62433e32008-04-22 14:45:40 -03003860 if (!hdw->state_pipeline_req ||
3861 hdw->state_pipeline_pause ||
3862 !hdw->state_pathway_ok) return 0;
3863 if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
3864 if (!hdw->state_encoder_ok ||
3865 !hdw->state_encoder_run) return 0;
Mike Isely72998b72008-04-03 04:51:19 -03003866 } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
3867 (hdw->hdw_desc->flag_digital_requires_cx23416)) {
3868 if (!hdw->state_encoder_ok) return 0;
Mike Iselyd913d632008-04-06 04:04:35 -03003869 if (hdw->state_encoder_run) return 0;
3870 if (hdw->hdw_desc->digital_control_scheme ==
3871 PVR2_DIGITAL_SCHEME_ONAIR) {
3872 /* OnAir digital receivers won't stream
3873 unless the analog encoder has run first.
3874 Why? I have no idea. But don't even
3875 try until we know the analog side is
3876 known to have run. */
3877 if (!hdw->state_encoder_runok) return 0;
3878 }
Mike Isely62433e32008-04-22 14:45:40 -03003879 }
Mike Isely681c7392007-11-26 01:48:52 -03003880 if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0;
3881 hdw->state_usbstream_run = !0;
3882 }
3883 trace_stbit("state_usbstream_run",hdw->state_usbstream_run);
3884 return !0;
3885}
3886
3887
3888/* Attempt to configure pipeline, if needed */
3889static int state_eval_pipeline_config(struct pvr2_hdw *hdw)
3890{
3891 if (hdw->state_pipeline_config ||
3892 hdw->state_pipeline_pause) return 0;
3893 pvr2_hdw_commit_execute(hdw);
3894 return !0;
3895}
3896
3897
3898/* Update pipeline idle and pipeline pause tracking states based on other
3899 inputs. This must be called whenever the other relevant inputs have
3900 changed. */
3901static int state_update_pipeline_state(struct pvr2_hdw *hdw)
3902{
3903 unsigned int st;
3904 int updatedFl = 0;
3905 /* Update pipeline state */
3906 st = !(hdw->state_encoder_run ||
3907 hdw->state_decoder_run ||
3908 hdw->state_usbstream_run ||
3909 (!hdw->state_decoder_quiescent));
3910 if (!st != !hdw->state_pipeline_idle) {
3911 hdw->state_pipeline_idle = st;
3912 updatedFl = !0;
3913 }
3914 if (hdw->state_pipeline_idle && hdw->state_pipeline_pause) {
3915 hdw->state_pipeline_pause = 0;
3916 updatedFl = !0;
3917 }
3918 return updatedFl;
3919}
3920
3921
3922typedef int (*state_eval_func)(struct pvr2_hdw *);
3923
3924/* Set of functions to be run to evaluate various states in the driver. */
Tobias Klauserebff0332008-04-22 14:45:45 -03003925static const state_eval_func eval_funcs[] = {
Mike Isely62433e32008-04-22 14:45:40 -03003926 state_eval_pathway_ok,
Mike Isely681c7392007-11-26 01:48:52 -03003927 state_eval_pipeline_config,
3928 state_eval_encoder_ok,
3929 state_eval_encoder_config,
3930 state_eval_decoder_run,
3931 state_eval_encoder_run,
3932 state_eval_usbstream_run,
3933};
3934
3935
3936/* Process various states and return true if we did anything interesting. */
3937static int pvr2_hdw_state_update(struct pvr2_hdw *hdw)
3938{
3939 unsigned int i;
3940 int state_updated = 0;
3941 int check_flag;
3942
3943 if (!hdw->state_stale) return 0;
3944 if ((hdw->fw1_state != FW1_STATE_OK) ||
3945 !hdw->flag_ok) {
3946 hdw->state_stale = 0;
3947 return !0;
3948 }
3949 /* This loop is the heart of the entire driver. It keeps trying to
3950 evaluate various bits of driver state until nothing changes for
3951 one full iteration. Each "bit of state" tracks some global
3952 aspect of the driver, e.g. whether decoder should run, if
3953 pipeline is configured, usb streaming is on, etc. We separately
3954 evaluate each of those questions based on other driver state to
3955 arrive at the correct running configuration. */
3956 do {
3957 check_flag = 0;
3958 state_update_pipeline_state(hdw);
3959 /* Iterate over each bit of state */
3960 for (i = 0; (i<ARRAY_SIZE(eval_funcs)) && hdw->flag_ok; i++) {
3961 if ((*eval_funcs[i])(hdw)) {
3962 check_flag = !0;
3963 state_updated = !0;
3964 state_update_pipeline_state(hdw);
3965 }
3966 }
3967 } while (check_flag && hdw->flag_ok);
3968 hdw->state_stale = 0;
3969 trace_stbit("state_stale",hdw->state_stale);
3970 return state_updated;
3971}
3972
3973
Mike Isely1cb03b72008-04-21 03:47:43 -03003974static unsigned int print_input_mask(unsigned int msk,
3975 char *buf,unsigned int acnt)
3976{
3977 unsigned int idx,ccnt;
3978 unsigned int tcnt = 0;
3979 for (idx = 0; idx < ARRAY_SIZE(control_values_input); idx++) {
3980 if (!((1 << idx) & msk)) continue;
3981 ccnt = scnprintf(buf+tcnt,
3982 acnt-tcnt,
3983 "%s%s",
3984 (tcnt ? ", " : ""),
3985 control_values_input[idx]);
3986 tcnt += ccnt;
3987 }
3988 return tcnt;
3989}
3990
3991
Mike Isely62433e32008-04-22 14:45:40 -03003992static const char *pvr2_pathway_state_name(int id)
3993{
3994 switch (id) {
3995 case PVR2_PATHWAY_ANALOG: return "analog";
3996 case PVR2_PATHWAY_DIGITAL: return "digital";
3997 default: return "unknown";
3998 }
3999}
4000
4001
Mike Isely681c7392007-11-26 01:48:52 -03004002static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
4003 char *buf,unsigned int acnt)
4004{
4005 switch (which) {
4006 case 0:
4007 return scnprintf(
4008 buf,acnt,
Mike Iselye9db1ff2008-04-22 14:45:41 -03004009 "driver:%s%s%s%s%s <mode=%s>",
Mike Isely681c7392007-11-26 01:48:52 -03004010 (hdw->flag_ok ? " <ok>" : " <fail>"),
4011 (hdw->flag_init_ok ? " <init>" : " <uninitialized>"),
4012 (hdw->flag_disconnected ? " <disconnected>" :
4013 " <connected>"),
4014 (hdw->flag_tripped ? " <tripped>" : ""),
Mike Isely62433e32008-04-22 14:45:40 -03004015 (hdw->flag_decoder_missed ? " <no decoder>" : ""),
4016 pvr2_pathway_state_name(hdw->pathway_state));
4017
Mike Isely681c7392007-11-26 01:48:52 -03004018 case 1:
4019 return scnprintf(
4020 buf,acnt,
4021 "pipeline:%s%s%s%s",
4022 (hdw->state_pipeline_idle ? " <idle>" : ""),
4023 (hdw->state_pipeline_config ?
4024 " <configok>" : " <stale>"),
4025 (hdw->state_pipeline_req ? " <req>" : ""),
4026 (hdw->state_pipeline_pause ? " <pause>" : ""));
4027 case 2:
4028 return scnprintf(
4029 buf,acnt,
Mike Isely62433e32008-04-22 14:45:40 -03004030 "worker:%s%s%s%s%s%s%s",
Mike Isely681c7392007-11-26 01:48:52 -03004031 (hdw->state_decoder_run ?
4032 " <decode:run>" :
4033 (hdw->state_decoder_quiescent ?
4034 "" : " <decode:stop>")),
4035 (hdw->state_decoder_quiescent ?
4036 " <decode:quiescent>" : ""),
4037 (hdw->state_encoder_ok ?
4038 "" : " <encode:init>"),
4039 (hdw->state_encoder_run ?
Mike Iselyd913d632008-04-06 04:04:35 -03004040 (hdw->state_encoder_runok ?
4041 " <encode:run>" :
4042 " <encode:firstrun>") :
4043 (hdw->state_encoder_runok ?
4044 " <encode:stop>" :
4045 " <encode:virgin>")),
Mike Isely681c7392007-11-26 01:48:52 -03004046 (hdw->state_encoder_config ?
4047 " <encode:configok>" :
4048 (hdw->state_encoder_waitok ?
Mike Iselyb9a37d92008-03-28 05:31:40 -03004049 "" : " <encode:waitok>")),
Mike Isely681c7392007-11-26 01:48:52 -03004050 (hdw->state_usbstream_run ?
Mike Isely62433e32008-04-22 14:45:40 -03004051 " <usb:run>" : " <usb:stop>"),
4052 (hdw->state_pathway_ok ?
Mike Iselye9db1ff2008-04-22 14:45:41 -03004053 " <pathway:ok>" : ""));
Mike Isely681c7392007-11-26 01:48:52 -03004054 case 3:
4055 return scnprintf(
4056 buf,acnt,
4057 "state: %s",
4058 pvr2_get_state_name(hdw->master_state));
Mike Iselyad0992e2008-03-28 05:34:45 -03004059 case 4: {
Mike Isely1cb03b72008-04-21 03:47:43 -03004060 unsigned int tcnt = 0;
4061 unsigned int ccnt;
4062
4063 ccnt = scnprintf(buf,
4064 acnt,
4065 "Hardware supported inputs: ");
4066 tcnt += ccnt;
4067 tcnt += print_input_mask(hdw->input_avail_mask,
4068 buf+tcnt,
4069 acnt-tcnt);
4070 if (hdw->input_avail_mask != hdw->input_allowed_mask) {
4071 ccnt = scnprintf(buf+tcnt,
4072 acnt-tcnt,
4073 "; allowed inputs: ");
4074 tcnt += ccnt;
4075 tcnt += print_input_mask(hdw->input_allowed_mask,
4076 buf+tcnt,
4077 acnt-tcnt);
4078 }
4079 return tcnt;
4080 }
4081 case 5: {
Mike Iselyad0992e2008-03-28 05:34:45 -03004082 struct pvr2_stream_stats stats;
4083 if (!hdw->vid_stream) break;
4084 pvr2_stream_get_stats(hdw->vid_stream,
4085 &stats,
4086 0);
4087 return scnprintf(
4088 buf,acnt,
4089 "Bytes streamed=%u"
4090 " URBs: queued=%u idle=%u ready=%u"
4091 " processed=%u failed=%u",
4092 stats.bytes_processed,
4093 stats.buffers_in_queue,
4094 stats.buffers_in_idle,
4095 stats.buffers_in_ready,
4096 stats.buffers_processed,
4097 stats.buffers_failed);
4098 }
Mike Isely681c7392007-11-26 01:48:52 -03004099 default: break;
4100 }
4101 return 0;
4102}
4103
4104
4105unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
4106 char *buf,unsigned int acnt)
4107{
4108 unsigned int bcnt,ccnt,idx;
4109 bcnt = 0;
4110 LOCK_TAKE(hdw->big_lock);
4111 for (idx = 0; ; idx++) {
4112 ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,acnt);
4113 if (!ccnt) break;
4114 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
4115 if (!acnt) break;
4116 buf[0] = '\n'; ccnt = 1;
4117 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
4118 }
4119 LOCK_GIVE(hdw->big_lock);
4120 return bcnt;
4121}
4122
4123
4124static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
4125{
4126 char buf[128];
4127 unsigned int idx,ccnt;
4128
4129 for (idx = 0; ; idx++) {
4130 ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
4131 if (!ccnt) break;
4132 printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
4133 }
4134}
4135
4136
4137/* Evaluate and update the driver's current state, taking various actions
4138 as appropriate for the update. */
4139static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw)
4140{
4141 unsigned int st;
4142 int state_updated = 0;
4143 int callback_flag = 0;
Mike Isely1b9c18c2008-04-22 14:45:41 -03004144 int analog_mode;
Mike Isely681c7392007-11-26 01:48:52 -03004145
4146 pvr2_trace(PVR2_TRACE_STBITS,
4147 "Drive state check START");
4148 if (pvrusb2_debug & PVR2_TRACE_STBITS) {
4149 pvr2_hdw_state_log_state(hdw);
4150 }
4151
4152 /* Process all state and get back over disposition */
4153 state_updated = pvr2_hdw_state_update(hdw);
4154
Mike Isely1b9c18c2008-04-22 14:45:41 -03004155 analog_mode = (hdw->pathway_state != PVR2_PATHWAY_DIGITAL);
4156
Mike Isely681c7392007-11-26 01:48:52 -03004157 /* Update master state based upon all other states. */
4158 if (!hdw->flag_ok) {
4159 st = PVR2_STATE_DEAD;
4160 } else if (hdw->fw1_state != FW1_STATE_OK) {
4161 st = PVR2_STATE_COLD;
Mike Isely72998b72008-04-03 04:51:19 -03004162 } else if ((analog_mode ||
4163 hdw->hdw_desc->flag_digital_requires_cx23416) &&
4164 !hdw->state_encoder_ok) {
Mike Isely681c7392007-11-26 01:48:52 -03004165 st = PVR2_STATE_WARM;
Mike Isely1b9c18c2008-04-22 14:45:41 -03004166 } else if (hdw->flag_tripped ||
4167 (analog_mode && hdw->flag_decoder_missed)) {
Mike Isely681c7392007-11-26 01:48:52 -03004168 st = PVR2_STATE_ERROR;
Mike Isely62433e32008-04-22 14:45:40 -03004169 } else if (hdw->state_usbstream_run &&
Mike Isely1b9c18c2008-04-22 14:45:41 -03004170 (!analog_mode ||
Mike Isely62433e32008-04-22 14:45:40 -03004171 (hdw->state_encoder_run && hdw->state_decoder_run))) {
Mike Isely681c7392007-11-26 01:48:52 -03004172 st = PVR2_STATE_RUN;
4173 } else {
4174 st = PVR2_STATE_READY;
4175 }
4176 if (hdw->master_state != st) {
4177 pvr2_trace(PVR2_TRACE_STATE,
4178 "Device state change from %s to %s",
4179 pvr2_get_state_name(hdw->master_state),
4180 pvr2_get_state_name(st));
Mike Isely40381cb2008-04-22 14:45:42 -03004181 pvr2_led_ctrl(hdw,st == PVR2_STATE_RUN);
Mike Isely681c7392007-11-26 01:48:52 -03004182 hdw->master_state = st;
4183 state_updated = !0;
4184 callback_flag = !0;
4185 }
4186 if (state_updated) {
4187 /* Trigger anyone waiting on any state changes here. */
4188 wake_up(&hdw->state_wait_data);
4189 }
4190
4191 if (pvrusb2_debug & PVR2_TRACE_STBITS) {
4192 pvr2_hdw_state_log_state(hdw);
4193 }
4194 pvr2_trace(PVR2_TRACE_STBITS,
4195 "Drive state check DONE callback=%d",callback_flag);
4196
4197 return callback_flag;
4198}
4199
4200
4201/* Cause kernel thread to check / update driver state */
4202static void pvr2_hdw_state_sched(struct pvr2_hdw *hdw)
4203{
4204 if (hdw->state_stale) return;
4205 hdw->state_stale = !0;
4206 trace_stbit("state_stale",hdw->state_stale);
4207 queue_work(hdw->workqueue,&hdw->workpoll);
4208}
4209
4210
Mike Iselyd8554972006-06-26 20:58:46 -03004211int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
4212{
4213 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
4214}
4215
4216
4217int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
4218{
4219 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
4220}
4221
4222
4223int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
4224{
4225 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
4226}
4227
4228
4229int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
4230{
4231 u32 cval,nval;
4232 int ret;
4233 if (~msk) {
4234 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
4235 if (ret) return ret;
4236 nval = (cval & ~msk) | (val & msk);
4237 pvr2_trace(PVR2_TRACE_GPIO,
4238 "GPIO direction changing 0x%x:0x%x"
4239 " from 0x%x to 0x%x",
4240 msk,val,cval,nval);
4241 } else {
4242 nval = val;
4243 pvr2_trace(PVR2_TRACE_GPIO,
4244 "GPIO direction changing to 0x%x",nval);
4245 }
4246 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
4247}
4248
4249
4250int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
4251{
4252 u32 cval,nval;
4253 int ret;
4254 if (~msk) {
4255 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
4256 if (ret) return ret;
4257 nval = (cval & ~msk) | (val & msk);
4258 pvr2_trace(PVR2_TRACE_GPIO,
4259 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
4260 msk,val,cval,nval);
4261 } else {
4262 nval = val;
4263 pvr2_trace(PVR2_TRACE_GPIO,
4264 "GPIO output changing to 0x%x",nval);
4265 }
4266 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
4267}
4268
4269
Mike Isely7fb20fa2008-04-22 14:45:37 -03004270unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
4271{
4272 return hdw->input_avail_mask;
4273}
4274
4275
Mike Isely1cb03b72008-04-21 03:47:43 -03004276unsigned int pvr2_hdw_get_input_allowed(struct pvr2_hdw *hdw)
4277{
4278 return hdw->input_allowed_mask;
4279}
4280
4281
4282static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v)
4283{
4284 if (hdw->input_val != v) {
4285 hdw->input_val = v;
4286 hdw->input_dirty = !0;
4287 }
4288
4289 /* Handle side effects - if we switch to a mode that needs the RF
4290 tuner, then select the right frequency choice as well and mark
4291 it dirty. */
4292 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
4293 hdw->freqSelector = 0;
4294 hdw->freqDirty = !0;
4295 } else if ((hdw->input_val == PVR2_CVAL_INPUT_TV) ||
4296 (hdw->input_val == PVR2_CVAL_INPUT_DTV)) {
4297 hdw->freqSelector = 1;
4298 hdw->freqDirty = !0;
4299 }
4300 return 0;
4301}
4302
4303
4304int pvr2_hdw_set_input_allowed(struct pvr2_hdw *hdw,
4305 unsigned int change_mask,
4306 unsigned int change_val)
4307{
4308 int ret = 0;
4309 unsigned int nv,m,idx;
4310 LOCK_TAKE(hdw->big_lock);
4311 do {
4312 nv = hdw->input_allowed_mask & ~change_mask;
4313 nv |= (change_val & change_mask);
4314 nv &= hdw->input_avail_mask;
4315 if (!nv) {
4316 /* No legal modes left; return error instead. */
4317 ret = -EPERM;
4318 break;
4319 }
4320 hdw->input_allowed_mask = nv;
4321 if ((1 << hdw->input_val) & hdw->input_allowed_mask) {
4322 /* Current mode is still in the allowed mask, so
4323 we're done. */
4324 break;
4325 }
4326 /* Select and switch to a mode that is still in the allowed
4327 mask */
4328 if (!hdw->input_allowed_mask) {
4329 /* Nothing legal; give up */
4330 break;
4331 }
4332 m = hdw->input_allowed_mask;
4333 for (idx = 0; idx < (sizeof(m) << 3); idx++) {
4334 if (!((1 << idx) & m)) continue;
4335 pvr2_hdw_set_input(hdw,idx);
4336 break;
4337 }
4338 } while (0);
4339 LOCK_GIVE(hdw->big_lock);
4340 return ret;
4341}
4342
4343
Mike Iselye61b6fc2006-07-18 22:42:18 -03004344/* Find I2C address of eeprom */
Adrian Bunk07e337e2006-06-30 11:30:20 -03004345static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03004346{
4347 int result;
4348 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03004349 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03004350 result = pvr2_send_request(hdw,
4351 hdw->cmd_buffer,1,
4352 hdw->cmd_buffer,1);
4353 if (result < 0) break;
4354 result = hdw->cmd_buffer[0];
4355 } while(0); LOCK_GIVE(hdw->ctl_lock);
4356 return result;
4357}
4358
4359
Mike Isely32ffa9a2006-09-23 22:26:52 -03004360int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
Hans Verkuilf3d092b2007-02-23 20:55:14 -03004361 u32 match_type, u32 match_chip, u64 reg_id,
4362 int setFl,u64 *val_ptr)
Mike Isely32ffa9a2006-09-23 22:26:52 -03004363{
4364#ifdef CONFIG_VIDEO_ADV_DEBUG
Mike Isely32ffa9a2006-09-23 22:26:52 -03004365 struct pvr2_i2c_client *cp;
4366 struct v4l2_register req;
Mike Isely6d988162006-09-28 17:53:49 -03004367 int stat = 0;
4368 int okFl = 0;
Mike Isely32ffa9a2006-09-23 22:26:52 -03004369
Mike Isely201f5c92007-01-28 16:08:36 -03004370 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
4371
Hans Verkuilf3d092b2007-02-23 20:55:14 -03004372 req.match_type = match_type;
4373 req.match_chip = match_chip;
Mike Isely32ffa9a2006-09-23 22:26:52 -03004374 req.reg = reg_id;
4375 if (setFl) req.val = *val_ptr;
4376 mutex_lock(&hdw->i2c_list_lock); do {
Trent Piephoe77e2c22007-10-10 05:37:42 -03004377 list_for_each_entry(cp, &hdw->i2c_clients, list) {
Mike Isely8481a752007-04-27 12:31:31 -03004378 if (!v4l2_chip_match_i2c_client(
4379 cp->client,
4380 req.match_type, req.match_chip)) {
Hans Verkuilf3d092b2007-02-23 20:55:14 -03004381 continue;
4382 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03004383 stat = pvr2_i2c_client_cmd(
Trent Piepho52ebc762007-01-23 22:38:13 -03004384 cp,(setFl ? VIDIOC_DBG_S_REGISTER :
4385 VIDIOC_DBG_G_REGISTER),&req);
Mike Isely32ffa9a2006-09-23 22:26:52 -03004386 if (!setFl) *val_ptr = req.val;
Mike Isely6d988162006-09-28 17:53:49 -03004387 okFl = !0;
4388 break;
Mike Isely32ffa9a2006-09-23 22:26:52 -03004389 }
4390 } while (0); mutex_unlock(&hdw->i2c_list_lock);
Mike Isely6d988162006-09-28 17:53:49 -03004391 if (okFl) {
4392 return stat;
4393 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03004394 return -EINVAL;
4395#else
4396 return -ENOSYS;
4397#endif
4398}
4399
4400
Mike Iselyd8554972006-06-26 20:58:46 -03004401/*
4402 Stuff for Emacs to see, in order to encourage consistent editing style:
4403 *** Local Variables: ***
4404 *** mode: c ***
4405 *** fill-column: 75 ***
4406 *** tab-width: 8 ***
4407 *** c-basic-offset: 8 ***
4408 *** End: ***
4409 */