blob: 195e974f5eb086912c83769b562d9abe789346e1 [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
70#define PVR2_CTL_WRITE_ENDPOINT 0x01
71#define PVR2_CTL_READ_ENDPOINT 0x81
72
73#define PVR2_GPIO_IN 0x9008
74#define PVR2_GPIO_OUT 0x900c
75#define PVR2_GPIO_DIR 0x9020
76
77#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__)
78
79#define PVR2_FIRMWARE_ENDPOINT 0x02
80
81/* size of a firmware chunk */
82#define FIRMWARE_CHUNK_SIZE 0x2000
83
Mike Iselyb30d2442006-06-25 20:05:01 -030084/* Define the list of additional controls we'll dynamically construct based
85 on query of the cx2341x module. */
86struct pvr2_mpeg_ids {
87 const char *strid;
88 int id;
89};
90static const struct pvr2_mpeg_ids mpeg_ids[] = {
91 {
92 .strid = "audio_layer",
93 .id = V4L2_CID_MPEG_AUDIO_ENCODING,
94 },{
95 .strid = "audio_bitrate",
96 .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE,
97 },{
98 /* Already using audio_mode elsewhere :-( */
99 .strid = "mpeg_audio_mode",
100 .id = V4L2_CID_MPEG_AUDIO_MODE,
101 },{
102 .strid = "mpeg_audio_mode_extension",
103 .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
104 },{
105 .strid = "audio_emphasis",
106 .id = V4L2_CID_MPEG_AUDIO_EMPHASIS,
107 },{
108 .strid = "audio_crc",
109 .id = V4L2_CID_MPEG_AUDIO_CRC,
110 },{
111 .strid = "video_aspect",
112 .id = V4L2_CID_MPEG_VIDEO_ASPECT,
113 },{
114 .strid = "video_b_frames",
115 .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
116 },{
117 .strid = "video_gop_size",
118 .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
119 },{
120 .strid = "video_gop_closure",
121 .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
122 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300123 .strid = "video_bitrate_mode",
124 .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
125 },{
126 .strid = "video_bitrate",
127 .id = V4L2_CID_MPEG_VIDEO_BITRATE,
128 },{
129 .strid = "video_bitrate_peak",
130 .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
131 },{
132 .strid = "video_temporal_decimation",
133 .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
134 },{
135 .strid = "stream_type",
136 .id = V4L2_CID_MPEG_STREAM_TYPE,
137 },{
138 .strid = "video_spatial_filter_mode",
139 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
140 },{
141 .strid = "video_spatial_filter",
142 .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
143 },{
144 .strid = "video_luma_spatial_filter_type",
145 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
146 },{
147 .strid = "video_chroma_spatial_filter_type",
148 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
149 },{
150 .strid = "video_temporal_filter_mode",
151 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
152 },{
153 .strid = "video_temporal_filter",
154 .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
155 },{
156 .strid = "video_median_filter_type",
157 .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
158 },{
159 .strid = "video_luma_median_filter_top",
160 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
161 },{
162 .strid = "video_luma_median_filter_bottom",
163 .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
164 },{
165 .strid = "video_chroma_median_filter_top",
166 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
167 },{
168 .strid = "video_chroma_median_filter_bottom",
169 .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
170 }
171};
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -0300172#define MPEGDEF_COUNT ARRAY_SIZE(mpeg_ids)
Mike Iselyc05c0462006-06-25 20:04:25 -0300173
Mike Iselyd8554972006-06-26 20:58:46 -0300174
Mike Isely434449f2006-08-08 09:10:06 -0300175static const char *control_values_srate[] = {
176 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100] = "44.1 kHz",
177 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000] = "48 kHz",
178 [V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000] = "32 kHz",
179};
Mike Iselyd8554972006-06-26 20:58:46 -0300180
Mike Iselyd8554972006-06-26 20:58:46 -0300181
182
183static const char *control_values_input[] = {
184 [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/
Mike Isely29bf5b12008-04-22 14:45:37 -0300185 [PVR2_CVAL_INPUT_DTV] = "dtv",
Mike Iselyd8554972006-06-26 20:58:46 -0300186 [PVR2_CVAL_INPUT_RADIO] = "radio",
187 [PVR2_CVAL_INPUT_SVIDEO] = "s-video",
188 [PVR2_CVAL_INPUT_COMPOSITE] = "composite",
189};
190
191
192static const char *control_values_audiomode[] = {
193 [V4L2_TUNER_MODE_MONO] = "Mono",
194 [V4L2_TUNER_MODE_STEREO] = "Stereo",
195 [V4L2_TUNER_MODE_LANG1] = "Lang1",
196 [V4L2_TUNER_MODE_LANG2] = "Lang2",
197 [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2",
198};
199
200
201static const char *control_values_hsm[] = {
202 [PVR2_CVAL_HSM_FAIL] = "Fail",
203 [PVR2_CVAL_HSM_HIGH] = "High",
204 [PVR2_CVAL_HSM_FULL] = "Full",
205};
206
207
Mike Isely681c7392007-11-26 01:48:52 -0300208static const char *pvr2_state_names[] = {
209 [PVR2_STATE_NONE] = "none",
210 [PVR2_STATE_DEAD] = "dead",
211 [PVR2_STATE_COLD] = "cold",
212 [PVR2_STATE_WARM] = "warm",
213 [PVR2_STATE_ERROR] = "error",
214 [PVR2_STATE_READY] = "ready",
215 [PVR2_STATE_RUN] = "run",
Mike Iselyd8554972006-06-26 20:58:46 -0300216};
217
Mike Isely681c7392007-11-26 01:48:52 -0300218
Mike Isely694dca2b2008-03-28 05:42:10 -0300219struct pvr2_fx2cmd_descdef {
Mike Isely1c9d10d2008-03-28 05:38:54 -0300220 unsigned char id;
221 unsigned char *desc;
222};
223
Mike Isely694dca2b2008-03-28 05:42:10 -0300224static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
Mike Isely1c9d10d2008-03-28 05:38:54 -0300225 {FX2CMD_MEM_WRITE_DWORD, "write encoder dword"},
226 {FX2CMD_MEM_READ_DWORD, "read encoder dword"},
227 {FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"},
228 {FX2CMD_REG_WRITE, "write encoder register"},
229 {FX2CMD_REG_READ, "read encoder register"},
230 {FX2CMD_MEMSEL, "encoder memsel"},
231 {FX2CMD_I2C_WRITE, "i2c write"},
232 {FX2CMD_I2C_READ, "i2c read"},
233 {FX2CMD_GET_USB_SPEED, "get USB speed"},
234 {FX2CMD_STREAMING_ON, "stream on"},
235 {FX2CMD_STREAMING_OFF, "stream off"},
236 {FX2CMD_FWPOST1, "fwpost1"},
237 {FX2CMD_POWER_OFF, "power off"},
238 {FX2CMD_POWER_ON, "power on"},
239 {FX2CMD_DEEP_RESET, "deep reset"},
240 {FX2CMD_GET_EEPROM_ADDR, "get rom addr"},
241 {FX2CMD_GET_IR_CODE, "get IR code"},
242 {FX2CMD_HCW_DEMOD_RESETIN, "hcw demod resetin"},
243 {FX2CMD_HCW_DTV_STREAMING_ON, "hcw dtv stream on"},
244 {FX2CMD_HCW_DTV_STREAMING_OFF, "hcw dtv stream off"},
245 {FX2CMD_ONAIR_DTV_STREAMING_ON, "onair dtv stream on"},
246 {FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"},
247 {FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"},
248 {FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"},
249};
250
251
Mike Isely681c7392007-11-26 01:48:52 -0300252static void pvr2_hdw_state_sched(struct pvr2_hdw *);
253static int pvr2_hdw_state_eval(struct pvr2_hdw *);
Mike Isely1bde0282006-12-27 23:30:13 -0300254static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
Mike Isely681c7392007-11-26 01:48:52 -0300255static void pvr2_hdw_worker_i2c(struct work_struct *work);
256static void pvr2_hdw_worker_poll(struct work_struct *work);
Mike Isely681c7392007-11-26 01:48:52 -0300257static int pvr2_hdw_wait(struct pvr2_hdw *,int state);
258static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *);
259static void pvr2_hdw_state_log_state(struct pvr2_hdw *);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300260static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
Mike Isely681c7392007-11-26 01:48:52 -0300261static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300262static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300263static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
264static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
Mike Isely681c7392007-11-26 01:48:52 -0300265static void pvr2_hdw_quiescent_timeout(unsigned long);
266static void pvr2_hdw_encoder_wait_timeout(unsigned long);
Mike Isely1c9d10d2008-03-28 05:38:54 -0300267static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300268static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
269 unsigned int timeout,int probe_fl,
270 void *write_data,unsigned int write_len,
271 void *read_data,unsigned int read_len);
Mike Iselyd8554972006-06-26 20:58:46 -0300272
Mike Isely681c7392007-11-26 01:48:52 -0300273
274static void trace_stbit(const char *name,int val)
275{
276 pvr2_trace(PVR2_TRACE_STBITS,
277 "State bit %s <-- %s",
278 name,(val ? "true" : "false"));
279}
280
Mike Iselyd8554972006-06-26 20:58:46 -0300281static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
282{
283 struct pvr2_hdw *hdw = cptr->hdw;
284 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
285 *vp = hdw->freqTable[hdw->freqProgSlot-1];
286 } else {
287 *vp = 0;
288 }
289 return 0;
290}
291
292static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
293{
294 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300295 unsigned int slotId = hdw->freqProgSlot;
296 if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) {
297 hdw->freqTable[slotId-1] = v;
298 /* Handle side effects correctly - if we're tuned to this
299 slot, then forgot the slot id relation since the stored
300 frequency has been changed. */
301 if (hdw->freqSelector) {
302 if (hdw->freqSlotRadio == slotId) {
303 hdw->freqSlotRadio = 0;
304 }
305 } else {
306 if (hdw->freqSlotTelevision == slotId) {
307 hdw->freqSlotTelevision = 0;
308 }
309 }
Mike Iselyd8554972006-06-26 20:58:46 -0300310 }
311 return 0;
312}
313
314static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
315{
316 *vp = cptr->hdw->freqProgSlot;
317 return 0;
318}
319
320static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
321{
322 struct pvr2_hdw *hdw = cptr->hdw;
323 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
324 hdw->freqProgSlot = v;
325 }
326 return 0;
327}
328
329static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
330{
Mike Isely1bde0282006-12-27 23:30:13 -0300331 struct pvr2_hdw *hdw = cptr->hdw;
332 *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision;
Mike Iselyd8554972006-06-26 20:58:46 -0300333 return 0;
334}
335
Mike Isely1bde0282006-12-27 23:30:13 -0300336static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId)
Mike Iselyd8554972006-06-26 20:58:46 -0300337{
338 unsigned freq = 0;
339 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300340 if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0;
341 if (slotId > 0) {
342 freq = hdw->freqTable[slotId-1];
343 if (!freq) return 0;
344 pvr2_hdw_set_cur_freq(hdw,freq);
Mike Iselyd8554972006-06-26 20:58:46 -0300345 }
Mike Isely1bde0282006-12-27 23:30:13 -0300346 if (hdw->freqSelector) {
347 hdw->freqSlotRadio = slotId;
348 } else {
349 hdw->freqSlotTelevision = slotId;
Mike Iselyd8554972006-06-26 20:58:46 -0300350 }
351 return 0;
352}
353
354static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
355{
Mike Isely1bde0282006-12-27 23:30:13 -0300356 *vp = pvr2_hdw_get_cur_freq(cptr->hdw);
Mike Iselyd8554972006-06-26 20:58:46 -0300357 return 0;
358}
359
360static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
361{
362 return cptr->hdw->freqDirty != 0;
363}
364
365static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
366{
367 cptr->hdw->freqDirty = 0;
368}
369
370static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
371{
Mike Isely1bde0282006-12-27 23:30:13 -0300372 pvr2_hdw_set_cur_freq(cptr->hdw,v);
Mike Iselyd8554972006-06-26 20:58:46 -0300373 return 0;
374}
375
Mike Isely3ad9fc32006-09-02 22:37:52 -0300376static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
377{
378 /* Actual maximum depends on the video standard in effect. */
379 if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
380 *vp = 480;
381 } else {
382 *vp = 576;
383 }
384 return 0;
385}
386
387static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
388{
Mike Isely989eb152007-11-26 01:53:12 -0300389 /* Actual minimum depends on device digitizer type. */
390 if (cptr->hdw->hdw_desc->flag_has_cx25840) {
Mike Isely3ad9fc32006-09-02 22:37:52 -0300391 *vp = 75;
392 } else {
393 *vp = 17;
394 }
395 return 0;
396}
397
Mike Isely1bde0282006-12-27 23:30:13 -0300398static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
399{
400 *vp = cptr->hdw->input_val;
401 return 0;
402}
403
Mike Isely29bf5b12008-04-22 14:45:37 -0300404static int ctrl_check_input(struct pvr2_ctrl *cptr,int v)
405{
Mike Isely7fb20fa2008-04-22 14:45:37 -0300406 return ((1 << v) & cptr->hdw->input_avail_mask) != 0;
Mike Isely29bf5b12008-04-22 14:45:37 -0300407}
408
Mike Isely1bde0282006-12-27 23:30:13 -0300409static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
410{
411 struct pvr2_hdw *hdw = cptr->hdw;
412
413 if (hdw->input_val != v) {
414 hdw->input_val = v;
415 hdw->input_dirty = !0;
416 }
417
418 /* Handle side effects - if we switch to a mode that needs the RF
419 tuner, then select the right frequency choice as well and mark
420 it dirty. */
421 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
422 hdw->freqSelector = 0;
423 hdw->freqDirty = !0;
Mike Isely29bf5b12008-04-22 14:45:37 -0300424 } else if ((hdw->input_val == PVR2_CVAL_INPUT_TV) ||
425 (hdw->input_val == PVR2_CVAL_INPUT_DTV)) {
Mike Isely1bde0282006-12-27 23:30:13 -0300426 hdw->freqSelector = 1;
427 hdw->freqDirty = !0;
428 }
429 return 0;
430}
431
432static int ctrl_isdirty_input(struct pvr2_ctrl *cptr)
433{
434 return cptr->hdw->input_dirty != 0;
435}
436
437static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr)
438{
439 cptr->hdw->input_dirty = 0;
440}
441
Mike Isely5549f542006-12-27 23:28:54 -0300442
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300443static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
444{
Mike Isely644afdb2007-01-20 00:19:23 -0300445 unsigned long fv;
446 struct pvr2_hdw *hdw = cptr->hdw;
447 if (hdw->tuner_signal_stale) {
448 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300449 }
Mike Isely644afdb2007-01-20 00:19:23 -0300450 fv = hdw->tuner_signal_info.rangehigh;
451 if (!fv) {
452 /* Safety fallback */
453 *vp = TV_MAX_FREQ;
454 return 0;
455 }
456 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
457 fv = (fv * 125) / 2;
458 } else {
459 fv = fv * 62500;
460 }
461 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300462 return 0;
463}
464
465static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
466{
Mike Isely644afdb2007-01-20 00:19:23 -0300467 unsigned long fv;
468 struct pvr2_hdw *hdw = cptr->hdw;
469 if (hdw->tuner_signal_stale) {
470 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300471 }
Mike Isely644afdb2007-01-20 00:19:23 -0300472 fv = hdw->tuner_signal_info.rangelow;
473 if (!fv) {
474 /* Safety fallback */
475 *vp = TV_MIN_FREQ;
476 return 0;
477 }
478 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
479 fv = (fv * 125) / 2;
480 } else {
481 fv = fv * 62500;
482 }
483 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300484 return 0;
485}
486
Mike Iselyb30d2442006-06-25 20:05:01 -0300487static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
488{
489 return cptr->hdw->enc_stale != 0;
490}
491
492static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
493{
494 cptr->hdw->enc_stale = 0;
Mike Isely681c7392007-11-26 01:48:52 -0300495 cptr->hdw->enc_unsafe_stale = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -0300496}
497
498static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
499{
500 int ret;
501 struct v4l2_ext_controls cs;
502 struct v4l2_ext_control c1;
503 memset(&cs,0,sizeof(cs));
504 memset(&c1,0,sizeof(c1));
505 cs.controls = &c1;
506 cs.count = 1;
507 c1.id = cptr->info->v4l_id;
Hans Verkuil01f1e442007-08-21 18:32:42 -0300508 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs,
Mike Iselyb30d2442006-06-25 20:05:01 -0300509 VIDIOC_G_EXT_CTRLS);
510 if (ret) return ret;
511 *vp = c1.value;
512 return 0;
513}
514
515static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
516{
517 int ret;
Mike Isely681c7392007-11-26 01:48:52 -0300518 struct pvr2_hdw *hdw = cptr->hdw;
Mike Iselyb30d2442006-06-25 20:05:01 -0300519 struct v4l2_ext_controls cs;
520 struct v4l2_ext_control c1;
521 memset(&cs,0,sizeof(cs));
522 memset(&c1,0,sizeof(c1));
523 cs.controls = &c1;
524 cs.count = 1;
525 c1.id = cptr->info->v4l_id;
526 c1.value = v;
Mike Isely681c7392007-11-26 01:48:52 -0300527 ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
528 hdw->state_encoder_run, &cs,
Mike Iselyb30d2442006-06-25 20:05:01 -0300529 VIDIOC_S_EXT_CTRLS);
Mike Isely681c7392007-11-26 01:48:52 -0300530 if (ret == -EBUSY) {
531 /* Oops. cx2341x is telling us it's not safe to change
532 this control while we're capturing. Make a note of this
533 fact so that the pipeline will be stopped the next time
534 controls are committed. Then go on ahead and store this
535 change anyway. */
536 ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
537 0, &cs,
538 VIDIOC_S_EXT_CTRLS);
539 if (!ret) hdw->enc_unsafe_stale = !0;
540 }
Mike Iselyb30d2442006-06-25 20:05:01 -0300541 if (ret) return ret;
Mike Isely681c7392007-11-26 01:48:52 -0300542 hdw->enc_stale = !0;
Mike Iselyb30d2442006-06-25 20:05:01 -0300543 return 0;
544}
545
546static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
547{
548 struct v4l2_queryctrl qctrl;
549 struct pvr2_ctl_info *info;
550 qctrl.id = cptr->info->v4l_id;
551 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
552 /* Strip out the const so we can adjust a function pointer. It's
553 OK to do this here because we know this is a dynamically created
554 control, so the underlying storage for the info pointer is (a)
555 private to us, and (b) not in read-only storage. Either we do
556 this or we significantly complicate the underlying control
557 implementation. */
558 info = (struct pvr2_ctl_info *)(cptr->info);
559 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
560 if (info->set_value) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300561 info->set_value = NULL;
Mike Iselyb30d2442006-06-25 20:05:01 -0300562 }
563 } else {
564 if (!(info->set_value)) {
565 info->set_value = ctrl_cx2341x_set;
566 }
567 }
568 return qctrl.flags;
569}
570
Mike Iselyd8554972006-06-26 20:58:46 -0300571static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
572{
Mike Isely681c7392007-11-26 01:48:52 -0300573 *vp = cptr->hdw->state_pipeline_req;
574 return 0;
575}
576
577static int ctrl_masterstate_get(struct pvr2_ctrl *cptr,int *vp)
578{
579 *vp = cptr->hdw->master_state;
Mike Iselyd8554972006-06-26 20:58:46 -0300580 return 0;
581}
582
583static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
584{
585 int result = pvr2_hdw_is_hsm(cptr->hdw);
586 *vp = PVR2_CVAL_HSM_FULL;
587 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
588 if (result) *vp = PVR2_CVAL_HSM_HIGH;
589 return 0;
590}
591
592static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
593{
594 *vp = cptr->hdw->std_mask_avail;
595 return 0;
596}
597
598static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
599{
600 struct pvr2_hdw *hdw = cptr->hdw;
601 v4l2_std_id ns;
602 ns = hdw->std_mask_avail;
603 ns = (ns & ~m) | (v & m);
604 if (ns == hdw->std_mask_avail) return 0;
605 hdw->std_mask_avail = ns;
606 pvr2_hdw_internal_set_std_avail(hdw);
607 pvr2_hdw_internal_find_stdenum(hdw);
608 return 0;
609}
610
611static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
612 char *bufPtr,unsigned int bufSize,
613 unsigned int *len)
614{
615 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
616 return 0;
617}
618
619static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
620 const char *bufPtr,unsigned int bufSize,
621 int *mskp,int *valp)
622{
623 int ret;
624 v4l2_std_id id;
625 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
626 if (ret < 0) return ret;
627 if (mskp) *mskp = id;
628 if (valp) *valp = id;
629 return 0;
630}
631
632static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
633{
634 *vp = cptr->hdw->std_mask_cur;
635 return 0;
636}
637
638static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
639{
640 struct pvr2_hdw *hdw = cptr->hdw;
641 v4l2_std_id ns;
642 ns = hdw->std_mask_cur;
643 ns = (ns & ~m) | (v & m);
644 if (ns == hdw->std_mask_cur) return 0;
645 hdw->std_mask_cur = ns;
646 hdw->std_dirty = !0;
647 pvr2_hdw_internal_find_stdenum(hdw);
648 return 0;
649}
650
651static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
652{
653 return cptr->hdw->std_dirty != 0;
654}
655
656static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
657{
658 cptr->hdw->std_dirty = 0;
659}
660
661static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
662{
Mike Isely18103c572007-01-20 00:09:47 -0300663 struct pvr2_hdw *hdw = cptr->hdw;
664 pvr2_i2c_core_status_poll(hdw);
665 *vp = hdw->tuner_signal_info.signal;
666 return 0;
667}
668
669static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
670{
671 int val = 0;
672 unsigned int subchan;
673 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely644afdb2007-01-20 00:19:23 -0300674 pvr2_i2c_core_status_poll(hdw);
Mike Isely18103c572007-01-20 00:09:47 -0300675 subchan = hdw->tuner_signal_info.rxsubchans;
676 if (subchan & V4L2_TUNER_SUB_MONO) {
677 val |= (1 << V4L2_TUNER_MODE_MONO);
678 }
679 if (subchan & V4L2_TUNER_SUB_STEREO) {
680 val |= (1 << V4L2_TUNER_MODE_STEREO);
681 }
682 if (subchan & V4L2_TUNER_SUB_LANG1) {
683 val |= (1 << V4L2_TUNER_MODE_LANG1);
684 }
685 if (subchan & V4L2_TUNER_SUB_LANG2) {
686 val |= (1 << V4L2_TUNER_MODE_LANG2);
687 }
688 *vp = val;
Mike Iselyd8554972006-06-26 20:58:46 -0300689 return 0;
690}
691
Mike Iselyd8554972006-06-26 20:58:46 -0300692
693static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
694{
695 struct pvr2_hdw *hdw = cptr->hdw;
696 if (v < 0) return -EINVAL;
697 if (v > hdw->std_enum_cnt) return -EINVAL;
698 hdw->std_enum_cur = v;
699 if (!v) return 0;
700 v--;
701 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
702 hdw->std_mask_cur = hdw->std_defs[v].id;
703 hdw->std_dirty = !0;
704 return 0;
705}
706
707
708static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
709{
710 *vp = cptr->hdw->std_enum_cur;
711 return 0;
712}
713
714
715static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
716{
717 return cptr->hdw->std_dirty != 0;
718}
719
720
721static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
722{
723 cptr->hdw->std_dirty = 0;
724}
725
726
727#define DEFINT(vmin,vmax) \
728 .type = pvr2_ctl_int, \
729 .def.type_int.min_value = vmin, \
730 .def.type_int.max_value = vmax
731
732#define DEFENUM(tab) \
733 .type = pvr2_ctl_enum, \
Mike Isely27c7b712007-01-20 00:39:17 -0300734 .def.type_enum.count = ARRAY_SIZE(tab), \
Mike Iselyd8554972006-06-26 20:58:46 -0300735 .def.type_enum.value_names = tab
736
Mike Isely33213962006-06-25 20:04:40 -0300737#define DEFBOOL \
738 .type = pvr2_ctl_bool
739
Mike Iselyd8554972006-06-26 20:58:46 -0300740#define DEFMASK(msk,tab) \
741 .type = pvr2_ctl_bitmask, \
742 .def.type_bitmask.valid_bits = msk, \
743 .def.type_bitmask.bit_names = tab
744
745#define DEFREF(vname) \
746 .set_value = ctrl_set_##vname, \
747 .get_value = ctrl_get_##vname, \
748 .is_dirty = ctrl_isdirty_##vname, \
749 .clear_dirty = ctrl_cleardirty_##vname
750
751
752#define VCREATE_FUNCS(vname) \
753static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
754{*vp = cptr->hdw->vname##_val; return 0;} \
755static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
756{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
757static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
758{return cptr->hdw->vname##_dirty != 0;} \
759static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
760{cptr->hdw->vname##_dirty = 0;}
761
762VCREATE_FUNCS(brightness)
763VCREATE_FUNCS(contrast)
764VCREATE_FUNCS(saturation)
765VCREATE_FUNCS(hue)
766VCREATE_FUNCS(volume)
767VCREATE_FUNCS(balance)
768VCREATE_FUNCS(bass)
769VCREATE_FUNCS(treble)
770VCREATE_FUNCS(mute)
Mike Iselyc05c0462006-06-25 20:04:25 -0300771VCREATE_FUNCS(audiomode)
772VCREATE_FUNCS(res_hor)
773VCREATE_FUNCS(res_ver)
Mike Iselyd8554972006-06-26 20:58:46 -0300774VCREATE_FUNCS(srate)
Mike Iselyd8554972006-06-26 20:58:46 -0300775
Mike Iselyd8554972006-06-26 20:58:46 -0300776/* Table definition of all controls which can be manipulated */
777static const struct pvr2_ctl_info control_defs[] = {
778 {
779 .v4l_id = V4L2_CID_BRIGHTNESS,
780 .desc = "Brightness",
781 .name = "brightness",
782 .default_value = 128,
783 DEFREF(brightness),
784 DEFINT(0,255),
785 },{
786 .v4l_id = V4L2_CID_CONTRAST,
787 .desc = "Contrast",
788 .name = "contrast",
789 .default_value = 68,
790 DEFREF(contrast),
791 DEFINT(0,127),
792 },{
793 .v4l_id = V4L2_CID_SATURATION,
794 .desc = "Saturation",
795 .name = "saturation",
796 .default_value = 64,
797 DEFREF(saturation),
798 DEFINT(0,127),
799 },{
800 .v4l_id = V4L2_CID_HUE,
801 .desc = "Hue",
802 .name = "hue",
803 .default_value = 0,
804 DEFREF(hue),
805 DEFINT(-128,127),
806 },{
807 .v4l_id = V4L2_CID_AUDIO_VOLUME,
808 .desc = "Volume",
809 .name = "volume",
Mike Isely139eecf2006-12-27 23:36:33 -0300810 .default_value = 62000,
Mike Iselyd8554972006-06-26 20:58:46 -0300811 DEFREF(volume),
812 DEFINT(0,65535),
813 },{
814 .v4l_id = V4L2_CID_AUDIO_BALANCE,
815 .desc = "Balance",
816 .name = "balance",
817 .default_value = 0,
818 DEFREF(balance),
819 DEFINT(-32768,32767),
820 },{
821 .v4l_id = V4L2_CID_AUDIO_BASS,
822 .desc = "Bass",
823 .name = "bass",
824 .default_value = 0,
825 DEFREF(bass),
826 DEFINT(-32768,32767),
827 },{
828 .v4l_id = V4L2_CID_AUDIO_TREBLE,
829 .desc = "Treble",
830 .name = "treble",
831 .default_value = 0,
832 DEFREF(treble),
833 DEFINT(-32768,32767),
834 },{
835 .v4l_id = V4L2_CID_AUDIO_MUTE,
836 .desc = "Mute",
837 .name = "mute",
838 .default_value = 0,
839 DEFREF(mute),
Mike Isely33213962006-06-25 20:04:40 -0300840 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300841 },{
Mike Iselyc05c0462006-06-25 20:04:25 -0300842 .desc = "Video Source",
843 .name = "input",
844 .internal_id = PVR2_CID_INPUT,
845 .default_value = PVR2_CVAL_INPUT_TV,
Mike Isely29bf5b12008-04-22 14:45:37 -0300846 .check_value = ctrl_check_input,
Mike Iselyc05c0462006-06-25 20:04:25 -0300847 DEFREF(input),
848 DEFENUM(control_values_input),
849 },{
850 .desc = "Audio Mode",
851 .name = "audio_mode",
852 .internal_id = PVR2_CID_AUDIOMODE,
853 .default_value = V4L2_TUNER_MODE_STEREO,
854 DEFREF(audiomode),
855 DEFENUM(control_values_audiomode),
856 },{
857 .desc = "Horizontal capture resolution",
858 .name = "resolution_hor",
859 .internal_id = PVR2_CID_HRES,
860 .default_value = 720,
861 DEFREF(res_hor),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300862 DEFINT(19,720),
Mike Iselyc05c0462006-06-25 20:04:25 -0300863 },{
864 .desc = "Vertical capture resolution",
865 .name = "resolution_ver",
866 .internal_id = PVR2_CID_VRES,
867 .default_value = 480,
868 DEFREF(res_ver),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300869 DEFINT(17,576),
870 /* Hook in check for video standard and adjust maximum
871 depending on the standard. */
872 .get_max_value = ctrl_vres_max_get,
873 .get_min_value = ctrl_vres_min_get,
Mike Iselyc05c0462006-06-25 20:04:25 -0300874 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300875 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
Mike Isely434449f2006-08-08 09:10:06 -0300876 .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
877 .desc = "Audio Sampling Frequency",
Mike Iselyd8554972006-06-26 20:58:46 -0300878 .name = "srate",
Mike Iselyd8554972006-06-26 20:58:46 -0300879 DEFREF(srate),
880 DEFENUM(control_values_srate),
881 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300882 .desc = "Tuner Frequency (Hz)",
883 .name = "frequency",
884 .internal_id = PVR2_CID_FREQUENCY,
Mike Isely1bde0282006-12-27 23:30:13 -0300885 .default_value = 0,
Mike Iselyd8554972006-06-26 20:58:46 -0300886 .set_value = ctrl_freq_set,
887 .get_value = ctrl_freq_get,
888 .is_dirty = ctrl_freq_is_dirty,
889 .clear_dirty = ctrl_freq_clear_dirty,
Mike Isely644afdb2007-01-20 00:19:23 -0300890 DEFINT(0,0),
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300891 /* Hook in check for input value (tv/radio) and adjust
892 max/min values accordingly */
893 .get_max_value = ctrl_freq_max_get,
894 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300895 },{
896 .desc = "Channel",
897 .name = "channel",
898 .set_value = ctrl_channel_set,
899 .get_value = ctrl_channel_get,
900 DEFINT(0,FREQTABLE_SIZE),
901 },{
902 .desc = "Channel Program Frequency",
903 .name = "freq_table_value",
904 .set_value = ctrl_channelfreq_set,
905 .get_value = ctrl_channelfreq_get,
Mike Isely644afdb2007-01-20 00:19:23 -0300906 DEFINT(0,0),
Mike Isely1bde0282006-12-27 23:30:13 -0300907 /* Hook in check for input value (tv/radio) and adjust
908 max/min values accordingly */
Mike Isely1bde0282006-12-27 23:30:13 -0300909 .get_max_value = ctrl_freq_max_get,
910 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300911 },{
912 .desc = "Channel Program ID",
913 .name = "freq_table_channel",
914 .set_value = ctrl_channelprog_set,
915 .get_value = ctrl_channelprog_get,
916 DEFINT(0,FREQTABLE_SIZE),
917 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300918 .desc = "Streaming Enabled",
919 .name = "streaming_enabled",
920 .get_value = ctrl_streamingenabled_get,
Mike Isely33213962006-06-25 20:04:40 -0300921 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300922 },{
923 .desc = "USB Speed",
924 .name = "usb_speed",
925 .get_value = ctrl_hsm_get,
926 DEFENUM(control_values_hsm),
927 },{
Mike Isely681c7392007-11-26 01:48:52 -0300928 .desc = "Master State",
929 .name = "master_state",
930 .get_value = ctrl_masterstate_get,
931 DEFENUM(pvr2_state_names),
932 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300933 .desc = "Signal Present",
934 .name = "signal_present",
935 .get_value = ctrl_signal_get,
Mike Isely18103c572007-01-20 00:09:47 -0300936 DEFINT(0,65535),
937 },{
938 .desc = "Audio Modes Present",
939 .name = "audio_modes_present",
940 .get_value = ctrl_audio_modes_present_get,
941 /* For this type we "borrow" the V4L2_TUNER_MODE enum from
942 v4l. Nothing outside of this module cares about this,
943 but I reuse it in order to also reuse the
944 control_values_audiomode string table. */
945 DEFMASK(((1 << V4L2_TUNER_MODE_MONO)|
946 (1 << V4L2_TUNER_MODE_STEREO)|
947 (1 << V4L2_TUNER_MODE_LANG1)|
948 (1 << V4L2_TUNER_MODE_LANG2)),
949 control_values_audiomode),
Mike Iselyd8554972006-06-26 20:58:46 -0300950 },{
951 .desc = "Video Standards Available Mask",
952 .name = "video_standard_mask_available",
953 .internal_id = PVR2_CID_STDAVAIL,
954 .skip_init = !0,
955 .get_value = ctrl_stdavail_get,
956 .set_value = ctrl_stdavail_set,
957 .val_to_sym = ctrl_std_val_to_sym,
958 .sym_to_val = ctrl_std_sym_to_val,
959 .type = pvr2_ctl_bitmask,
960 },{
961 .desc = "Video Standards In Use Mask",
962 .name = "video_standard_mask_active",
963 .internal_id = PVR2_CID_STDCUR,
964 .skip_init = !0,
965 .get_value = ctrl_stdcur_get,
966 .set_value = ctrl_stdcur_set,
967 .is_dirty = ctrl_stdcur_is_dirty,
968 .clear_dirty = ctrl_stdcur_clear_dirty,
969 .val_to_sym = ctrl_std_val_to_sym,
970 .sym_to_val = ctrl_std_sym_to_val,
971 .type = pvr2_ctl_bitmask,
972 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300973 .desc = "Video Standard Name",
974 .name = "video_standard",
975 .internal_id = PVR2_CID_STDENUM,
976 .skip_init = !0,
977 .get_value = ctrl_stdenumcur_get,
978 .set_value = ctrl_stdenumcur_set,
979 .is_dirty = ctrl_stdenumcur_is_dirty,
980 .clear_dirty = ctrl_stdenumcur_clear_dirty,
981 .type = pvr2_ctl_enum,
982 }
983};
984
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -0300985#define CTRLDEF_COUNT ARRAY_SIZE(control_defs)
Mike Iselyd8554972006-06-26 20:58:46 -0300986
987
988const char *pvr2_config_get_name(enum pvr2_config cfg)
989{
990 switch (cfg) {
991 case pvr2_config_empty: return "empty";
992 case pvr2_config_mpeg: return "mpeg";
993 case pvr2_config_vbi: return "vbi";
Mike Isely16eb40d2006-12-30 18:27:32 -0300994 case pvr2_config_pcm: return "pcm";
995 case pvr2_config_rawvideo: return "raw video";
Mike Iselyd8554972006-06-26 20:58:46 -0300996 }
997 return "<unknown>";
998}
999
1000
1001struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
1002{
1003 return hdw->usb_dev;
1004}
1005
1006
1007unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
1008{
1009 return hdw->serial_number;
1010}
1011
Mike Isely31a18542007-04-08 01:11:47 -03001012
1013const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
1014{
1015 return hdw->bus_info;
1016}
1017
1018
Mike Isely1bde0282006-12-27 23:30:13 -03001019unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
1020{
1021 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
1022}
1023
1024/* Set the currently tuned frequency and account for all possible
1025 driver-core side effects of this action. */
1026void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val)
1027{
Mike Isely7c74e572007-01-20 00:15:41 -03001028 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
Mike Isely1bde0282006-12-27 23:30:13 -03001029 if (hdw->freqSelector) {
1030 /* Swing over to radio frequency selection */
1031 hdw->freqSelector = 0;
1032 hdw->freqDirty = !0;
1033 }
Mike Isely1bde0282006-12-27 23:30:13 -03001034 if (hdw->freqValRadio != val) {
1035 hdw->freqValRadio = val;
1036 hdw->freqSlotRadio = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001037 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001038 }
Mike Isely7c74e572007-01-20 00:15:41 -03001039 } else {
Mike Isely1bde0282006-12-27 23:30:13 -03001040 if (!(hdw->freqSelector)) {
1041 /* Swing over to television frequency selection */
1042 hdw->freqSelector = 1;
1043 hdw->freqDirty = !0;
1044 }
Mike Isely1bde0282006-12-27 23:30:13 -03001045 if (hdw->freqValTelevision != val) {
1046 hdw->freqValTelevision = val;
1047 hdw->freqSlotTelevision = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001048 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001049 }
Mike Isely1bde0282006-12-27 23:30:13 -03001050 }
1051}
1052
Mike Iselyd8554972006-06-26 20:58:46 -03001053int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
1054{
1055 return hdw->unit_number;
1056}
1057
1058
1059/* Attempt to locate one of the given set of files. Messages are logged
1060 appropriate to what has been found. The return value will be 0 or
1061 greater on success (it will be the index of the file name found) and
1062 fw_entry will be filled in. Otherwise a negative error is returned on
1063 failure. If the return value is -ENOENT then no viable firmware file
1064 could be located. */
1065static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
1066 const struct firmware **fw_entry,
1067 const char *fwtypename,
1068 unsigned int fwcount,
1069 const char *fwnames[])
1070{
1071 unsigned int idx;
1072 int ret = -EINVAL;
1073 for (idx = 0; idx < fwcount; idx++) {
1074 ret = request_firmware(fw_entry,
1075 fwnames[idx],
1076 &hdw->usb_dev->dev);
1077 if (!ret) {
1078 trace_firmware("Located %s firmware: %s;"
1079 " uploading...",
1080 fwtypename,
1081 fwnames[idx]);
1082 return idx;
1083 }
1084 if (ret == -ENOENT) continue;
1085 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1086 "request_firmware fatal error with code=%d",ret);
1087 return ret;
1088 }
1089 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1090 "***WARNING***"
1091 " Device %s firmware"
1092 " seems to be missing.",
1093 fwtypename);
1094 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1095 "Did you install the pvrusb2 firmware files"
1096 " in their proper location?");
1097 if (fwcount == 1) {
1098 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1099 "request_firmware unable to locate %s file %s",
1100 fwtypename,fwnames[0]);
1101 } else {
1102 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1103 "request_firmware unable to locate"
1104 " one of the following %s files:",
1105 fwtypename);
1106 for (idx = 0; idx < fwcount; idx++) {
1107 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1108 "request_firmware: Failed to find %s",
1109 fwnames[idx]);
1110 }
1111 }
1112 return ret;
1113}
1114
1115
1116/*
1117 * pvr2_upload_firmware1().
1118 *
1119 * Send the 8051 firmware to the device. After the upload, arrange for
1120 * device to re-enumerate.
1121 *
1122 * NOTE : the pointer to the firmware data given by request_firmware()
1123 * is not suitable for an usb transaction.
1124 *
1125 */
Adrian Bunk07e337e2006-06-30 11:30:20 -03001126static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001127{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001128 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001129 void *fw_ptr;
1130 unsigned int pipe;
1131 int ret;
1132 u16 address;
Mike Isely1d643a32007-09-08 22:18:50 -03001133
Mike Isely989eb152007-11-26 01:53:12 -03001134 if (!hdw->hdw_desc->fx2_firmware.cnt) {
Mike Isely1d643a32007-09-08 22:18:50 -03001135 hdw->fw1_state = FW1_STATE_OK;
Mike Isely56dcbfa2007-11-26 02:00:51 -03001136 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1137 "Connected device type defines"
1138 " no firmware to upload; ignoring firmware");
1139 return -ENOTTY;
Mike Isely1d643a32007-09-08 22:18:50 -03001140 }
1141
Mike Iselyd8554972006-06-26 20:58:46 -03001142 hdw->fw1_state = FW1_STATE_FAILED; // default result
1143
1144 trace_firmware("pvr2_upload_firmware1");
1145
1146 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
Mike Isely989eb152007-11-26 01:53:12 -03001147 hdw->hdw_desc->fx2_firmware.cnt,
1148 hdw->hdw_desc->fx2_firmware.lst);
Mike Iselyd8554972006-06-26 20:58:46 -03001149 if (ret < 0) {
1150 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
1151 return ret;
1152 }
1153
1154 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
1155 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
1156
1157 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
1158
1159 if (fw_entry->size != 0x2000){
1160 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
1161 release_firmware(fw_entry);
1162 return -ENOMEM;
1163 }
1164
1165 fw_ptr = kmalloc(0x800, GFP_KERNEL);
1166 if (fw_ptr == NULL){
1167 release_firmware(fw_entry);
1168 return -ENOMEM;
1169 }
1170
1171 /* We have to hold the CPU during firmware upload. */
1172 pvr2_hdw_cpureset_assert(hdw,1);
1173
1174 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
1175 chunk. */
1176
1177 ret = 0;
1178 for(address = 0; address < fw_entry->size; address += 0x800) {
1179 memcpy(fw_ptr, fw_entry->data + address, 0x800);
1180 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
1181 0, fw_ptr, 0x800, HZ);
1182 }
1183
1184 trace_firmware("Upload done, releasing device's CPU");
1185
1186 /* Now release the CPU. It will disconnect and reconnect later. */
1187 pvr2_hdw_cpureset_assert(hdw,0);
1188
1189 kfree(fw_ptr);
1190 release_firmware(fw_entry);
1191
1192 trace_firmware("Upload done (%d bytes sent)",ret);
1193
1194 /* We should have written 8192 bytes */
1195 if (ret == 8192) {
1196 hdw->fw1_state = FW1_STATE_RELOAD;
1197 return 0;
1198 }
1199
1200 return -EIO;
1201}
1202
1203
1204/*
1205 * pvr2_upload_firmware2()
1206 *
1207 * This uploads encoder firmware on endpoint 2.
1208 *
1209 */
1210
1211int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
1212{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001213 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001214 void *fw_ptr;
Mike Isely90060d32007-02-08 02:02:53 -03001215 unsigned int pipe, fw_len, fw_done, bcnt, icnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001216 int actual_length;
1217 int ret = 0;
1218 int fwidx;
1219 static const char *fw_files[] = {
1220 CX2341X_FIRM_ENC_FILENAME,
1221 };
1222
Mike Isely989eb152007-11-26 01:53:12 -03001223 if (hdw->hdw_desc->flag_skip_cx23416_firmware) {
Mike Isely1d643a32007-09-08 22:18:50 -03001224 return 0;
1225 }
1226
Mike Iselyd8554972006-06-26 20:58:46 -03001227 trace_firmware("pvr2_upload_firmware2");
1228
1229 ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001230 ARRAY_SIZE(fw_files), fw_files);
Mike Iselyd8554972006-06-26 20:58:46 -03001231 if (ret < 0) return ret;
1232 fwidx = ret;
1233 ret = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001234 /* Since we're about to completely reinitialize the encoder,
1235 invalidate our cached copy of its configuration state. Next
1236 time we configure the encoder, then we'll fully configure it. */
1237 hdw->enc_cur_valid = 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001238
1239 /* First prepare firmware loading */
1240 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
1241 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
1242 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1243 ret |= pvr2_hdw_cmd_deep_reset(hdw);
1244 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
1245 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
1246 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1247 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
1248 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
1249 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
1250 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
1251 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
1252 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
1253 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
1254 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
1255 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
Mike Isely1c9d10d2008-03-28 05:38:54 -03001256 ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_FWPOST1);
1257 ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
Mike Iselyd8554972006-06-26 20:58:46 -03001258
1259 if (ret) {
1260 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1261 "firmware2 upload prep failed, ret=%d",ret);
1262 release_firmware(fw_entry);
1263 return ret;
1264 }
1265
1266 /* Now send firmware */
1267
1268 fw_len = fw_entry->size;
1269
Mike Isely90060d32007-02-08 02:02:53 -03001270 if (fw_len % sizeof(u32)) {
Mike Iselyd8554972006-06-26 20:58:46 -03001271 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1272 "size of %s firmware"
Mike Isely48dc30a2007-03-03 10:13:05 -02001273 " must be a multiple of %zu bytes",
Mike Isely90060d32007-02-08 02:02:53 -03001274 fw_files[fwidx],sizeof(u32));
Mike Iselyd8554972006-06-26 20:58:46 -03001275 release_firmware(fw_entry);
1276 return -1;
1277 }
1278
1279 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1280 if (fw_ptr == NULL){
1281 release_firmware(fw_entry);
1282 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1283 "failed to allocate memory for firmware2 upload");
1284 return -ENOMEM;
1285 }
1286
1287 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1288
Mike Isely90060d32007-02-08 02:02:53 -03001289 fw_done = 0;
1290 for (fw_done = 0; fw_done < fw_len;) {
1291 bcnt = fw_len - fw_done;
1292 if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE;
1293 memcpy(fw_ptr, fw_entry->data + fw_done, bcnt);
1294 /* Usbsnoop log shows that we must swap bytes... */
1295 for (icnt = 0; icnt < bcnt/4 ; icnt++)
1296 ((u32 *)fw_ptr)[icnt] =
1297 ___swab32(((u32 *)fw_ptr)[icnt]);
Mike Iselyd8554972006-06-26 20:58:46 -03001298
Mike Isely90060d32007-02-08 02:02:53 -03001299 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001300 &actual_length, HZ);
Mike Isely90060d32007-02-08 02:02:53 -03001301 ret |= (actual_length != bcnt);
1302 if (ret) break;
1303 fw_done += bcnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001304 }
1305
1306 trace_firmware("upload of %s : %i / %i ",
1307 fw_files[fwidx],fw_done,fw_len);
1308
1309 kfree(fw_ptr);
1310 release_firmware(fw_entry);
1311
1312 if (ret) {
1313 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1314 "firmware2 upload transfer failure");
1315 return ret;
1316 }
1317
1318 /* Finish upload */
1319
1320 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1321 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
Mike Isely1c9d10d2008-03-28 05:38:54 -03001322 ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
Mike Iselyd8554972006-06-26 20:58:46 -03001323
1324 if (ret) {
1325 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1326 "firmware2 upload post-proc failure");
Mike Iselyd8554972006-06-26 20:58:46 -03001327 }
1328 return ret;
1329}
1330
1331
Mike Isely681c7392007-11-26 01:48:52 -03001332static const char *pvr2_get_state_name(unsigned int st)
Mike Iselyd8554972006-06-26 20:58:46 -03001333{
Mike Isely681c7392007-11-26 01:48:52 -03001334 if (st < ARRAY_SIZE(pvr2_state_names)) {
1335 return pvr2_state_names[st];
Mike Iselyd8554972006-06-26 20:58:46 -03001336 }
Mike Isely681c7392007-11-26 01:48:52 -03001337 return "???";
Mike Iselyd8554972006-06-26 20:58:46 -03001338}
1339
Mike Isely681c7392007-11-26 01:48:52 -03001340static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
Mike Iselyd8554972006-06-26 20:58:46 -03001341{
Mike Isely681c7392007-11-26 01:48:52 -03001342 if (!hdw->decoder_ctrl) {
1343 if (!hdw->flag_decoder_missed) {
1344 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1345 "WARNING: No decoder present");
1346 hdw->flag_decoder_missed = !0;
1347 trace_stbit("flag_decoder_missed",
1348 hdw->flag_decoder_missed);
1349 }
1350 return -EIO;
Mike Iselyd8554972006-06-26 20:58:46 -03001351 }
Mike Isely681c7392007-11-26 01:48:52 -03001352 hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt,enablefl);
Mike Iselyd8554972006-06-26 20:58:46 -03001353 return 0;
1354}
1355
1356
Mike Isely681c7392007-11-26 01:48:52 -03001357void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr)
1358{
1359 if (hdw->decoder_ctrl == ptr) return;
1360 hdw->decoder_ctrl = ptr;
1361 if (hdw->decoder_ctrl && hdw->flag_decoder_missed) {
1362 hdw->flag_decoder_missed = 0;
1363 trace_stbit("flag_decoder_missed",
1364 hdw->flag_decoder_missed);
1365 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1366 "Decoder has appeared");
1367 pvr2_hdw_state_sched(hdw);
1368 }
1369}
1370
1371
1372int pvr2_hdw_get_state(struct pvr2_hdw *hdw)
1373{
1374 return hdw->master_state;
1375}
1376
1377
1378static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *hdw)
1379{
1380 if (!hdw->flag_tripped) return 0;
1381 hdw->flag_tripped = 0;
1382 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1383 "Clearing driver error statuss");
1384 return !0;
1385}
1386
1387
1388int pvr2_hdw_untrip(struct pvr2_hdw *hdw)
1389{
1390 int fl;
1391 LOCK_TAKE(hdw->big_lock); do {
1392 fl = pvr2_hdw_untrip_unlocked(hdw);
1393 } while (0); LOCK_GIVE(hdw->big_lock);
1394 if (fl) pvr2_hdw_state_sched(hdw);
1395 return 0;
1396}
1397
1398
1399const char *pvr2_hdw_get_state_name(unsigned int id)
1400{
1401 if (id >= ARRAY_SIZE(pvr2_state_names)) return NULL;
1402 return pvr2_state_names[id];
1403}
1404
1405
Mike Iselyd8554972006-06-26 20:58:46 -03001406int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1407{
Mike Isely681c7392007-11-26 01:48:52 -03001408 return hdw->state_pipeline_req != 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001409}
1410
1411
1412int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1413{
Mike Isely681c7392007-11-26 01:48:52 -03001414 int ret,st;
Mike Iselyd8554972006-06-26 20:58:46 -03001415 LOCK_TAKE(hdw->big_lock); do {
Mike Isely681c7392007-11-26 01:48:52 -03001416 pvr2_hdw_untrip_unlocked(hdw);
1417 if ((!enable_flag) != !(hdw->state_pipeline_req)) {
1418 hdw->state_pipeline_req = enable_flag != 0;
1419 pvr2_trace(PVR2_TRACE_START_STOP,
1420 "/*--TRACE_STREAM--*/ %s",
1421 enable_flag ? "enable" : "disable");
1422 }
1423 pvr2_hdw_state_sched(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001424 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely681c7392007-11-26 01:48:52 -03001425 if ((ret = pvr2_hdw_wait(hdw,0)) < 0) return ret;
1426 if (enable_flag) {
1427 while ((st = hdw->master_state) != PVR2_STATE_RUN) {
1428 if (st != PVR2_STATE_READY) return -EIO;
1429 if ((ret = pvr2_hdw_wait(hdw,st)) < 0) return ret;
1430 }
1431 }
Mike Iselyd8554972006-06-26 20:58:46 -03001432 return 0;
1433}
1434
1435
1436int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1437{
Mike Isely681c7392007-11-26 01:48:52 -03001438 int fl;
Mike Iselyd8554972006-06-26 20:58:46 -03001439 LOCK_TAKE(hdw->big_lock);
Mike Isely681c7392007-11-26 01:48:52 -03001440 if ((fl = (hdw->desired_stream_type != config)) != 0) {
1441 hdw->desired_stream_type = config;
1442 hdw->state_pipeline_config = 0;
1443 trace_stbit("state_pipeline_config",
1444 hdw->state_pipeline_config);
1445 pvr2_hdw_state_sched(hdw);
1446 }
Mike Iselyd8554972006-06-26 20:58:46 -03001447 LOCK_GIVE(hdw->big_lock);
Mike Isely681c7392007-11-26 01:48:52 -03001448 if (fl) return 0;
1449 return pvr2_hdw_wait(hdw,0);
Mike Iselyd8554972006-06-26 20:58:46 -03001450}
1451
1452
1453static int get_default_tuner_type(struct pvr2_hdw *hdw)
1454{
1455 int unit_number = hdw->unit_number;
1456 int tp = -1;
1457 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1458 tp = tuner[unit_number];
1459 }
1460 if (tp < 0) return -EINVAL;
1461 hdw->tuner_type = tp;
Mike Iselyaaf78842007-11-26 02:04:11 -03001462 hdw->tuner_updated = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03001463 return 0;
1464}
1465
1466
1467static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1468{
1469 int unit_number = hdw->unit_number;
1470 int tp = 0;
1471 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1472 tp = video_std[unit_number];
Mike Isely6a540252007-12-02 23:51:34 -03001473 if (tp) return tp;
Mike Iselyd8554972006-06-26 20:58:46 -03001474 }
Mike Isely6a540252007-12-02 23:51:34 -03001475 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001476}
1477
1478
1479static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1480{
1481 int unit_number = hdw->unit_number;
1482 int tp = 0;
1483 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1484 tp = tolerance[unit_number];
1485 }
1486 return tp;
1487}
1488
1489
1490static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1491{
1492 /* Try a harmless request to fetch the eeprom's address over
1493 endpoint 1. See what happens. Only the full FX2 image can
1494 respond to this. If this probe fails then likely the FX2
1495 firmware needs be loaded. */
1496 int result;
1497 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03001498 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03001499 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1500 hdw->cmd_buffer,1,
1501 hdw->cmd_buffer,1);
1502 if (result < 0) break;
1503 } while(0); LOCK_GIVE(hdw->ctl_lock);
1504 if (result) {
1505 pvr2_trace(PVR2_TRACE_INIT,
1506 "Probe of device endpoint 1 result status %d",
1507 result);
1508 } else {
1509 pvr2_trace(PVR2_TRACE_INIT,
1510 "Probe of device endpoint 1 succeeded");
1511 }
1512 return result == 0;
1513}
1514
Mike Isely9f66d4e2007-09-08 22:28:51 -03001515struct pvr2_std_hack {
1516 v4l2_std_id pat; /* Pattern to match */
1517 v4l2_std_id msk; /* Which bits we care about */
1518 v4l2_std_id std; /* What additional standards or default to set */
1519};
1520
1521/* This data structure labels specific combinations of standards from
1522 tveeprom that we'll try to recognize. If we recognize one, then assume
1523 a specified default standard to use. This is here because tveeprom only
1524 tells us about available standards not the intended default standard (if
1525 any) for the device in question. We guess the default based on what has
1526 been reported as available. Note that this is only for guessing a
1527 default - which can always be overridden explicitly - and if the user
1528 has otherwise named a default then that default will always be used in
1529 place of this table. */
Tobias Klauserebff0332008-04-22 14:45:45 -03001530static const struct pvr2_std_hack std_eeprom_maps[] = {
Mike Isely9f66d4e2007-09-08 22:28:51 -03001531 { /* PAL(B/G) */
1532 .pat = V4L2_STD_B|V4L2_STD_GH,
1533 .std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G,
1534 },
1535 { /* NTSC(M) */
1536 .pat = V4L2_STD_MN,
1537 .std = V4L2_STD_NTSC_M,
1538 },
1539 { /* PAL(I) */
1540 .pat = V4L2_STD_PAL_I,
1541 .std = V4L2_STD_PAL_I,
1542 },
1543 { /* SECAM(L/L') */
1544 .pat = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
1545 .std = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
1546 },
1547 { /* PAL(D/D1/K) */
1548 .pat = V4L2_STD_DK,
Roel Kluinea2562d2007-12-02 23:04:57 -03001549 .std = V4L2_STD_PAL_D|V4L2_STD_PAL_D1|V4L2_STD_PAL_K,
Mike Isely9f66d4e2007-09-08 22:28:51 -03001550 },
1551};
1552
Mike Iselyd8554972006-06-26 20:58:46 -03001553static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1554{
1555 char buf[40];
1556 unsigned int bcnt;
Mike Isely3d290bd2007-12-03 01:47:12 -03001557 v4l2_std_id std1,std2,std3;
Mike Iselyd8554972006-06-26 20:58:46 -03001558
1559 std1 = get_default_standard(hdw);
Mike Isely3d290bd2007-12-03 01:47:12 -03001560 std3 = std1 ? 0 : hdw->hdw_desc->default_std_mask;
Mike Iselyd8554972006-06-26 20:58:46 -03001561
1562 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
Mike Isely56585382007-09-08 22:32:12 -03001563 pvr2_trace(PVR2_TRACE_STD,
Mike Isely56dcbfa2007-11-26 02:00:51 -03001564 "Supported video standard(s) reported available"
1565 " in hardware: %.*s",
Mike Iselyd8554972006-06-26 20:58:46 -03001566 bcnt,buf);
1567
1568 hdw->std_mask_avail = hdw->std_mask_eeprom;
1569
Mike Isely3d290bd2007-12-03 01:47:12 -03001570 std2 = (std1|std3) & ~hdw->std_mask_avail;
Mike Iselyd8554972006-06-26 20:58:46 -03001571 if (std2) {
1572 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
Mike Isely56585382007-09-08 22:32:12 -03001573 pvr2_trace(PVR2_TRACE_STD,
Mike Iselyd8554972006-06-26 20:58:46 -03001574 "Expanding supported video standards"
1575 " to include: %.*s",
1576 bcnt,buf);
1577 hdw->std_mask_avail |= std2;
1578 }
1579
1580 pvr2_hdw_internal_set_std_avail(hdw);
1581
1582 if (std1) {
1583 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
Mike Isely56585382007-09-08 22:32:12 -03001584 pvr2_trace(PVR2_TRACE_STD,
Mike Iselyd8554972006-06-26 20:58:46 -03001585 "Initial video standard forced to %.*s",
1586 bcnt,buf);
1587 hdw->std_mask_cur = std1;
1588 hdw->std_dirty = !0;
1589 pvr2_hdw_internal_find_stdenum(hdw);
1590 return;
1591 }
Mike Isely3d290bd2007-12-03 01:47:12 -03001592 if (std3) {
1593 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std3);
1594 pvr2_trace(PVR2_TRACE_STD,
1595 "Initial video standard"
1596 " (determined by device type): %.*s",bcnt,buf);
1597 hdw->std_mask_cur = std3;
1598 hdw->std_dirty = !0;
1599 pvr2_hdw_internal_find_stdenum(hdw);
1600 return;
1601 }
Mike Iselyd8554972006-06-26 20:58:46 -03001602
Mike Isely9f66d4e2007-09-08 22:28:51 -03001603 {
1604 unsigned int idx;
1605 for (idx = 0; idx < ARRAY_SIZE(std_eeprom_maps); idx++) {
1606 if (std_eeprom_maps[idx].msk ?
1607 ((std_eeprom_maps[idx].pat ^
1608 hdw->std_mask_eeprom) &
1609 std_eeprom_maps[idx].msk) :
1610 (std_eeprom_maps[idx].pat !=
1611 hdw->std_mask_eeprom)) continue;
1612 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),
1613 std_eeprom_maps[idx].std);
Mike Isely56585382007-09-08 22:32:12 -03001614 pvr2_trace(PVR2_TRACE_STD,
Mike Isely9f66d4e2007-09-08 22:28:51 -03001615 "Initial video standard guessed as %.*s",
1616 bcnt,buf);
1617 hdw->std_mask_cur = std_eeprom_maps[idx].std;
1618 hdw->std_dirty = !0;
1619 pvr2_hdw_internal_find_stdenum(hdw);
1620 return;
1621 }
1622 }
1623
Mike Iselyd8554972006-06-26 20:58:46 -03001624 if (hdw->std_enum_cnt > 1) {
1625 // Autoselect the first listed standard
1626 hdw->std_enum_cur = 1;
1627 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1628 hdw->std_dirty = !0;
Mike Isely56585382007-09-08 22:32:12 -03001629 pvr2_trace(PVR2_TRACE_STD,
Mike Iselyd8554972006-06-26 20:58:46 -03001630 "Initial video standard auto-selected to %s",
1631 hdw->std_defs[hdw->std_enum_cur-1].name);
1632 return;
1633 }
1634
Mike Isely0885ba12006-06-25 21:30:47 -03001635 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
Mike Iselyd8554972006-06-26 20:58:46 -03001636 "Unable to select a viable initial video standard");
1637}
1638
1639
1640static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1641{
1642 int ret;
1643 unsigned int idx;
1644 struct pvr2_ctrl *cptr;
1645 int reloadFl = 0;
Mike Isely989eb152007-11-26 01:53:12 -03001646 if (hdw->hdw_desc->fx2_firmware.cnt) {
Mike Isely1d643a32007-09-08 22:18:50 -03001647 if (!reloadFl) {
1648 reloadFl =
1649 (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1650 == 0);
1651 if (reloadFl) {
1652 pvr2_trace(PVR2_TRACE_INIT,
1653 "USB endpoint config looks strange"
1654 "; possibly firmware needs to be"
1655 " loaded");
1656 }
1657 }
1658 if (!reloadFl) {
1659 reloadFl = !pvr2_hdw_check_firmware(hdw);
1660 if (reloadFl) {
1661 pvr2_trace(PVR2_TRACE_INIT,
1662 "Check for FX2 firmware failed"
1663 "; possibly firmware needs to be"
1664 " loaded");
1665 }
1666 }
Mike Iselyd8554972006-06-26 20:58:46 -03001667 if (reloadFl) {
Mike Isely1d643a32007-09-08 22:18:50 -03001668 if (pvr2_upload_firmware1(hdw) != 0) {
1669 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1670 "Failure uploading firmware1");
1671 }
1672 return;
Mike Iselyd8554972006-06-26 20:58:46 -03001673 }
1674 }
Mike Iselyd8554972006-06-26 20:58:46 -03001675 hdw->fw1_state = FW1_STATE_OK;
1676
1677 if (initusbreset) {
1678 pvr2_hdw_device_reset(hdw);
1679 }
1680 if (!pvr2_hdw_dev_ok(hdw)) return;
1681
Mike Isely989eb152007-11-26 01:53:12 -03001682 for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
1683 request_module(hdw->hdw_desc->client_modules.lst[idx]);
Mike Iselyd8554972006-06-26 20:58:46 -03001684 }
1685
Mike Isely989eb152007-11-26 01:53:12 -03001686 if (!hdw->hdw_desc->flag_no_powerup) {
Mike Isely1d643a32007-09-08 22:18:50 -03001687 pvr2_hdw_cmd_powerup(hdw);
1688 if (!pvr2_hdw_dev_ok(hdw)) return;
Mike Iselyd8554972006-06-26 20:58:46 -03001689 }
1690
1691 // This step MUST happen after the earlier powerup step.
1692 pvr2_i2c_core_init(hdw);
1693 if (!pvr2_hdw_dev_ok(hdw)) return;
1694
Mike Iselyc05c0462006-06-25 20:04:25 -03001695 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001696 cptr = hdw->controls + idx;
1697 if (cptr->info->skip_init) continue;
1698 if (!cptr->info->set_value) continue;
1699 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1700 }
1701
Mike Isely1bde0282006-12-27 23:30:13 -03001702 /* Set up special default values for the television and radio
1703 frequencies here. It's not really important what these defaults
1704 are, but I set them to something usable in the Chicago area just
1705 to make driver testing a little easier. */
1706
1707 /* US Broadcast channel 7 (175.25 MHz) */
1708 hdw->freqValTelevision = 175250000L;
1709 /* 104.3 MHz, a usable FM station for my area */
1710 hdw->freqValRadio = 104300000L;
1711
Mike Iselyd8554972006-06-26 20:58:46 -03001712 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1713 // thread-safe against the normal pvr2_send_request() mechanism.
1714 // (We should make it thread safe).
1715
Mike Iselyaaf78842007-11-26 02:04:11 -03001716 if (hdw->hdw_desc->flag_has_hauppauge_rom) {
1717 ret = pvr2_hdw_get_eeprom_addr(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001718 if (!pvr2_hdw_dev_ok(hdw)) return;
Mike Iselyaaf78842007-11-26 02:04:11 -03001719 if (ret < 0) {
1720 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1721 "Unable to determine location of eeprom,"
1722 " skipping");
1723 } else {
1724 hdw->eeprom_addr = ret;
1725 pvr2_eeprom_analyze(hdw);
1726 if (!pvr2_hdw_dev_ok(hdw)) return;
1727 }
1728 } else {
1729 hdw->tuner_type = hdw->hdw_desc->default_tuner_type;
1730 hdw->tuner_updated = !0;
1731 hdw->std_mask_eeprom = V4L2_STD_ALL;
Mike Iselyd8554972006-06-26 20:58:46 -03001732 }
1733
1734 pvr2_hdw_setup_std(hdw);
1735
1736 if (!get_default_tuner_type(hdw)) {
1737 pvr2_trace(PVR2_TRACE_INIT,
1738 "pvr2_hdw_setup: Tuner type overridden to %d",
1739 hdw->tuner_type);
1740 }
1741
Mike Iselyd8554972006-06-26 20:58:46 -03001742 pvr2_i2c_core_check_stale(hdw);
1743 hdw->tuner_updated = 0;
1744
1745 if (!pvr2_hdw_dev_ok(hdw)) return;
1746
Mike Isely681c7392007-11-26 01:48:52 -03001747 pvr2_hdw_commit_setup(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001748
1749 hdw->vid_stream = pvr2_stream_create();
1750 if (!pvr2_hdw_dev_ok(hdw)) return;
1751 pvr2_trace(PVR2_TRACE_INIT,
1752 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1753 if (hdw->vid_stream) {
1754 idx = get_default_error_tolerance(hdw);
1755 if (idx) {
1756 pvr2_trace(PVR2_TRACE_INIT,
1757 "pvr2_hdw_setup: video stream %p"
1758 " setting tolerance %u",
1759 hdw->vid_stream,idx);
1760 }
1761 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1762 PVR2_VID_ENDPOINT,idx);
1763 }
1764
1765 if (!pvr2_hdw_dev_ok(hdw)) return;
1766
Mike Iselyd8554972006-06-26 20:58:46 -03001767 hdw->flag_init_ok = !0;
Mike Isely681c7392007-11-26 01:48:52 -03001768
1769 pvr2_hdw_state_sched(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001770}
1771
1772
Mike Isely681c7392007-11-26 01:48:52 -03001773/* Set up the structure and attempt to put the device into a usable state.
1774 This can be a time-consuming operation, which is why it is not done
1775 internally as part of the create() step. */
1776static void pvr2_hdw_setup(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001777{
1778 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
Mike Isely681c7392007-11-26 01:48:52 -03001779 do {
Mike Iselyd8554972006-06-26 20:58:46 -03001780 pvr2_hdw_setup_low(hdw);
1781 pvr2_trace(PVR2_TRACE_INIT,
1782 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
Mike Isely681c7392007-11-26 01:48:52 -03001783 hdw,pvr2_hdw_dev_ok(hdw),hdw->flag_init_ok);
Mike Iselyd8554972006-06-26 20:58:46 -03001784 if (pvr2_hdw_dev_ok(hdw)) {
Mike Isely681c7392007-11-26 01:48:52 -03001785 if (hdw->flag_init_ok) {
Mike Iselyd8554972006-06-26 20:58:46 -03001786 pvr2_trace(
1787 PVR2_TRACE_INFO,
1788 "Device initialization"
1789 " completed successfully.");
1790 break;
1791 }
1792 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1793 pvr2_trace(
1794 PVR2_TRACE_INFO,
1795 "Device microcontroller firmware"
1796 " (re)loaded; it should now reset"
1797 " and reconnect.");
1798 break;
1799 }
1800 pvr2_trace(
1801 PVR2_TRACE_ERROR_LEGS,
1802 "Device initialization was not successful.");
1803 if (hdw->fw1_state == FW1_STATE_MISSING) {
1804 pvr2_trace(
1805 PVR2_TRACE_ERROR_LEGS,
1806 "Giving up since device"
1807 " microcontroller firmware"
1808 " appears to be missing.");
1809 break;
1810 }
1811 }
1812 if (procreload) {
1813 pvr2_trace(
1814 PVR2_TRACE_ERROR_LEGS,
1815 "Attempting pvrusb2 recovery by reloading"
1816 " primary firmware.");
1817 pvr2_trace(
1818 PVR2_TRACE_ERROR_LEGS,
1819 "If this works, device should disconnect"
1820 " and reconnect in a sane state.");
1821 hdw->fw1_state = FW1_STATE_UNKNOWN;
1822 pvr2_upload_firmware1(hdw);
1823 } else {
1824 pvr2_trace(
1825 PVR2_TRACE_ERROR_LEGS,
1826 "***WARNING*** pvrusb2 device hardware"
1827 " appears to be jammed"
1828 " and I can't clear it.");
1829 pvr2_trace(
1830 PVR2_TRACE_ERROR_LEGS,
1831 "You might need to power cycle"
1832 " the pvrusb2 device"
1833 " in order to recover.");
1834 }
Mike Isely681c7392007-11-26 01:48:52 -03001835 } while (0);
Mike Iselyd8554972006-06-26 20:58:46 -03001836 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001837}
1838
1839
Mike Iselyc4a88282008-04-22 14:45:44 -03001840/* Perform second stage initialization. Set callback pointer first so that
1841 we can avoid a possible initialization race (if the kernel thread runs
1842 before the callback has been set). */
Mike Isely794b1602008-04-22 14:45:45 -03001843int pvr2_hdw_initialize(struct pvr2_hdw *hdw,
1844 void (*callback_func)(void *),
1845 void *callback_data)
Mike Iselyc4a88282008-04-22 14:45:44 -03001846{
1847 LOCK_TAKE(hdw->big_lock); do {
1848 hdw->state_data = callback_data;
1849 hdw->state_func = callback_func;
1850 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely794b1602008-04-22 14:45:45 -03001851 pvr2_hdw_setup(hdw);
1852 return hdw->flag_init_ok;
Mike Iselyc4a88282008-04-22 14:45:44 -03001853}
1854
1855
1856/* Create, set up, and return a structure for interacting with the
1857 underlying hardware. */
Mike Iselyd8554972006-06-26 20:58:46 -03001858struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1859 const struct usb_device_id *devid)
1860{
Mike Isely7fb20fa2008-04-22 14:45:37 -03001861 unsigned int idx,cnt1,cnt2,m;
Mike Iselyd8554972006-06-26 20:58:46 -03001862 struct pvr2_hdw *hdw;
Mike Iselyd8554972006-06-26 20:58:46 -03001863 int valid_std_mask;
1864 struct pvr2_ctrl *cptr;
Mike Isely989eb152007-11-26 01:53:12 -03001865 const struct pvr2_device_desc *hdw_desc;
Mike Iselyd8554972006-06-26 20:58:46 -03001866 __u8 ifnum;
Mike Iselyb30d2442006-06-25 20:05:01 -03001867 struct v4l2_queryctrl qctrl;
1868 struct pvr2_ctl_info *ciptr;
Mike Iselyd8554972006-06-26 20:58:46 -03001869
Mike Iselyd130fa82007-12-08 17:20:06 -03001870 hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info);
Mike Iselyd8554972006-06-26 20:58:46 -03001871
Mike Iselyca545f72007-01-20 00:37:11 -03001872 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -03001873 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
Mike Isely989eb152007-11-26 01:53:12 -03001874 hdw,hdw_desc->description);
Mike Iselyd8554972006-06-26 20:58:46 -03001875 if (!hdw) goto fail;
Mike Isely681c7392007-11-26 01:48:52 -03001876
1877 init_timer(&hdw->quiescent_timer);
1878 hdw->quiescent_timer.data = (unsigned long)hdw;
1879 hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout;
1880
1881 init_timer(&hdw->encoder_wait_timer);
1882 hdw->encoder_wait_timer.data = (unsigned long)hdw;
1883 hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout;
1884
1885 hdw->master_state = PVR2_STATE_DEAD;
1886
1887 init_waitqueue_head(&hdw->state_wait_data);
1888
Mike Isely18103c572007-01-20 00:09:47 -03001889 hdw->tuner_signal_stale = !0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001890 cx2341x_fill_defaults(&hdw->enc_ctl_state);
Mike Iselyd8554972006-06-26 20:58:46 -03001891
Mike Isely7fb20fa2008-04-22 14:45:37 -03001892 /* Calculate which inputs are OK */
1893 m = 0;
1894 if (hdw_desc->flag_has_analogtuner) m |= 1 << PVR2_CVAL_INPUT_TV;
Mike Iselye8f5bac2008-04-22 14:45:40 -03001895 if (hdw_desc->digital_control_scheme != PVR2_DIGITAL_SCHEME_NONE) {
1896 m |= 1 << PVR2_CVAL_INPUT_DTV;
1897 }
Mike Isely7fb20fa2008-04-22 14:45:37 -03001898 if (hdw_desc->flag_has_svideo) m |= 1 << PVR2_CVAL_INPUT_SVIDEO;
1899 if (hdw_desc->flag_has_composite) m |= 1 << PVR2_CVAL_INPUT_COMPOSITE;
1900 if (hdw_desc->flag_has_fmradio) m |= 1 << PVR2_CVAL_INPUT_RADIO;
1901 hdw->input_avail_mask = m;
1902
Mike Isely62433e32008-04-22 14:45:40 -03001903 /* If not a hybrid device, pathway_state never changes. So
1904 initialize it here to what it should forever be. */
1905 if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_DTV))) {
1906 hdw->pathway_state = PVR2_PATHWAY_ANALOG;
1907 } else if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_TV))) {
1908 hdw->pathway_state = PVR2_PATHWAY_DIGITAL;
1909 }
1910
Mike Iselyc05c0462006-06-25 20:04:25 -03001911 hdw->control_cnt = CTRLDEF_COUNT;
Mike Iselyb30d2442006-06-25 20:05:01 -03001912 hdw->control_cnt += MPEGDEF_COUNT;
Mike Iselyca545f72007-01-20 00:37:11 -03001913 hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001914 GFP_KERNEL);
1915 if (!hdw->controls) goto fail;
Mike Isely989eb152007-11-26 01:53:12 -03001916 hdw->hdw_desc = hdw_desc;
Mike Iselyc05c0462006-06-25 20:04:25 -03001917 for (idx = 0; idx < hdw->control_cnt; idx++) {
1918 cptr = hdw->controls + idx;
1919 cptr->hdw = hdw;
1920 }
Mike Iselyd8554972006-06-26 20:58:46 -03001921 for (idx = 0; idx < 32; idx++) {
1922 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1923 }
Mike Iselyc05c0462006-06-25 20:04:25 -03001924 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001925 cptr = hdw->controls + idx;
Mike Iselyd8554972006-06-26 20:58:46 -03001926 cptr->info = control_defs+idx;
1927 }
Mike Iselydbc40a02008-04-22 14:45:39 -03001928
1929 /* Ensure that default input choice is a valid one. */
1930 m = hdw->input_avail_mask;
1931 if (m) for (idx = 0; idx < (sizeof(m) << 3); idx++) {
1932 if (!((1 << idx) & m)) continue;
1933 hdw->input_val = idx;
1934 break;
1935 }
1936
Mike Iselyb30d2442006-06-25 20:05:01 -03001937 /* Define and configure additional controls from cx2341x module. */
Mike Iselyca545f72007-01-20 00:37:11 -03001938 hdw->mpeg_ctrl_info = kzalloc(
Mike Iselyb30d2442006-06-25 20:05:01 -03001939 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
1940 if (!hdw->mpeg_ctrl_info) goto fail;
Mike Iselyb30d2442006-06-25 20:05:01 -03001941 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
1942 cptr = hdw->controls + idx + CTRLDEF_COUNT;
1943 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
1944 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
1945 ciptr->name = mpeg_ids[idx].strid;
1946 ciptr->v4l_id = mpeg_ids[idx].id;
1947 ciptr->skip_init = !0;
1948 ciptr->get_value = ctrl_cx2341x_get;
1949 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
1950 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
1951 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
1952 qctrl.id = ciptr->v4l_id;
1953 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
1954 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
1955 ciptr->set_value = ctrl_cx2341x_set;
1956 }
1957 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
1958 PVR2_CTLD_INFO_DESC_SIZE);
1959 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
1960 ciptr->default_value = qctrl.default_value;
1961 switch (qctrl.type) {
1962 default:
1963 case V4L2_CTRL_TYPE_INTEGER:
1964 ciptr->type = pvr2_ctl_int;
1965 ciptr->def.type_int.min_value = qctrl.minimum;
1966 ciptr->def.type_int.max_value = qctrl.maximum;
1967 break;
1968 case V4L2_CTRL_TYPE_BOOLEAN:
1969 ciptr->type = pvr2_ctl_bool;
1970 break;
1971 case V4L2_CTRL_TYPE_MENU:
1972 ciptr->type = pvr2_ctl_enum;
1973 ciptr->def.type_enum.value_names =
1974 cx2341x_ctrl_get_menu(ciptr->v4l_id);
1975 for (cnt1 = 0;
1976 ciptr->def.type_enum.value_names[cnt1] != NULL;
1977 cnt1++) { }
1978 ciptr->def.type_enum.count = cnt1;
1979 break;
1980 }
1981 cptr->info = ciptr;
1982 }
Mike Iselyd8554972006-06-26 20:58:46 -03001983
1984 // Initialize video standard enum dynamic control
1985 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
1986 if (cptr) {
1987 memcpy(&hdw->std_info_enum,cptr->info,
1988 sizeof(hdw->std_info_enum));
1989 cptr->info = &hdw->std_info_enum;
1990
1991 }
1992 // Initialize control data regarding video standard masks
1993 valid_std_mask = pvr2_std_get_usable();
1994 for (idx = 0; idx < 32; idx++) {
1995 if (!(valid_std_mask & (1 << idx))) continue;
1996 cnt1 = pvr2_std_id_to_str(
1997 hdw->std_mask_names[idx],
1998 sizeof(hdw->std_mask_names[idx])-1,
1999 1 << idx);
2000 hdw->std_mask_names[idx][cnt1] = 0;
2001 }
2002 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
2003 if (cptr) {
2004 memcpy(&hdw->std_info_avail,cptr->info,
2005 sizeof(hdw->std_info_avail));
2006 cptr->info = &hdw->std_info_avail;
2007 hdw->std_info_avail.def.type_bitmask.bit_names =
2008 hdw->std_mask_ptrs;
2009 hdw->std_info_avail.def.type_bitmask.valid_bits =
2010 valid_std_mask;
2011 }
2012 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
2013 if (cptr) {
2014 memcpy(&hdw->std_info_cur,cptr->info,
2015 sizeof(hdw->std_info_cur));
2016 cptr->info = &hdw->std_info_cur;
2017 hdw->std_info_cur.def.type_bitmask.bit_names =
2018 hdw->std_mask_ptrs;
2019 hdw->std_info_avail.def.type_bitmask.valid_bits =
2020 valid_std_mask;
2021 }
2022
2023 hdw->eeprom_addr = -1;
2024 hdw->unit_number = -1;
Mike Isely80793842006-12-27 23:12:28 -03002025 hdw->v4l_minor_number_video = -1;
2026 hdw->v4l_minor_number_vbi = -1;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002027 hdw->v4l_minor_number_radio = -1;
Mike Iselyd8554972006-06-26 20:58:46 -03002028 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2029 if (!hdw->ctl_write_buffer) goto fail;
2030 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2031 if (!hdw->ctl_read_buffer) goto fail;
2032 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
2033 if (!hdw->ctl_write_urb) goto fail;
2034 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
2035 if (!hdw->ctl_read_urb) goto fail;
2036
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002037 mutex_lock(&pvr2_unit_mtx); do {
Mike Iselyd8554972006-06-26 20:58:46 -03002038 for (idx = 0; idx < PVR_NUM; idx++) {
2039 if (unit_pointers[idx]) continue;
2040 hdw->unit_number = idx;
2041 unit_pointers[idx] = hdw;
2042 break;
2043 }
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002044 } while (0); mutex_unlock(&pvr2_unit_mtx);
Mike Iselyd8554972006-06-26 20:58:46 -03002045
2046 cnt1 = 0;
2047 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
2048 cnt1 += cnt2;
2049 if (hdw->unit_number >= 0) {
2050 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
2051 ('a' + hdw->unit_number));
2052 cnt1 += cnt2;
2053 }
2054 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
2055 hdw->name[cnt1] = 0;
2056
Mike Isely681c7392007-11-26 01:48:52 -03002057 hdw->workqueue = create_singlethread_workqueue(hdw->name);
2058 INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll);
2059 INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c);
Mike Isely681c7392007-11-26 01:48:52 -03002060
Mike Iselyd8554972006-06-26 20:58:46 -03002061 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
2062 hdw->unit_number,hdw->name);
2063
2064 hdw->tuner_type = -1;
2065 hdw->flag_ok = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002066
2067 hdw->usb_intf = intf;
2068 hdw->usb_dev = interface_to_usbdev(intf);
2069
Mike Isely31a18542007-04-08 01:11:47 -03002070 scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
2071 "usb %s address %d",
2072 hdw->usb_dev->dev.bus_id,
2073 hdw->usb_dev->devnum);
2074
Mike Iselyd8554972006-06-26 20:58:46 -03002075 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2076 usb_set_interface(hdw->usb_dev,ifnum,0);
2077
2078 mutex_init(&hdw->ctl_lock_mutex);
2079 mutex_init(&hdw->big_lock_mutex);
2080
2081 return hdw;
2082 fail:
2083 if (hdw) {
Mike Isely681c7392007-11-26 01:48:52 -03002084 del_timer_sync(&hdw->quiescent_timer);
2085 del_timer_sync(&hdw->encoder_wait_timer);
2086 if (hdw->workqueue) {
2087 flush_workqueue(hdw->workqueue);
2088 destroy_workqueue(hdw->workqueue);
2089 hdw->workqueue = NULL;
2090 }
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002091 usb_free_urb(hdw->ctl_read_urb);
2092 usb_free_urb(hdw->ctl_write_urb);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002093 kfree(hdw->ctl_read_buffer);
2094 kfree(hdw->ctl_write_buffer);
2095 kfree(hdw->controls);
2096 kfree(hdw->mpeg_ctrl_info);
Mike Isely681c7392007-11-26 01:48:52 -03002097 kfree(hdw->std_defs);
2098 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002099 kfree(hdw);
2100 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002101 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002102}
2103
2104
2105/* Remove _all_ associations between this driver and the underlying USB
2106 layer. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002107static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002108{
2109 if (hdw->flag_disconnected) return;
2110 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
2111 if (hdw->ctl_read_urb) {
2112 usb_kill_urb(hdw->ctl_read_urb);
2113 usb_free_urb(hdw->ctl_read_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002114 hdw->ctl_read_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002115 }
2116 if (hdw->ctl_write_urb) {
2117 usb_kill_urb(hdw->ctl_write_urb);
2118 usb_free_urb(hdw->ctl_write_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002119 hdw->ctl_write_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002120 }
2121 if (hdw->ctl_read_buffer) {
2122 kfree(hdw->ctl_read_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002123 hdw->ctl_read_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002124 }
2125 if (hdw->ctl_write_buffer) {
2126 kfree(hdw->ctl_write_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002127 hdw->ctl_write_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002128 }
Mike Iselyd8554972006-06-26 20:58:46 -03002129 hdw->flag_disconnected = !0;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002130 hdw->usb_dev = NULL;
2131 hdw->usb_intf = NULL;
Mike Isely681c7392007-11-26 01:48:52 -03002132 pvr2_hdw_render_useless(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002133}
2134
2135
2136/* Destroy hardware interaction structure */
2137void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2138{
Mike Isely401c27c2007-09-08 22:11:46 -03002139 if (!hdw) return;
Mike Iselyd8554972006-06-26 20:58:46 -03002140 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
Mike Isely681c7392007-11-26 01:48:52 -03002141 if (hdw->workqueue) {
2142 flush_workqueue(hdw->workqueue);
2143 destroy_workqueue(hdw->workqueue);
2144 hdw->workqueue = NULL;
2145 }
Mike Isely8f591002008-04-22 14:45:45 -03002146 del_timer_sync(&hdw->quiescent_timer);
2147 del_timer_sync(&hdw->encoder_wait_timer);
Mike Iselyd8554972006-06-26 20:58:46 -03002148 if (hdw->fw_buffer) {
2149 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002150 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002151 }
2152 if (hdw->vid_stream) {
2153 pvr2_stream_destroy(hdw->vid_stream);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002154 hdw->vid_stream = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002155 }
Mike Iselyd8554972006-06-26 20:58:46 -03002156 if (hdw->decoder_ctrl) {
2157 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2158 }
2159 pvr2_i2c_core_done(hdw);
2160 pvr2_hdw_remove_usb_stuff(hdw);
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002161 mutex_lock(&pvr2_unit_mtx); do {
Mike Iselyd8554972006-06-26 20:58:46 -03002162 if ((hdw->unit_number >= 0) &&
2163 (hdw->unit_number < PVR_NUM) &&
2164 (unit_pointers[hdw->unit_number] == hdw)) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002165 unit_pointers[hdw->unit_number] = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002166 }
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002167 } while (0); mutex_unlock(&pvr2_unit_mtx);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002168 kfree(hdw->controls);
2169 kfree(hdw->mpeg_ctrl_info);
2170 kfree(hdw->std_defs);
2171 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002172 kfree(hdw);
2173}
2174
2175
Mike Iselyd8554972006-06-26 20:58:46 -03002176int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2177{
2178 return (hdw && hdw->flag_ok);
2179}
2180
2181
2182/* Called when hardware has been unplugged */
2183void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2184{
2185 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2186 LOCK_TAKE(hdw->big_lock);
2187 LOCK_TAKE(hdw->ctl_lock);
2188 pvr2_hdw_remove_usb_stuff(hdw);
2189 LOCK_GIVE(hdw->ctl_lock);
2190 LOCK_GIVE(hdw->big_lock);
2191}
2192
2193
2194// Attempt to autoselect an appropriate value for std_enum_cur given
2195// whatever is currently in std_mask_cur
Adrian Bunk07e337e2006-06-30 11:30:20 -03002196static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002197{
2198 unsigned int idx;
2199 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2200 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2201 hdw->std_enum_cur = idx;
2202 return;
2203 }
2204 }
2205 hdw->std_enum_cur = 0;
2206}
2207
2208
2209// Calculate correct set of enumerated standards based on currently known
2210// set of available standards bits.
Adrian Bunk07e337e2006-06-30 11:30:20 -03002211static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002212{
2213 struct v4l2_standard *newstd;
2214 unsigned int std_cnt;
2215 unsigned int idx;
2216
2217 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2218
2219 if (hdw->std_defs) {
2220 kfree(hdw->std_defs);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002221 hdw->std_defs = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002222 }
2223 hdw->std_enum_cnt = 0;
2224 if (hdw->std_enum_names) {
2225 kfree(hdw->std_enum_names);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002226 hdw->std_enum_names = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002227 }
2228
2229 if (!std_cnt) {
2230 pvr2_trace(
2231 PVR2_TRACE_ERROR_LEGS,
2232 "WARNING: Failed to identify any viable standards");
2233 }
2234 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2235 hdw->std_enum_names[0] = "none";
2236 for (idx = 0; idx < std_cnt; idx++) {
2237 hdw->std_enum_names[idx+1] =
2238 newstd[idx].name;
2239 }
2240 // Set up the dynamic control for this standard
2241 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2242 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2243 hdw->std_defs = newstd;
2244 hdw->std_enum_cnt = std_cnt+1;
2245 hdw->std_enum_cur = 0;
2246 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2247}
2248
2249
2250int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2251 struct v4l2_standard *std,
2252 unsigned int idx)
2253{
2254 int ret = -EINVAL;
2255 if (!idx) return ret;
2256 LOCK_TAKE(hdw->big_lock); do {
2257 if (idx >= hdw->std_enum_cnt) break;
2258 idx--;
2259 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2260 ret = 0;
2261 } while (0); LOCK_GIVE(hdw->big_lock);
2262 return ret;
2263}
2264
2265
2266/* Get the number of defined controls */
2267unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2268{
Mike Iselyc05c0462006-06-25 20:04:25 -03002269 return hdw->control_cnt;
Mike Iselyd8554972006-06-26 20:58:46 -03002270}
2271
2272
2273/* Retrieve a control handle given its index (0..count-1) */
2274struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2275 unsigned int idx)
2276{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002277 if (idx >= hdw->control_cnt) return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002278 return hdw->controls + idx;
2279}
2280
2281
2282/* Retrieve a control handle given its index (0..count-1) */
2283struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2284 unsigned int ctl_id)
2285{
2286 struct pvr2_ctrl *cptr;
2287 unsigned int idx;
2288 int i;
2289
2290 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002291 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002292 cptr = hdw->controls + idx;
2293 i = cptr->info->internal_id;
2294 if (i && (i == ctl_id)) return cptr;
2295 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002296 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002297}
2298
2299
Mike Iselya761f432006-06-25 20:04:44 -03002300/* Given a V4L ID, retrieve the control structure associated with it. */
Mike Iselyd8554972006-06-26 20:58:46 -03002301struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2302{
2303 struct pvr2_ctrl *cptr;
2304 unsigned int idx;
2305 int i;
2306
2307 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002308 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002309 cptr = hdw->controls + idx;
2310 i = cptr->info->v4l_id;
2311 if (i && (i == ctl_id)) return cptr;
2312 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002313 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002314}
2315
2316
Mike Iselya761f432006-06-25 20:04:44 -03002317/* Given a V4L ID for its immediate predecessor, retrieve the control
2318 structure associated with it. */
2319struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2320 unsigned int ctl_id)
2321{
2322 struct pvr2_ctrl *cptr,*cp2;
2323 unsigned int idx;
2324 int i;
2325
2326 /* This could be made a lot more efficient, but for now... */
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002327 cp2 = NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002328 for (idx = 0; idx < hdw->control_cnt; idx++) {
2329 cptr = hdw->controls + idx;
2330 i = cptr->info->v4l_id;
2331 if (!i) continue;
2332 if (i <= ctl_id) continue;
2333 if (cp2 && (cp2->info->v4l_id < i)) continue;
2334 cp2 = cptr;
2335 }
2336 return cp2;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002337 return NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002338}
2339
2340
Mike Iselyd8554972006-06-26 20:58:46 -03002341static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2342{
2343 switch (tp) {
2344 case pvr2_ctl_int: return "integer";
2345 case pvr2_ctl_enum: return "enum";
Mike Isely33213962006-06-25 20:04:40 -03002346 case pvr2_ctl_bool: return "boolean";
Mike Iselyd8554972006-06-26 20:58:46 -03002347 case pvr2_ctl_bitmask: return "bitmask";
2348 }
2349 return "";
2350}
2351
2352
Mike Isely681c7392007-11-26 01:48:52 -03002353/* Figure out if we need to commit control changes. If so, mark internal
2354 state flags to indicate this fact and return true. Otherwise do nothing
2355 else and return false. */
2356static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002357{
Mike Iselyd8554972006-06-26 20:58:46 -03002358 unsigned int idx;
2359 struct pvr2_ctrl *cptr;
2360 int value;
2361 int commit_flag = 0;
2362 char buf[100];
2363 unsigned int bcnt,ccnt;
2364
Mike Iselyc05c0462006-06-25 20:04:25 -03002365 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002366 cptr = hdw->controls + idx;
Al Viro5fa12472008-03-29 03:07:38 +00002367 if (!cptr->info->is_dirty) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002368 if (!cptr->info->is_dirty(cptr)) continue;
Mike Iselyfe23a282007-01-20 00:10:55 -03002369 commit_flag = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002370
Mike Iselyfe23a282007-01-20 00:10:55 -03002371 if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002372 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2373 cptr->info->name);
2374 value = 0;
2375 cptr->info->get_value(cptr,&value);
2376 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2377 buf+bcnt,
2378 sizeof(buf)-bcnt,&ccnt);
2379 bcnt += ccnt;
2380 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2381 get_ctrl_typename(cptr->info->type));
2382 pvr2_trace(PVR2_TRACE_CTL,
2383 "/*--TRACE_COMMIT--*/ %.*s",
2384 bcnt,buf);
2385 }
2386
2387 if (!commit_flag) {
2388 /* Nothing has changed */
2389 return 0;
2390 }
2391
Mike Isely681c7392007-11-26 01:48:52 -03002392 hdw->state_pipeline_config = 0;
2393 trace_stbit("state_pipeline_config",hdw->state_pipeline_config);
2394 pvr2_hdw_state_sched(hdw);
2395
2396 return !0;
2397}
2398
2399
2400/* Perform all operations needed to commit all control changes. This must
2401 be performed in synchronization with the pipeline state and is thus
2402 expected to be called as part of the driver's worker thread. Return
2403 true if commit successful, otherwise return false to indicate that
2404 commit isn't possible at this time. */
2405static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
2406{
2407 unsigned int idx;
2408 struct pvr2_ctrl *cptr;
2409 int disruptive_change;
2410
Mike Iselyd8554972006-06-26 20:58:46 -03002411 /* When video standard changes, reset the hres and vres values -
2412 but if the user has pending changes there, then let the changes
2413 take priority. */
2414 if (hdw->std_dirty) {
2415 /* Rewrite the vertical resolution to be appropriate to the
2416 video standard that has been selected. */
2417 int nvres;
2418 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2419 nvres = 480;
2420 } else {
2421 nvres = 576;
2422 }
2423 if (nvres != hdw->res_ver_val) {
2424 hdw->res_ver_val = nvres;
2425 hdw->res_ver_dirty = !0;
2426 }
Mike Iselyd8554972006-06-26 20:58:46 -03002427 }
2428
Mike Isely38d9a2c2008-03-28 05:30:48 -03002429 if (hdw->input_dirty && hdw->state_pathway_ok &&
Mike Isely62433e32008-04-22 14:45:40 -03002430 (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ?
2431 PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) !=
2432 hdw->pathway_state)) {
2433 /* Change of mode being asked for... */
2434 hdw->state_pathway_ok = 0;
Mike Iselye9db1ff2008-04-22 14:45:41 -03002435 trace_stbit("state_pathway_ok",hdw->state_pathway_ok);
Mike Isely62433e32008-04-22 14:45:40 -03002436 }
2437 if (!hdw->state_pathway_ok) {
2438 /* Can't commit anything until pathway is ok. */
2439 return 0;
2440 }
Mike Isely681c7392007-11-26 01:48:52 -03002441 /* If any of the below has changed, then we can't do the update
2442 while the pipeline is running. Pipeline must be paused first
2443 and decoder -> encoder connection be made quiescent before we
2444 can proceed. */
2445 disruptive_change =
2446 (hdw->std_dirty ||
2447 hdw->enc_unsafe_stale ||
2448 hdw->srate_dirty ||
2449 hdw->res_ver_dirty ||
2450 hdw->res_hor_dirty ||
2451 hdw->input_dirty ||
2452 (hdw->active_stream_type != hdw->desired_stream_type));
2453 if (disruptive_change && !hdw->state_pipeline_idle) {
2454 /* Pipeline is not idle; we can't proceed. Arrange to
2455 cause pipeline to stop so that we can try this again
2456 later.... */
2457 hdw->state_pipeline_pause = !0;
2458 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002459 }
2460
Mike Iselyb30d2442006-06-25 20:05:01 -03002461 if (hdw->srate_dirty) {
2462 /* Write new sample rate into control structure since
2463 * the master copy is stale. We must track srate
2464 * separate from the mpeg control structure because
2465 * other logic also uses this value. */
2466 struct v4l2_ext_controls cs;
2467 struct v4l2_ext_control c1;
2468 memset(&cs,0,sizeof(cs));
2469 memset(&c1,0,sizeof(c1));
2470 cs.controls = &c1;
2471 cs.count = 1;
2472 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2473 c1.value = hdw->srate_val;
Hans Verkuil01f1e442007-08-21 18:32:42 -03002474 cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
Mike Iselyb30d2442006-06-25 20:05:01 -03002475 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002476
Mike Iselyd8554972006-06-26 20:58:46 -03002477 /* Scan i2c core at this point - before we clear all the dirty
2478 bits. Various parts of the i2c core will notice dirty bits as
2479 appropriate and arrange to broadcast or directly send updates to
2480 the client drivers in order to keep everything in sync */
2481 pvr2_i2c_core_check_stale(hdw);
2482
Mike Iselyc05c0462006-06-25 20:04:25 -03002483 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002484 cptr = hdw->controls + idx;
2485 if (!cptr->info->clear_dirty) continue;
2486 cptr->info->clear_dirty(cptr);
2487 }
2488
Mike Isely681c7392007-11-26 01:48:52 -03002489 if (hdw->active_stream_type != hdw->desired_stream_type) {
2490 /* Handle any side effects of stream config here */
2491 hdw->active_stream_type = hdw->desired_stream_type;
2492 }
2493
Mike Iselyd8554972006-06-26 20:58:46 -03002494 /* Now execute i2c core update */
2495 pvr2_i2c_core_sync(hdw);
2496
Mike Isely62433e32008-04-22 14:45:40 -03002497 if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
2498 hdw->state_encoder_run) {
2499 /* If encoder isn't running or it can't be touched, then
2500 this will get worked out later when we start the
2501 encoder. */
Mike Isely681c7392007-11-26 01:48:52 -03002502 if (pvr2_encoder_adjust(hdw) < 0) return !0;
2503 }
Mike Iselyd8554972006-06-26 20:58:46 -03002504
Mike Isely681c7392007-11-26 01:48:52 -03002505 hdw->state_pipeline_config = !0;
2506 trace_stbit("state_pipeline_config",hdw->state_pipeline_config);
2507 return !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002508}
2509
2510
2511int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2512{
Mike Isely681c7392007-11-26 01:48:52 -03002513 int fl;
2514 LOCK_TAKE(hdw->big_lock);
2515 fl = pvr2_hdw_commit_setup(hdw);
2516 LOCK_GIVE(hdw->big_lock);
2517 if (!fl) return 0;
2518 return pvr2_hdw_wait(hdw,0);
Mike Iselyd8554972006-06-26 20:58:46 -03002519}
2520
2521
Mike Isely681c7392007-11-26 01:48:52 -03002522static void pvr2_hdw_worker_i2c(struct work_struct *work)
Mike Iselyd8554972006-06-26 20:58:46 -03002523{
Mike Isely681c7392007-11-26 01:48:52 -03002524 struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync);
Mike Iselyd8554972006-06-26 20:58:46 -03002525 LOCK_TAKE(hdw->big_lock); do {
2526 pvr2_i2c_core_sync(hdw);
2527 } while (0); LOCK_GIVE(hdw->big_lock);
2528}
2529
2530
Mike Isely681c7392007-11-26 01:48:52 -03002531static void pvr2_hdw_worker_poll(struct work_struct *work)
Mike Iselyd8554972006-06-26 20:58:46 -03002532{
Mike Isely681c7392007-11-26 01:48:52 -03002533 int fl = 0;
2534 struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,workpoll);
Mike Iselyd8554972006-06-26 20:58:46 -03002535 LOCK_TAKE(hdw->big_lock); do {
Mike Isely681c7392007-11-26 01:48:52 -03002536 fl = pvr2_hdw_state_eval(hdw);
2537 } while (0); LOCK_GIVE(hdw->big_lock);
2538 if (fl && hdw->state_func) {
2539 hdw->state_func(hdw->state_data);
2540 }
2541}
2542
2543
Mike Isely681c7392007-11-26 01:48:52 -03002544static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state)
Mike Iselyd8554972006-06-26 20:58:46 -03002545{
Mike Isely681c7392007-11-26 01:48:52 -03002546 return wait_event_interruptible(
2547 hdw->state_wait_data,
2548 (hdw->state_stale == 0) &&
2549 (!state || (hdw->master_state != state)));
Mike Iselyd8554972006-06-26 20:58:46 -03002550}
2551
Mike Isely681c7392007-11-26 01:48:52 -03002552
Mike Iselyd8554972006-06-26 20:58:46 -03002553/* Return name for this driver instance */
2554const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2555{
2556 return hdw->name;
2557}
2558
2559
Mike Isely78a47102007-11-26 01:58:20 -03002560const char *pvr2_hdw_get_desc(struct pvr2_hdw *hdw)
2561{
2562 return hdw->hdw_desc->description;
2563}
2564
2565
2566const char *pvr2_hdw_get_type(struct pvr2_hdw *hdw)
2567{
2568 return hdw->hdw_desc->shortname;
2569}
2570
2571
Mike Iselyd8554972006-06-26 20:58:46 -03002572int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2573{
2574 int result;
2575 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03002576 hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED;
Mike Iselyd8554972006-06-26 20:58:46 -03002577 result = pvr2_send_request(hdw,
2578 hdw->cmd_buffer,1,
2579 hdw->cmd_buffer,1);
2580 if (result < 0) break;
2581 result = (hdw->cmd_buffer[0] != 0);
2582 } while(0); LOCK_GIVE(hdw->ctl_lock);
2583 return result;
2584}
2585
2586
Mike Isely18103c572007-01-20 00:09:47 -03002587/* Execute poll of tuner status */
2588void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002589{
Mike Iselyd8554972006-06-26 20:58:46 -03002590 LOCK_TAKE(hdw->big_lock); do {
Mike Isely18103c572007-01-20 00:09:47 -03002591 pvr2_i2c_core_status_poll(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002592 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely18103c572007-01-20 00:09:47 -03002593}
2594
2595
2596/* Return information about the tuner */
2597int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
2598{
2599 LOCK_TAKE(hdw->big_lock); do {
2600 if (hdw->tuner_signal_stale) {
2601 pvr2_i2c_core_status_poll(hdw);
2602 }
2603 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
2604 } while (0); LOCK_GIVE(hdw->big_lock);
2605 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002606}
2607
2608
2609/* Get handle to video output stream */
2610struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2611{
2612 return hp->vid_stream;
2613}
2614
2615
2616void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2617{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002618 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002619 LOCK_TAKE(hdw->big_lock); do {
2620 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002621 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002622 pvr2_i2c_core_check_stale(hdw);
2623 hdw->log_requested = 0;
2624 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002625 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002626 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely681c7392007-11-26 01:48:52 -03002627 pvr2_hdw_state_log_state(hdw);
Mike Isely4f1a3e52006-06-25 20:04:31 -03002628 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002629 } while (0); LOCK_GIVE(hdw->big_lock);
2630}
2631
Mike Isely4db666c2007-09-08 22:16:27 -03002632
2633/* Grab EEPROM contents, needed for direct method. */
2634#define EEPROM_SIZE 8192
2635#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
2636static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw)
2637{
2638 struct i2c_msg msg[2];
2639 u8 *eeprom;
2640 u8 iadd[2];
2641 u8 addr;
2642 u16 eepromSize;
2643 unsigned int offs;
2644 int ret;
2645 int mode16 = 0;
2646 unsigned pcnt,tcnt;
2647 eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
2648 if (!eeprom) {
2649 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2650 "Failed to allocate memory"
2651 " required to read eeprom");
2652 return NULL;
2653 }
2654
2655 trace_eeprom("Value for eeprom addr from controller was 0x%x",
2656 hdw->eeprom_addr);
2657 addr = hdw->eeprom_addr;
2658 /* Seems that if the high bit is set, then the *real* eeprom
2659 address is shifted right now bit position (noticed this in
2660 newer PVR USB2 hardware) */
2661 if (addr & 0x80) addr >>= 1;
2662
2663 /* FX2 documentation states that a 16bit-addressed eeprom is
2664 expected if the I2C address is an odd number (yeah, this is
2665 strange but it's what they do) */
2666 mode16 = (addr & 1);
2667 eepromSize = (mode16 ? EEPROM_SIZE : 256);
2668 trace_eeprom("Examining %d byte eeprom at location 0x%x"
2669 " using %d bit addressing",eepromSize,addr,
2670 mode16 ? 16 : 8);
2671
2672 msg[0].addr = addr;
2673 msg[0].flags = 0;
2674 msg[0].len = mode16 ? 2 : 1;
2675 msg[0].buf = iadd;
2676 msg[1].addr = addr;
2677 msg[1].flags = I2C_M_RD;
2678
2679 /* We have to do the actual eeprom data fetch ourselves, because
2680 (1) we're only fetching part of the eeprom, and (2) if we were
2681 getting the whole thing our I2C driver can't grab it in one
2682 pass - which is what tveeprom is otherwise going to attempt */
2683 memset(eeprom,0,EEPROM_SIZE);
2684 for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
2685 pcnt = 16;
2686 if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
2687 offs = tcnt + (eepromSize - EEPROM_SIZE);
2688 if (mode16) {
2689 iadd[0] = offs >> 8;
2690 iadd[1] = offs;
2691 } else {
2692 iadd[0] = offs;
2693 }
2694 msg[1].len = pcnt;
2695 msg[1].buf = eeprom+tcnt;
2696 if ((ret = i2c_transfer(&hdw->i2c_adap,
2697 msg,ARRAY_SIZE(msg))) != 2) {
2698 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2699 "eeprom fetch set offs err=%d",ret);
2700 kfree(eeprom);
2701 return NULL;
2702 }
2703 }
2704 return eeprom;
2705}
2706
2707
2708void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
2709 int prom_flag,
2710 int enable_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002711{
2712 int ret;
2713 u16 address;
2714 unsigned int pipe;
2715 LOCK_TAKE(hdw->big_lock); do {
Al Viro5fa12472008-03-29 03:07:38 +00002716 if ((hdw->fw_buffer == NULL) == !enable_flag) break;
Mike Iselyd8554972006-06-26 20:58:46 -03002717
2718 if (!enable_flag) {
2719 pvr2_trace(PVR2_TRACE_FIRMWARE,
2720 "Cleaning up after CPU firmware fetch");
2721 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002722 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002723 hdw->fw_size = 0;
Mike Isely4db666c2007-09-08 22:16:27 -03002724 if (hdw->fw_cpu_flag) {
2725 /* Now release the CPU. It will disconnect
2726 and reconnect later. */
2727 pvr2_hdw_cpureset_assert(hdw,0);
2728 }
Mike Iselyd8554972006-06-26 20:58:46 -03002729 break;
2730 }
2731
Mike Isely4db666c2007-09-08 22:16:27 -03002732 hdw->fw_cpu_flag = (prom_flag == 0);
2733 if (hdw->fw_cpu_flag) {
2734 pvr2_trace(PVR2_TRACE_FIRMWARE,
2735 "Preparing to suck out CPU firmware");
2736 hdw->fw_size = 0x2000;
2737 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
2738 if (!hdw->fw_buffer) {
2739 hdw->fw_size = 0;
2740 break;
2741 }
2742
2743 /* We have to hold the CPU during firmware upload. */
2744 pvr2_hdw_cpureset_assert(hdw,1);
2745
2746 /* download the firmware from address 0000-1fff in 2048
2747 (=0x800) bytes chunk. */
2748
2749 pvr2_trace(PVR2_TRACE_FIRMWARE,
2750 "Grabbing CPU firmware");
2751 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2752 for(address = 0; address < hdw->fw_size;
2753 address += 0x800) {
2754 ret = usb_control_msg(hdw->usb_dev,pipe,
2755 0xa0,0xc0,
2756 address,0,
2757 hdw->fw_buffer+address,
2758 0x800,HZ);
2759 if (ret < 0) break;
2760 }
2761
2762 pvr2_trace(PVR2_TRACE_FIRMWARE,
2763 "Done grabbing CPU firmware");
2764 } else {
2765 pvr2_trace(PVR2_TRACE_FIRMWARE,
2766 "Sucking down EEPROM contents");
2767 hdw->fw_buffer = pvr2_full_eeprom_fetch(hdw);
2768 if (!hdw->fw_buffer) {
2769 pvr2_trace(PVR2_TRACE_FIRMWARE,
2770 "EEPROM content suck failed.");
2771 break;
2772 }
2773 hdw->fw_size = EEPROM_SIZE;
2774 pvr2_trace(PVR2_TRACE_FIRMWARE,
2775 "Done sucking down EEPROM contents");
Mike Iselyd8554972006-06-26 20:58:46 -03002776 }
2777
Mike Iselyd8554972006-06-26 20:58:46 -03002778 } while (0); LOCK_GIVE(hdw->big_lock);
2779}
2780
2781
2782/* Return true if we're in a mode for retrieval CPU firmware */
2783int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2784{
Al Viro5fa12472008-03-29 03:07:38 +00002785 return hdw->fw_buffer != NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002786}
2787
2788
2789int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2790 char *buf,unsigned int cnt)
2791{
2792 int ret = -EINVAL;
2793 LOCK_TAKE(hdw->big_lock); do {
2794 if (!buf) break;
2795 if (!cnt) break;
2796
2797 if (!hdw->fw_buffer) {
2798 ret = -EIO;
2799 break;
2800 }
2801
2802 if (offs >= hdw->fw_size) {
2803 pvr2_trace(PVR2_TRACE_FIRMWARE,
2804 "Read firmware data offs=%d EOF",
2805 offs);
2806 ret = 0;
2807 break;
2808 }
2809
2810 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2811
2812 memcpy(buf,hdw->fw_buffer+offs,cnt);
2813
2814 pvr2_trace(PVR2_TRACE_FIRMWARE,
2815 "Read firmware data offs=%d cnt=%d",
2816 offs,cnt);
2817 ret = cnt;
2818 } while (0); LOCK_GIVE(hdw->big_lock);
2819
2820 return ret;
2821}
2822
2823
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002824int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002825 enum pvr2_v4l_type index)
Mike Iselyd8554972006-06-26 20:58:46 -03002826{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002827 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002828 case pvr2_v4l_type_video: return hdw->v4l_minor_number_video;
2829 case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi;
2830 case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002831 default: return -1;
2832 }
Mike Iselyd8554972006-06-26 20:58:46 -03002833}
2834
2835
Pantelis Koukousoulas2fdf3d92006-12-27 23:07:58 -03002836/* Store a v4l minor device number */
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002837void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002838 enum pvr2_v4l_type index,int v)
Mike Iselyd8554972006-06-26 20:58:46 -03002839{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002840 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002841 case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
2842 case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
2843 case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002844 default: break;
2845 }
Mike Iselyd8554972006-06-26 20:58:46 -03002846}
2847
2848
David Howells7d12e782006-10-05 14:55:46 +01002849static void pvr2_ctl_write_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002850{
2851 struct pvr2_hdw *hdw = urb->context;
2852 hdw->ctl_write_pend_flag = 0;
2853 if (hdw->ctl_read_pend_flag) return;
2854 complete(&hdw->ctl_done);
2855}
2856
2857
David Howells7d12e782006-10-05 14:55:46 +01002858static void pvr2_ctl_read_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002859{
2860 struct pvr2_hdw *hdw = urb->context;
2861 hdw->ctl_read_pend_flag = 0;
2862 if (hdw->ctl_write_pend_flag) return;
2863 complete(&hdw->ctl_done);
2864}
2865
2866
2867static void pvr2_ctl_timeout(unsigned long data)
2868{
2869 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2870 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2871 hdw->ctl_timeout_flag = !0;
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002872 if (hdw->ctl_write_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002873 usb_unlink_urb(hdw->ctl_write_urb);
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002874 if (hdw->ctl_read_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002875 usb_unlink_urb(hdw->ctl_read_urb);
Mike Iselyd8554972006-06-26 20:58:46 -03002876 }
2877}
2878
2879
Mike Iselye61b6fc2006-07-18 22:42:18 -03002880/* Issue a command and get a response from the device. This extended
2881 version includes a probe flag (which if set means that device errors
2882 should not be logged or treated as fatal) and a timeout in jiffies.
2883 This can be used to non-lethally probe the health of endpoint 1. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002884static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2885 unsigned int timeout,int probe_fl,
2886 void *write_data,unsigned int write_len,
2887 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002888{
2889 unsigned int idx;
2890 int status = 0;
2891 struct timer_list timer;
2892 if (!hdw->ctl_lock_held) {
2893 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2894 "Attempted to execute control transfer"
2895 " without lock!!");
2896 return -EDEADLK;
2897 }
Mike Isely681c7392007-11-26 01:48:52 -03002898 if (!hdw->flag_ok && !probe_fl) {
Mike Iselyd8554972006-06-26 20:58:46 -03002899 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2900 "Attempted to execute control transfer"
2901 " when device not ok");
2902 return -EIO;
2903 }
2904 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2905 if (!probe_fl) {
2906 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2907 "Attempted to execute control transfer"
2908 " when USB is disconnected");
2909 }
2910 return -ENOTTY;
2911 }
2912
2913 /* Ensure that we have sane parameters */
2914 if (!write_data) write_len = 0;
2915 if (!read_data) read_len = 0;
2916 if (write_len > PVR2_CTL_BUFFSIZE) {
2917 pvr2_trace(
2918 PVR2_TRACE_ERROR_LEGS,
2919 "Attempted to execute %d byte"
2920 " control-write transfer (limit=%d)",
2921 write_len,PVR2_CTL_BUFFSIZE);
2922 return -EINVAL;
2923 }
2924 if (read_len > PVR2_CTL_BUFFSIZE) {
2925 pvr2_trace(
2926 PVR2_TRACE_ERROR_LEGS,
2927 "Attempted to execute %d byte"
2928 " control-read transfer (limit=%d)",
2929 write_len,PVR2_CTL_BUFFSIZE);
2930 return -EINVAL;
2931 }
2932 if ((!write_len) && (!read_len)) {
2933 pvr2_trace(
2934 PVR2_TRACE_ERROR_LEGS,
2935 "Attempted to execute null control transfer?");
2936 return -EINVAL;
2937 }
2938
2939
2940 hdw->cmd_debug_state = 1;
2941 if (write_len) {
2942 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2943 } else {
2944 hdw->cmd_debug_code = 0;
2945 }
2946 hdw->cmd_debug_write_len = write_len;
2947 hdw->cmd_debug_read_len = read_len;
2948
2949 /* Initialize common stuff */
2950 init_completion(&hdw->ctl_done);
2951 hdw->ctl_timeout_flag = 0;
2952 hdw->ctl_write_pend_flag = 0;
2953 hdw->ctl_read_pend_flag = 0;
2954 init_timer(&timer);
2955 timer.expires = jiffies + timeout;
2956 timer.data = (unsigned long)hdw;
2957 timer.function = pvr2_ctl_timeout;
2958
2959 if (write_len) {
2960 hdw->cmd_debug_state = 2;
2961 /* Transfer write data to internal buffer */
2962 for (idx = 0; idx < write_len; idx++) {
2963 hdw->ctl_write_buffer[idx] =
2964 ((unsigned char *)write_data)[idx];
2965 }
2966 /* Initiate a write request */
2967 usb_fill_bulk_urb(hdw->ctl_write_urb,
2968 hdw->usb_dev,
2969 usb_sndbulkpipe(hdw->usb_dev,
2970 PVR2_CTL_WRITE_ENDPOINT),
2971 hdw->ctl_write_buffer,
2972 write_len,
2973 pvr2_ctl_write_complete,
2974 hdw);
2975 hdw->ctl_write_urb->actual_length = 0;
2976 hdw->ctl_write_pend_flag = !0;
2977 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2978 if (status < 0) {
2979 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2980 "Failed to submit write-control"
2981 " URB status=%d",status);
2982 hdw->ctl_write_pend_flag = 0;
2983 goto done;
2984 }
2985 }
2986
2987 if (read_len) {
2988 hdw->cmd_debug_state = 3;
2989 memset(hdw->ctl_read_buffer,0x43,read_len);
2990 /* Initiate a read request */
2991 usb_fill_bulk_urb(hdw->ctl_read_urb,
2992 hdw->usb_dev,
2993 usb_rcvbulkpipe(hdw->usb_dev,
2994 PVR2_CTL_READ_ENDPOINT),
2995 hdw->ctl_read_buffer,
2996 read_len,
2997 pvr2_ctl_read_complete,
2998 hdw);
2999 hdw->ctl_read_urb->actual_length = 0;
3000 hdw->ctl_read_pend_flag = !0;
3001 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
3002 if (status < 0) {
3003 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3004 "Failed to submit read-control"
3005 " URB status=%d",status);
3006 hdw->ctl_read_pend_flag = 0;
3007 goto done;
3008 }
3009 }
3010
3011 /* Start timer */
3012 add_timer(&timer);
3013
3014 /* Now wait for all I/O to complete */
3015 hdw->cmd_debug_state = 4;
3016 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
3017 wait_for_completion(&hdw->ctl_done);
3018 }
3019 hdw->cmd_debug_state = 5;
3020
3021 /* Stop timer */
3022 del_timer_sync(&timer);
3023
3024 hdw->cmd_debug_state = 6;
3025 status = 0;
3026
3027 if (hdw->ctl_timeout_flag) {
3028 status = -ETIMEDOUT;
3029 if (!probe_fl) {
3030 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3031 "Timed out control-write");
3032 }
3033 goto done;
3034 }
3035
3036 if (write_len) {
3037 /* Validate results of write request */
3038 if ((hdw->ctl_write_urb->status != 0) &&
3039 (hdw->ctl_write_urb->status != -ENOENT) &&
3040 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
3041 (hdw->ctl_write_urb->status != -ECONNRESET)) {
3042 /* USB subsystem is reporting some kind of failure
3043 on the write */
3044 status = hdw->ctl_write_urb->status;
3045 if (!probe_fl) {
3046 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3047 "control-write URB failure,"
3048 " status=%d",
3049 status);
3050 }
3051 goto done;
3052 }
3053 if (hdw->ctl_write_urb->actual_length < write_len) {
3054 /* Failed to write enough data */
3055 status = -EIO;
3056 if (!probe_fl) {
3057 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3058 "control-write URB short,"
3059 " expected=%d got=%d",
3060 write_len,
3061 hdw->ctl_write_urb->actual_length);
3062 }
3063 goto done;
3064 }
3065 }
3066 if (read_len) {
3067 /* Validate results of read request */
3068 if ((hdw->ctl_read_urb->status != 0) &&
3069 (hdw->ctl_read_urb->status != -ENOENT) &&
3070 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
3071 (hdw->ctl_read_urb->status != -ECONNRESET)) {
3072 /* USB subsystem is reporting some kind of failure
3073 on the read */
3074 status = hdw->ctl_read_urb->status;
3075 if (!probe_fl) {
3076 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3077 "control-read URB failure,"
3078 " status=%d",
3079 status);
3080 }
3081 goto done;
3082 }
3083 if (hdw->ctl_read_urb->actual_length < read_len) {
3084 /* Failed to read enough data */
3085 status = -EIO;
3086 if (!probe_fl) {
3087 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3088 "control-read URB short,"
3089 " expected=%d got=%d",
3090 read_len,
3091 hdw->ctl_read_urb->actual_length);
3092 }
3093 goto done;
3094 }
3095 /* Transfer retrieved data out from internal buffer */
3096 for (idx = 0; idx < read_len; idx++) {
3097 ((unsigned char *)read_data)[idx] =
3098 hdw->ctl_read_buffer[idx];
3099 }
3100 }
3101
3102 done:
3103
3104 hdw->cmd_debug_state = 0;
3105 if ((status < 0) && (!probe_fl)) {
Mike Isely681c7392007-11-26 01:48:52 -03003106 pvr2_hdw_render_useless(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03003107 }
3108 return status;
3109}
3110
3111
3112int pvr2_send_request(struct pvr2_hdw *hdw,
3113 void *write_data,unsigned int write_len,
3114 void *read_data,unsigned int read_len)
3115{
3116 return pvr2_send_request_ex(hdw,HZ*4,0,
3117 write_data,write_len,
3118 read_data,read_len);
3119}
3120
Mike Isely1c9d10d2008-03-28 05:38:54 -03003121
3122static int pvr2_issue_simple_cmd(struct pvr2_hdw *hdw,u32 cmdcode)
3123{
3124 int ret;
3125 unsigned int cnt = 1;
3126 unsigned int args = 0;
3127 LOCK_TAKE(hdw->ctl_lock);
3128 hdw->cmd_buffer[0] = cmdcode & 0xffu;
3129 args = (cmdcode >> 8) & 0xffu;
3130 args = (args > 2) ? 2 : args;
3131 if (args) {
3132 cnt += args;
3133 hdw->cmd_buffer[1] = (cmdcode >> 16) & 0xffu;
3134 if (args > 1) {
3135 hdw->cmd_buffer[2] = (cmdcode >> 24) & 0xffu;
3136 }
3137 }
3138 if (pvrusb2_debug & PVR2_TRACE_INIT) {
3139 unsigned int idx;
3140 unsigned int ccnt,bcnt;
3141 char tbuf[50];
3142 cmdcode &= 0xffu;
3143 bcnt = 0;
3144 ccnt = scnprintf(tbuf+bcnt,
3145 sizeof(tbuf)-bcnt,
3146 "Sending FX2 command 0x%x",cmdcode);
3147 bcnt += ccnt;
3148 for (idx = 0; idx < ARRAY_SIZE(pvr2_fx2cmd_desc); idx++) {
3149 if (pvr2_fx2cmd_desc[idx].id == cmdcode) {
3150 ccnt = scnprintf(tbuf+bcnt,
3151 sizeof(tbuf)-bcnt,
3152 " \"%s\"",
3153 pvr2_fx2cmd_desc[idx].desc);
3154 bcnt += ccnt;
3155 break;
3156 }
3157 }
3158 if (args) {
3159 ccnt = scnprintf(tbuf+bcnt,
3160 sizeof(tbuf)-bcnt,
3161 " (%u",hdw->cmd_buffer[1]);
3162 bcnt += ccnt;
3163 if (args > 1) {
3164 ccnt = scnprintf(tbuf+bcnt,
3165 sizeof(tbuf)-bcnt,
3166 ",%u",hdw->cmd_buffer[2]);
3167 bcnt += ccnt;
3168 }
3169 ccnt = scnprintf(tbuf+bcnt,
3170 sizeof(tbuf)-bcnt,
3171 ")");
3172 bcnt += ccnt;
3173 }
3174 pvr2_trace(PVR2_TRACE_INIT,"%.*s",bcnt,tbuf);
3175 }
3176 ret = pvr2_send_request(hdw,hdw->cmd_buffer,cnt,NULL,0);
3177 LOCK_GIVE(hdw->ctl_lock);
3178 return ret;
3179}
3180
3181
Mike Iselyd8554972006-06-26 20:58:46 -03003182int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
3183{
3184 int ret;
3185
3186 LOCK_TAKE(hdw->ctl_lock);
3187
Michael Krufky8d364362007-01-22 02:17:55 -03003188 hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03003189 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
3190 hdw->cmd_buffer[5] = 0;
3191 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3192 hdw->cmd_buffer[7] = reg & 0xff;
3193
3194
3195 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
3196
3197 LOCK_GIVE(hdw->ctl_lock);
3198
3199 return ret;
3200}
3201
3202
Adrian Bunk07e337e2006-06-30 11:30:20 -03003203static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03003204{
3205 int ret = 0;
3206
3207 LOCK_TAKE(hdw->ctl_lock);
3208
Michael Krufky8d364362007-01-22 02:17:55 -03003209 hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03003210 hdw->cmd_buffer[1] = 0;
3211 hdw->cmd_buffer[2] = 0;
3212 hdw->cmd_buffer[3] = 0;
3213 hdw->cmd_buffer[4] = 0;
3214 hdw->cmd_buffer[5] = 0;
3215 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3216 hdw->cmd_buffer[7] = reg & 0xff;
3217
3218 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
3219 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
3220
3221 LOCK_GIVE(hdw->ctl_lock);
3222
3223 return ret;
3224}
3225
3226
Mike Isely681c7392007-11-26 01:48:52 -03003227void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003228{
3229 if (!hdw->flag_ok) return;
Mike Isely681c7392007-11-26 01:48:52 -03003230 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3231 "Device being rendered inoperable");
Mike Iselyd8554972006-06-26 20:58:46 -03003232 if (hdw->vid_stream) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003233 pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003234 }
Mike Isely681c7392007-11-26 01:48:52 -03003235 hdw->flag_ok = 0;
3236 trace_stbit("flag_ok",hdw->flag_ok);
3237 pvr2_hdw_state_sched(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03003238}
3239
3240
3241void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
3242{
3243 int ret;
3244 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003245 ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -03003246 if (ret == 1) {
3247 ret = usb_reset_device(hdw->usb_dev);
3248 usb_unlock_device(hdw->usb_dev);
3249 } else {
3250 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3251 "Failed to lock USB device ret=%d",ret);
3252 }
3253 if (init_pause_msec) {
3254 pvr2_trace(PVR2_TRACE_INFO,
3255 "Waiting %u msec for hardware to settle",
3256 init_pause_msec);
3257 msleep(init_pause_msec);
3258 }
3259
3260}
3261
3262
3263void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
3264{
3265 char da[1];
3266 unsigned int pipe;
3267 int ret;
3268
3269 if (!hdw->usb_dev) return;
3270
3271 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
3272
3273 da[0] = val ? 0x01 : 0x00;
3274
3275 /* Write the CPUCS register on the 8051. The lsb of the register
3276 is the reset bit; a 1 asserts reset while a 0 clears it. */
3277 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
3278 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
3279 if (ret < 0) {
3280 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3281 "cpureset_assert(%d) error=%d",val,ret);
3282 pvr2_hdw_render_useless(hdw);
3283 }
3284}
3285
3286
3287int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
3288{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003289 return pvr2_issue_simple_cmd(hdw,FX2CMD_DEEP_RESET);
Mike Iselyd8554972006-06-26 20:58:46 -03003290}
3291
3292
Michael Krufkye1edb192008-04-22 14:45:39 -03003293int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
3294{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003295 return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_ON);
Michael Krufkye1edb192008-04-22 14:45:39 -03003296}
3297
Mike Isely1c9d10d2008-03-28 05:38:54 -03003298
Michael Krufkye1edb192008-04-22 14:45:39 -03003299int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw)
3300{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003301 return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_OFF);
Michael Krufkye1edb192008-04-22 14:45:39 -03003302}
3303
Mike Iselyd8554972006-06-26 20:58:46 -03003304
3305int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
3306{
3307 if (!hdw->decoder_ctrl) {
3308 pvr2_trace(PVR2_TRACE_INIT,
3309 "Unable to reset decoder: nothing attached");
3310 return -ENOTTY;
3311 }
3312
3313 if (!hdw->decoder_ctrl->force_reset) {
3314 pvr2_trace(PVR2_TRACE_INIT,
3315 "Unable to reset decoder: not implemented");
3316 return -ENOTTY;
3317 }
3318
3319 pvr2_trace(PVR2_TRACE_INIT,
3320 "Requesting decoder reset");
3321 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
3322 return 0;
3323}
3324
3325
Mike Isely62433e32008-04-22 14:45:40 -03003326static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
Mike Isely84147f32008-04-22 14:45:40 -03003327{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003328 hdw->flag_ok = !0;
3329 return pvr2_issue_simple_cmd(hdw,
3330 FX2CMD_HCW_DEMOD_RESETIN |
3331 (1 << 8) |
3332 ((onoff ? 1 : 0) << 16));
Mike Isely84147f32008-04-22 14:45:40 -03003333}
3334
Mike Isely84147f32008-04-22 14:45:40 -03003335
Mike Isely62433e32008-04-22 14:45:40 -03003336static int pvr2_hdw_cmd_onair_fe_power_ctrl(struct pvr2_hdw *hdw, int onoff)
Mike Isely84147f32008-04-22 14:45:40 -03003337{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003338 hdw->flag_ok = !0;
3339 return pvr2_issue_simple_cmd(hdw,(onoff ?
3340 FX2CMD_ONAIR_DTV_POWER_ON :
3341 FX2CMD_ONAIR_DTV_POWER_OFF));
Mike Isely84147f32008-04-22 14:45:40 -03003342}
3343
Mike Isely62433e32008-04-22 14:45:40 -03003344
3345static int pvr2_hdw_cmd_onair_digital_path_ctrl(struct pvr2_hdw *hdw,
3346 int onoff)
Mike Isely84147f32008-04-22 14:45:40 -03003347{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003348 return pvr2_issue_simple_cmd(hdw,(onoff ?
3349 FX2CMD_ONAIR_DTV_STREAMING_ON :
3350 FX2CMD_ONAIR_DTV_STREAMING_OFF));
Mike Isely84147f32008-04-22 14:45:40 -03003351}
3352
Mike Isely62433e32008-04-22 14:45:40 -03003353
3354static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl)
3355{
3356 int cmode;
3357 /* Compare digital/analog desired setting with current setting. If
3358 they don't match, fix it... */
3359 cmode = (digitalFl ? PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG);
3360 if (cmode == hdw->pathway_state) {
3361 /* They match; nothing to do */
3362 return;
3363 }
3364
3365 switch (hdw->hdw_desc->digital_control_scheme) {
3366 case PVR2_DIGITAL_SCHEME_HAUPPAUGE:
3367 pvr2_hdw_cmd_hcw_demod_reset(hdw,digitalFl);
3368 if (cmode == PVR2_PATHWAY_ANALOG) {
3369 /* If moving to analog mode, also force the decoder
3370 to reset. If no decoder is attached, then it's
3371 ok to ignore this because if/when the decoder
3372 attaches, it will reset itself at that time. */
3373 pvr2_hdw_cmd_decoder_reset(hdw);
3374 }
3375 break;
3376 case PVR2_DIGITAL_SCHEME_ONAIR:
3377 /* Supposedly we should always have the power on whether in
3378 digital or analog mode. But for now do what appears to
3379 work... */
Mike Iselybb0c2fe2008-03-28 05:41:19 -03003380 pvr2_hdw_cmd_onair_fe_power_ctrl(hdw,digitalFl);
Mike Isely62433e32008-04-22 14:45:40 -03003381 break;
3382 default: break;
3383 }
3384
Mike Isely1b9c18c2008-04-22 14:45:41 -03003385 pvr2_hdw_untrip_unlocked(hdw);
Mike Isely62433e32008-04-22 14:45:40 -03003386 hdw->pathway_state = cmode;
3387}
3388
3389
Mike Isely40381cb2008-04-22 14:45:42 -03003390void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff)
Mike Iselyc55a97d2008-04-22 14:45:41 -03003391{
3392 /* change some GPIO data
3393 *
3394 * note: bit d7 of dir appears to control the LED,
3395 * so we shut it off here.
3396 *
Mike Iselyc55a97d2008-04-22 14:45:41 -03003397 */
Mike Isely40381cb2008-04-22 14:45:42 -03003398 if (onoff) {
Mike Iselyc55a97d2008-04-22 14:45:41 -03003399 pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000481);
Mike Isely40381cb2008-04-22 14:45:42 -03003400 } else {
Mike Iselyc55a97d2008-04-22 14:45:41 -03003401 pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000401);
Mike Isely40381cb2008-04-22 14:45:42 -03003402 }
Mike Iselyc55a97d2008-04-22 14:45:41 -03003403 pvr2_hdw_gpio_chg_out(hdw, 0xffffffff, 0x00000000);
Mike Isely40381cb2008-04-22 14:45:42 -03003404}
Mike Iselyc55a97d2008-04-22 14:45:41 -03003405
Mike Isely40381cb2008-04-22 14:45:42 -03003406
3407typedef void (*led_method_func)(struct pvr2_hdw *,int);
3408
3409static led_method_func led_methods[] = {
3410 [PVR2_LED_SCHEME_HAUPPAUGE] = pvr2_led_ctrl_hauppauge,
3411};
3412
3413
3414/* Toggle LED */
3415static void pvr2_led_ctrl(struct pvr2_hdw *hdw,int onoff)
3416{
3417 unsigned int scheme_id;
3418 led_method_func fp;
3419
3420 if ((!onoff) == (!hdw->led_on)) return;
3421
3422 hdw->led_on = onoff != 0;
3423
3424 scheme_id = hdw->hdw_desc->led_scheme;
3425 if (scheme_id < ARRAY_SIZE(led_methods)) {
3426 fp = led_methods[scheme_id];
3427 } else {
3428 fp = NULL;
3429 }
3430
3431 if (fp) (*fp)(hdw,onoff);
Mike Iselyc55a97d2008-04-22 14:45:41 -03003432}
3433
3434
Mike Iselye61b6fc2006-07-18 22:42:18 -03003435/* Stop / start video stream transport */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003436static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03003437{
Mike Iselybb0c2fe2008-03-28 05:41:19 -03003438 int ret;
3439
3440 /* If we're in analog mode, then just issue the usual analog
3441 command. */
3442 if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
3443 return pvr2_issue_simple_cmd(hdw,
3444 (runFl ?
3445 FX2CMD_STREAMING_ON :
3446 FX2CMD_STREAMING_OFF));
3447 /*Note: Not reached */
Mike Isely62433e32008-04-22 14:45:40 -03003448 }
Mike Iselybb0c2fe2008-03-28 05:41:19 -03003449
3450 if (hdw->pathway_state != PVR2_PATHWAY_DIGITAL) {
3451 /* Whoops, we don't know what mode we're in... */
3452 return -EINVAL;
3453 }
3454
3455 /* To get here we have to be in digital mode. The mechanism here
3456 is unfortunately different for different vendors. So we switch
3457 on the device's digital scheme attribute in order to figure out
3458 what to do. */
3459 switch (hdw->hdw_desc->digital_control_scheme) {
3460 case PVR2_DIGITAL_SCHEME_HAUPPAUGE:
3461 return pvr2_issue_simple_cmd(hdw,
3462 (runFl ?
3463 FX2CMD_HCW_DTV_STREAMING_ON :
3464 FX2CMD_HCW_DTV_STREAMING_OFF));
3465 case PVR2_DIGITAL_SCHEME_ONAIR:
3466 ret = pvr2_issue_simple_cmd(hdw,
3467 (runFl ?
3468 FX2CMD_STREAMING_ON :
3469 FX2CMD_STREAMING_OFF));
3470 if (ret) return ret;
3471 return pvr2_hdw_cmd_onair_digital_path_ctrl(hdw,runFl);
3472 default:
3473 return -EINVAL;
3474 }
Mike Iselyd8554972006-06-26 20:58:46 -03003475}
3476
3477
Mike Isely62433e32008-04-22 14:45:40 -03003478/* Evaluate whether or not state_pathway_ok can change */
3479static int state_eval_pathway_ok(struct pvr2_hdw *hdw)
3480{
3481 if (hdw->state_pathway_ok) {
3482 /* Nothing to do if pathway is already ok */
3483 return 0;
3484 }
3485 if (!hdw->state_pipeline_idle) {
3486 /* Not allowed to change anything if pipeline is not idle */
3487 return 0;
3488 }
3489 pvr2_hdw_cmd_modeswitch(hdw,hdw->input_val == PVR2_CVAL_INPUT_DTV);
3490 hdw->state_pathway_ok = !0;
Mike Iselye9db1ff2008-04-22 14:45:41 -03003491 trace_stbit("state_pathway_ok",hdw->state_pathway_ok);
Mike Isely62433e32008-04-22 14:45:40 -03003492 return !0;
3493}
3494
3495
Mike Isely681c7392007-11-26 01:48:52 -03003496/* Evaluate whether or not state_encoder_ok can change */
3497static int state_eval_encoder_ok(struct pvr2_hdw *hdw)
3498{
3499 if (hdw->state_encoder_ok) return 0;
3500 if (hdw->flag_tripped) return 0;
3501 if (hdw->state_encoder_run) return 0;
3502 if (hdw->state_encoder_config) return 0;
3503 if (hdw->state_decoder_run) return 0;
3504 if (hdw->state_usbstream_run) return 0;
Mike Isely62433e32008-04-22 14:45:40 -03003505 if (hdw->pathway_state != PVR2_PATHWAY_ANALOG) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003506 if (pvr2_upload_firmware2(hdw) < 0) {
3507 hdw->flag_tripped = !0;
3508 trace_stbit("flag_tripped",hdw->flag_tripped);
3509 return !0;
3510 }
3511 hdw->state_encoder_ok = !0;
3512 trace_stbit("state_encoder_ok",hdw->state_encoder_ok);
3513 return !0;
3514}
3515
3516
3517/* Evaluate whether or not state_encoder_config can change */
3518static int state_eval_encoder_config(struct pvr2_hdw *hdw)
3519{
3520 if (hdw->state_encoder_config) {
3521 if (hdw->state_encoder_ok) {
3522 if (hdw->state_pipeline_req &&
3523 !hdw->state_pipeline_pause) return 0;
3524 }
3525 hdw->state_encoder_config = 0;
3526 hdw->state_encoder_waitok = 0;
3527 trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
3528 /* paranoia - solve race if timer just completed */
3529 del_timer_sync(&hdw->encoder_wait_timer);
3530 } else {
Mike Isely62433e32008-04-22 14:45:40 -03003531 if (!hdw->state_pathway_ok ||
3532 (hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
3533 !hdw->state_encoder_ok ||
Mike Isely681c7392007-11-26 01:48:52 -03003534 !hdw->state_pipeline_idle ||
3535 hdw->state_pipeline_pause ||
3536 !hdw->state_pipeline_req ||
3537 !hdw->state_pipeline_config) {
3538 /* We must reset the enforced wait interval if
3539 anything has happened that might have disturbed
3540 the encoder. This should be a rare case. */
3541 if (timer_pending(&hdw->encoder_wait_timer)) {
3542 del_timer_sync(&hdw->encoder_wait_timer);
3543 }
3544 if (hdw->state_encoder_waitok) {
3545 /* Must clear the state - therefore we did
3546 something to a state bit and must also
3547 return true. */
3548 hdw->state_encoder_waitok = 0;
3549 trace_stbit("state_encoder_waitok",
3550 hdw->state_encoder_waitok);
3551 return !0;
3552 }
3553 return 0;
3554 }
3555 if (!hdw->state_encoder_waitok) {
3556 if (!timer_pending(&hdw->encoder_wait_timer)) {
3557 /* waitok flag wasn't set and timer isn't
3558 running. Check flag once more to avoid
3559 a race then start the timer. This is
3560 the point when we measure out a minimal
3561 quiet interval before doing something to
3562 the encoder. */
3563 if (!hdw->state_encoder_waitok) {
3564 hdw->encoder_wait_timer.expires =
3565 jiffies + (HZ*50/1000);
3566 add_timer(&hdw->encoder_wait_timer);
3567 }
3568 }
3569 /* We can't continue until we know we have been
3570 quiet for the interval measured by this
3571 timer. */
3572 return 0;
3573 }
3574 pvr2_encoder_configure(hdw);
3575 if (hdw->state_encoder_ok) hdw->state_encoder_config = !0;
3576 }
3577 trace_stbit("state_encoder_config",hdw->state_encoder_config);
3578 return !0;
3579}
3580
3581
3582/* Evaluate whether or not state_encoder_run can change */
3583static int state_eval_encoder_run(struct pvr2_hdw *hdw)
3584{
3585 if (hdw->state_encoder_run) {
3586 if (hdw->state_encoder_ok) {
Mike Isely62433e32008-04-22 14:45:40 -03003587 if (hdw->state_decoder_run &&
3588 hdw->state_pathway_ok) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003589 if (pvr2_encoder_stop(hdw) < 0) return !0;
3590 }
3591 hdw->state_encoder_run = 0;
3592 } else {
3593 if (!hdw->state_encoder_ok) return 0;
3594 if (!hdw->state_decoder_run) return 0;
Mike Isely62433e32008-04-22 14:45:40 -03003595 if (!hdw->state_pathway_ok) return 0;
3596 if (hdw->pathway_state != PVR2_PATHWAY_ANALOG) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003597 if (pvr2_encoder_start(hdw) < 0) return !0;
3598 hdw->state_encoder_run = !0;
3599 }
3600 trace_stbit("state_encoder_run",hdw->state_encoder_run);
3601 return !0;
3602}
3603
3604
3605/* Timeout function for quiescent timer. */
3606static void pvr2_hdw_quiescent_timeout(unsigned long data)
3607{
3608 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
3609 hdw->state_decoder_quiescent = !0;
3610 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
3611 hdw->state_stale = !0;
3612 queue_work(hdw->workqueue,&hdw->workpoll);
3613}
3614
3615
3616/* Timeout function for encoder wait timer. */
3617static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
3618{
3619 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
3620 hdw->state_encoder_waitok = !0;
3621 trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
3622 hdw->state_stale = !0;
3623 queue_work(hdw->workqueue,&hdw->workpoll);
3624}
3625
3626
3627/* Evaluate whether or not state_decoder_run can change */
3628static int state_eval_decoder_run(struct pvr2_hdw *hdw)
3629{
3630 if (hdw->state_decoder_run) {
3631 if (hdw->state_encoder_ok) {
3632 if (hdw->state_pipeline_req &&
Mike Isely62433e32008-04-22 14:45:40 -03003633 !hdw->state_pipeline_pause &&
3634 hdw->state_pathway_ok) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003635 }
3636 if (!hdw->flag_decoder_missed) {
3637 pvr2_decoder_enable(hdw,0);
3638 }
3639 hdw->state_decoder_quiescent = 0;
3640 hdw->state_decoder_run = 0;
3641 /* paranoia - solve race if timer just completed */
3642 del_timer_sync(&hdw->quiescent_timer);
3643 } else {
3644 if (!hdw->state_decoder_quiescent) {
3645 if (!timer_pending(&hdw->quiescent_timer)) {
3646 /* We don't do something about the
3647 quiescent timer until right here because
3648 we also want to catch cases where the
3649 decoder was already not running (like
3650 after initialization) as opposed to
3651 knowing that we had just stopped it.
3652 The second flag check is here to cover a
3653 race - the timer could have run and set
3654 this flag just after the previous check
3655 but before we did the pending check. */
3656 if (!hdw->state_decoder_quiescent) {
3657 hdw->quiescent_timer.expires =
3658 jiffies + (HZ*50/1000);
3659 add_timer(&hdw->quiescent_timer);
3660 }
3661 }
3662 /* Don't allow decoder to start again until it has
3663 been quiesced first. This little detail should
3664 hopefully further stabilize the encoder. */
3665 return 0;
3666 }
Mike Isely62433e32008-04-22 14:45:40 -03003667 if (!hdw->state_pathway_ok ||
3668 (hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
3669 !hdw->state_pipeline_req ||
Mike Isely681c7392007-11-26 01:48:52 -03003670 hdw->state_pipeline_pause ||
3671 !hdw->state_pipeline_config ||
3672 !hdw->state_encoder_config ||
3673 !hdw->state_encoder_ok) return 0;
3674 del_timer_sync(&hdw->quiescent_timer);
3675 if (hdw->flag_decoder_missed) return 0;
3676 if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
3677 hdw->state_decoder_quiescent = 0;
3678 hdw->state_decoder_run = !0;
3679 }
3680 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
3681 trace_stbit("state_decoder_run",hdw->state_decoder_run);
3682 return !0;
3683}
3684
3685
3686/* Evaluate whether or not state_usbstream_run can change */
3687static int state_eval_usbstream_run(struct pvr2_hdw *hdw)
3688{
3689 if (hdw->state_usbstream_run) {
Mike Isely62433e32008-04-22 14:45:40 -03003690 if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
3691 if (hdw->state_encoder_ok &&
3692 hdw->state_encoder_run &&
3693 hdw->state_pathway_ok) return 0;
3694 } else {
3695 if (hdw->state_pipeline_req &&
3696 !hdw->state_pipeline_pause &&
3697 hdw->state_pathway_ok) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003698 }
3699 pvr2_hdw_cmd_usbstream(hdw,0);
3700 hdw->state_usbstream_run = 0;
3701 } else {
Mike Isely62433e32008-04-22 14:45:40 -03003702 if (!hdw->state_pipeline_req ||
3703 hdw->state_pipeline_pause ||
3704 !hdw->state_pathway_ok) return 0;
3705 if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
3706 if (!hdw->state_encoder_ok ||
3707 !hdw->state_encoder_run) return 0;
3708 }
Mike Isely681c7392007-11-26 01:48:52 -03003709 if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0;
3710 hdw->state_usbstream_run = !0;
3711 }
3712 trace_stbit("state_usbstream_run",hdw->state_usbstream_run);
3713 return !0;
3714}
3715
3716
3717/* Attempt to configure pipeline, if needed */
3718static int state_eval_pipeline_config(struct pvr2_hdw *hdw)
3719{
3720 if (hdw->state_pipeline_config ||
3721 hdw->state_pipeline_pause) return 0;
3722 pvr2_hdw_commit_execute(hdw);
3723 return !0;
3724}
3725
3726
3727/* Update pipeline idle and pipeline pause tracking states based on other
3728 inputs. This must be called whenever the other relevant inputs have
3729 changed. */
3730static int state_update_pipeline_state(struct pvr2_hdw *hdw)
3731{
3732 unsigned int st;
3733 int updatedFl = 0;
3734 /* Update pipeline state */
3735 st = !(hdw->state_encoder_run ||
3736 hdw->state_decoder_run ||
3737 hdw->state_usbstream_run ||
3738 (!hdw->state_decoder_quiescent));
3739 if (!st != !hdw->state_pipeline_idle) {
3740 hdw->state_pipeline_idle = st;
3741 updatedFl = !0;
3742 }
3743 if (hdw->state_pipeline_idle && hdw->state_pipeline_pause) {
3744 hdw->state_pipeline_pause = 0;
3745 updatedFl = !0;
3746 }
3747 return updatedFl;
3748}
3749
3750
3751typedef int (*state_eval_func)(struct pvr2_hdw *);
3752
3753/* Set of functions to be run to evaluate various states in the driver. */
Tobias Klauserebff0332008-04-22 14:45:45 -03003754static const state_eval_func eval_funcs[] = {
Mike Isely62433e32008-04-22 14:45:40 -03003755 state_eval_pathway_ok,
Mike Isely681c7392007-11-26 01:48:52 -03003756 state_eval_pipeline_config,
3757 state_eval_encoder_ok,
3758 state_eval_encoder_config,
3759 state_eval_decoder_run,
3760 state_eval_encoder_run,
3761 state_eval_usbstream_run,
3762};
3763
3764
3765/* Process various states and return true if we did anything interesting. */
3766static int pvr2_hdw_state_update(struct pvr2_hdw *hdw)
3767{
3768 unsigned int i;
3769 int state_updated = 0;
3770 int check_flag;
3771
3772 if (!hdw->state_stale) return 0;
3773 if ((hdw->fw1_state != FW1_STATE_OK) ||
3774 !hdw->flag_ok) {
3775 hdw->state_stale = 0;
3776 return !0;
3777 }
3778 /* This loop is the heart of the entire driver. It keeps trying to
3779 evaluate various bits of driver state until nothing changes for
3780 one full iteration. Each "bit of state" tracks some global
3781 aspect of the driver, e.g. whether decoder should run, if
3782 pipeline is configured, usb streaming is on, etc. We separately
3783 evaluate each of those questions based on other driver state to
3784 arrive at the correct running configuration. */
3785 do {
3786 check_flag = 0;
3787 state_update_pipeline_state(hdw);
3788 /* Iterate over each bit of state */
3789 for (i = 0; (i<ARRAY_SIZE(eval_funcs)) && hdw->flag_ok; i++) {
3790 if ((*eval_funcs[i])(hdw)) {
3791 check_flag = !0;
3792 state_updated = !0;
3793 state_update_pipeline_state(hdw);
3794 }
3795 }
3796 } while (check_flag && hdw->flag_ok);
3797 hdw->state_stale = 0;
3798 trace_stbit("state_stale",hdw->state_stale);
3799 return state_updated;
3800}
3801
3802
Mike Isely62433e32008-04-22 14:45:40 -03003803static const char *pvr2_pathway_state_name(int id)
3804{
3805 switch (id) {
3806 case PVR2_PATHWAY_ANALOG: return "analog";
3807 case PVR2_PATHWAY_DIGITAL: return "digital";
3808 default: return "unknown";
3809 }
3810}
3811
3812
Mike Isely681c7392007-11-26 01:48:52 -03003813static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
3814 char *buf,unsigned int acnt)
3815{
3816 switch (which) {
3817 case 0:
3818 return scnprintf(
3819 buf,acnt,
Mike Iselye9db1ff2008-04-22 14:45:41 -03003820 "driver:%s%s%s%s%s <mode=%s>",
Mike Isely681c7392007-11-26 01:48:52 -03003821 (hdw->flag_ok ? " <ok>" : " <fail>"),
3822 (hdw->flag_init_ok ? " <init>" : " <uninitialized>"),
3823 (hdw->flag_disconnected ? " <disconnected>" :
3824 " <connected>"),
3825 (hdw->flag_tripped ? " <tripped>" : ""),
Mike Isely62433e32008-04-22 14:45:40 -03003826 (hdw->flag_decoder_missed ? " <no decoder>" : ""),
3827 pvr2_pathway_state_name(hdw->pathway_state));
3828
Mike Isely681c7392007-11-26 01:48:52 -03003829 case 1:
3830 return scnprintf(
3831 buf,acnt,
3832 "pipeline:%s%s%s%s",
3833 (hdw->state_pipeline_idle ? " <idle>" : ""),
3834 (hdw->state_pipeline_config ?
3835 " <configok>" : " <stale>"),
3836 (hdw->state_pipeline_req ? " <req>" : ""),
3837 (hdw->state_pipeline_pause ? " <pause>" : ""));
3838 case 2:
3839 return scnprintf(
3840 buf,acnt,
Mike Isely62433e32008-04-22 14:45:40 -03003841 "worker:%s%s%s%s%s%s%s",
Mike Isely681c7392007-11-26 01:48:52 -03003842 (hdw->state_decoder_run ?
3843 " <decode:run>" :
3844 (hdw->state_decoder_quiescent ?
3845 "" : " <decode:stop>")),
3846 (hdw->state_decoder_quiescent ?
3847 " <decode:quiescent>" : ""),
3848 (hdw->state_encoder_ok ?
3849 "" : " <encode:init>"),
3850 (hdw->state_encoder_run ?
3851 " <encode:run>" : " <encode:stop>"),
3852 (hdw->state_encoder_config ?
3853 " <encode:configok>" :
3854 (hdw->state_encoder_waitok ?
Mike Iselyb9a37d92008-03-28 05:31:40 -03003855 "" : " <encode:waitok>")),
Mike Isely681c7392007-11-26 01:48:52 -03003856 (hdw->state_usbstream_run ?
Mike Isely62433e32008-04-22 14:45:40 -03003857 " <usb:run>" : " <usb:stop>"),
3858 (hdw->state_pathway_ok ?
Mike Iselye9db1ff2008-04-22 14:45:41 -03003859 " <pathway:ok>" : ""));
Mike Isely681c7392007-11-26 01:48:52 -03003860 case 3:
3861 return scnprintf(
3862 buf,acnt,
3863 "state: %s",
3864 pvr2_get_state_name(hdw->master_state));
Mike Iselyad0992e2008-03-28 05:34:45 -03003865 case 4: {
3866 struct pvr2_stream_stats stats;
3867 if (!hdw->vid_stream) break;
3868 pvr2_stream_get_stats(hdw->vid_stream,
3869 &stats,
3870 0);
3871 return scnprintf(
3872 buf,acnt,
3873 "Bytes streamed=%u"
3874 " URBs: queued=%u idle=%u ready=%u"
3875 " processed=%u failed=%u",
3876 stats.bytes_processed,
3877 stats.buffers_in_queue,
3878 stats.buffers_in_idle,
3879 stats.buffers_in_ready,
3880 stats.buffers_processed,
3881 stats.buffers_failed);
3882 }
Mike Isely681c7392007-11-26 01:48:52 -03003883 default: break;
3884 }
3885 return 0;
3886}
3887
3888
3889unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
3890 char *buf,unsigned int acnt)
3891{
3892 unsigned int bcnt,ccnt,idx;
3893 bcnt = 0;
3894 LOCK_TAKE(hdw->big_lock);
3895 for (idx = 0; ; idx++) {
3896 ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,acnt);
3897 if (!ccnt) break;
3898 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
3899 if (!acnt) break;
3900 buf[0] = '\n'; ccnt = 1;
3901 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
3902 }
3903 LOCK_GIVE(hdw->big_lock);
3904 return bcnt;
3905}
3906
3907
3908static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
3909{
3910 char buf[128];
3911 unsigned int idx,ccnt;
3912
3913 for (idx = 0; ; idx++) {
3914 ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
3915 if (!ccnt) break;
3916 printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
3917 }
3918}
3919
3920
3921/* Evaluate and update the driver's current state, taking various actions
3922 as appropriate for the update. */
3923static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw)
3924{
3925 unsigned int st;
3926 int state_updated = 0;
3927 int callback_flag = 0;
Mike Isely1b9c18c2008-04-22 14:45:41 -03003928 int analog_mode;
Mike Isely681c7392007-11-26 01:48:52 -03003929
3930 pvr2_trace(PVR2_TRACE_STBITS,
3931 "Drive state check START");
3932 if (pvrusb2_debug & PVR2_TRACE_STBITS) {
3933 pvr2_hdw_state_log_state(hdw);
3934 }
3935
3936 /* Process all state and get back over disposition */
3937 state_updated = pvr2_hdw_state_update(hdw);
3938
Mike Isely1b9c18c2008-04-22 14:45:41 -03003939 analog_mode = (hdw->pathway_state != PVR2_PATHWAY_DIGITAL);
3940
Mike Isely681c7392007-11-26 01:48:52 -03003941 /* Update master state based upon all other states. */
3942 if (!hdw->flag_ok) {
3943 st = PVR2_STATE_DEAD;
3944 } else if (hdw->fw1_state != FW1_STATE_OK) {
3945 st = PVR2_STATE_COLD;
Mike Isely1b9c18c2008-04-22 14:45:41 -03003946 } else if (analog_mode && !hdw->state_encoder_ok) {
Mike Isely681c7392007-11-26 01:48:52 -03003947 st = PVR2_STATE_WARM;
Mike Isely1b9c18c2008-04-22 14:45:41 -03003948 } else if (hdw->flag_tripped ||
3949 (analog_mode && hdw->flag_decoder_missed)) {
Mike Isely681c7392007-11-26 01:48:52 -03003950 st = PVR2_STATE_ERROR;
Mike Isely62433e32008-04-22 14:45:40 -03003951 } else if (hdw->state_usbstream_run &&
Mike Isely1b9c18c2008-04-22 14:45:41 -03003952 (!analog_mode ||
Mike Isely62433e32008-04-22 14:45:40 -03003953 (hdw->state_encoder_run && hdw->state_decoder_run))) {
Mike Isely681c7392007-11-26 01:48:52 -03003954 st = PVR2_STATE_RUN;
3955 } else {
3956 st = PVR2_STATE_READY;
3957 }
3958 if (hdw->master_state != st) {
3959 pvr2_trace(PVR2_TRACE_STATE,
3960 "Device state change from %s to %s",
3961 pvr2_get_state_name(hdw->master_state),
3962 pvr2_get_state_name(st));
Mike Isely40381cb2008-04-22 14:45:42 -03003963 pvr2_led_ctrl(hdw,st == PVR2_STATE_RUN);
Mike Isely681c7392007-11-26 01:48:52 -03003964 hdw->master_state = st;
3965 state_updated = !0;
3966 callback_flag = !0;
3967 }
3968 if (state_updated) {
3969 /* Trigger anyone waiting on any state changes here. */
3970 wake_up(&hdw->state_wait_data);
3971 }
3972
3973 if (pvrusb2_debug & PVR2_TRACE_STBITS) {
3974 pvr2_hdw_state_log_state(hdw);
3975 }
3976 pvr2_trace(PVR2_TRACE_STBITS,
3977 "Drive state check DONE callback=%d",callback_flag);
3978
3979 return callback_flag;
3980}
3981
3982
3983/* Cause kernel thread to check / update driver state */
3984static void pvr2_hdw_state_sched(struct pvr2_hdw *hdw)
3985{
3986 if (hdw->state_stale) return;
3987 hdw->state_stale = !0;
3988 trace_stbit("state_stale",hdw->state_stale);
3989 queue_work(hdw->workqueue,&hdw->workpoll);
3990}
3991
3992
3993void pvr2_hdw_get_debug_info_unlocked(const struct pvr2_hdw *hdw,
3994 struct pvr2_hdw_debug_info *ptr)
Mike Iselyd8554972006-06-26 20:58:46 -03003995{
3996 ptr->big_lock_held = hdw->big_lock_held;
3997 ptr->ctl_lock_held = hdw->ctl_lock_held;
Mike Iselyd8554972006-06-26 20:58:46 -03003998 ptr->flag_disconnected = hdw->flag_disconnected;
3999 ptr->flag_init_ok = hdw->flag_init_ok;
Mike Isely681c7392007-11-26 01:48:52 -03004000 ptr->flag_ok = hdw->flag_ok;
4001 ptr->fw1_state = hdw->fw1_state;
4002 ptr->flag_decoder_missed = hdw->flag_decoder_missed;
4003 ptr->flag_tripped = hdw->flag_tripped;
4004 ptr->state_encoder_ok = hdw->state_encoder_ok;
4005 ptr->state_encoder_run = hdw->state_encoder_run;
4006 ptr->state_decoder_run = hdw->state_decoder_run;
4007 ptr->state_usbstream_run = hdw->state_usbstream_run;
4008 ptr->state_decoder_quiescent = hdw->state_decoder_quiescent;
4009 ptr->state_pipeline_config = hdw->state_pipeline_config;
4010 ptr->state_pipeline_req = hdw->state_pipeline_req;
4011 ptr->state_pipeline_pause = hdw->state_pipeline_pause;
4012 ptr->state_pipeline_idle = hdw->state_pipeline_idle;
Mike Iselyd8554972006-06-26 20:58:46 -03004013 ptr->cmd_debug_state = hdw->cmd_debug_state;
4014 ptr->cmd_code = hdw->cmd_debug_code;
4015 ptr->cmd_debug_write_len = hdw->cmd_debug_write_len;
4016 ptr->cmd_debug_read_len = hdw->cmd_debug_read_len;
4017 ptr->cmd_debug_timeout = hdw->ctl_timeout_flag;
4018 ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag;
4019 ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag;
4020 ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status;
4021 ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status;
4022}
4023
4024
Mike Isely681c7392007-11-26 01:48:52 -03004025void pvr2_hdw_get_debug_info_locked(struct pvr2_hdw *hdw,
4026 struct pvr2_hdw_debug_info *ptr)
4027{
4028 LOCK_TAKE(hdw->ctl_lock); do {
4029 pvr2_hdw_get_debug_info_unlocked(hdw,ptr);
4030 } while(0); LOCK_GIVE(hdw->ctl_lock);
4031}
4032
4033
Mike Iselyd8554972006-06-26 20:58:46 -03004034int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
4035{
4036 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
4037}
4038
4039
4040int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
4041{
4042 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
4043}
4044
4045
4046int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
4047{
4048 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
4049}
4050
4051
4052int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
4053{
4054 u32 cval,nval;
4055 int ret;
4056 if (~msk) {
4057 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
4058 if (ret) return ret;
4059 nval = (cval & ~msk) | (val & msk);
4060 pvr2_trace(PVR2_TRACE_GPIO,
4061 "GPIO direction changing 0x%x:0x%x"
4062 " from 0x%x to 0x%x",
4063 msk,val,cval,nval);
4064 } else {
4065 nval = val;
4066 pvr2_trace(PVR2_TRACE_GPIO,
4067 "GPIO direction changing to 0x%x",nval);
4068 }
4069 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
4070}
4071
4072
4073int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
4074{
4075 u32 cval,nval;
4076 int ret;
4077 if (~msk) {
4078 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
4079 if (ret) return ret;
4080 nval = (cval & ~msk) | (val & msk);
4081 pvr2_trace(PVR2_TRACE_GPIO,
4082 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
4083 msk,val,cval,nval);
4084 } else {
4085 nval = val;
4086 pvr2_trace(PVR2_TRACE_GPIO,
4087 "GPIO output changing to 0x%x",nval);
4088 }
4089 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
4090}
4091
4092
Mike Isely7fb20fa2008-04-22 14:45:37 -03004093unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
4094{
4095 return hdw->input_avail_mask;
4096}
4097
4098
Mike Iselye61b6fc2006-07-18 22:42:18 -03004099/* Find I2C address of eeprom */
Adrian Bunk07e337e2006-06-30 11:30:20 -03004100static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03004101{
4102 int result;
4103 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03004104 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03004105 result = pvr2_send_request(hdw,
4106 hdw->cmd_buffer,1,
4107 hdw->cmd_buffer,1);
4108 if (result < 0) break;
4109 result = hdw->cmd_buffer[0];
4110 } while(0); LOCK_GIVE(hdw->ctl_lock);
4111 return result;
4112}
4113
4114
Mike Isely32ffa9a2006-09-23 22:26:52 -03004115int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
Hans Verkuilf3d092b2007-02-23 20:55:14 -03004116 u32 match_type, u32 match_chip, u64 reg_id,
4117 int setFl,u64 *val_ptr)
Mike Isely32ffa9a2006-09-23 22:26:52 -03004118{
4119#ifdef CONFIG_VIDEO_ADV_DEBUG
Mike Isely32ffa9a2006-09-23 22:26:52 -03004120 struct pvr2_i2c_client *cp;
4121 struct v4l2_register req;
Mike Isely6d988162006-09-28 17:53:49 -03004122 int stat = 0;
4123 int okFl = 0;
Mike Isely32ffa9a2006-09-23 22:26:52 -03004124
Mike Isely201f5c92007-01-28 16:08:36 -03004125 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
4126
Hans Verkuilf3d092b2007-02-23 20:55:14 -03004127 req.match_type = match_type;
4128 req.match_chip = match_chip;
Mike Isely32ffa9a2006-09-23 22:26:52 -03004129 req.reg = reg_id;
4130 if (setFl) req.val = *val_ptr;
4131 mutex_lock(&hdw->i2c_list_lock); do {
Trent Piephoe77e2c22007-10-10 05:37:42 -03004132 list_for_each_entry(cp, &hdw->i2c_clients, list) {
Mike Isely8481a752007-04-27 12:31:31 -03004133 if (!v4l2_chip_match_i2c_client(
4134 cp->client,
4135 req.match_type, req.match_chip)) {
Hans Verkuilf3d092b2007-02-23 20:55:14 -03004136 continue;
4137 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03004138 stat = pvr2_i2c_client_cmd(
Trent Piepho52ebc762007-01-23 22:38:13 -03004139 cp,(setFl ? VIDIOC_DBG_S_REGISTER :
4140 VIDIOC_DBG_G_REGISTER),&req);
Mike Isely32ffa9a2006-09-23 22:26:52 -03004141 if (!setFl) *val_ptr = req.val;
Mike Isely6d988162006-09-28 17:53:49 -03004142 okFl = !0;
4143 break;
Mike Isely32ffa9a2006-09-23 22:26:52 -03004144 }
4145 } while (0); mutex_unlock(&hdw->i2c_list_lock);
Mike Isely6d988162006-09-28 17:53:49 -03004146 if (okFl) {
4147 return stat;
4148 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03004149 return -EINVAL;
4150#else
4151 return -ENOSYS;
4152#endif
4153}
4154
4155
Mike Iselyd8554972006-06-26 20:58:46 -03004156/*
4157 Stuff for Emacs to see, in order to encourage consistent editing style:
4158 *** Local Variables: ***
4159 *** mode: c ***
4160 *** fill-column: 75 ***
4161 *** tab-width: 8 ***
4162 *** c-basic-offset: 8 ***
4163 *** End: ***
4164 */