blob: 72e9056557bda0b7a12b20459cb417dae25bfbc4 [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 Isely694dca22008-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 Isely694dca22008-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 Isely1cb03b72008-04-21 03:47:43 -0300252static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v);
Mike Isely681c7392007-11-26 01:48:52 -0300253static void pvr2_hdw_state_sched(struct pvr2_hdw *);
254static int pvr2_hdw_state_eval(struct pvr2_hdw *);
Mike Isely1bde0282006-12-27 23:30:13 -0300255static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
Mike Isely681c7392007-11-26 01:48:52 -0300256static void pvr2_hdw_worker_i2c(struct work_struct *work);
257static void pvr2_hdw_worker_poll(struct work_struct *work);
Mike Isely681c7392007-11-26 01:48:52 -0300258static int pvr2_hdw_wait(struct pvr2_hdw *,int state);
259static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *);
260static void pvr2_hdw_state_log_state(struct pvr2_hdw *);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300261static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl);
Mike Isely681c7392007-11-26 01:48:52 -0300262static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300263static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300264static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw);
265static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
Mike Isely681c7392007-11-26 01:48:52 -0300266static void pvr2_hdw_quiescent_timeout(unsigned long);
267static void pvr2_hdw_encoder_wait_timeout(unsigned long);
Mike Iselyd913d632008-04-06 04:04:35 -0300268static void pvr2_hdw_encoder_run_timeout(unsigned long);
Mike Isely1c9d10d2008-03-28 05:38:54 -0300269static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
Adrian Bunk07e337e2006-06-30 11:30:20 -0300270static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
271 unsigned int timeout,int probe_fl,
272 void *write_data,unsigned int write_len,
273 void *read_data,unsigned int read_len);
Mike Iselyd8554972006-06-26 20:58:46 -0300274
Mike Isely681c7392007-11-26 01:48:52 -0300275
276static void trace_stbit(const char *name,int val)
277{
278 pvr2_trace(PVR2_TRACE_STBITS,
279 "State bit %s <-- %s",
280 name,(val ? "true" : "false"));
281}
282
Mike Iselyd8554972006-06-26 20:58:46 -0300283static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
284{
285 struct pvr2_hdw *hdw = cptr->hdw;
286 if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) {
287 *vp = hdw->freqTable[hdw->freqProgSlot-1];
288 } else {
289 *vp = 0;
290 }
291 return 0;
292}
293
294static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v)
295{
296 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300297 unsigned int slotId = hdw->freqProgSlot;
298 if ((slotId > 0) && (slotId <= FREQTABLE_SIZE)) {
299 hdw->freqTable[slotId-1] = v;
300 /* Handle side effects correctly - if we're tuned to this
301 slot, then forgot the slot id relation since the stored
302 frequency has been changed. */
303 if (hdw->freqSelector) {
304 if (hdw->freqSlotRadio == slotId) {
305 hdw->freqSlotRadio = 0;
306 }
307 } else {
308 if (hdw->freqSlotTelevision == slotId) {
309 hdw->freqSlotTelevision = 0;
310 }
311 }
Mike Iselyd8554972006-06-26 20:58:46 -0300312 }
313 return 0;
314}
315
316static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp)
317{
318 *vp = cptr->hdw->freqProgSlot;
319 return 0;
320}
321
322static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v)
323{
324 struct pvr2_hdw *hdw = cptr->hdw;
325 if ((v >= 0) && (v <= FREQTABLE_SIZE)) {
326 hdw->freqProgSlot = v;
327 }
328 return 0;
329}
330
331static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp)
332{
Mike Isely1bde0282006-12-27 23:30:13 -0300333 struct pvr2_hdw *hdw = cptr->hdw;
334 *vp = hdw->freqSelector ? hdw->freqSlotRadio : hdw->freqSlotTelevision;
Mike Iselyd8554972006-06-26 20:58:46 -0300335 return 0;
336}
337
Mike Isely1bde0282006-12-27 23:30:13 -0300338static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int slotId)
Mike Iselyd8554972006-06-26 20:58:46 -0300339{
340 unsigned freq = 0;
341 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely1bde0282006-12-27 23:30:13 -0300342 if ((slotId < 0) || (slotId > FREQTABLE_SIZE)) return 0;
343 if (slotId > 0) {
344 freq = hdw->freqTable[slotId-1];
345 if (!freq) return 0;
346 pvr2_hdw_set_cur_freq(hdw,freq);
Mike Iselyd8554972006-06-26 20:58:46 -0300347 }
Mike Isely1bde0282006-12-27 23:30:13 -0300348 if (hdw->freqSelector) {
349 hdw->freqSlotRadio = slotId;
350 } else {
351 hdw->freqSlotTelevision = slotId;
Mike Iselyd8554972006-06-26 20:58:46 -0300352 }
353 return 0;
354}
355
356static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp)
357{
Mike Isely1bde0282006-12-27 23:30:13 -0300358 *vp = pvr2_hdw_get_cur_freq(cptr->hdw);
Mike Iselyd8554972006-06-26 20:58:46 -0300359 return 0;
360}
361
362static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr)
363{
364 return cptr->hdw->freqDirty != 0;
365}
366
367static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr)
368{
369 cptr->hdw->freqDirty = 0;
370}
371
372static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
373{
Mike Isely1bde0282006-12-27 23:30:13 -0300374 pvr2_hdw_set_cur_freq(cptr->hdw,v);
Mike Iselyd8554972006-06-26 20:58:46 -0300375 return 0;
376}
377
Mike Isely3ad9fc32006-09-02 22:37:52 -0300378static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
379{
380 /* Actual maximum depends on the video standard in effect. */
381 if (cptr->hdw->std_mask_cur & V4L2_STD_525_60) {
382 *vp = 480;
383 } else {
384 *vp = 576;
385 }
386 return 0;
387}
388
389static int ctrl_vres_min_get(struct pvr2_ctrl *cptr,int *vp)
390{
Mike Isely989eb152007-11-26 01:53:12 -0300391 /* Actual minimum depends on device digitizer type. */
392 if (cptr->hdw->hdw_desc->flag_has_cx25840) {
Mike Isely3ad9fc32006-09-02 22:37:52 -0300393 *vp = 75;
394 } else {
395 *vp = 17;
396 }
397 return 0;
398}
399
Mike Isely1bde0282006-12-27 23:30:13 -0300400static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)
401{
402 *vp = cptr->hdw->input_val;
403 return 0;
404}
405
Mike Isely29bf5b12008-04-22 14:45:37 -0300406static int ctrl_check_input(struct pvr2_ctrl *cptr,int v)
407{
Mike Isely1cb03b72008-04-21 03:47:43 -0300408 return ((1 << v) & cptr->hdw->input_allowed_mask) != 0;
Mike Isely29bf5b12008-04-22 14:45:37 -0300409}
410
Mike Isely1bde0282006-12-27 23:30:13 -0300411static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
412{
Mike Isely1cb03b72008-04-21 03:47:43 -0300413 return pvr2_hdw_set_input(cptr->hdw,v);
Mike Isely1bde0282006-12-27 23:30:13 -0300414}
415
416static int ctrl_isdirty_input(struct pvr2_ctrl *cptr)
417{
418 return cptr->hdw->input_dirty != 0;
419}
420
421static void ctrl_cleardirty_input(struct pvr2_ctrl *cptr)
422{
423 cptr->hdw->input_dirty = 0;
424}
425
Mike Isely5549f542006-12-27 23:28:54 -0300426
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300427static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
428{
Mike Isely644afdb2007-01-20 00:19:23 -0300429 unsigned long fv;
430 struct pvr2_hdw *hdw = cptr->hdw;
431 if (hdw->tuner_signal_stale) {
432 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300433 }
Mike Isely644afdb2007-01-20 00:19:23 -0300434 fv = hdw->tuner_signal_info.rangehigh;
435 if (!fv) {
436 /* Safety fallback */
437 *vp = TV_MAX_FREQ;
438 return 0;
439 }
440 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
441 fv = (fv * 125) / 2;
442 } else {
443 fv = fv * 62500;
444 }
445 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300446 return 0;
447}
448
449static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
450{
Mike Isely644afdb2007-01-20 00:19:23 -0300451 unsigned long fv;
452 struct pvr2_hdw *hdw = cptr->hdw;
453 if (hdw->tuner_signal_stale) {
454 pvr2_i2c_core_status_poll(hdw);
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300455 }
Mike Isely644afdb2007-01-20 00:19:23 -0300456 fv = hdw->tuner_signal_info.rangelow;
457 if (!fv) {
458 /* Safety fallback */
459 *vp = TV_MIN_FREQ;
460 return 0;
461 }
462 if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
463 fv = (fv * 125) / 2;
464 } else {
465 fv = fv * 62500;
466 }
467 *vp = fv;
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300468 return 0;
469}
470
Mike Iselyb30d2442006-06-25 20:05:01 -0300471static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
472{
473 return cptr->hdw->enc_stale != 0;
474}
475
476static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr)
477{
478 cptr->hdw->enc_stale = 0;
Mike Isely681c7392007-11-26 01:48:52 -0300479 cptr->hdw->enc_unsafe_stale = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -0300480}
481
482static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
483{
484 int ret;
485 struct v4l2_ext_controls cs;
486 struct v4l2_ext_control c1;
487 memset(&cs,0,sizeof(cs));
488 memset(&c1,0,sizeof(c1));
489 cs.controls = &c1;
490 cs.count = 1;
491 c1.id = cptr->info->v4l_id;
Hans Verkuil01f1e442007-08-21 18:32:42 -0300492 ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs,
Mike Iselyb30d2442006-06-25 20:05:01 -0300493 VIDIOC_G_EXT_CTRLS);
494 if (ret) return ret;
495 *vp = c1.value;
496 return 0;
497}
498
499static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
500{
501 int ret;
Mike Isely681c7392007-11-26 01:48:52 -0300502 struct pvr2_hdw *hdw = cptr->hdw;
Mike Iselyb30d2442006-06-25 20:05:01 -0300503 struct v4l2_ext_controls cs;
504 struct v4l2_ext_control c1;
505 memset(&cs,0,sizeof(cs));
506 memset(&c1,0,sizeof(c1));
507 cs.controls = &c1;
508 cs.count = 1;
509 c1.id = cptr->info->v4l_id;
510 c1.value = v;
Mike Isely681c7392007-11-26 01:48:52 -0300511 ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
512 hdw->state_encoder_run, &cs,
Mike Iselyb30d2442006-06-25 20:05:01 -0300513 VIDIOC_S_EXT_CTRLS);
Mike Isely681c7392007-11-26 01:48:52 -0300514 if (ret == -EBUSY) {
515 /* Oops. cx2341x is telling us it's not safe to change
516 this control while we're capturing. Make a note of this
517 fact so that the pipeline will be stopped the next time
518 controls are committed. Then go on ahead and store this
519 change anyway. */
520 ret = cx2341x_ext_ctrls(&hdw->enc_ctl_state,
521 0, &cs,
522 VIDIOC_S_EXT_CTRLS);
523 if (!ret) hdw->enc_unsafe_stale = !0;
524 }
Mike Iselyb30d2442006-06-25 20:05:01 -0300525 if (ret) return ret;
Mike Isely681c7392007-11-26 01:48:52 -0300526 hdw->enc_stale = !0;
Mike Iselyb30d2442006-06-25 20:05:01 -0300527 return 0;
528}
529
530static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
531{
532 struct v4l2_queryctrl qctrl;
533 struct pvr2_ctl_info *info;
534 qctrl.id = cptr->info->v4l_id;
535 cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
536 /* Strip out the const so we can adjust a function pointer. It's
537 OK to do this here because we know this is a dynamically created
538 control, so the underlying storage for the info pointer is (a)
539 private to us, and (b) not in read-only storage. Either we do
540 this or we significantly complicate the underlying control
541 implementation. */
542 info = (struct pvr2_ctl_info *)(cptr->info);
543 if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) {
544 if (info->set_value) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -0300545 info->set_value = NULL;
Mike Iselyb30d2442006-06-25 20:05:01 -0300546 }
547 } else {
548 if (!(info->set_value)) {
549 info->set_value = ctrl_cx2341x_set;
550 }
551 }
552 return qctrl.flags;
553}
554
Mike Iselyd8554972006-06-26 20:58:46 -0300555static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp)
556{
Mike Isely681c7392007-11-26 01:48:52 -0300557 *vp = cptr->hdw->state_pipeline_req;
558 return 0;
559}
560
561static int ctrl_masterstate_get(struct pvr2_ctrl *cptr,int *vp)
562{
563 *vp = cptr->hdw->master_state;
Mike Iselyd8554972006-06-26 20:58:46 -0300564 return 0;
565}
566
567static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp)
568{
569 int result = pvr2_hdw_is_hsm(cptr->hdw);
570 *vp = PVR2_CVAL_HSM_FULL;
571 if (result < 0) *vp = PVR2_CVAL_HSM_FAIL;
572 if (result) *vp = PVR2_CVAL_HSM_HIGH;
573 return 0;
574}
575
576static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp)
577{
578 *vp = cptr->hdw->std_mask_avail;
579 return 0;
580}
581
582static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v)
583{
584 struct pvr2_hdw *hdw = cptr->hdw;
585 v4l2_std_id ns;
586 ns = hdw->std_mask_avail;
587 ns = (ns & ~m) | (v & m);
588 if (ns == hdw->std_mask_avail) return 0;
589 hdw->std_mask_avail = ns;
590 pvr2_hdw_internal_set_std_avail(hdw);
591 pvr2_hdw_internal_find_stdenum(hdw);
592 return 0;
593}
594
595static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val,
596 char *bufPtr,unsigned int bufSize,
597 unsigned int *len)
598{
599 *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val);
600 return 0;
601}
602
603static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr,
604 const char *bufPtr,unsigned int bufSize,
605 int *mskp,int *valp)
606{
607 int ret;
608 v4l2_std_id id;
609 ret = pvr2_std_str_to_id(&id,bufPtr,bufSize);
610 if (ret < 0) return ret;
611 if (mskp) *mskp = id;
612 if (valp) *valp = id;
613 return 0;
614}
615
616static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp)
617{
618 *vp = cptr->hdw->std_mask_cur;
619 return 0;
620}
621
622static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v)
623{
624 struct pvr2_hdw *hdw = cptr->hdw;
625 v4l2_std_id ns;
626 ns = hdw->std_mask_cur;
627 ns = (ns & ~m) | (v & m);
628 if (ns == hdw->std_mask_cur) return 0;
629 hdw->std_mask_cur = ns;
630 hdw->std_dirty = !0;
631 pvr2_hdw_internal_find_stdenum(hdw);
632 return 0;
633}
634
635static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr)
636{
637 return cptr->hdw->std_dirty != 0;
638}
639
640static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
641{
642 cptr->hdw->std_dirty = 0;
643}
644
645static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
646{
Mike Isely18103c52007-01-20 00:09:47 -0300647 struct pvr2_hdw *hdw = cptr->hdw;
648 pvr2_i2c_core_status_poll(hdw);
649 *vp = hdw->tuner_signal_info.signal;
650 return 0;
651}
652
653static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
654{
655 int val = 0;
656 unsigned int subchan;
657 struct pvr2_hdw *hdw = cptr->hdw;
Mike Isely644afdb2007-01-20 00:19:23 -0300658 pvr2_i2c_core_status_poll(hdw);
Mike Isely18103c52007-01-20 00:09:47 -0300659 subchan = hdw->tuner_signal_info.rxsubchans;
660 if (subchan & V4L2_TUNER_SUB_MONO) {
661 val |= (1 << V4L2_TUNER_MODE_MONO);
662 }
663 if (subchan & V4L2_TUNER_SUB_STEREO) {
664 val |= (1 << V4L2_TUNER_MODE_STEREO);
665 }
666 if (subchan & V4L2_TUNER_SUB_LANG1) {
667 val |= (1 << V4L2_TUNER_MODE_LANG1);
668 }
669 if (subchan & V4L2_TUNER_SUB_LANG2) {
670 val |= (1 << V4L2_TUNER_MODE_LANG2);
671 }
672 *vp = val;
Mike Iselyd8554972006-06-26 20:58:46 -0300673 return 0;
674}
675
Mike Iselyd8554972006-06-26 20:58:46 -0300676
677static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v)
678{
679 struct pvr2_hdw *hdw = cptr->hdw;
680 if (v < 0) return -EINVAL;
681 if (v > hdw->std_enum_cnt) return -EINVAL;
682 hdw->std_enum_cur = v;
683 if (!v) return 0;
684 v--;
685 if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0;
686 hdw->std_mask_cur = hdw->std_defs[v].id;
687 hdw->std_dirty = !0;
688 return 0;
689}
690
691
692static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp)
693{
694 *vp = cptr->hdw->std_enum_cur;
695 return 0;
696}
697
698
699static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr)
700{
701 return cptr->hdw->std_dirty != 0;
702}
703
704
705static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr)
706{
707 cptr->hdw->std_dirty = 0;
708}
709
710
711#define DEFINT(vmin,vmax) \
712 .type = pvr2_ctl_int, \
713 .def.type_int.min_value = vmin, \
714 .def.type_int.max_value = vmax
715
716#define DEFENUM(tab) \
717 .type = pvr2_ctl_enum, \
Mike Isely27c7b712007-01-20 00:39:17 -0300718 .def.type_enum.count = ARRAY_SIZE(tab), \
Mike Iselyd8554972006-06-26 20:58:46 -0300719 .def.type_enum.value_names = tab
720
Mike Isely33213962006-06-25 20:04:40 -0300721#define DEFBOOL \
722 .type = pvr2_ctl_bool
723
Mike Iselyd8554972006-06-26 20:58:46 -0300724#define DEFMASK(msk,tab) \
725 .type = pvr2_ctl_bitmask, \
726 .def.type_bitmask.valid_bits = msk, \
727 .def.type_bitmask.bit_names = tab
728
729#define DEFREF(vname) \
730 .set_value = ctrl_set_##vname, \
731 .get_value = ctrl_get_##vname, \
732 .is_dirty = ctrl_isdirty_##vname, \
733 .clear_dirty = ctrl_cleardirty_##vname
734
735
736#define VCREATE_FUNCS(vname) \
737static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \
738{*vp = cptr->hdw->vname##_val; return 0;} \
739static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \
740{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \
741static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \
742{return cptr->hdw->vname##_dirty != 0;} \
743static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \
744{cptr->hdw->vname##_dirty = 0;}
745
746VCREATE_FUNCS(brightness)
747VCREATE_FUNCS(contrast)
748VCREATE_FUNCS(saturation)
749VCREATE_FUNCS(hue)
750VCREATE_FUNCS(volume)
751VCREATE_FUNCS(balance)
752VCREATE_FUNCS(bass)
753VCREATE_FUNCS(treble)
754VCREATE_FUNCS(mute)
Mike Iselyc05c0462006-06-25 20:04:25 -0300755VCREATE_FUNCS(audiomode)
756VCREATE_FUNCS(res_hor)
757VCREATE_FUNCS(res_ver)
Mike Iselyd8554972006-06-26 20:58:46 -0300758VCREATE_FUNCS(srate)
Mike Iselyd8554972006-06-26 20:58:46 -0300759
Mike Iselyd8554972006-06-26 20:58:46 -0300760/* Table definition of all controls which can be manipulated */
761static const struct pvr2_ctl_info control_defs[] = {
762 {
763 .v4l_id = V4L2_CID_BRIGHTNESS,
764 .desc = "Brightness",
765 .name = "brightness",
766 .default_value = 128,
767 DEFREF(brightness),
768 DEFINT(0,255),
769 },{
770 .v4l_id = V4L2_CID_CONTRAST,
771 .desc = "Contrast",
772 .name = "contrast",
773 .default_value = 68,
774 DEFREF(contrast),
775 DEFINT(0,127),
776 },{
777 .v4l_id = V4L2_CID_SATURATION,
778 .desc = "Saturation",
779 .name = "saturation",
780 .default_value = 64,
781 DEFREF(saturation),
782 DEFINT(0,127),
783 },{
784 .v4l_id = V4L2_CID_HUE,
785 .desc = "Hue",
786 .name = "hue",
787 .default_value = 0,
788 DEFREF(hue),
789 DEFINT(-128,127),
790 },{
791 .v4l_id = V4L2_CID_AUDIO_VOLUME,
792 .desc = "Volume",
793 .name = "volume",
Mike Isely139eecf2006-12-27 23:36:33 -0300794 .default_value = 62000,
Mike Iselyd8554972006-06-26 20:58:46 -0300795 DEFREF(volume),
796 DEFINT(0,65535),
797 },{
798 .v4l_id = V4L2_CID_AUDIO_BALANCE,
799 .desc = "Balance",
800 .name = "balance",
801 .default_value = 0,
802 DEFREF(balance),
803 DEFINT(-32768,32767),
804 },{
805 .v4l_id = V4L2_CID_AUDIO_BASS,
806 .desc = "Bass",
807 .name = "bass",
808 .default_value = 0,
809 DEFREF(bass),
810 DEFINT(-32768,32767),
811 },{
812 .v4l_id = V4L2_CID_AUDIO_TREBLE,
813 .desc = "Treble",
814 .name = "treble",
815 .default_value = 0,
816 DEFREF(treble),
817 DEFINT(-32768,32767),
818 },{
819 .v4l_id = V4L2_CID_AUDIO_MUTE,
820 .desc = "Mute",
821 .name = "mute",
822 .default_value = 0,
823 DEFREF(mute),
Mike Isely33213962006-06-25 20:04:40 -0300824 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300825 },{
Mike Iselyc05c0462006-06-25 20:04:25 -0300826 .desc = "Video Source",
827 .name = "input",
828 .internal_id = PVR2_CID_INPUT,
829 .default_value = PVR2_CVAL_INPUT_TV,
Mike Isely29bf5b12008-04-22 14:45:37 -0300830 .check_value = ctrl_check_input,
Mike Iselyc05c0462006-06-25 20:04:25 -0300831 DEFREF(input),
832 DEFENUM(control_values_input),
833 },{
834 .desc = "Audio Mode",
835 .name = "audio_mode",
836 .internal_id = PVR2_CID_AUDIOMODE,
837 .default_value = V4L2_TUNER_MODE_STEREO,
838 DEFREF(audiomode),
839 DEFENUM(control_values_audiomode),
840 },{
841 .desc = "Horizontal capture resolution",
842 .name = "resolution_hor",
843 .internal_id = PVR2_CID_HRES,
844 .default_value = 720,
845 DEFREF(res_hor),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300846 DEFINT(19,720),
Mike Iselyc05c0462006-06-25 20:04:25 -0300847 },{
848 .desc = "Vertical capture resolution",
849 .name = "resolution_ver",
850 .internal_id = PVR2_CID_VRES,
851 .default_value = 480,
852 DEFREF(res_ver),
Mike Isely3ad9fc32006-09-02 22:37:52 -0300853 DEFINT(17,576),
854 /* Hook in check for video standard and adjust maximum
855 depending on the standard. */
856 .get_max_value = ctrl_vres_max_get,
857 .get_min_value = ctrl_vres_min_get,
Mike Iselyc05c0462006-06-25 20:04:25 -0300858 },{
Mike Iselyb30d2442006-06-25 20:05:01 -0300859 .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
Mike Isely434449f2006-08-08 09:10:06 -0300860 .default_value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
861 .desc = "Audio Sampling Frequency",
Mike Iselyd8554972006-06-26 20:58:46 -0300862 .name = "srate",
Mike Iselyd8554972006-06-26 20:58:46 -0300863 DEFREF(srate),
864 DEFENUM(control_values_srate),
865 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300866 .desc = "Tuner Frequency (Hz)",
867 .name = "frequency",
868 .internal_id = PVR2_CID_FREQUENCY,
Mike Isely1bde0282006-12-27 23:30:13 -0300869 .default_value = 0,
Mike Iselyd8554972006-06-26 20:58:46 -0300870 .set_value = ctrl_freq_set,
871 .get_value = ctrl_freq_get,
872 .is_dirty = ctrl_freq_is_dirty,
873 .clear_dirty = ctrl_freq_clear_dirty,
Mike Isely644afdb2007-01-20 00:19:23 -0300874 DEFINT(0,0),
Pantelis Koukousoulas25d85272006-12-27 23:06:04 -0300875 /* Hook in check for input value (tv/radio) and adjust
876 max/min values accordingly */
877 .get_max_value = ctrl_freq_max_get,
878 .get_min_value = ctrl_freq_min_get,
Mike Iselyd8554972006-06-26 20:58:46 -0300879 },{
880 .desc = "Channel",
881 .name = "channel",
882 .set_value = ctrl_channel_set,
883 .get_value = ctrl_channel_get,
884 DEFINT(0,FREQTABLE_SIZE),
885 },{
886 .desc = "Channel Program Frequency",
887 .name = "freq_table_value",
888 .set_value = ctrl_channelfreq_set,
889 .get_value = ctrl_channelfreq_get,
Mike Isely644afdb2007-01-20 00:19:23 -0300890 DEFINT(0,0),
Mike Isely1bde0282006-12-27 23:30:13 -0300891 /* Hook in check for input value (tv/radio) and adjust
892 max/min values accordingly */
Mike Isely1bde0282006-12-27 23:30:13 -0300893 .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 Program ID",
897 .name = "freq_table_channel",
898 .set_value = ctrl_channelprog_set,
899 .get_value = ctrl_channelprog_get,
900 DEFINT(0,FREQTABLE_SIZE),
901 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300902 .desc = "Streaming Enabled",
903 .name = "streaming_enabled",
904 .get_value = ctrl_streamingenabled_get,
Mike Isely33213962006-06-25 20:04:40 -0300905 DEFBOOL,
Mike Iselyd8554972006-06-26 20:58:46 -0300906 },{
907 .desc = "USB Speed",
908 .name = "usb_speed",
909 .get_value = ctrl_hsm_get,
910 DEFENUM(control_values_hsm),
911 },{
Mike Isely681c7392007-11-26 01:48:52 -0300912 .desc = "Master State",
913 .name = "master_state",
914 .get_value = ctrl_masterstate_get,
915 DEFENUM(pvr2_state_names),
916 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300917 .desc = "Signal Present",
918 .name = "signal_present",
919 .get_value = ctrl_signal_get,
Mike Isely18103c52007-01-20 00:09:47 -0300920 DEFINT(0,65535),
921 },{
922 .desc = "Audio Modes Present",
923 .name = "audio_modes_present",
924 .get_value = ctrl_audio_modes_present_get,
925 /* For this type we "borrow" the V4L2_TUNER_MODE enum from
926 v4l. Nothing outside of this module cares about this,
927 but I reuse it in order to also reuse the
928 control_values_audiomode string table. */
929 DEFMASK(((1 << V4L2_TUNER_MODE_MONO)|
930 (1 << V4L2_TUNER_MODE_STEREO)|
931 (1 << V4L2_TUNER_MODE_LANG1)|
932 (1 << V4L2_TUNER_MODE_LANG2)),
933 control_values_audiomode),
Mike Iselyd8554972006-06-26 20:58:46 -0300934 },{
935 .desc = "Video Standards Available Mask",
936 .name = "video_standard_mask_available",
937 .internal_id = PVR2_CID_STDAVAIL,
938 .skip_init = !0,
939 .get_value = ctrl_stdavail_get,
940 .set_value = ctrl_stdavail_set,
941 .val_to_sym = ctrl_std_val_to_sym,
942 .sym_to_val = ctrl_std_sym_to_val,
943 .type = pvr2_ctl_bitmask,
944 },{
945 .desc = "Video Standards In Use Mask",
946 .name = "video_standard_mask_active",
947 .internal_id = PVR2_CID_STDCUR,
948 .skip_init = !0,
949 .get_value = ctrl_stdcur_get,
950 .set_value = ctrl_stdcur_set,
951 .is_dirty = ctrl_stdcur_is_dirty,
952 .clear_dirty = ctrl_stdcur_clear_dirty,
953 .val_to_sym = ctrl_std_val_to_sym,
954 .sym_to_val = ctrl_std_sym_to_val,
955 .type = pvr2_ctl_bitmask,
956 },{
Mike Iselyd8554972006-06-26 20:58:46 -0300957 .desc = "Video Standard Name",
958 .name = "video_standard",
959 .internal_id = PVR2_CID_STDENUM,
960 .skip_init = !0,
961 .get_value = ctrl_stdenumcur_get,
962 .set_value = ctrl_stdenumcur_set,
963 .is_dirty = ctrl_stdenumcur_is_dirty,
964 .clear_dirty = ctrl_stdenumcur_clear_dirty,
965 .type = pvr2_ctl_enum,
966 }
967};
968
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -0300969#define CTRLDEF_COUNT ARRAY_SIZE(control_defs)
Mike Iselyd8554972006-06-26 20:58:46 -0300970
971
972const char *pvr2_config_get_name(enum pvr2_config cfg)
973{
974 switch (cfg) {
975 case pvr2_config_empty: return "empty";
976 case pvr2_config_mpeg: return "mpeg";
977 case pvr2_config_vbi: return "vbi";
Mike Isely16eb40d2006-12-30 18:27:32 -0300978 case pvr2_config_pcm: return "pcm";
979 case pvr2_config_rawvideo: return "raw video";
Mike Iselyd8554972006-06-26 20:58:46 -0300980 }
981 return "<unknown>";
982}
983
984
985struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw)
986{
987 return hdw->usb_dev;
988}
989
990
991unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw)
992{
993 return hdw->serial_number;
994}
995
Mike Isely31a18542007-04-08 01:11:47 -0300996
997const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
998{
999 return hdw->bus_info;
1000}
1001
1002
Mike Isely1bde0282006-12-27 23:30:13 -03001003unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
1004{
1005 return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
1006}
1007
1008/* Set the currently tuned frequency and account for all possible
1009 driver-core side effects of this action. */
Adrian Bunkf55a8712008-04-18 05:38:56 -03001010static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *hdw,unsigned long val)
Mike Isely1bde0282006-12-27 23:30:13 -03001011{
Mike Isely7c74e572007-01-20 00:15:41 -03001012 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
Mike Isely1bde0282006-12-27 23:30:13 -03001013 if (hdw->freqSelector) {
1014 /* Swing over to radio frequency selection */
1015 hdw->freqSelector = 0;
1016 hdw->freqDirty = !0;
1017 }
Mike Isely1bde0282006-12-27 23:30:13 -03001018 if (hdw->freqValRadio != val) {
1019 hdw->freqValRadio = val;
1020 hdw->freqSlotRadio = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001021 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001022 }
Mike Isely7c74e572007-01-20 00:15:41 -03001023 } else {
Mike Isely1bde0282006-12-27 23:30:13 -03001024 if (!(hdw->freqSelector)) {
1025 /* Swing over to television frequency selection */
1026 hdw->freqSelector = 1;
1027 hdw->freqDirty = !0;
1028 }
Mike Isely1bde0282006-12-27 23:30:13 -03001029 if (hdw->freqValTelevision != val) {
1030 hdw->freqValTelevision = val;
1031 hdw->freqSlotTelevision = 0;
Mike Isely7c74e572007-01-20 00:15:41 -03001032 hdw->freqDirty = !0;
Mike Isely1bde0282006-12-27 23:30:13 -03001033 }
Mike Isely1bde0282006-12-27 23:30:13 -03001034 }
1035}
1036
Mike Iselyd8554972006-06-26 20:58:46 -03001037int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw)
1038{
1039 return hdw->unit_number;
1040}
1041
1042
1043/* Attempt to locate one of the given set of files. Messages are logged
1044 appropriate to what has been found. The return value will be 0 or
1045 greater on success (it will be the index of the file name found) and
1046 fw_entry will be filled in. Otherwise a negative error is returned on
1047 failure. If the return value is -ENOENT then no viable firmware file
1048 could be located. */
1049static int pvr2_locate_firmware(struct pvr2_hdw *hdw,
1050 const struct firmware **fw_entry,
1051 const char *fwtypename,
1052 unsigned int fwcount,
1053 const char *fwnames[])
1054{
1055 unsigned int idx;
1056 int ret = -EINVAL;
1057 for (idx = 0; idx < fwcount; idx++) {
1058 ret = request_firmware(fw_entry,
1059 fwnames[idx],
1060 &hdw->usb_dev->dev);
1061 if (!ret) {
1062 trace_firmware("Located %s firmware: %s;"
1063 " uploading...",
1064 fwtypename,
1065 fwnames[idx]);
1066 return idx;
1067 }
1068 if (ret == -ENOENT) continue;
1069 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1070 "request_firmware fatal error with code=%d",ret);
1071 return ret;
1072 }
1073 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1074 "***WARNING***"
1075 " Device %s firmware"
1076 " seems to be missing.",
1077 fwtypename);
1078 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1079 "Did you install the pvrusb2 firmware files"
1080 " in their proper location?");
1081 if (fwcount == 1) {
1082 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1083 "request_firmware unable to locate %s file %s",
1084 fwtypename,fwnames[0]);
1085 } else {
1086 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1087 "request_firmware unable to locate"
1088 " one of the following %s files:",
1089 fwtypename);
1090 for (idx = 0; idx < fwcount; idx++) {
1091 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1092 "request_firmware: Failed to find %s",
1093 fwnames[idx]);
1094 }
1095 }
1096 return ret;
1097}
1098
1099
1100/*
1101 * pvr2_upload_firmware1().
1102 *
1103 * Send the 8051 firmware to the device. After the upload, arrange for
1104 * device to re-enumerate.
1105 *
1106 * NOTE : the pointer to the firmware data given by request_firmware()
1107 * is not suitable for an usb transaction.
1108 *
1109 */
Adrian Bunk07e337e2006-06-30 11:30:20 -03001110static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001111{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001112 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001113 void *fw_ptr;
1114 unsigned int pipe;
1115 int ret;
1116 u16 address;
Mike Isely1d643a32007-09-08 22:18:50 -03001117
Mike Isely989eb152007-11-26 01:53:12 -03001118 if (!hdw->hdw_desc->fx2_firmware.cnt) {
Mike Isely1d643a32007-09-08 22:18:50 -03001119 hdw->fw1_state = FW1_STATE_OK;
Mike Isely56dcbfa2007-11-26 02:00:51 -03001120 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1121 "Connected device type defines"
1122 " no firmware to upload; ignoring firmware");
1123 return -ENOTTY;
Mike Isely1d643a32007-09-08 22:18:50 -03001124 }
1125
Mike Iselyd8554972006-06-26 20:58:46 -03001126 hdw->fw1_state = FW1_STATE_FAILED; // default result
1127
1128 trace_firmware("pvr2_upload_firmware1");
1129
1130 ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller",
Mike Isely989eb152007-11-26 01:53:12 -03001131 hdw->hdw_desc->fx2_firmware.cnt,
1132 hdw->hdw_desc->fx2_firmware.lst);
Mike Iselyd8554972006-06-26 20:58:46 -03001133 if (ret < 0) {
1134 if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING;
1135 return ret;
1136 }
1137
1138 usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0);
1139 usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f));
1140
1141 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
1142
1143 if (fw_entry->size != 0x2000){
1144 pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size");
1145 release_firmware(fw_entry);
1146 return -ENOMEM;
1147 }
1148
1149 fw_ptr = kmalloc(0x800, GFP_KERNEL);
1150 if (fw_ptr == NULL){
1151 release_firmware(fw_entry);
1152 return -ENOMEM;
1153 }
1154
1155 /* We have to hold the CPU during firmware upload. */
1156 pvr2_hdw_cpureset_assert(hdw,1);
1157
1158 /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes
1159 chunk. */
1160
1161 ret = 0;
1162 for(address = 0; address < fw_entry->size; address += 0x800) {
1163 memcpy(fw_ptr, fw_entry->data + address, 0x800);
1164 ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address,
1165 0, fw_ptr, 0x800, HZ);
1166 }
1167
1168 trace_firmware("Upload done, releasing device's CPU");
1169
1170 /* Now release the CPU. It will disconnect and reconnect later. */
1171 pvr2_hdw_cpureset_assert(hdw,0);
1172
1173 kfree(fw_ptr);
1174 release_firmware(fw_entry);
1175
1176 trace_firmware("Upload done (%d bytes sent)",ret);
1177
1178 /* We should have written 8192 bytes */
1179 if (ret == 8192) {
1180 hdw->fw1_state = FW1_STATE_RELOAD;
1181 return 0;
1182 }
1183
1184 return -EIO;
1185}
1186
1187
1188/*
1189 * pvr2_upload_firmware2()
1190 *
1191 * This uploads encoder firmware on endpoint 2.
1192 *
1193 */
1194
1195int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
1196{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03001197 const struct firmware *fw_entry = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03001198 void *fw_ptr;
Mike Isely90060d32007-02-08 02:02:53 -03001199 unsigned int pipe, fw_len, fw_done, bcnt, icnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001200 int actual_length;
1201 int ret = 0;
1202 int fwidx;
1203 static const char *fw_files[] = {
1204 CX2341X_FIRM_ENC_FILENAME,
1205 };
1206
Mike Isely989eb152007-11-26 01:53:12 -03001207 if (hdw->hdw_desc->flag_skip_cx23416_firmware) {
Mike Isely1d643a32007-09-08 22:18:50 -03001208 return 0;
1209 }
1210
Mike Iselyd8554972006-06-26 20:58:46 -03001211 trace_firmware("pvr2_upload_firmware2");
1212
1213 ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
Ahmed S. Darwisheca8ebf2007-01-20 00:35:03 -03001214 ARRAY_SIZE(fw_files), fw_files);
Mike Iselyd8554972006-06-26 20:58:46 -03001215 if (ret < 0) return ret;
1216 fwidx = ret;
1217 ret = 0;
Mike Iselyb30d2442006-06-25 20:05:01 -03001218 /* Since we're about to completely reinitialize the encoder,
1219 invalidate our cached copy of its configuration state. Next
1220 time we configure the encoder, then we'll fully configure it. */
1221 hdw->enc_cur_valid = 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001222
Mike Iselyd913d632008-04-06 04:04:35 -03001223 /* Encoder is about to be reset so note that as far as we're
1224 concerned now, the encoder has never been run. */
1225 del_timer_sync(&hdw->encoder_run_timer);
1226 if (hdw->state_encoder_runok) {
1227 hdw->state_encoder_runok = 0;
1228 trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
1229 }
1230
Mike Iselyd8554972006-06-26 20:58:46 -03001231 /* First prepare firmware loading */
1232 ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
1233 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
1234 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1235 ret |= pvr2_hdw_cmd_deep_reset(hdw);
1236 ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/
1237 ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/
1238 ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/
1239 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/
1240 ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/
1241 ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/
1242 ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/
1243 ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/
1244 ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/
1245 ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
1246 ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
1247 ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
Mike Isely1c9d10d2008-03-28 05:38:54 -03001248 ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_FWPOST1);
1249 ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
Mike Iselyd8554972006-06-26 20:58:46 -03001250
1251 if (ret) {
1252 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1253 "firmware2 upload prep failed, ret=%d",ret);
1254 release_firmware(fw_entry);
1255 return ret;
1256 }
1257
1258 /* Now send firmware */
1259
1260 fw_len = fw_entry->size;
1261
Mike Isely90060d32007-02-08 02:02:53 -03001262 if (fw_len % sizeof(u32)) {
Mike Iselyd8554972006-06-26 20:58:46 -03001263 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1264 "size of %s firmware"
Mike Isely48dc30a2007-03-03 10:13:05 -02001265 " must be a multiple of %zu bytes",
Mike Isely90060d32007-02-08 02:02:53 -03001266 fw_files[fwidx],sizeof(u32));
Mike Iselyd8554972006-06-26 20:58:46 -03001267 release_firmware(fw_entry);
1268 return -1;
1269 }
1270
1271 fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
1272 if (fw_ptr == NULL){
1273 release_firmware(fw_entry);
1274 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1275 "failed to allocate memory for firmware2 upload");
1276 return -ENOMEM;
1277 }
1278
1279 pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
1280
Mike Isely90060d32007-02-08 02:02:53 -03001281 fw_done = 0;
1282 for (fw_done = 0; fw_done < fw_len;) {
1283 bcnt = fw_len - fw_done;
1284 if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE;
1285 memcpy(fw_ptr, fw_entry->data + fw_done, bcnt);
1286 /* Usbsnoop log shows that we must swap bytes... */
1287 for (icnt = 0; icnt < bcnt/4 ; icnt++)
1288 ((u32 *)fw_ptr)[icnt] =
1289 ___swab32(((u32 *)fw_ptr)[icnt]);
Mike Iselyd8554972006-06-26 20:58:46 -03001290
Mike Isely90060d32007-02-08 02:02:53 -03001291 ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001292 &actual_length, HZ);
Mike Isely90060d32007-02-08 02:02:53 -03001293 ret |= (actual_length != bcnt);
1294 if (ret) break;
1295 fw_done += bcnt;
Mike Iselyd8554972006-06-26 20:58:46 -03001296 }
1297
1298 trace_firmware("upload of %s : %i / %i ",
1299 fw_files[fwidx],fw_done,fw_len);
1300
1301 kfree(fw_ptr);
1302 release_firmware(fw_entry);
1303
1304 if (ret) {
1305 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1306 "firmware2 upload transfer failure");
1307 return ret;
1308 }
1309
1310 /* Finish upload */
1311
1312 ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
1313 ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
Mike Isely1c9d10d2008-03-28 05:38:54 -03001314 ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16));
Mike Iselyd8554972006-06-26 20:58:46 -03001315
1316 if (ret) {
1317 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1318 "firmware2 upload post-proc failure");
Mike Iselyd8554972006-06-26 20:58:46 -03001319 }
1320 return ret;
1321}
1322
1323
Mike Isely681c7392007-11-26 01:48:52 -03001324static const char *pvr2_get_state_name(unsigned int st)
Mike Iselyd8554972006-06-26 20:58:46 -03001325{
Mike Isely681c7392007-11-26 01:48:52 -03001326 if (st < ARRAY_SIZE(pvr2_state_names)) {
1327 return pvr2_state_names[st];
Mike Iselyd8554972006-06-26 20:58:46 -03001328 }
Mike Isely681c7392007-11-26 01:48:52 -03001329 return "???";
Mike Iselyd8554972006-06-26 20:58:46 -03001330}
1331
Mike Isely681c7392007-11-26 01:48:52 -03001332static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
Mike Iselyd8554972006-06-26 20:58:46 -03001333{
Mike Isely681c7392007-11-26 01:48:52 -03001334 if (!hdw->decoder_ctrl) {
1335 if (!hdw->flag_decoder_missed) {
1336 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1337 "WARNING: No decoder present");
1338 hdw->flag_decoder_missed = !0;
1339 trace_stbit("flag_decoder_missed",
1340 hdw->flag_decoder_missed);
1341 }
1342 return -EIO;
Mike Iselyd8554972006-06-26 20:58:46 -03001343 }
Mike Isely681c7392007-11-26 01:48:52 -03001344 hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt,enablefl);
Mike Iselyd8554972006-06-26 20:58:46 -03001345 return 0;
1346}
1347
1348
Mike Isely681c7392007-11-26 01:48:52 -03001349void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr)
1350{
1351 if (hdw->decoder_ctrl == ptr) return;
1352 hdw->decoder_ctrl = ptr;
1353 if (hdw->decoder_ctrl && hdw->flag_decoder_missed) {
1354 hdw->flag_decoder_missed = 0;
1355 trace_stbit("flag_decoder_missed",
1356 hdw->flag_decoder_missed);
1357 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1358 "Decoder has appeared");
1359 pvr2_hdw_state_sched(hdw);
1360 }
1361}
1362
1363
1364int pvr2_hdw_get_state(struct pvr2_hdw *hdw)
1365{
1366 return hdw->master_state;
1367}
1368
1369
1370static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *hdw)
1371{
1372 if (!hdw->flag_tripped) return 0;
1373 hdw->flag_tripped = 0;
1374 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1375 "Clearing driver error statuss");
1376 return !0;
1377}
1378
1379
1380int pvr2_hdw_untrip(struct pvr2_hdw *hdw)
1381{
1382 int fl;
1383 LOCK_TAKE(hdw->big_lock); do {
1384 fl = pvr2_hdw_untrip_unlocked(hdw);
1385 } while (0); LOCK_GIVE(hdw->big_lock);
1386 if (fl) pvr2_hdw_state_sched(hdw);
1387 return 0;
1388}
1389
1390
Mike Isely681c7392007-11-26 01:48:52 -03001391
1392
Mike Iselyd8554972006-06-26 20:58:46 -03001393int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw)
1394{
Mike Isely681c7392007-11-26 01:48:52 -03001395 return hdw->state_pipeline_req != 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001396}
1397
1398
1399int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag)
1400{
Mike Isely681c7392007-11-26 01:48:52 -03001401 int ret,st;
Mike Iselyd8554972006-06-26 20:58:46 -03001402 LOCK_TAKE(hdw->big_lock); do {
Mike Isely681c7392007-11-26 01:48:52 -03001403 pvr2_hdw_untrip_unlocked(hdw);
1404 if ((!enable_flag) != !(hdw->state_pipeline_req)) {
1405 hdw->state_pipeline_req = enable_flag != 0;
1406 pvr2_trace(PVR2_TRACE_START_STOP,
1407 "/*--TRACE_STREAM--*/ %s",
1408 enable_flag ? "enable" : "disable");
1409 }
1410 pvr2_hdw_state_sched(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001411 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely681c7392007-11-26 01:48:52 -03001412 if ((ret = pvr2_hdw_wait(hdw,0)) < 0) return ret;
1413 if (enable_flag) {
1414 while ((st = hdw->master_state) != PVR2_STATE_RUN) {
1415 if (st != PVR2_STATE_READY) return -EIO;
1416 if ((ret = pvr2_hdw_wait(hdw,st)) < 0) return ret;
1417 }
1418 }
Mike Iselyd8554972006-06-26 20:58:46 -03001419 return 0;
1420}
1421
1422
1423int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config)
1424{
Mike Isely681c7392007-11-26 01:48:52 -03001425 int fl;
Mike Iselyd8554972006-06-26 20:58:46 -03001426 LOCK_TAKE(hdw->big_lock);
Mike Isely681c7392007-11-26 01:48:52 -03001427 if ((fl = (hdw->desired_stream_type != config)) != 0) {
1428 hdw->desired_stream_type = config;
1429 hdw->state_pipeline_config = 0;
1430 trace_stbit("state_pipeline_config",
1431 hdw->state_pipeline_config);
1432 pvr2_hdw_state_sched(hdw);
1433 }
Mike Iselyd8554972006-06-26 20:58:46 -03001434 LOCK_GIVE(hdw->big_lock);
Mike Isely681c7392007-11-26 01:48:52 -03001435 if (fl) return 0;
1436 return pvr2_hdw_wait(hdw,0);
Mike Iselyd8554972006-06-26 20:58:46 -03001437}
1438
1439
1440static int get_default_tuner_type(struct pvr2_hdw *hdw)
1441{
1442 int unit_number = hdw->unit_number;
1443 int tp = -1;
1444 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1445 tp = tuner[unit_number];
1446 }
1447 if (tp < 0) return -EINVAL;
1448 hdw->tuner_type = tp;
Mike Iselyaaf78842007-11-26 02:04:11 -03001449 hdw->tuner_updated = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03001450 return 0;
1451}
1452
1453
1454static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw)
1455{
1456 int unit_number = hdw->unit_number;
1457 int tp = 0;
1458 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1459 tp = video_std[unit_number];
Mike Isely6a540252007-12-02 23:51:34 -03001460 if (tp) return tp;
Mike Iselyd8554972006-06-26 20:58:46 -03001461 }
Mike Isely6a540252007-12-02 23:51:34 -03001462 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03001463}
1464
1465
1466static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw)
1467{
1468 int unit_number = hdw->unit_number;
1469 int tp = 0;
1470 if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
1471 tp = tolerance[unit_number];
1472 }
1473 return tp;
1474}
1475
1476
1477static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
1478{
1479 /* Try a harmless request to fetch the eeprom's address over
1480 endpoint 1. See what happens. Only the full FX2 image can
1481 respond to this. If this probe fails then likely the FX2
1482 firmware needs be loaded. */
1483 int result;
1484 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03001485 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03001486 result = pvr2_send_request_ex(hdw,HZ*1,!0,
1487 hdw->cmd_buffer,1,
1488 hdw->cmd_buffer,1);
1489 if (result < 0) break;
1490 } while(0); LOCK_GIVE(hdw->ctl_lock);
1491 if (result) {
1492 pvr2_trace(PVR2_TRACE_INIT,
1493 "Probe of device endpoint 1 result status %d",
1494 result);
1495 } else {
1496 pvr2_trace(PVR2_TRACE_INIT,
1497 "Probe of device endpoint 1 succeeded");
1498 }
1499 return result == 0;
1500}
1501
Mike Isely9f66d4e2007-09-08 22:28:51 -03001502struct pvr2_std_hack {
1503 v4l2_std_id pat; /* Pattern to match */
1504 v4l2_std_id msk; /* Which bits we care about */
1505 v4l2_std_id std; /* What additional standards or default to set */
1506};
1507
1508/* This data structure labels specific combinations of standards from
1509 tveeprom that we'll try to recognize. If we recognize one, then assume
1510 a specified default standard to use. This is here because tveeprom only
1511 tells us about available standards not the intended default standard (if
1512 any) for the device in question. We guess the default based on what has
1513 been reported as available. Note that this is only for guessing a
1514 default - which can always be overridden explicitly - and if the user
1515 has otherwise named a default then that default will always be used in
1516 place of this table. */
Tobias Klauserebff0332008-04-22 14:45:45 -03001517static const struct pvr2_std_hack std_eeprom_maps[] = {
Mike Isely9f66d4e2007-09-08 22:28:51 -03001518 { /* PAL(B/G) */
1519 .pat = V4L2_STD_B|V4L2_STD_GH,
1520 .std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G,
1521 },
1522 { /* NTSC(M) */
1523 .pat = V4L2_STD_MN,
1524 .std = V4L2_STD_NTSC_M,
1525 },
1526 { /* PAL(I) */
1527 .pat = V4L2_STD_PAL_I,
1528 .std = V4L2_STD_PAL_I,
1529 },
1530 { /* SECAM(L/L') */
1531 .pat = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
1532 .std = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
1533 },
1534 { /* PAL(D/D1/K) */
1535 .pat = V4L2_STD_DK,
Roel Kluinea2562d2007-12-02 23:04:57 -03001536 .std = V4L2_STD_PAL_D|V4L2_STD_PAL_D1|V4L2_STD_PAL_K,
Mike Isely9f66d4e2007-09-08 22:28:51 -03001537 },
1538};
1539
Mike Iselyd8554972006-06-26 20:58:46 -03001540static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1541{
1542 char buf[40];
1543 unsigned int bcnt;
Mike Isely3d290bd2007-12-03 01:47:12 -03001544 v4l2_std_id std1,std2,std3;
Mike Iselyd8554972006-06-26 20:58:46 -03001545
1546 std1 = get_default_standard(hdw);
Mike Isely3d290bd2007-12-03 01:47:12 -03001547 std3 = std1 ? 0 : hdw->hdw_desc->default_std_mask;
Mike Iselyd8554972006-06-26 20:58:46 -03001548
1549 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
Mike Isely56585382007-09-08 22:32:12 -03001550 pvr2_trace(PVR2_TRACE_STD,
Mike Isely56dcbfa2007-11-26 02:00:51 -03001551 "Supported video standard(s) reported available"
1552 " in hardware: %.*s",
Mike Iselyd8554972006-06-26 20:58:46 -03001553 bcnt,buf);
1554
1555 hdw->std_mask_avail = hdw->std_mask_eeprom;
1556
Mike Isely3d290bd2007-12-03 01:47:12 -03001557 std2 = (std1|std3) & ~hdw->std_mask_avail;
Mike Iselyd8554972006-06-26 20:58:46 -03001558 if (std2) {
1559 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
Mike Isely56585382007-09-08 22:32:12 -03001560 pvr2_trace(PVR2_TRACE_STD,
Mike Iselyd8554972006-06-26 20:58:46 -03001561 "Expanding supported video standards"
1562 " to include: %.*s",
1563 bcnt,buf);
1564 hdw->std_mask_avail |= std2;
1565 }
1566
1567 pvr2_hdw_internal_set_std_avail(hdw);
1568
1569 if (std1) {
1570 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
Mike Isely56585382007-09-08 22:32:12 -03001571 pvr2_trace(PVR2_TRACE_STD,
Mike Iselyd8554972006-06-26 20:58:46 -03001572 "Initial video standard forced to %.*s",
1573 bcnt,buf);
1574 hdw->std_mask_cur = std1;
1575 hdw->std_dirty = !0;
1576 pvr2_hdw_internal_find_stdenum(hdw);
1577 return;
1578 }
Mike Isely3d290bd2007-12-03 01:47:12 -03001579 if (std3) {
1580 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std3);
1581 pvr2_trace(PVR2_TRACE_STD,
1582 "Initial video standard"
1583 " (determined by device type): %.*s",bcnt,buf);
1584 hdw->std_mask_cur = std3;
1585 hdw->std_dirty = !0;
1586 pvr2_hdw_internal_find_stdenum(hdw);
1587 return;
1588 }
Mike Iselyd8554972006-06-26 20:58:46 -03001589
Mike Isely9f66d4e2007-09-08 22:28:51 -03001590 {
1591 unsigned int idx;
1592 for (idx = 0; idx < ARRAY_SIZE(std_eeprom_maps); idx++) {
1593 if (std_eeprom_maps[idx].msk ?
1594 ((std_eeprom_maps[idx].pat ^
1595 hdw->std_mask_eeprom) &
1596 std_eeprom_maps[idx].msk) :
1597 (std_eeprom_maps[idx].pat !=
1598 hdw->std_mask_eeprom)) continue;
1599 bcnt = pvr2_std_id_to_str(buf,sizeof(buf),
1600 std_eeprom_maps[idx].std);
Mike Isely56585382007-09-08 22:32:12 -03001601 pvr2_trace(PVR2_TRACE_STD,
Mike Isely9f66d4e2007-09-08 22:28:51 -03001602 "Initial video standard guessed as %.*s",
1603 bcnt,buf);
1604 hdw->std_mask_cur = std_eeprom_maps[idx].std;
1605 hdw->std_dirty = !0;
1606 pvr2_hdw_internal_find_stdenum(hdw);
1607 return;
1608 }
1609 }
1610
Mike Iselyd8554972006-06-26 20:58:46 -03001611 if (hdw->std_enum_cnt > 1) {
1612 // Autoselect the first listed standard
1613 hdw->std_enum_cur = 1;
1614 hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
1615 hdw->std_dirty = !0;
Mike Isely56585382007-09-08 22:32:12 -03001616 pvr2_trace(PVR2_TRACE_STD,
Mike Iselyd8554972006-06-26 20:58:46 -03001617 "Initial video standard auto-selected to %s",
1618 hdw->std_defs[hdw->std_enum_cur-1].name);
1619 return;
1620 }
1621
Mike Isely0885ba12006-06-25 21:30:47 -03001622 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
Mike Iselyd8554972006-06-26 20:58:46 -03001623 "Unable to select a viable initial video standard");
1624}
1625
1626
1627static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1628{
1629 int ret;
1630 unsigned int idx;
1631 struct pvr2_ctrl *cptr;
1632 int reloadFl = 0;
Mike Isely989eb152007-11-26 01:53:12 -03001633 if (hdw->hdw_desc->fx2_firmware.cnt) {
Mike Isely1d643a32007-09-08 22:18:50 -03001634 if (!reloadFl) {
1635 reloadFl =
1636 (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
1637 == 0);
1638 if (reloadFl) {
1639 pvr2_trace(PVR2_TRACE_INIT,
1640 "USB endpoint config looks strange"
1641 "; possibly firmware needs to be"
1642 " loaded");
1643 }
1644 }
1645 if (!reloadFl) {
1646 reloadFl = !pvr2_hdw_check_firmware(hdw);
1647 if (reloadFl) {
1648 pvr2_trace(PVR2_TRACE_INIT,
1649 "Check for FX2 firmware failed"
1650 "; possibly firmware needs to be"
1651 " loaded");
1652 }
1653 }
Mike Iselyd8554972006-06-26 20:58:46 -03001654 if (reloadFl) {
Mike Isely1d643a32007-09-08 22:18:50 -03001655 if (pvr2_upload_firmware1(hdw) != 0) {
1656 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1657 "Failure uploading firmware1");
1658 }
1659 return;
Mike Iselyd8554972006-06-26 20:58:46 -03001660 }
1661 }
Mike Iselyd8554972006-06-26 20:58:46 -03001662 hdw->fw1_state = FW1_STATE_OK;
1663
1664 if (initusbreset) {
1665 pvr2_hdw_device_reset(hdw);
1666 }
1667 if (!pvr2_hdw_dev_ok(hdw)) return;
1668
Mike Isely989eb152007-11-26 01:53:12 -03001669 for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
1670 request_module(hdw->hdw_desc->client_modules.lst[idx]);
Mike Iselyd8554972006-06-26 20:58:46 -03001671 }
1672
Mike Isely989eb152007-11-26 01:53:12 -03001673 if (!hdw->hdw_desc->flag_no_powerup) {
Mike Isely1d643a32007-09-08 22:18:50 -03001674 pvr2_hdw_cmd_powerup(hdw);
1675 if (!pvr2_hdw_dev_ok(hdw)) return;
Mike Iselyd8554972006-06-26 20:58:46 -03001676 }
1677
1678 // This step MUST happen after the earlier powerup step.
1679 pvr2_i2c_core_init(hdw);
1680 if (!pvr2_hdw_dev_ok(hdw)) return;
1681
Mike Iselyc05c0462006-06-25 20:04:25 -03001682 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001683 cptr = hdw->controls + idx;
1684 if (cptr->info->skip_init) continue;
1685 if (!cptr->info->set_value) continue;
1686 cptr->info->set_value(cptr,~0,cptr->info->default_value);
1687 }
1688
Mike Isely1bde0282006-12-27 23:30:13 -03001689 /* Set up special default values for the television and radio
1690 frequencies here. It's not really important what these defaults
1691 are, but I set them to something usable in the Chicago area just
1692 to make driver testing a little easier. */
1693
1694 /* US Broadcast channel 7 (175.25 MHz) */
1695 hdw->freqValTelevision = 175250000L;
1696 /* 104.3 MHz, a usable FM station for my area */
1697 hdw->freqValRadio = 104300000L;
1698
Mike Iselyd8554972006-06-26 20:58:46 -03001699 // Do not use pvr2_reset_ctl_endpoints() here. It is not
1700 // thread-safe against the normal pvr2_send_request() mechanism.
1701 // (We should make it thread safe).
1702
Mike Iselyaaf78842007-11-26 02:04:11 -03001703 if (hdw->hdw_desc->flag_has_hauppauge_rom) {
1704 ret = pvr2_hdw_get_eeprom_addr(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001705 if (!pvr2_hdw_dev_ok(hdw)) return;
Mike Iselyaaf78842007-11-26 02:04:11 -03001706 if (ret < 0) {
1707 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1708 "Unable to determine location of eeprom,"
1709 " skipping");
1710 } else {
1711 hdw->eeprom_addr = ret;
1712 pvr2_eeprom_analyze(hdw);
1713 if (!pvr2_hdw_dev_ok(hdw)) return;
1714 }
1715 } else {
1716 hdw->tuner_type = hdw->hdw_desc->default_tuner_type;
1717 hdw->tuner_updated = !0;
1718 hdw->std_mask_eeprom = V4L2_STD_ALL;
Mike Iselyd8554972006-06-26 20:58:46 -03001719 }
1720
1721 pvr2_hdw_setup_std(hdw);
1722
1723 if (!get_default_tuner_type(hdw)) {
1724 pvr2_trace(PVR2_TRACE_INIT,
1725 "pvr2_hdw_setup: Tuner type overridden to %d",
1726 hdw->tuner_type);
1727 }
1728
Mike Iselyd8554972006-06-26 20:58:46 -03001729 pvr2_i2c_core_check_stale(hdw);
1730 hdw->tuner_updated = 0;
1731
1732 if (!pvr2_hdw_dev_ok(hdw)) return;
1733
Mike Isely681c7392007-11-26 01:48:52 -03001734 pvr2_hdw_commit_setup(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001735
1736 hdw->vid_stream = pvr2_stream_create();
1737 if (!pvr2_hdw_dev_ok(hdw)) return;
1738 pvr2_trace(PVR2_TRACE_INIT,
1739 "pvr2_hdw_setup: video stream is %p",hdw->vid_stream);
1740 if (hdw->vid_stream) {
1741 idx = get_default_error_tolerance(hdw);
1742 if (idx) {
1743 pvr2_trace(PVR2_TRACE_INIT,
1744 "pvr2_hdw_setup: video stream %p"
1745 " setting tolerance %u",
1746 hdw->vid_stream,idx);
1747 }
1748 pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev,
1749 PVR2_VID_ENDPOINT,idx);
1750 }
1751
1752 if (!pvr2_hdw_dev_ok(hdw)) return;
1753
Mike Iselyd8554972006-06-26 20:58:46 -03001754 hdw->flag_init_ok = !0;
Mike Isely681c7392007-11-26 01:48:52 -03001755
1756 pvr2_hdw_state_sched(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001757}
1758
1759
Mike Isely681c7392007-11-26 01:48:52 -03001760/* Set up the structure and attempt to put the device into a usable state.
1761 This can be a time-consuming operation, which is why it is not done
1762 internally as part of the create() step. */
1763static void pvr2_hdw_setup(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03001764{
1765 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw);
Mike Isely681c7392007-11-26 01:48:52 -03001766 do {
Mike Iselyd8554972006-06-26 20:58:46 -03001767 pvr2_hdw_setup_low(hdw);
1768 pvr2_trace(PVR2_TRACE_INIT,
1769 "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d",
Mike Isely681c7392007-11-26 01:48:52 -03001770 hdw,pvr2_hdw_dev_ok(hdw),hdw->flag_init_ok);
Mike Iselyd8554972006-06-26 20:58:46 -03001771 if (pvr2_hdw_dev_ok(hdw)) {
Mike Isely681c7392007-11-26 01:48:52 -03001772 if (hdw->flag_init_ok) {
Mike Iselyd8554972006-06-26 20:58:46 -03001773 pvr2_trace(
1774 PVR2_TRACE_INFO,
1775 "Device initialization"
1776 " completed successfully.");
1777 break;
1778 }
1779 if (hdw->fw1_state == FW1_STATE_RELOAD) {
1780 pvr2_trace(
1781 PVR2_TRACE_INFO,
1782 "Device microcontroller firmware"
1783 " (re)loaded; it should now reset"
1784 " and reconnect.");
1785 break;
1786 }
1787 pvr2_trace(
1788 PVR2_TRACE_ERROR_LEGS,
1789 "Device initialization was not successful.");
1790 if (hdw->fw1_state == FW1_STATE_MISSING) {
1791 pvr2_trace(
1792 PVR2_TRACE_ERROR_LEGS,
1793 "Giving up since device"
1794 " microcontroller firmware"
1795 " appears to be missing.");
1796 break;
1797 }
1798 }
1799 if (procreload) {
1800 pvr2_trace(
1801 PVR2_TRACE_ERROR_LEGS,
1802 "Attempting pvrusb2 recovery by reloading"
1803 " primary firmware.");
1804 pvr2_trace(
1805 PVR2_TRACE_ERROR_LEGS,
1806 "If this works, device should disconnect"
1807 " and reconnect in a sane state.");
1808 hdw->fw1_state = FW1_STATE_UNKNOWN;
1809 pvr2_upload_firmware1(hdw);
1810 } else {
1811 pvr2_trace(
1812 PVR2_TRACE_ERROR_LEGS,
1813 "***WARNING*** pvrusb2 device hardware"
1814 " appears to be jammed"
1815 " and I can't clear it.");
1816 pvr2_trace(
1817 PVR2_TRACE_ERROR_LEGS,
1818 "You might need to power cycle"
1819 " the pvrusb2 device"
1820 " in order to recover.");
1821 }
Mike Isely681c7392007-11-26 01:48:52 -03001822 } while (0);
Mike Iselyd8554972006-06-26 20:58:46 -03001823 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03001824}
1825
1826
Mike Iselyc4a88282008-04-22 14:45:44 -03001827/* Perform second stage initialization. Set callback pointer first so that
1828 we can avoid a possible initialization race (if the kernel thread runs
1829 before the callback has been set). */
Mike Isely794b1602008-04-22 14:45:45 -03001830int pvr2_hdw_initialize(struct pvr2_hdw *hdw,
1831 void (*callback_func)(void *),
1832 void *callback_data)
Mike Iselyc4a88282008-04-22 14:45:44 -03001833{
1834 LOCK_TAKE(hdw->big_lock); do {
Mike Isely97f26ff2008-04-07 02:22:43 -03001835 if (hdw->flag_disconnected) {
1836 /* Handle a race here: If we're already
1837 disconnected by this point, then give up. If we
1838 get past this then we'll remain connected for
1839 the duration of initialization since the entire
1840 initialization sequence is now protected by the
1841 big_lock. */
1842 break;
1843 }
Mike Iselyc4a88282008-04-22 14:45:44 -03001844 hdw->state_data = callback_data;
1845 hdw->state_func = callback_func;
Mike Isely97f26ff2008-04-07 02:22:43 -03001846 pvr2_hdw_setup(hdw);
Mike Iselyc4a88282008-04-22 14:45:44 -03001847 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely794b1602008-04-22 14:45:45 -03001848 return hdw->flag_init_ok;
Mike Iselyc4a88282008-04-22 14:45:44 -03001849}
1850
1851
1852/* Create, set up, and return a structure for interacting with the
1853 underlying hardware. */
Mike Iselyd8554972006-06-26 20:58:46 -03001854struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
1855 const struct usb_device_id *devid)
1856{
Mike Isely7fb20fa2008-04-22 14:45:37 -03001857 unsigned int idx,cnt1,cnt2,m;
Mike Iselyd8554972006-06-26 20:58:46 -03001858 struct pvr2_hdw *hdw;
Mike Iselyd8554972006-06-26 20:58:46 -03001859 int valid_std_mask;
1860 struct pvr2_ctrl *cptr;
Mike Isely989eb152007-11-26 01:53:12 -03001861 const struct pvr2_device_desc *hdw_desc;
Mike Iselyd8554972006-06-26 20:58:46 -03001862 __u8 ifnum;
Mike Iselyb30d2442006-06-25 20:05:01 -03001863 struct v4l2_queryctrl qctrl;
1864 struct pvr2_ctl_info *ciptr;
Mike Iselyd8554972006-06-26 20:58:46 -03001865
Mike Iselyd130fa82007-12-08 17:20:06 -03001866 hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info);
Mike Iselyd8554972006-06-26 20:58:46 -03001867
Mike Iselyca545f72007-01-20 00:37:11 -03001868 hdw = kzalloc(sizeof(*hdw),GFP_KERNEL);
Mike Iselyd8554972006-06-26 20:58:46 -03001869 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"",
Mike Isely989eb152007-11-26 01:53:12 -03001870 hdw,hdw_desc->description);
Mike Iselyd8554972006-06-26 20:58:46 -03001871 if (!hdw) goto fail;
Mike Isely681c7392007-11-26 01:48:52 -03001872
1873 init_timer(&hdw->quiescent_timer);
1874 hdw->quiescent_timer.data = (unsigned long)hdw;
1875 hdw->quiescent_timer.function = pvr2_hdw_quiescent_timeout;
1876
1877 init_timer(&hdw->encoder_wait_timer);
1878 hdw->encoder_wait_timer.data = (unsigned long)hdw;
1879 hdw->encoder_wait_timer.function = pvr2_hdw_encoder_wait_timeout;
1880
Mike Iselyd913d632008-04-06 04:04:35 -03001881 init_timer(&hdw->encoder_run_timer);
1882 hdw->encoder_run_timer.data = (unsigned long)hdw;
1883 hdw->encoder_run_timer.function = pvr2_hdw_encoder_run_timeout;
1884
Mike Isely681c7392007-11-26 01:48:52 -03001885 hdw->master_state = PVR2_STATE_DEAD;
1886
1887 init_waitqueue_head(&hdw->state_wait_data);
1888
Mike Isely18103c52007-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;
Mike Isely1cb03b72008-04-21 03:47:43 -03001902 hdw->input_allowed_mask = hdw->input_avail_mask;
Mike Isely7fb20fa2008-04-22 14:45:37 -03001903
Mike Isely62433e32008-04-22 14:45:40 -03001904 /* If not a hybrid device, pathway_state never changes. So
1905 initialize it here to what it should forever be. */
1906 if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_DTV))) {
1907 hdw->pathway_state = PVR2_PATHWAY_ANALOG;
1908 } else if (!(hdw->input_avail_mask & (1 << PVR2_CVAL_INPUT_TV))) {
1909 hdw->pathway_state = PVR2_PATHWAY_DIGITAL;
1910 }
1911
Mike Iselyc05c0462006-06-25 20:04:25 -03001912 hdw->control_cnt = CTRLDEF_COUNT;
Mike Iselyb30d2442006-06-25 20:05:01 -03001913 hdw->control_cnt += MPEGDEF_COUNT;
Mike Iselyca545f72007-01-20 00:37:11 -03001914 hdw->controls = kzalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt,
Mike Iselyd8554972006-06-26 20:58:46 -03001915 GFP_KERNEL);
1916 if (!hdw->controls) goto fail;
Mike Isely989eb152007-11-26 01:53:12 -03001917 hdw->hdw_desc = hdw_desc;
Mike Iselyc05c0462006-06-25 20:04:25 -03001918 for (idx = 0; idx < hdw->control_cnt; idx++) {
1919 cptr = hdw->controls + idx;
1920 cptr->hdw = hdw;
1921 }
Mike Iselyd8554972006-06-26 20:58:46 -03001922 for (idx = 0; idx < 32; idx++) {
1923 hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx];
1924 }
Mike Iselyc05c0462006-06-25 20:04:25 -03001925 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03001926 cptr = hdw->controls + idx;
Mike Iselyd8554972006-06-26 20:58:46 -03001927 cptr->info = control_defs+idx;
1928 }
Mike Iselydbc40a02008-04-22 14:45:39 -03001929
1930 /* Ensure that default input choice is a valid one. */
1931 m = hdw->input_avail_mask;
1932 if (m) for (idx = 0; idx < (sizeof(m) << 3); idx++) {
1933 if (!((1 << idx) & m)) continue;
1934 hdw->input_val = idx;
1935 break;
1936 }
1937
Mike Iselyb30d2442006-06-25 20:05:01 -03001938 /* Define and configure additional controls from cx2341x module. */
Mike Iselyca545f72007-01-20 00:37:11 -03001939 hdw->mpeg_ctrl_info = kzalloc(
Mike Iselyb30d2442006-06-25 20:05:01 -03001940 sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
1941 if (!hdw->mpeg_ctrl_info) goto fail;
Mike Iselyb30d2442006-06-25 20:05:01 -03001942 for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
1943 cptr = hdw->controls + idx + CTRLDEF_COUNT;
1944 ciptr = &(hdw->mpeg_ctrl_info[idx].info);
1945 ciptr->desc = hdw->mpeg_ctrl_info[idx].desc;
1946 ciptr->name = mpeg_ids[idx].strid;
1947 ciptr->v4l_id = mpeg_ids[idx].id;
1948 ciptr->skip_init = !0;
1949 ciptr->get_value = ctrl_cx2341x_get;
1950 ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags;
1951 ciptr->is_dirty = ctrl_cx2341x_is_dirty;
1952 if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty;
1953 qctrl.id = ciptr->v4l_id;
1954 cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl);
1955 if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) {
1956 ciptr->set_value = ctrl_cx2341x_set;
1957 }
1958 strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name,
1959 PVR2_CTLD_INFO_DESC_SIZE);
1960 hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0;
1961 ciptr->default_value = qctrl.default_value;
1962 switch (qctrl.type) {
1963 default:
1964 case V4L2_CTRL_TYPE_INTEGER:
1965 ciptr->type = pvr2_ctl_int;
1966 ciptr->def.type_int.min_value = qctrl.minimum;
1967 ciptr->def.type_int.max_value = qctrl.maximum;
1968 break;
1969 case V4L2_CTRL_TYPE_BOOLEAN:
1970 ciptr->type = pvr2_ctl_bool;
1971 break;
1972 case V4L2_CTRL_TYPE_MENU:
1973 ciptr->type = pvr2_ctl_enum;
1974 ciptr->def.type_enum.value_names =
1975 cx2341x_ctrl_get_menu(ciptr->v4l_id);
1976 for (cnt1 = 0;
1977 ciptr->def.type_enum.value_names[cnt1] != NULL;
1978 cnt1++) { }
1979 ciptr->def.type_enum.count = cnt1;
1980 break;
1981 }
1982 cptr->info = ciptr;
1983 }
Mike Iselyd8554972006-06-26 20:58:46 -03001984
1985 // Initialize video standard enum dynamic control
1986 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM);
1987 if (cptr) {
1988 memcpy(&hdw->std_info_enum,cptr->info,
1989 sizeof(hdw->std_info_enum));
1990 cptr->info = &hdw->std_info_enum;
1991
1992 }
1993 // Initialize control data regarding video standard masks
1994 valid_std_mask = pvr2_std_get_usable();
1995 for (idx = 0; idx < 32; idx++) {
1996 if (!(valid_std_mask & (1 << idx))) continue;
1997 cnt1 = pvr2_std_id_to_str(
1998 hdw->std_mask_names[idx],
1999 sizeof(hdw->std_mask_names[idx])-1,
2000 1 << idx);
2001 hdw->std_mask_names[idx][cnt1] = 0;
2002 }
2003 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
2004 if (cptr) {
2005 memcpy(&hdw->std_info_avail,cptr->info,
2006 sizeof(hdw->std_info_avail));
2007 cptr->info = &hdw->std_info_avail;
2008 hdw->std_info_avail.def.type_bitmask.bit_names =
2009 hdw->std_mask_ptrs;
2010 hdw->std_info_avail.def.type_bitmask.valid_bits =
2011 valid_std_mask;
2012 }
2013 cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR);
2014 if (cptr) {
2015 memcpy(&hdw->std_info_cur,cptr->info,
2016 sizeof(hdw->std_info_cur));
2017 cptr->info = &hdw->std_info_cur;
2018 hdw->std_info_cur.def.type_bitmask.bit_names =
2019 hdw->std_mask_ptrs;
2020 hdw->std_info_avail.def.type_bitmask.valid_bits =
2021 valid_std_mask;
2022 }
2023
2024 hdw->eeprom_addr = -1;
2025 hdw->unit_number = -1;
Mike Isely80793842006-12-27 23:12:28 -03002026 hdw->v4l_minor_number_video = -1;
2027 hdw->v4l_minor_number_vbi = -1;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002028 hdw->v4l_minor_number_radio = -1;
Mike Iselyd8554972006-06-26 20:58:46 -03002029 hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2030 if (!hdw->ctl_write_buffer) goto fail;
2031 hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL);
2032 if (!hdw->ctl_read_buffer) goto fail;
2033 hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL);
2034 if (!hdw->ctl_write_urb) goto fail;
2035 hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
2036 if (!hdw->ctl_read_urb) goto fail;
2037
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002038 mutex_lock(&pvr2_unit_mtx); do {
Mike Iselyd8554972006-06-26 20:58:46 -03002039 for (idx = 0; idx < PVR_NUM; idx++) {
2040 if (unit_pointers[idx]) continue;
2041 hdw->unit_number = idx;
2042 unit_pointers[idx] = hdw;
2043 break;
2044 }
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002045 } while (0); mutex_unlock(&pvr2_unit_mtx);
Mike Iselyd8554972006-06-26 20:58:46 -03002046
2047 cnt1 = 0;
2048 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
2049 cnt1 += cnt2;
2050 if (hdw->unit_number >= 0) {
2051 cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c",
2052 ('a' + hdw->unit_number));
2053 cnt1 += cnt2;
2054 }
2055 if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1;
2056 hdw->name[cnt1] = 0;
2057
Mike Isely681c7392007-11-26 01:48:52 -03002058 hdw->workqueue = create_singlethread_workqueue(hdw->name);
2059 INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll);
2060 INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c);
Mike Isely681c7392007-11-26 01:48:52 -03002061
Mike Iselyd8554972006-06-26 20:58:46 -03002062 pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
2063 hdw->unit_number,hdw->name);
2064
2065 hdw->tuner_type = -1;
2066 hdw->flag_ok = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002067
2068 hdw->usb_intf = intf;
2069 hdw->usb_dev = interface_to_usbdev(intf);
2070
Mike Isely31a18542007-04-08 01:11:47 -03002071 scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
2072 "usb %s address %d",
2073 hdw->usb_dev->dev.bus_id,
2074 hdw->usb_dev->devnum);
2075
Mike Iselyd8554972006-06-26 20:58:46 -03002076 ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
2077 usb_set_interface(hdw->usb_dev,ifnum,0);
2078
2079 mutex_init(&hdw->ctl_lock_mutex);
2080 mutex_init(&hdw->big_lock_mutex);
2081
2082 return hdw;
2083 fail:
2084 if (hdw) {
Mike Isely681c7392007-11-26 01:48:52 -03002085 del_timer_sync(&hdw->quiescent_timer);
Mike Iselyd913d632008-04-06 04:04:35 -03002086 del_timer_sync(&hdw->encoder_run_timer);
Mike Isely681c7392007-11-26 01:48:52 -03002087 del_timer_sync(&hdw->encoder_wait_timer);
2088 if (hdw->workqueue) {
2089 flush_workqueue(hdw->workqueue);
2090 destroy_workqueue(hdw->workqueue);
2091 hdw->workqueue = NULL;
2092 }
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002093 usb_free_urb(hdw->ctl_read_urb);
2094 usb_free_urb(hdw->ctl_write_urb);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002095 kfree(hdw->ctl_read_buffer);
2096 kfree(hdw->ctl_write_buffer);
2097 kfree(hdw->controls);
2098 kfree(hdw->mpeg_ctrl_info);
Mike Isely681c7392007-11-26 01:48:52 -03002099 kfree(hdw->std_defs);
2100 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002101 kfree(hdw);
2102 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002103 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002104}
2105
2106
2107/* Remove _all_ associations between this driver and the underlying USB
2108 layer. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002109static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002110{
2111 if (hdw->flag_disconnected) return;
2112 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw);
2113 if (hdw->ctl_read_urb) {
2114 usb_kill_urb(hdw->ctl_read_urb);
2115 usb_free_urb(hdw->ctl_read_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002116 hdw->ctl_read_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002117 }
2118 if (hdw->ctl_write_urb) {
2119 usb_kill_urb(hdw->ctl_write_urb);
2120 usb_free_urb(hdw->ctl_write_urb);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002121 hdw->ctl_write_urb = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002122 }
2123 if (hdw->ctl_read_buffer) {
2124 kfree(hdw->ctl_read_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002125 hdw->ctl_read_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002126 }
2127 if (hdw->ctl_write_buffer) {
2128 kfree(hdw->ctl_write_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002129 hdw->ctl_write_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002130 }
Mike Iselyd8554972006-06-26 20:58:46 -03002131 hdw->flag_disconnected = !0;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002132 hdw->usb_dev = NULL;
2133 hdw->usb_intf = NULL;
Mike Isely681c7392007-11-26 01:48:52 -03002134 pvr2_hdw_render_useless(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002135}
2136
2137
2138/* Destroy hardware interaction structure */
2139void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
2140{
Mike Isely401c27c2007-09-08 22:11:46 -03002141 if (!hdw) return;
Mike Iselyd8554972006-06-26 20:58:46 -03002142 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
Mike Isely681c7392007-11-26 01:48:52 -03002143 if (hdw->workqueue) {
2144 flush_workqueue(hdw->workqueue);
2145 destroy_workqueue(hdw->workqueue);
2146 hdw->workqueue = NULL;
2147 }
Mike Isely8f591002008-04-22 14:45:45 -03002148 del_timer_sync(&hdw->quiescent_timer);
Mike Iselyd913d632008-04-06 04:04:35 -03002149 del_timer_sync(&hdw->encoder_run_timer);
Mike Isely8f591002008-04-22 14:45:45 -03002150 del_timer_sync(&hdw->encoder_wait_timer);
Mike Iselyd8554972006-06-26 20:58:46 -03002151 if (hdw->fw_buffer) {
2152 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002153 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002154 }
2155 if (hdw->vid_stream) {
2156 pvr2_stream_destroy(hdw->vid_stream);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002157 hdw->vid_stream = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002158 }
Mike Iselyd8554972006-06-26 20:58:46 -03002159 if (hdw->decoder_ctrl) {
2160 hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
2161 }
2162 pvr2_i2c_core_done(hdw);
2163 pvr2_hdw_remove_usb_stuff(hdw);
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002164 mutex_lock(&pvr2_unit_mtx); do {
Mike Iselyd8554972006-06-26 20:58:46 -03002165 if ((hdw->unit_number >= 0) &&
2166 (hdw->unit_number < PVR_NUM) &&
2167 (unit_pointers[hdw->unit_number] == hdw)) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002168 unit_pointers[hdw->unit_number] = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002169 }
Matthias Kaehlcke8df0c872007-04-28 20:00:18 -03002170 } while (0); mutex_unlock(&pvr2_unit_mtx);
Mariusz Kozlowski22071a42007-01-07 10:33:39 -03002171 kfree(hdw->controls);
2172 kfree(hdw->mpeg_ctrl_info);
2173 kfree(hdw->std_defs);
2174 kfree(hdw->std_enum_names);
Mike Iselyd8554972006-06-26 20:58:46 -03002175 kfree(hdw);
2176}
2177
2178
Mike Iselyd8554972006-06-26 20:58:46 -03002179int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw)
2180{
2181 return (hdw && hdw->flag_ok);
2182}
2183
2184
2185/* Called when hardware has been unplugged */
2186void pvr2_hdw_disconnect(struct pvr2_hdw *hdw)
2187{
2188 pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw);
2189 LOCK_TAKE(hdw->big_lock);
2190 LOCK_TAKE(hdw->ctl_lock);
2191 pvr2_hdw_remove_usb_stuff(hdw);
2192 LOCK_GIVE(hdw->ctl_lock);
2193 LOCK_GIVE(hdw->big_lock);
2194}
2195
2196
2197// Attempt to autoselect an appropriate value for std_enum_cur given
2198// whatever is currently in std_mask_cur
Adrian Bunk07e337e2006-06-30 11:30:20 -03002199static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002200{
2201 unsigned int idx;
2202 for (idx = 1; idx < hdw->std_enum_cnt; idx++) {
2203 if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) {
2204 hdw->std_enum_cur = idx;
2205 return;
2206 }
2207 }
2208 hdw->std_enum_cur = 0;
2209}
2210
2211
2212// Calculate correct set of enumerated standards based on currently known
2213// set of available standards bits.
Adrian Bunk07e337e2006-06-30 11:30:20 -03002214static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002215{
2216 struct v4l2_standard *newstd;
2217 unsigned int std_cnt;
2218 unsigned int idx;
2219
2220 newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail);
2221
2222 if (hdw->std_defs) {
2223 kfree(hdw->std_defs);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002224 hdw->std_defs = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002225 }
2226 hdw->std_enum_cnt = 0;
2227 if (hdw->std_enum_names) {
2228 kfree(hdw->std_enum_names);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002229 hdw->std_enum_names = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002230 }
2231
2232 if (!std_cnt) {
2233 pvr2_trace(
2234 PVR2_TRACE_ERROR_LEGS,
2235 "WARNING: Failed to identify any viable standards");
2236 }
2237 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2238 hdw->std_enum_names[0] = "none";
2239 for (idx = 0; idx < std_cnt; idx++) {
2240 hdw->std_enum_names[idx+1] =
2241 newstd[idx].name;
2242 }
2243 // Set up the dynamic control for this standard
2244 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names;
2245 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2246 hdw->std_defs = newstd;
2247 hdw->std_enum_cnt = std_cnt+1;
2248 hdw->std_enum_cur = 0;
2249 hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail;
2250}
2251
2252
2253int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,
2254 struct v4l2_standard *std,
2255 unsigned int idx)
2256{
2257 int ret = -EINVAL;
2258 if (!idx) return ret;
2259 LOCK_TAKE(hdw->big_lock); do {
2260 if (idx >= hdw->std_enum_cnt) break;
2261 idx--;
2262 memcpy(std,hdw->std_defs+idx,sizeof(*std));
2263 ret = 0;
2264 } while (0); LOCK_GIVE(hdw->big_lock);
2265 return ret;
2266}
2267
2268
2269/* Get the number of defined controls */
2270unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw)
2271{
Mike Iselyc05c0462006-06-25 20:04:25 -03002272 return hdw->control_cnt;
Mike Iselyd8554972006-06-26 20:58:46 -03002273}
2274
2275
2276/* Retrieve a control handle given its index (0..count-1) */
2277struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw,
2278 unsigned int idx)
2279{
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002280 if (idx >= hdw->control_cnt) return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002281 return hdw->controls + idx;
2282}
2283
2284
2285/* Retrieve a control handle given its index (0..count-1) */
2286struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw,
2287 unsigned int ctl_id)
2288{
2289 struct pvr2_ctrl *cptr;
2290 unsigned int idx;
2291 int i;
2292
2293 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002294 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002295 cptr = hdw->controls + idx;
2296 i = cptr->info->internal_id;
2297 if (i && (i == ctl_id)) return cptr;
2298 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002299 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002300}
2301
2302
Mike Iselya761f432006-06-25 20:04:44 -03002303/* Given a V4L ID, retrieve the control structure associated with it. */
Mike Iselyd8554972006-06-26 20:58:46 -03002304struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id)
2305{
2306 struct pvr2_ctrl *cptr;
2307 unsigned int idx;
2308 int i;
2309
2310 /* This could be made a lot more efficient, but for now... */
Mike Iselyc05c0462006-06-25 20:04:25 -03002311 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002312 cptr = hdw->controls + idx;
2313 i = cptr->info->v4l_id;
2314 if (i && (i == ctl_id)) return cptr;
2315 }
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002316 return NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002317}
2318
2319
Mike Iselya761f432006-06-25 20:04:44 -03002320/* Given a V4L ID for its immediate predecessor, retrieve the control
2321 structure associated with it. */
2322struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw,
2323 unsigned int ctl_id)
2324{
2325 struct pvr2_ctrl *cptr,*cp2;
2326 unsigned int idx;
2327 int i;
2328
2329 /* This could be made a lot more efficient, but for now... */
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002330 cp2 = NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002331 for (idx = 0; idx < hdw->control_cnt; idx++) {
2332 cptr = hdw->controls + idx;
2333 i = cptr->info->v4l_id;
2334 if (!i) continue;
2335 if (i <= ctl_id) continue;
2336 if (cp2 && (cp2->info->v4l_id < i)) continue;
2337 cp2 = cptr;
2338 }
2339 return cp2;
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002340 return NULL;
Mike Iselya761f432006-06-25 20:04:44 -03002341}
2342
2343
Mike Iselyd8554972006-06-26 20:58:46 -03002344static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
2345{
2346 switch (tp) {
2347 case pvr2_ctl_int: return "integer";
2348 case pvr2_ctl_enum: return "enum";
Mike Isely33213962006-06-25 20:04:40 -03002349 case pvr2_ctl_bool: return "boolean";
Mike Iselyd8554972006-06-26 20:58:46 -03002350 case pvr2_ctl_bitmask: return "bitmask";
2351 }
2352 return "";
2353}
2354
2355
Mike Isely681c7392007-11-26 01:48:52 -03002356/* Figure out if we need to commit control changes. If so, mark internal
2357 state flags to indicate this fact and return true. Otherwise do nothing
2358 else and return false. */
2359static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002360{
Mike Iselyd8554972006-06-26 20:58:46 -03002361 unsigned int idx;
2362 struct pvr2_ctrl *cptr;
2363 int value;
2364 int commit_flag = 0;
2365 char buf[100];
2366 unsigned int bcnt,ccnt;
2367
Mike Iselyc05c0462006-06-25 20:04:25 -03002368 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002369 cptr = hdw->controls + idx;
Al Viro5fa12472008-03-29 03:07:38 +00002370 if (!cptr->info->is_dirty) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002371 if (!cptr->info->is_dirty(cptr)) continue;
Mike Iselyfe23a282007-01-20 00:10:55 -03002372 commit_flag = !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002373
Mike Iselyfe23a282007-01-20 00:10:55 -03002374 if (!(pvrusb2_debug & PVR2_TRACE_CTL)) continue;
Mike Iselyd8554972006-06-26 20:58:46 -03002375 bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ",
2376 cptr->info->name);
2377 value = 0;
2378 cptr->info->get_value(cptr,&value);
2379 pvr2_ctrl_value_to_sym_internal(cptr,~0,value,
2380 buf+bcnt,
2381 sizeof(buf)-bcnt,&ccnt);
2382 bcnt += ccnt;
2383 bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>",
2384 get_ctrl_typename(cptr->info->type));
2385 pvr2_trace(PVR2_TRACE_CTL,
2386 "/*--TRACE_COMMIT--*/ %.*s",
2387 bcnt,buf);
2388 }
2389
2390 if (!commit_flag) {
2391 /* Nothing has changed */
2392 return 0;
2393 }
2394
Mike Isely681c7392007-11-26 01:48:52 -03002395 hdw->state_pipeline_config = 0;
2396 trace_stbit("state_pipeline_config",hdw->state_pipeline_config);
2397 pvr2_hdw_state_sched(hdw);
2398
2399 return !0;
2400}
2401
2402
2403/* Perform all operations needed to commit all control changes. This must
2404 be performed in synchronization with the pipeline state and is thus
2405 expected to be called as part of the driver's worker thread. Return
2406 true if commit successful, otherwise return false to indicate that
2407 commit isn't possible at this time. */
2408static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
2409{
2410 unsigned int idx;
2411 struct pvr2_ctrl *cptr;
2412 int disruptive_change;
2413
Mike Iselyd8554972006-06-26 20:58:46 -03002414 /* When video standard changes, reset the hres and vres values -
2415 but if the user has pending changes there, then let the changes
2416 take priority. */
2417 if (hdw->std_dirty) {
2418 /* Rewrite the vertical resolution to be appropriate to the
2419 video standard that has been selected. */
2420 int nvres;
2421 if (hdw->std_mask_cur & V4L2_STD_525_60) {
2422 nvres = 480;
2423 } else {
2424 nvres = 576;
2425 }
2426 if (nvres != hdw->res_ver_val) {
2427 hdw->res_ver_val = nvres;
2428 hdw->res_ver_dirty = !0;
2429 }
Mike Iselyd8554972006-06-26 20:58:46 -03002430 }
2431
Mike Isely38d9a2c2008-03-28 05:30:48 -03002432 if (hdw->input_dirty && hdw->state_pathway_ok &&
Mike Isely62433e32008-04-22 14:45:40 -03002433 (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ?
2434 PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) !=
2435 hdw->pathway_state)) {
2436 /* Change of mode being asked for... */
2437 hdw->state_pathway_ok = 0;
Mike Iselye9db1ff2008-04-22 14:45:41 -03002438 trace_stbit("state_pathway_ok",hdw->state_pathway_ok);
Mike Isely62433e32008-04-22 14:45:40 -03002439 }
2440 if (!hdw->state_pathway_ok) {
2441 /* Can't commit anything until pathway is ok. */
2442 return 0;
2443 }
Mike Isely681c7392007-11-26 01:48:52 -03002444 /* If any of the below has changed, then we can't do the update
2445 while the pipeline is running. Pipeline must be paused first
2446 and decoder -> encoder connection be made quiescent before we
2447 can proceed. */
2448 disruptive_change =
2449 (hdw->std_dirty ||
2450 hdw->enc_unsafe_stale ||
2451 hdw->srate_dirty ||
2452 hdw->res_ver_dirty ||
2453 hdw->res_hor_dirty ||
2454 hdw->input_dirty ||
2455 (hdw->active_stream_type != hdw->desired_stream_type));
2456 if (disruptive_change && !hdw->state_pipeline_idle) {
2457 /* Pipeline is not idle; we can't proceed. Arrange to
2458 cause pipeline to stop so that we can try this again
2459 later.... */
2460 hdw->state_pipeline_pause = !0;
2461 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002462 }
2463
Mike Iselyb30d2442006-06-25 20:05:01 -03002464 if (hdw->srate_dirty) {
2465 /* Write new sample rate into control structure since
2466 * the master copy is stale. We must track srate
2467 * separate from the mpeg control structure because
2468 * other logic also uses this value. */
2469 struct v4l2_ext_controls cs;
2470 struct v4l2_ext_control c1;
2471 memset(&cs,0,sizeof(cs));
2472 memset(&c1,0,sizeof(c1));
2473 cs.controls = &c1;
2474 cs.count = 1;
2475 c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
2476 c1.value = hdw->srate_val;
Hans Verkuil01f1e442007-08-21 18:32:42 -03002477 cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
Mike Iselyb30d2442006-06-25 20:05:01 -03002478 }
Mike Iselyc05c0462006-06-25 20:04:25 -03002479
Mike Iselyd8554972006-06-26 20:58:46 -03002480 /* Scan i2c core at this point - before we clear all the dirty
2481 bits. Various parts of the i2c core will notice dirty bits as
2482 appropriate and arrange to broadcast or directly send updates to
2483 the client drivers in order to keep everything in sync */
2484 pvr2_i2c_core_check_stale(hdw);
2485
Mike Iselyc05c0462006-06-25 20:04:25 -03002486 for (idx = 0; idx < hdw->control_cnt; idx++) {
Mike Iselyd8554972006-06-26 20:58:46 -03002487 cptr = hdw->controls + idx;
2488 if (!cptr->info->clear_dirty) continue;
2489 cptr->info->clear_dirty(cptr);
2490 }
2491
Mike Isely681c7392007-11-26 01:48:52 -03002492 if (hdw->active_stream_type != hdw->desired_stream_type) {
2493 /* Handle any side effects of stream config here */
2494 hdw->active_stream_type = hdw->desired_stream_type;
2495 }
2496
Mike Iselyd8554972006-06-26 20:58:46 -03002497 /* Now execute i2c core update */
2498 pvr2_i2c_core_sync(hdw);
2499
Mike Isely62433e32008-04-22 14:45:40 -03002500 if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
2501 hdw->state_encoder_run) {
2502 /* If encoder isn't running or it can't be touched, then
2503 this will get worked out later when we start the
2504 encoder. */
Mike Isely681c7392007-11-26 01:48:52 -03002505 if (pvr2_encoder_adjust(hdw) < 0) return !0;
2506 }
Mike Iselyd8554972006-06-26 20:58:46 -03002507
Mike Isely681c7392007-11-26 01:48:52 -03002508 hdw->state_pipeline_config = !0;
2509 trace_stbit("state_pipeline_config",hdw->state_pipeline_config);
2510 return !0;
Mike Iselyd8554972006-06-26 20:58:46 -03002511}
2512
2513
2514int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
2515{
Mike Isely681c7392007-11-26 01:48:52 -03002516 int fl;
2517 LOCK_TAKE(hdw->big_lock);
2518 fl = pvr2_hdw_commit_setup(hdw);
2519 LOCK_GIVE(hdw->big_lock);
2520 if (!fl) return 0;
2521 return pvr2_hdw_wait(hdw,0);
Mike Iselyd8554972006-06-26 20:58:46 -03002522}
2523
2524
Mike Isely681c7392007-11-26 01:48:52 -03002525static void pvr2_hdw_worker_i2c(struct work_struct *work)
Mike Iselyd8554972006-06-26 20:58:46 -03002526{
Mike Isely681c7392007-11-26 01:48:52 -03002527 struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync);
Mike Iselyd8554972006-06-26 20:58:46 -03002528 LOCK_TAKE(hdw->big_lock); do {
2529 pvr2_i2c_core_sync(hdw);
2530 } while (0); LOCK_GIVE(hdw->big_lock);
2531}
2532
2533
Mike Isely681c7392007-11-26 01:48:52 -03002534static void pvr2_hdw_worker_poll(struct work_struct *work)
Mike Iselyd8554972006-06-26 20:58:46 -03002535{
Mike Isely681c7392007-11-26 01:48:52 -03002536 int fl = 0;
2537 struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,workpoll);
Mike Iselyd8554972006-06-26 20:58:46 -03002538 LOCK_TAKE(hdw->big_lock); do {
Mike Isely681c7392007-11-26 01:48:52 -03002539 fl = pvr2_hdw_state_eval(hdw);
2540 } while (0); LOCK_GIVE(hdw->big_lock);
2541 if (fl && hdw->state_func) {
2542 hdw->state_func(hdw->state_data);
2543 }
2544}
2545
2546
Mike Isely681c7392007-11-26 01:48:52 -03002547static int pvr2_hdw_wait(struct pvr2_hdw *hdw,int state)
Mike Iselyd8554972006-06-26 20:58:46 -03002548{
Mike Isely681c7392007-11-26 01:48:52 -03002549 return wait_event_interruptible(
2550 hdw->state_wait_data,
2551 (hdw->state_stale == 0) &&
2552 (!state || (hdw->master_state != state)));
Mike Iselyd8554972006-06-26 20:58:46 -03002553}
2554
Mike Isely681c7392007-11-26 01:48:52 -03002555
Mike Iselyd8554972006-06-26 20:58:46 -03002556/* Return name for this driver instance */
2557const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw)
2558{
2559 return hdw->name;
2560}
2561
2562
Mike Isely78a47102007-11-26 01:58:20 -03002563const char *pvr2_hdw_get_desc(struct pvr2_hdw *hdw)
2564{
2565 return hdw->hdw_desc->description;
2566}
2567
2568
2569const char *pvr2_hdw_get_type(struct pvr2_hdw *hdw)
2570{
2571 return hdw->hdw_desc->shortname;
2572}
2573
2574
Mike Iselyd8554972006-06-26 20:58:46 -03002575int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
2576{
2577 int result;
2578 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03002579 hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED;
Mike Iselyd8554972006-06-26 20:58:46 -03002580 result = pvr2_send_request(hdw,
2581 hdw->cmd_buffer,1,
2582 hdw->cmd_buffer,1);
2583 if (result < 0) break;
2584 result = (hdw->cmd_buffer[0] != 0);
2585 } while(0); LOCK_GIVE(hdw->ctl_lock);
2586 return result;
2587}
2588
2589
Mike Isely18103c52007-01-20 00:09:47 -03002590/* Execute poll of tuner status */
2591void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03002592{
Mike Iselyd8554972006-06-26 20:58:46 -03002593 LOCK_TAKE(hdw->big_lock); do {
Mike Isely18103c52007-01-20 00:09:47 -03002594 pvr2_i2c_core_status_poll(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002595 } while (0); LOCK_GIVE(hdw->big_lock);
Mike Isely18103c52007-01-20 00:09:47 -03002596}
2597
2598
2599/* Return information about the tuner */
2600int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
2601{
2602 LOCK_TAKE(hdw->big_lock); do {
2603 if (hdw->tuner_signal_stale) {
2604 pvr2_i2c_core_status_poll(hdw);
2605 }
2606 memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
2607 } while (0); LOCK_GIVE(hdw->big_lock);
2608 return 0;
Mike Iselyd8554972006-06-26 20:58:46 -03002609}
2610
2611
2612/* Get handle to video output stream */
2613struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp)
2614{
2615 return hp->vid_stream;
2616}
2617
2618
2619void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
2620{
Mike Isely4f1a3e52006-06-25 20:04:31 -03002621 int nr = pvr2_hdw_get_unit_number(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03002622 LOCK_TAKE(hdw->big_lock); do {
2623 hdw->log_requested = !0;
Mike Isely4f1a3e52006-06-25 20:04:31 -03002624 printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002625 pvr2_i2c_core_check_stale(hdw);
2626 hdw->log_requested = 0;
2627 pvr2_i2c_core_sync(hdw);
Mike Iselyb30d2442006-06-25 20:05:01 -03002628 pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
Hans Verkuil99eb44f2006-06-26 18:24:05 -03002629 cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
Mike Isely681c7392007-11-26 01:48:52 -03002630 pvr2_hdw_state_log_state(hdw);
Mike Isely4f1a3e52006-06-25 20:04:31 -03002631 printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr);
Mike Iselyd8554972006-06-26 20:58:46 -03002632 } while (0); LOCK_GIVE(hdw->big_lock);
2633}
2634
Mike Isely4db666c2007-09-08 22:16:27 -03002635
2636/* Grab EEPROM contents, needed for direct method. */
2637#define EEPROM_SIZE 8192
2638#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
2639static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw)
2640{
2641 struct i2c_msg msg[2];
2642 u8 *eeprom;
2643 u8 iadd[2];
2644 u8 addr;
2645 u16 eepromSize;
2646 unsigned int offs;
2647 int ret;
2648 int mode16 = 0;
2649 unsigned pcnt,tcnt;
2650 eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
2651 if (!eeprom) {
2652 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2653 "Failed to allocate memory"
2654 " required to read eeprom");
2655 return NULL;
2656 }
2657
2658 trace_eeprom("Value for eeprom addr from controller was 0x%x",
2659 hdw->eeprom_addr);
2660 addr = hdw->eeprom_addr;
2661 /* Seems that if the high bit is set, then the *real* eeprom
2662 address is shifted right now bit position (noticed this in
2663 newer PVR USB2 hardware) */
2664 if (addr & 0x80) addr >>= 1;
2665
2666 /* FX2 documentation states that a 16bit-addressed eeprom is
2667 expected if the I2C address is an odd number (yeah, this is
2668 strange but it's what they do) */
2669 mode16 = (addr & 1);
2670 eepromSize = (mode16 ? EEPROM_SIZE : 256);
2671 trace_eeprom("Examining %d byte eeprom at location 0x%x"
2672 " using %d bit addressing",eepromSize,addr,
2673 mode16 ? 16 : 8);
2674
2675 msg[0].addr = addr;
2676 msg[0].flags = 0;
2677 msg[0].len = mode16 ? 2 : 1;
2678 msg[0].buf = iadd;
2679 msg[1].addr = addr;
2680 msg[1].flags = I2C_M_RD;
2681
2682 /* We have to do the actual eeprom data fetch ourselves, because
2683 (1) we're only fetching part of the eeprom, and (2) if we were
2684 getting the whole thing our I2C driver can't grab it in one
2685 pass - which is what tveeprom is otherwise going to attempt */
2686 memset(eeprom,0,EEPROM_SIZE);
2687 for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
2688 pcnt = 16;
2689 if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
2690 offs = tcnt + (eepromSize - EEPROM_SIZE);
2691 if (mode16) {
2692 iadd[0] = offs >> 8;
2693 iadd[1] = offs;
2694 } else {
2695 iadd[0] = offs;
2696 }
2697 msg[1].len = pcnt;
2698 msg[1].buf = eeprom+tcnt;
2699 if ((ret = i2c_transfer(&hdw->i2c_adap,
2700 msg,ARRAY_SIZE(msg))) != 2) {
2701 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2702 "eeprom fetch set offs err=%d",ret);
2703 kfree(eeprom);
2704 return NULL;
2705 }
2706 }
2707 return eeprom;
2708}
2709
2710
2711void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
2712 int prom_flag,
2713 int enable_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002714{
2715 int ret;
2716 u16 address;
2717 unsigned int pipe;
2718 LOCK_TAKE(hdw->big_lock); do {
Al Viro5fa12472008-03-29 03:07:38 +00002719 if ((hdw->fw_buffer == NULL) == !enable_flag) break;
Mike Iselyd8554972006-06-26 20:58:46 -03002720
2721 if (!enable_flag) {
2722 pvr2_trace(PVR2_TRACE_FIRMWARE,
2723 "Cleaning up after CPU firmware fetch");
2724 kfree(hdw->fw_buffer);
Mike Iselya0fd1cb2006-06-30 11:35:28 -03002725 hdw->fw_buffer = NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002726 hdw->fw_size = 0;
Mike Isely4db666c2007-09-08 22:16:27 -03002727 if (hdw->fw_cpu_flag) {
2728 /* Now release the CPU. It will disconnect
2729 and reconnect later. */
2730 pvr2_hdw_cpureset_assert(hdw,0);
2731 }
Mike Iselyd8554972006-06-26 20:58:46 -03002732 break;
2733 }
2734
Mike Isely4db666c2007-09-08 22:16:27 -03002735 hdw->fw_cpu_flag = (prom_flag == 0);
2736 if (hdw->fw_cpu_flag) {
2737 pvr2_trace(PVR2_TRACE_FIRMWARE,
2738 "Preparing to suck out CPU firmware");
2739 hdw->fw_size = 0x2000;
2740 hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
2741 if (!hdw->fw_buffer) {
2742 hdw->fw_size = 0;
2743 break;
2744 }
2745
2746 /* We have to hold the CPU during firmware upload. */
2747 pvr2_hdw_cpureset_assert(hdw,1);
2748
2749 /* download the firmware from address 0000-1fff in 2048
2750 (=0x800) bytes chunk. */
2751
2752 pvr2_trace(PVR2_TRACE_FIRMWARE,
2753 "Grabbing CPU firmware");
2754 pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
2755 for(address = 0; address < hdw->fw_size;
2756 address += 0x800) {
2757 ret = usb_control_msg(hdw->usb_dev,pipe,
2758 0xa0,0xc0,
2759 address,0,
2760 hdw->fw_buffer+address,
2761 0x800,HZ);
2762 if (ret < 0) break;
2763 }
2764
2765 pvr2_trace(PVR2_TRACE_FIRMWARE,
2766 "Done grabbing CPU firmware");
2767 } else {
2768 pvr2_trace(PVR2_TRACE_FIRMWARE,
2769 "Sucking down EEPROM contents");
2770 hdw->fw_buffer = pvr2_full_eeprom_fetch(hdw);
2771 if (!hdw->fw_buffer) {
2772 pvr2_trace(PVR2_TRACE_FIRMWARE,
2773 "EEPROM content suck failed.");
2774 break;
2775 }
2776 hdw->fw_size = EEPROM_SIZE;
2777 pvr2_trace(PVR2_TRACE_FIRMWARE,
2778 "Done sucking down EEPROM contents");
Mike Iselyd8554972006-06-26 20:58:46 -03002779 }
2780
Mike Iselyd8554972006-06-26 20:58:46 -03002781 } while (0); LOCK_GIVE(hdw->big_lock);
2782}
2783
2784
2785/* Return true if we're in a mode for retrieval CPU firmware */
2786int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
2787{
Al Viro5fa12472008-03-29 03:07:38 +00002788 return hdw->fw_buffer != NULL;
Mike Iselyd8554972006-06-26 20:58:46 -03002789}
2790
2791
2792int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs,
2793 char *buf,unsigned int cnt)
2794{
2795 int ret = -EINVAL;
2796 LOCK_TAKE(hdw->big_lock); do {
2797 if (!buf) break;
2798 if (!cnt) break;
2799
2800 if (!hdw->fw_buffer) {
2801 ret = -EIO;
2802 break;
2803 }
2804
2805 if (offs >= hdw->fw_size) {
2806 pvr2_trace(PVR2_TRACE_FIRMWARE,
2807 "Read firmware data offs=%d EOF",
2808 offs);
2809 ret = 0;
2810 break;
2811 }
2812
2813 if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs;
2814
2815 memcpy(buf,hdw->fw_buffer+offs,cnt);
2816
2817 pvr2_trace(PVR2_TRACE_FIRMWARE,
2818 "Read firmware data offs=%d cnt=%d",
2819 offs,cnt);
2820 ret = cnt;
2821 } while (0); LOCK_GIVE(hdw->big_lock);
2822
2823 return ret;
2824}
2825
2826
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002827int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002828 enum pvr2_v4l_type index)
Mike Iselyd8554972006-06-26 20:58:46 -03002829{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002830 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002831 case pvr2_v4l_type_video: return hdw->v4l_minor_number_video;
2832 case pvr2_v4l_type_vbi: return hdw->v4l_minor_number_vbi;
2833 case pvr2_v4l_type_radio: return hdw->v4l_minor_number_radio;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002834 default: return -1;
2835 }
Mike Iselyd8554972006-06-26 20:58:46 -03002836}
2837
2838
Pantelis Koukousoulas2fdf3d92006-12-27 23:07:58 -03002839/* Store a v4l minor device number */
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002840void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,
Mike Isely80793842006-12-27 23:12:28 -03002841 enum pvr2_v4l_type index,int v)
Mike Iselyd8554972006-06-26 20:58:46 -03002842{
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002843 switch (index) {
Mike Isely80793842006-12-27 23:12:28 -03002844 case pvr2_v4l_type_video: hdw->v4l_minor_number_video = v;
2845 case pvr2_v4l_type_vbi: hdw->v4l_minor_number_vbi = v;
2846 case pvr2_v4l_type_radio: hdw->v4l_minor_number_radio = v;
Mike Iselyfd5a75f2006-12-27 23:11:22 -03002847 default: break;
2848 }
Mike Iselyd8554972006-06-26 20:58:46 -03002849}
2850
2851
David Howells7d12e782006-10-05 14:55:46 +01002852static void pvr2_ctl_write_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002853{
2854 struct pvr2_hdw *hdw = urb->context;
2855 hdw->ctl_write_pend_flag = 0;
2856 if (hdw->ctl_read_pend_flag) return;
2857 complete(&hdw->ctl_done);
2858}
2859
2860
David Howells7d12e782006-10-05 14:55:46 +01002861static void pvr2_ctl_read_complete(struct urb *urb)
Mike Iselyd8554972006-06-26 20:58:46 -03002862{
2863 struct pvr2_hdw *hdw = urb->context;
2864 hdw->ctl_read_pend_flag = 0;
2865 if (hdw->ctl_write_pend_flag) return;
2866 complete(&hdw->ctl_done);
2867}
2868
2869
2870static void pvr2_ctl_timeout(unsigned long data)
2871{
2872 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
2873 if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
2874 hdw->ctl_timeout_flag = !0;
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002875 if (hdw->ctl_write_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002876 usb_unlink_urb(hdw->ctl_write_urb);
Mariusz Kozlowski5e55d2c2006-11-08 15:34:31 +01002877 if (hdw->ctl_read_pend_flag)
Mike Iselyd8554972006-06-26 20:58:46 -03002878 usb_unlink_urb(hdw->ctl_read_urb);
Mike Iselyd8554972006-06-26 20:58:46 -03002879 }
2880}
2881
2882
Mike Iselye61b6fc2006-07-18 22:42:18 -03002883/* Issue a command and get a response from the device. This extended
2884 version includes a probe flag (which if set means that device errors
2885 should not be logged or treated as fatal) and a timeout in jiffies.
2886 This can be used to non-lethally probe the health of endpoint 1. */
Adrian Bunk07e337e2006-06-30 11:30:20 -03002887static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
2888 unsigned int timeout,int probe_fl,
2889 void *write_data,unsigned int write_len,
2890 void *read_data,unsigned int read_len)
Mike Iselyd8554972006-06-26 20:58:46 -03002891{
2892 unsigned int idx;
2893 int status = 0;
2894 struct timer_list timer;
2895 if (!hdw->ctl_lock_held) {
2896 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2897 "Attempted to execute control transfer"
2898 " without lock!!");
2899 return -EDEADLK;
2900 }
Mike Isely681c7392007-11-26 01:48:52 -03002901 if (!hdw->flag_ok && !probe_fl) {
Mike Iselyd8554972006-06-26 20:58:46 -03002902 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2903 "Attempted to execute control transfer"
2904 " when device not ok");
2905 return -EIO;
2906 }
2907 if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) {
2908 if (!probe_fl) {
2909 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2910 "Attempted to execute control transfer"
2911 " when USB is disconnected");
2912 }
2913 return -ENOTTY;
2914 }
2915
2916 /* Ensure that we have sane parameters */
2917 if (!write_data) write_len = 0;
2918 if (!read_data) read_len = 0;
2919 if (write_len > PVR2_CTL_BUFFSIZE) {
2920 pvr2_trace(
2921 PVR2_TRACE_ERROR_LEGS,
2922 "Attempted to execute %d byte"
2923 " control-write transfer (limit=%d)",
2924 write_len,PVR2_CTL_BUFFSIZE);
2925 return -EINVAL;
2926 }
2927 if (read_len > PVR2_CTL_BUFFSIZE) {
2928 pvr2_trace(
2929 PVR2_TRACE_ERROR_LEGS,
2930 "Attempted to execute %d byte"
2931 " control-read transfer (limit=%d)",
2932 write_len,PVR2_CTL_BUFFSIZE);
2933 return -EINVAL;
2934 }
2935 if ((!write_len) && (!read_len)) {
2936 pvr2_trace(
2937 PVR2_TRACE_ERROR_LEGS,
2938 "Attempted to execute null control transfer?");
2939 return -EINVAL;
2940 }
2941
2942
2943 hdw->cmd_debug_state = 1;
2944 if (write_len) {
2945 hdw->cmd_debug_code = ((unsigned char *)write_data)[0];
2946 } else {
2947 hdw->cmd_debug_code = 0;
2948 }
2949 hdw->cmd_debug_write_len = write_len;
2950 hdw->cmd_debug_read_len = read_len;
2951
2952 /* Initialize common stuff */
2953 init_completion(&hdw->ctl_done);
2954 hdw->ctl_timeout_flag = 0;
2955 hdw->ctl_write_pend_flag = 0;
2956 hdw->ctl_read_pend_flag = 0;
2957 init_timer(&timer);
2958 timer.expires = jiffies + timeout;
2959 timer.data = (unsigned long)hdw;
2960 timer.function = pvr2_ctl_timeout;
2961
2962 if (write_len) {
2963 hdw->cmd_debug_state = 2;
2964 /* Transfer write data to internal buffer */
2965 for (idx = 0; idx < write_len; idx++) {
2966 hdw->ctl_write_buffer[idx] =
2967 ((unsigned char *)write_data)[idx];
2968 }
2969 /* Initiate a write request */
2970 usb_fill_bulk_urb(hdw->ctl_write_urb,
2971 hdw->usb_dev,
2972 usb_sndbulkpipe(hdw->usb_dev,
2973 PVR2_CTL_WRITE_ENDPOINT),
2974 hdw->ctl_write_buffer,
2975 write_len,
2976 pvr2_ctl_write_complete,
2977 hdw);
2978 hdw->ctl_write_urb->actual_length = 0;
2979 hdw->ctl_write_pend_flag = !0;
2980 status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
2981 if (status < 0) {
2982 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
2983 "Failed to submit write-control"
2984 " URB status=%d",status);
2985 hdw->ctl_write_pend_flag = 0;
2986 goto done;
2987 }
2988 }
2989
2990 if (read_len) {
2991 hdw->cmd_debug_state = 3;
2992 memset(hdw->ctl_read_buffer,0x43,read_len);
2993 /* Initiate a read request */
2994 usb_fill_bulk_urb(hdw->ctl_read_urb,
2995 hdw->usb_dev,
2996 usb_rcvbulkpipe(hdw->usb_dev,
2997 PVR2_CTL_READ_ENDPOINT),
2998 hdw->ctl_read_buffer,
2999 read_len,
3000 pvr2_ctl_read_complete,
3001 hdw);
3002 hdw->ctl_read_urb->actual_length = 0;
3003 hdw->ctl_read_pend_flag = !0;
3004 status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
3005 if (status < 0) {
3006 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3007 "Failed to submit read-control"
3008 " URB status=%d",status);
3009 hdw->ctl_read_pend_flag = 0;
3010 goto done;
3011 }
3012 }
3013
3014 /* Start timer */
3015 add_timer(&timer);
3016
3017 /* Now wait for all I/O to complete */
3018 hdw->cmd_debug_state = 4;
3019 while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) {
3020 wait_for_completion(&hdw->ctl_done);
3021 }
3022 hdw->cmd_debug_state = 5;
3023
3024 /* Stop timer */
3025 del_timer_sync(&timer);
3026
3027 hdw->cmd_debug_state = 6;
3028 status = 0;
3029
3030 if (hdw->ctl_timeout_flag) {
3031 status = -ETIMEDOUT;
3032 if (!probe_fl) {
3033 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3034 "Timed out control-write");
3035 }
3036 goto done;
3037 }
3038
3039 if (write_len) {
3040 /* Validate results of write request */
3041 if ((hdw->ctl_write_urb->status != 0) &&
3042 (hdw->ctl_write_urb->status != -ENOENT) &&
3043 (hdw->ctl_write_urb->status != -ESHUTDOWN) &&
3044 (hdw->ctl_write_urb->status != -ECONNRESET)) {
3045 /* USB subsystem is reporting some kind of failure
3046 on the write */
3047 status = hdw->ctl_write_urb->status;
3048 if (!probe_fl) {
3049 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3050 "control-write URB failure,"
3051 " status=%d",
3052 status);
3053 }
3054 goto done;
3055 }
3056 if (hdw->ctl_write_urb->actual_length < write_len) {
3057 /* Failed to write enough data */
3058 status = -EIO;
3059 if (!probe_fl) {
3060 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3061 "control-write URB short,"
3062 " expected=%d got=%d",
3063 write_len,
3064 hdw->ctl_write_urb->actual_length);
3065 }
3066 goto done;
3067 }
3068 }
3069 if (read_len) {
3070 /* Validate results of read request */
3071 if ((hdw->ctl_read_urb->status != 0) &&
3072 (hdw->ctl_read_urb->status != -ENOENT) &&
3073 (hdw->ctl_read_urb->status != -ESHUTDOWN) &&
3074 (hdw->ctl_read_urb->status != -ECONNRESET)) {
3075 /* USB subsystem is reporting some kind of failure
3076 on the read */
3077 status = hdw->ctl_read_urb->status;
3078 if (!probe_fl) {
3079 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3080 "control-read URB failure,"
3081 " status=%d",
3082 status);
3083 }
3084 goto done;
3085 }
3086 if (hdw->ctl_read_urb->actual_length < read_len) {
3087 /* Failed to read enough data */
3088 status = -EIO;
3089 if (!probe_fl) {
3090 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3091 "control-read URB short,"
3092 " expected=%d got=%d",
3093 read_len,
3094 hdw->ctl_read_urb->actual_length);
3095 }
3096 goto done;
3097 }
3098 /* Transfer retrieved data out from internal buffer */
3099 for (idx = 0; idx < read_len; idx++) {
3100 ((unsigned char *)read_data)[idx] =
3101 hdw->ctl_read_buffer[idx];
3102 }
3103 }
3104
3105 done:
3106
3107 hdw->cmd_debug_state = 0;
3108 if ((status < 0) && (!probe_fl)) {
Mike Isely681c7392007-11-26 01:48:52 -03003109 pvr2_hdw_render_useless(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03003110 }
3111 return status;
3112}
3113
3114
3115int pvr2_send_request(struct pvr2_hdw *hdw,
3116 void *write_data,unsigned int write_len,
3117 void *read_data,unsigned int read_len)
3118{
3119 return pvr2_send_request_ex(hdw,HZ*4,0,
3120 write_data,write_len,
3121 read_data,read_len);
3122}
3123
Mike Isely1c9d10d2008-03-28 05:38:54 -03003124
3125static int pvr2_issue_simple_cmd(struct pvr2_hdw *hdw,u32 cmdcode)
3126{
3127 int ret;
3128 unsigned int cnt = 1;
3129 unsigned int args = 0;
3130 LOCK_TAKE(hdw->ctl_lock);
3131 hdw->cmd_buffer[0] = cmdcode & 0xffu;
3132 args = (cmdcode >> 8) & 0xffu;
3133 args = (args > 2) ? 2 : args;
3134 if (args) {
3135 cnt += args;
3136 hdw->cmd_buffer[1] = (cmdcode >> 16) & 0xffu;
3137 if (args > 1) {
3138 hdw->cmd_buffer[2] = (cmdcode >> 24) & 0xffu;
3139 }
3140 }
3141 if (pvrusb2_debug & PVR2_TRACE_INIT) {
3142 unsigned int idx;
3143 unsigned int ccnt,bcnt;
3144 char tbuf[50];
3145 cmdcode &= 0xffu;
3146 bcnt = 0;
3147 ccnt = scnprintf(tbuf+bcnt,
3148 sizeof(tbuf)-bcnt,
3149 "Sending FX2 command 0x%x",cmdcode);
3150 bcnt += ccnt;
3151 for (idx = 0; idx < ARRAY_SIZE(pvr2_fx2cmd_desc); idx++) {
3152 if (pvr2_fx2cmd_desc[idx].id == cmdcode) {
3153 ccnt = scnprintf(tbuf+bcnt,
3154 sizeof(tbuf)-bcnt,
3155 " \"%s\"",
3156 pvr2_fx2cmd_desc[idx].desc);
3157 bcnt += ccnt;
3158 break;
3159 }
3160 }
3161 if (args) {
3162 ccnt = scnprintf(tbuf+bcnt,
3163 sizeof(tbuf)-bcnt,
3164 " (%u",hdw->cmd_buffer[1]);
3165 bcnt += ccnt;
3166 if (args > 1) {
3167 ccnt = scnprintf(tbuf+bcnt,
3168 sizeof(tbuf)-bcnt,
3169 ",%u",hdw->cmd_buffer[2]);
3170 bcnt += ccnt;
3171 }
3172 ccnt = scnprintf(tbuf+bcnt,
3173 sizeof(tbuf)-bcnt,
3174 ")");
3175 bcnt += ccnt;
3176 }
3177 pvr2_trace(PVR2_TRACE_INIT,"%.*s",bcnt,tbuf);
3178 }
3179 ret = pvr2_send_request(hdw,hdw->cmd_buffer,cnt,NULL,0);
3180 LOCK_GIVE(hdw->ctl_lock);
3181 return ret;
3182}
3183
3184
Mike Iselyd8554972006-06-26 20:58:46 -03003185int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
3186{
3187 int ret;
3188
3189 LOCK_TAKE(hdw->ctl_lock);
3190
Michael Krufky8d364362007-01-22 02:17:55 -03003191 hdw->cmd_buffer[0] = FX2CMD_REG_WRITE; /* write register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03003192 PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
3193 hdw->cmd_buffer[5] = 0;
3194 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3195 hdw->cmd_buffer[7] = reg & 0xff;
3196
3197
3198 ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0);
3199
3200 LOCK_GIVE(hdw->ctl_lock);
3201
3202 return ret;
3203}
3204
3205
Adrian Bunk07e337e2006-06-30 11:30:20 -03003206static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
Mike Iselyd8554972006-06-26 20:58:46 -03003207{
3208 int ret = 0;
3209
3210 LOCK_TAKE(hdw->ctl_lock);
3211
Michael Krufky8d364362007-01-22 02:17:55 -03003212 hdw->cmd_buffer[0] = FX2CMD_REG_READ; /* read register prefix */
Mike Iselyd8554972006-06-26 20:58:46 -03003213 hdw->cmd_buffer[1] = 0;
3214 hdw->cmd_buffer[2] = 0;
3215 hdw->cmd_buffer[3] = 0;
3216 hdw->cmd_buffer[4] = 0;
3217 hdw->cmd_buffer[5] = 0;
3218 hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
3219 hdw->cmd_buffer[7] = reg & 0xff;
3220
3221 ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4);
3222 *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0);
3223
3224 LOCK_GIVE(hdw->ctl_lock);
3225
3226 return ret;
3227}
3228
3229
Mike Isely681c7392007-11-26 01:48:52 -03003230void pvr2_hdw_render_useless(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03003231{
3232 if (!hdw->flag_ok) return;
Mike Isely681c7392007-11-26 01:48:52 -03003233 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3234 "Device being rendered inoperable");
Mike Iselyd8554972006-06-26 20:58:46 -03003235 if (hdw->vid_stream) {
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003236 pvr2_stream_setup(hdw->vid_stream,NULL,0,0);
Mike Iselyd8554972006-06-26 20:58:46 -03003237 }
Mike Isely681c7392007-11-26 01:48:52 -03003238 hdw->flag_ok = 0;
3239 trace_stbit("flag_ok",hdw->flag_ok);
3240 pvr2_hdw_state_sched(hdw);
Mike Iselyd8554972006-06-26 20:58:46 -03003241}
3242
3243
3244void pvr2_hdw_device_reset(struct pvr2_hdw *hdw)
3245{
3246 int ret;
3247 pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset...");
Mike Iselya0fd1cb2006-06-30 11:35:28 -03003248 ret = usb_lock_device_for_reset(hdw->usb_dev,NULL);
Mike Iselyd8554972006-06-26 20:58:46 -03003249 if (ret == 1) {
3250 ret = usb_reset_device(hdw->usb_dev);
3251 usb_unlock_device(hdw->usb_dev);
3252 } else {
3253 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3254 "Failed to lock USB device ret=%d",ret);
3255 }
3256 if (init_pause_msec) {
3257 pvr2_trace(PVR2_TRACE_INFO,
3258 "Waiting %u msec for hardware to settle",
3259 init_pause_msec);
3260 msleep(init_pause_msec);
3261 }
3262
3263}
3264
3265
3266void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val)
3267{
3268 char da[1];
3269 unsigned int pipe;
3270 int ret;
3271
3272 if (!hdw->usb_dev) return;
3273
3274 pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val);
3275
3276 da[0] = val ? 0x01 : 0x00;
3277
3278 /* Write the CPUCS register on the 8051. The lsb of the register
3279 is the reset bit; a 1 asserts reset while a 0 clears it. */
3280 pipe = usb_sndctrlpipe(hdw->usb_dev, 0);
3281 ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ);
3282 if (ret < 0) {
3283 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
3284 "cpureset_assert(%d) error=%d",val,ret);
3285 pvr2_hdw_render_useless(hdw);
3286 }
3287}
3288
3289
3290int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
3291{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003292 return pvr2_issue_simple_cmd(hdw,FX2CMD_DEEP_RESET);
Mike Iselyd8554972006-06-26 20:58:46 -03003293}
3294
3295
Michael Krufkye1edb192008-04-22 14:45:39 -03003296int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
3297{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003298 return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_ON);
Michael Krufkye1edb192008-04-22 14:45:39 -03003299}
3300
Mike Isely1c9d10d2008-03-28 05:38:54 -03003301
Michael Krufkye1edb192008-04-22 14:45:39 -03003302int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw)
3303{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003304 return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_OFF);
Michael Krufkye1edb192008-04-22 14:45:39 -03003305}
3306
Mike Iselyd8554972006-06-26 20:58:46 -03003307
3308int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
3309{
3310 if (!hdw->decoder_ctrl) {
3311 pvr2_trace(PVR2_TRACE_INIT,
3312 "Unable to reset decoder: nothing attached");
3313 return -ENOTTY;
3314 }
3315
3316 if (!hdw->decoder_ctrl->force_reset) {
3317 pvr2_trace(PVR2_TRACE_INIT,
3318 "Unable to reset decoder: not implemented");
3319 return -ENOTTY;
3320 }
3321
3322 pvr2_trace(PVR2_TRACE_INIT,
3323 "Requesting decoder reset");
3324 hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
3325 return 0;
3326}
3327
3328
Mike Isely62433e32008-04-22 14:45:40 -03003329static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff)
Mike Isely84147f32008-04-22 14:45:40 -03003330{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003331 hdw->flag_ok = !0;
3332 return pvr2_issue_simple_cmd(hdw,
3333 FX2CMD_HCW_DEMOD_RESETIN |
3334 (1 << 8) |
3335 ((onoff ? 1 : 0) << 16));
Mike Isely84147f32008-04-22 14:45:40 -03003336}
3337
Mike Isely84147f32008-04-22 14:45:40 -03003338
Mike Isely62433e32008-04-22 14:45:40 -03003339static int pvr2_hdw_cmd_onair_fe_power_ctrl(struct pvr2_hdw *hdw, int onoff)
Mike Isely84147f32008-04-22 14:45:40 -03003340{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003341 hdw->flag_ok = !0;
3342 return pvr2_issue_simple_cmd(hdw,(onoff ?
3343 FX2CMD_ONAIR_DTV_POWER_ON :
3344 FX2CMD_ONAIR_DTV_POWER_OFF));
Mike Isely84147f32008-04-22 14:45:40 -03003345}
3346
Mike Isely62433e32008-04-22 14:45:40 -03003347
3348static int pvr2_hdw_cmd_onair_digital_path_ctrl(struct pvr2_hdw *hdw,
3349 int onoff)
Mike Isely84147f32008-04-22 14:45:40 -03003350{
Mike Isely1c9d10d2008-03-28 05:38:54 -03003351 return pvr2_issue_simple_cmd(hdw,(onoff ?
3352 FX2CMD_ONAIR_DTV_STREAMING_ON :
3353 FX2CMD_ONAIR_DTV_STREAMING_OFF));
Mike Isely84147f32008-04-22 14:45:40 -03003354}
3355
Mike Isely62433e32008-04-22 14:45:40 -03003356
3357static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl)
3358{
3359 int cmode;
3360 /* Compare digital/analog desired setting with current setting. If
3361 they don't match, fix it... */
3362 cmode = (digitalFl ? PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG);
3363 if (cmode == hdw->pathway_state) {
3364 /* They match; nothing to do */
3365 return;
3366 }
3367
3368 switch (hdw->hdw_desc->digital_control_scheme) {
3369 case PVR2_DIGITAL_SCHEME_HAUPPAUGE:
3370 pvr2_hdw_cmd_hcw_demod_reset(hdw,digitalFl);
3371 if (cmode == PVR2_PATHWAY_ANALOG) {
3372 /* If moving to analog mode, also force the decoder
3373 to reset. If no decoder is attached, then it's
3374 ok to ignore this because if/when the decoder
3375 attaches, it will reset itself at that time. */
3376 pvr2_hdw_cmd_decoder_reset(hdw);
3377 }
3378 break;
3379 case PVR2_DIGITAL_SCHEME_ONAIR:
3380 /* Supposedly we should always have the power on whether in
3381 digital or analog mode. But for now do what appears to
3382 work... */
Mike Iselybb0c2fe2008-03-28 05:41:19 -03003383 pvr2_hdw_cmd_onair_fe_power_ctrl(hdw,digitalFl);
Mike Isely62433e32008-04-22 14:45:40 -03003384 break;
3385 default: break;
3386 }
3387
Mike Isely1b9c18c2008-04-22 14:45:41 -03003388 pvr2_hdw_untrip_unlocked(hdw);
Mike Isely62433e32008-04-22 14:45:40 -03003389 hdw->pathway_state = cmode;
3390}
3391
3392
Mike Isely40381cb2008-04-22 14:45:42 -03003393void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff)
Mike Iselyc55a97d2008-04-22 14:45:41 -03003394{
3395 /* change some GPIO data
3396 *
3397 * note: bit d7 of dir appears to control the LED,
3398 * so we shut it off here.
3399 *
Mike Iselyc55a97d2008-04-22 14:45:41 -03003400 */
Mike Isely40381cb2008-04-22 14:45:42 -03003401 if (onoff) {
Mike Iselyc55a97d2008-04-22 14:45:41 -03003402 pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000481);
Mike Isely40381cb2008-04-22 14:45:42 -03003403 } else {
Mike Iselyc55a97d2008-04-22 14:45:41 -03003404 pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000401);
Mike Isely40381cb2008-04-22 14:45:42 -03003405 }
Mike Iselyc55a97d2008-04-22 14:45:41 -03003406 pvr2_hdw_gpio_chg_out(hdw, 0xffffffff, 0x00000000);
Mike Isely40381cb2008-04-22 14:45:42 -03003407}
Mike Iselyc55a97d2008-04-22 14:45:41 -03003408
Mike Isely40381cb2008-04-22 14:45:42 -03003409
3410typedef void (*led_method_func)(struct pvr2_hdw *,int);
3411
3412static led_method_func led_methods[] = {
3413 [PVR2_LED_SCHEME_HAUPPAUGE] = pvr2_led_ctrl_hauppauge,
3414};
3415
3416
3417/* Toggle LED */
3418static void pvr2_led_ctrl(struct pvr2_hdw *hdw,int onoff)
3419{
3420 unsigned int scheme_id;
3421 led_method_func fp;
3422
3423 if ((!onoff) == (!hdw->led_on)) return;
3424
3425 hdw->led_on = onoff != 0;
3426
3427 scheme_id = hdw->hdw_desc->led_scheme;
3428 if (scheme_id < ARRAY_SIZE(led_methods)) {
3429 fp = led_methods[scheme_id];
3430 } else {
3431 fp = NULL;
3432 }
3433
3434 if (fp) (*fp)(hdw,onoff);
Mike Iselyc55a97d2008-04-22 14:45:41 -03003435}
3436
3437
Mike Iselye61b6fc2006-07-18 22:42:18 -03003438/* Stop / start video stream transport */
Adrian Bunk07e337e2006-06-30 11:30:20 -03003439static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
Mike Iselyd8554972006-06-26 20:58:46 -03003440{
Mike Iselybb0c2fe2008-03-28 05:41:19 -03003441 int ret;
3442
3443 /* If we're in analog mode, then just issue the usual analog
3444 command. */
3445 if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
3446 return pvr2_issue_simple_cmd(hdw,
3447 (runFl ?
3448 FX2CMD_STREAMING_ON :
3449 FX2CMD_STREAMING_OFF));
3450 /*Note: Not reached */
Mike Isely62433e32008-04-22 14:45:40 -03003451 }
Mike Iselybb0c2fe2008-03-28 05:41:19 -03003452
3453 if (hdw->pathway_state != PVR2_PATHWAY_DIGITAL) {
3454 /* Whoops, we don't know what mode we're in... */
3455 return -EINVAL;
3456 }
3457
3458 /* To get here we have to be in digital mode. The mechanism here
3459 is unfortunately different for different vendors. So we switch
3460 on the device's digital scheme attribute in order to figure out
3461 what to do. */
3462 switch (hdw->hdw_desc->digital_control_scheme) {
3463 case PVR2_DIGITAL_SCHEME_HAUPPAUGE:
3464 return pvr2_issue_simple_cmd(hdw,
3465 (runFl ?
3466 FX2CMD_HCW_DTV_STREAMING_ON :
3467 FX2CMD_HCW_DTV_STREAMING_OFF));
3468 case PVR2_DIGITAL_SCHEME_ONAIR:
3469 ret = pvr2_issue_simple_cmd(hdw,
3470 (runFl ?
3471 FX2CMD_STREAMING_ON :
3472 FX2CMD_STREAMING_OFF));
3473 if (ret) return ret;
3474 return pvr2_hdw_cmd_onair_digital_path_ctrl(hdw,runFl);
3475 default:
3476 return -EINVAL;
3477 }
Mike Iselyd8554972006-06-26 20:58:46 -03003478}
3479
3480
Mike Isely62433e32008-04-22 14:45:40 -03003481/* Evaluate whether or not state_pathway_ok can change */
3482static int state_eval_pathway_ok(struct pvr2_hdw *hdw)
3483{
3484 if (hdw->state_pathway_ok) {
3485 /* Nothing to do if pathway is already ok */
3486 return 0;
3487 }
3488 if (!hdw->state_pipeline_idle) {
3489 /* Not allowed to change anything if pipeline is not idle */
3490 return 0;
3491 }
3492 pvr2_hdw_cmd_modeswitch(hdw,hdw->input_val == PVR2_CVAL_INPUT_DTV);
3493 hdw->state_pathway_ok = !0;
Mike Iselye9db1ff2008-04-22 14:45:41 -03003494 trace_stbit("state_pathway_ok",hdw->state_pathway_ok);
Mike Isely62433e32008-04-22 14:45:40 -03003495 return !0;
3496}
3497
3498
Mike Isely681c7392007-11-26 01:48:52 -03003499/* Evaluate whether or not state_encoder_ok can change */
3500static int state_eval_encoder_ok(struct pvr2_hdw *hdw)
3501{
3502 if (hdw->state_encoder_ok) return 0;
3503 if (hdw->flag_tripped) return 0;
3504 if (hdw->state_encoder_run) return 0;
3505 if (hdw->state_encoder_config) return 0;
3506 if (hdw->state_decoder_run) return 0;
3507 if (hdw->state_usbstream_run) return 0;
Mike Isely72998b72008-04-03 04:51:19 -03003508 if (hdw->pathway_state == PVR2_PATHWAY_DIGITAL) {
3509 if (!hdw->hdw_desc->flag_digital_requires_cx23416) return 0;
3510 } else if (hdw->pathway_state != PVR2_PATHWAY_ANALOG) {
3511 return 0;
3512 }
3513
Mike Isely681c7392007-11-26 01:48:52 -03003514 if (pvr2_upload_firmware2(hdw) < 0) {
3515 hdw->flag_tripped = !0;
3516 trace_stbit("flag_tripped",hdw->flag_tripped);
3517 return !0;
3518 }
3519 hdw->state_encoder_ok = !0;
3520 trace_stbit("state_encoder_ok",hdw->state_encoder_ok);
3521 return !0;
3522}
3523
3524
3525/* Evaluate whether or not state_encoder_config can change */
3526static int state_eval_encoder_config(struct pvr2_hdw *hdw)
3527{
3528 if (hdw->state_encoder_config) {
3529 if (hdw->state_encoder_ok) {
3530 if (hdw->state_pipeline_req &&
3531 !hdw->state_pipeline_pause) return 0;
3532 }
3533 hdw->state_encoder_config = 0;
3534 hdw->state_encoder_waitok = 0;
3535 trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
3536 /* paranoia - solve race if timer just completed */
3537 del_timer_sync(&hdw->encoder_wait_timer);
3538 } else {
Mike Isely62433e32008-04-22 14:45:40 -03003539 if (!hdw->state_pathway_ok ||
3540 (hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
3541 !hdw->state_encoder_ok ||
Mike Isely681c7392007-11-26 01:48:52 -03003542 !hdw->state_pipeline_idle ||
3543 hdw->state_pipeline_pause ||
3544 !hdw->state_pipeline_req ||
3545 !hdw->state_pipeline_config) {
3546 /* We must reset the enforced wait interval if
3547 anything has happened that might have disturbed
3548 the encoder. This should be a rare case. */
3549 if (timer_pending(&hdw->encoder_wait_timer)) {
3550 del_timer_sync(&hdw->encoder_wait_timer);
3551 }
3552 if (hdw->state_encoder_waitok) {
3553 /* Must clear the state - therefore we did
3554 something to a state bit and must also
3555 return true. */
3556 hdw->state_encoder_waitok = 0;
3557 trace_stbit("state_encoder_waitok",
3558 hdw->state_encoder_waitok);
3559 return !0;
3560 }
3561 return 0;
3562 }
3563 if (!hdw->state_encoder_waitok) {
3564 if (!timer_pending(&hdw->encoder_wait_timer)) {
3565 /* waitok flag wasn't set and timer isn't
3566 running. Check flag once more to avoid
3567 a race then start the timer. This is
3568 the point when we measure out a minimal
3569 quiet interval before doing something to
3570 the encoder. */
3571 if (!hdw->state_encoder_waitok) {
3572 hdw->encoder_wait_timer.expires =
3573 jiffies + (HZ*50/1000);
3574 add_timer(&hdw->encoder_wait_timer);
3575 }
3576 }
3577 /* We can't continue until we know we have been
3578 quiet for the interval measured by this
3579 timer. */
3580 return 0;
3581 }
3582 pvr2_encoder_configure(hdw);
3583 if (hdw->state_encoder_ok) hdw->state_encoder_config = !0;
3584 }
3585 trace_stbit("state_encoder_config",hdw->state_encoder_config);
3586 return !0;
3587}
3588
3589
Mike Iselyd913d632008-04-06 04:04:35 -03003590/* Return true if the encoder should not be running. */
3591static int state_check_disable_encoder_run(struct pvr2_hdw *hdw)
3592{
3593 if (!hdw->state_encoder_ok) {
3594 /* Encoder isn't healthy at the moment, so stop it. */
3595 return !0;
3596 }
3597 if (!hdw->state_pathway_ok) {
3598 /* Mode is not understood at the moment (i.e. it wants to
3599 change), so encoder must be stopped. */
3600 return !0;
3601 }
3602
3603 switch (hdw->pathway_state) {
3604 case PVR2_PATHWAY_ANALOG:
3605 if (!hdw->state_decoder_run) {
3606 /* We're in analog mode and the decoder is not
3607 running; thus the encoder should be stopped as
3608 well. */
3609 return !0;
3610 }
3611 break;
3612 case PVR2_PATHWAY_DIGITAL:
3613 if (hdw->state_encoder_runok) {
3614 /* This is a funny case. We're in digital mode so
3615 really the encoder should be stopped. However
3616 if it really is running, only kill it after
3617 runok has been set. This gives a chance for the
3618 onair quirk to function (encoder must run
3619 briefly first, at least once, before onair
3620 digital streaming can work). */
3621 return !0;
3622 }
3623 break;
3624 default:
3625 /* Unknown mode; so encoder should be stopped. */
3626 return !0;
3627 }
3628
3629 /* If we get here, we haven't found a reason to stop the
3630 encoder. */
3631 return 0;
3632}
3633
3634
3635/* Return true if the encoder should be running. */
3636static int state_check_enable_encoder_run(struct pvr2_hdw *hdw)
3637{
3638 if (!hdw->state_encoder_ok) {
3639 /* Don't run the encoder if it isn't healthy... */
3640 return 0;
3641 }
3642 if (!hdw->state_pathway_ok) {
3643 /* Don't run the encoder if we don't (yet) know what mode
3644 we need to be in... */
3645 return 0;
3646 }
3647
3648 switch (hdw->pathway_state) {
3649 case PVR2_PATHWAY_ANALOG:
3650 if (hdw->state_decoder_run) {
3651 /* In analog mode, if the decoder is running, then
3652 run the encoder. */
3653 return !0;
3654 }
3655 break;
3656 case PVR2_PATHWAY_DIGITAL:
3657 if ((hdw->hdw_desc->digital_control_scheme ==
3658 PVR2_DIGITAL_SCHEME_ONAIR) &&
3659 !hdw->state_encoder_runok) {
3660 /* This is a quirk. OnAir hardware won't stream
3661 digital until the encoder has been run at least
3662 once, for a minimal period of time (empiricially
3663 measured to be 1/4 second). So if we're on
3664 OnAir hardware and the encoder has never been
3665 run at all, then start the encoder. Normal
3666 state machine logic in the driver will
3667 automatically handle the remaining bits. */
3668 return !0;
3669 }
3670 break;
3671 default:
3672 /* For completeness (unknown mode; encoder won't run ever) */
3673 break;
3674 }
3675 /* If we get here, then we haven't found any reason to run the
3676 encoder, so don't run it. */
3677 return 0;
3678}
3679
3680
Mike Isely681c7392007-11-26 01:48:52 -03003681/* Evaluate whether or not state_encoder_run can change */
3682static int state_eval_encoder_run(struct pvr2_hdw *hdw)
3683{
3684 if (hdw->state_encoder_run) {
Mike Iselyd913d632008-04-06 04:04:35 -03003685 if (!state_check_disable_encoder_run(hdw)) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003686 if (hdw->state_encoder_ok) {
Mike Iselyd913d632008-04-06 04:04:35 -03003687 del_timer_sync(&hdw->encoder_run_timer);
Mike Isely681c7392007-11-26 01:48:52 -03003688 if (pvr2_encoder_stop(hdw) < 0) return !0;
3689 }
3690 hdw->state_encoder_run = 0;
3691 } else {
Mike Iselyd913d632008-04-06 04:04:35 -03003692 if (!state_check_enable_encoder_run(hdw)) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003693 if (pvr2_encoder_start(hdw) < 0) return !0;
3694 hdw->state_encoder_run = !0;
Mike Iselyd913d632008-04-06 04:04:35 -03003695 if (!hdw->state_encoder_runok) {
3696 hdw->encoder_run_timer.expires =
3697 jiffies + (HZ*250/1000);
3698 add_timer(&hdw->encoder_run_timer);
3699 }
Mike Isely681c7392007-11-26 01:48:52 -03003700 }
3701 trace_stbit("state_encoder_run",hdw->state_encoder_run);
3702 return !0;
3703}
3704
3705
3706/* Timeout function for quiescent timer. */
3707static void pvr2_hdw_quiescent_timeout(unsigned long data)
3708{
3709 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
3710 hdw->state_decoder_quiescent = !0;
3711 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
3712 hdw->state_stale = !0;
3713 queue_work(hdw->workqueue,&hdw->workpoll);
3714}
3715
3716
3717/* Timeout function for encoder wait timer. */
3718static void pvr2_hdw_encoder_wait_timeout(unsigned long data)
3719{
3720 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
3721 hdw->state_encoder_waitok = !0;
3722 trace_stbit("state_encoder_waitok",hdw->state_encoder_waitok);
3723 hdw->state_stale = !0;
3724 queue_work(hdw->workqueue,&hdw->workpoll);
3725}
3726
3727
Mike Iselyd913d632008-04-06 04:04:35 -03003728/* Timeout function for encoder run timer. */
3729static void pvr2_hdw_encoder_run_timeout(unsigned long data)
3730{
3731 struct pvr2_hdw *hdw = (struct pvr2_hdw *)data;
3732 if (!hdw->state_encoder_runok) {
3733 hdw->state_encoder_runok = !0;
3734 trace_stbit("state_encoder_runok",hdw->state_encoder_runok);
3735 hdw->state_stale = !0;
3736 queue_work(hdw->workqueue,&hdw->workpoll);
3737 }
3738}
3739
3740
Mike Isely681c7392007-11-26 01:48:52 -03003741/* Evaluate whether or not state_decoder_run can change */
3742static int state_eval_decoder_run(struct pvr2_hdw *hdw)
3743{
3744 if (hdw->state_decoder_run) {
3745 if (hdw->state_encoder_ok) {
3746 if (hdw->state_pipeline_req &&
Mike Isely62433e32008-04-22 14:45:40 -03003747 !hdw->state_pipeline_pause &&
3748 hdw->state_pathway_ok) return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003749 }
3750 if (!hdw->flag_decoder_missed) {
3751 pvr2_decoder_enable(hdw,0);
3752 }
3753 hdw->state_decoder_quiescent = 0;
3754 hdw->state_decoder_run = 0;
3755 /* paranoia - solve race if timer just completed */
3756 del_timer_sync(&hdw->quiescent_timer);
3757 } else {
3758 if (!hdw->state_decoder_quiescent) {
3759 if (!timer_pending(&hdw->quiescent_timer)) {
3760 /* We don't do something about the
3761 quiescent timer until right here because
3762 we also want to catch cases where the
3763 decoder was already not running (like
3764 after initialization) as opposed to
3765 knowing that we had just stopped it.
3766 The second flag check is here to cover a
3767 race - the timer could have run and set
3768 this flag just after the previous check
3769 but before we did the pending check. */
3770 if (!hdw->state_decoder_quiescent) {
3771 hdw->quiescent_timer.expires =
3772 jiffies + (HZ*50/1000);
3773 add_timer(&hdw->quiescent_timer);
3774 }
3775 }
3776 /* Don't allow decoder to start again until it has
3777 been quiesced first. This little detail should
3778 hopefully further stabilize the encoder. */
3779 return 0;
3780 }
Mike Isely62433e32008-04-22 14:45:40 -03003781 if (!hdw->state_pathway_ok ||
3782 (hdw->pathway_state != PVR2_PATHWAY_ANALOG) ||
3783 !hdw->state_pipeline_req ||
Mike Isely681c7392007-11-26 01:48:52 -03003784 hdw->state_pipeline_pause ||
3785 !hdw->state_pipeline_config ||
3786 !hdw->state_encoder_config ||
3787 !hdw->state_encoder_ok) return 0;
3788 del_timer_sync(&hdw->quiescent_timer);
3789 if (hdw->flag_decoder_missed) return 0;
3790 if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
3791 hdw->state_decoder_quiescent = 0;
3792 hdw->state_decoder_run = !0;
3793 }
3794 trace_stbit("state_decoder_quiescent",hdw->state_decoder_quiescent);
3795 trace_stbit("state_decoder_run",hdw->state_decoder_run);
3796 return !0;
3797}
3798
3799
3800/* Evaluate whether or not state_usbstream_run can change */
3801static int state_eval_usbstream_run(struct pvr2_hdw *hdw)
3802{
3803 if (hdw->state_usbstream_run) {
Mike Isely72998b72008-04-03 04:51:19 -03003804 int fl = !0;
Mike Isely62433e32008-04-22 14:45:40 -03003805 if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
Mike Isely72998b72008-04-03 04:51:19 -03003806 fl = (hdw->state_encoder_ok &&
3807 hdw->state_encoder_run);
3808 } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
3809 (hdw->hdw_desc->flag_digital_requires_cx23416)) {
3810 fl = hdw->state_encoder_ok;
3811 }
3812 if (fl &&
3813 hdw->state_pipeline_req &&
3814 !hdw->state_pipeline_pause &&
3815 hdw->state_pathway_ok) {
3816 return 0;
Mike Isely681c7392007-11-26 01:48:52 -03003817 }
3818 pvr2_hdw_cmd_usbstream(hdw,0);
3819 hdw->state_usbstream_run = 0;
3820 } else {
Mike Isely62433e32008-04-22 14:45:40 -03003821 if (!hdw->state_pipeline_req ||
3822 hdw->state_pipeline_pause ||
3823 !hdw->state_pathway_ok) return 0;
3824 if (hdw->pathway_state == PVR2_PATHWAY_ANALOG) {
3825 if (!hdw->state_encoder_ok ||
3826 !hdw->state_encoder_run) return 0;
Mike Isely72998b72008-04-03 04:51:19 -03003827 } else if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) &&
3828 (hdw->hdw_desc->flag_digital_requires_cx23416)) {
3829 if (!hdw->state_encoder_ok) return 0;
Mike Iselyd913d632008-04-06 04:04:35 -03003830 if (hdw->state_encoder_run) return 0;
3831 if (hdw->hdw_desc->digital_control_scheme ==
3832 PVR2_DIGITAL_SCHEME_ONAIR) {
3833 /* OnAir digital receivers won't stream
3834 unless the analog encoder has run first.
3835 Why? I have no idea. But don't even
3836 try until we know the analog side is
3837 known to have run. */
3838 if (!hdw->state_encoder_runok) return 0;
3839 }
Mike Isely62433e32008-04-22 14:45:40 -03003840 }
Mike Isely681c7392007-11-26 01:48:52 -03003841 if (pvr2_hdw_cmd_usbstream(hdw,!0) < 0) return 0;
3842 hdw->state_usbstream_run = !0;
3843 }
3844 trace_stbit("state_usbstream_run",hdw->state_usbstream_run);
3845 return !0;
3846}
3847
3848
3849/* Attempt to configure pipeline, if needed */
3850static int state_eval_pipeline_config(struct pvr2_hdw *hdw)
3851{
3852 if (hdw->state_pipeline_config ||
3853 hdw->state_pipeline_pause) return 0;
3854 pvr2_hdw_commit_execute(hdw);
3855 return !0;
3856}
3857
3858
3859/* Update pipeline idle and pipeline pause tracking states based on other
3860 inputs. This must be called whenever the other relevant inputs have
3861 changed. */
3862static int state_update_pipeline_state(struct pvr2_hdw *hdw)
3863{
3864 unsigned int st;
3865 int updatedFl = 0;
3866 /* Update pipeline state */
3867 st = !(hdw->state_encoder_run ||
3868 hdw->state_decoder_run ||
3869 hdw->state_usbstream_run ||
3870 (!hdw->state_decoder_quiescent));
3871 if (!st != !hdw->state_pipeline_idle) {
3872 hdw->state_pipeline_idle = st;
3873 updatedFl = !0;
3874 }
3875 if (hdw->state_pipeline_idle && hdw->state_pipeline_pause) {
3876 hdw->state_pipeline_pause = 0;
3877 updatedFl = !0;
3878 }
3879 return updatedFl;
3880}
3881
3882
3883typedef int (*state_eval_func)(struct pvr2_hdw *);
3884
3885/* Set of functions to be run to evaluate various states in the driver. */
Tobias Klauserebff0332008-04-22 14:45:45 -03003886static const state_eval_func eval_funcs[] = {
Mike Isely62433e32008-04-22 14:45:40 -03003887 state_eval_pathway_ok,
Mike Isely681c7392007-11-26 01:48:52 -03003888 state_eval_pipeline_config,
3889 state_eval_encoder_ok,
3890 state_eval_encoder_config,
3891 state_eval_decoder_run,
3892 state_eval_encoder_run,
3893 state_eval_usbstream_run,
3894};
3895
3896
3897/* Process various states and return true if we did anything interesting. */
3898static int pvr2_hdw_state_update(struct pvr2_hdw *hdw)
3899{
3900 unsigned int i;
3901 int state_updated = 0;
3902 int check_flag;
3903
3904 if (!hdw->state_stale) return 0;
3905 if ((hdw->fw1_state != FW1_STATE_OK) ||
3906 !hdw->flag_ok) {
3907 hdw->state_stale = 0;
3908 return !0;
3909 }
3910 /* This loop is the heart of the entire driver. It keeps trying to
3911 evaluate various bits of driver state until nothing changes for
3912 one full iteration. Each "bit of state" tracks some global
3913 aspect of the driver, e.g. whether decoder should run, if
3914 pipeline is configured, usb streaming is on, etc. We separately
3915 evaluate each of those questions based on other driver state to
3916 arrive at the correct running configuration. */
3917 do {
3918 check_flag = 0;
3919 state_update_pipeline_state(hdw);
3920 /* Iterate over each bit of state */
3921 for (i = 0; (i<ARRAY_SIZE(eval_funcs)) && hdw->flag_ok; i++) {
3922 if ((*eval_funcs[i])(hdw)) {
3923 check_flag = !0;
3924 state_updated = !0;
3925 state_update_pipeline_state(hdw);
3926 }
3927 }
3928 } while (check_flag && hdw->flag_ok);
3929 hdw->state_stale = 0;
3930 trace_stbit("state_stale",hdw->state_stale);
3931 return state_updated;
3932}
3933
3934
Mike Isely1cb03b72008-04-21 03:47:43 -03003935static unsigned int print_input_mask(unsigned int msk,
3936 char *buf,unsigned int acnt)
3937{
3938 unsigned int idx,ccnt;
3939 unsigned int tcnt = 0;
3940 for (idx = 0; idx < ARRAY_SIZE(control_values_input); idx++) {
3941 if (!((1 << idx) & msk)) continue;
3942 ccnt = scnprintf(buf+tcnt,
3943 acnt-tcnt,
3944 "%s%s",
3945 (tcnt ? ", " : ""),
3946 control_values_input[idx]);
3947 tcnt += ccnt;
3948 }
3949 return tcnt;
3950}
3951
3952
Mike Isely62433e32008-04-22 14:45:40 -03003953static const char *pvr2_pathway_state_name(int id)
3954{
3955 switch (id) {
3956 case PVR2_PATHWAY_ANALOG: return "analog";
3957 case PVR2_PATHWAY_DIGITAL: return "digital";
3958 default: return "unknown";
3959 }
3960}
3961
3962
Mike Isely681c7392007-11-26 01:48:52 -03003963static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
3964 char *buf,unsigned int acnt)
3965{
3966 switch (which) {
3967 case 0:
3968 return scnprintf(
3969 buf,acnt,
Mike Iselye9db1ff2008-04-22 14:45:41 -03003970 "driver:%s%s%s%s%s <mode=%s>",
Mike Isely681c7392007-11-26 01:48:52 -03003971 (hdw->flag_ok ? " <ok>" : " <fail>"),
3972 (hdw->flag_init_ok ? " <init>" : " <uninitialized>"),
3973 (hdw->flag_disconnected ? " <disconnected>" :
3974 " <connected>"),
3975 (hdw->flag_tripped ? " <tripped>" : ""),
Mike Isely62433e32008-04-22 14:45:40 -03003976 (hdw->flag_decoder_missed ? " <no decoder>" : ""),
3977 pvr2_pathway_state_name(hdw->pathway_state));
3978
Mike Isely681c7392007-11-26 01:48:52 -03003979 case 1:
3980 return scnprintf(
3981 buf,acnt,
3982 "pipeline:%s%s%s%s",
3983 (hdw->state_pipeline_idle ? " <idle>" : ""),
3984 (hdw->state_pipeline_config ?
3985 " <configok>" : " <stale>"),
3986 (hdw->state_pipeline_req ? " <req>" : ""),
3987 (hdw->state_pipeline_pause ? " <pause>" : ""));
3988 case 2:
3989 return scnprintf(
3990 buf,acnt,
Mike Isely62433e32008-04-22 14:45:40 -03003991 "worker:%s%s%s%s%s%s%s",
Mike Isely681c7392007-11-26 01:48:52 -03003992 (hdw->state_decoder_run ?
3993 " <decode:run>" :
3994 (hdw->state_decoder_quiescent ?
3995 "" : " <decode:stop>")),
3996 (hdw->state_decoder_quiescent ?
3997 " <decode:quiescent>" : ""),
3998 (hdw->state_encoder_ok ?
3999 "" : " <encode:init>"),
4000 (hdw->state_encoder_run ?
Mike Iselyd913d632008-04-06 04:04:35 -03004001 (hdw->state_encoder_runok ?
4002 " <encode:run>" :
4003 " <encode:firstrun>") :
4004 (hdw->state_encoder_runok ?
4005 " <encode:stop>" :
4006 " <encode:virgin>")),
Mike Isely681c7392007-11-26 01:48:52 -03004007 (hdw->state_encoder_config ?
4008 " <encode:configok>" :
4009 (hdw->state_encoder_waitok ?
Mike Iselyb9a37d92008-03-28 05:31:40 -03004010 "" : " <encode:waitok>")),
Mike Isely681c7392007-11-26 01:48:52 -03004011 (hdw->state_usbstream_run ?
Mike Isely62433e32008-04-22 14:45:40 -03004012 " <usb:run>" : " <usb:stop>"),
4013 (hdw->state_pathway_ok ?
Mike Iselye9db1ff2008-04-22 14:45:41 -03004014 " <pathway:ok>" : ""));
Mike Isely681c7392007-11-26 01:48:52 -03004015 case 3:
4016 return scnprintf(
4017 buf,acnt,
4018 "state: %s",
4019 pvr2_get_state_name(hdw->master_state));
Mike Iselyad0992e2008-03-28 05:34:45 -03004020 case 4: {
Mike Isely1cb03b72008-04-21 03:47:43 -03004021 unsigned int tcnt = 0;
4022 unsigned int ccnt;
4023
4024 ccnt = scnprintf(buf,
4025 acnt,
4026 "Hardware supported inputs: ");
4027 tcnt += ccnt;
4028 tcnt += print_input_mask(hdw->input_avail_mask,
4029 buf+tcnt,
4030 acnt-tcnt);
4031 if (hdw->input_avail_mask != hdw->input_allowed_mask) {
4032 ccnt = scnprintf(buf+tcnt,
4033 acnt-tcnt,
4034 "; allowed inputs: ");
4035 tcnt += ccnt;
4036 tcnt += print_input_mask(hdw->input_allowed_mask,
4037 buf+tcnt,
4038 acnt-tcnt);
4039 }
4040 return tcnt;
4041 }
4042 case 5: {
Mike Iselyad0992e2008-03-28 05:34:45 -03004043 struct pvr2_stream_stats stats;
4044 if (!hdw->vid_stream) break;
4045 pvr2_stream_get_stats(hdw->vid_stream,
4046 &stats,
4047 0);
4048 return scnprintf(
4049 buf,acnt,
4050 "Bytes streamed=%u"
4051 " URBs: queued=%u idle=%u ready=%u"
4052 " processed=%u failed=%u",
4053 stats.bytes_processed,
4054 stats.buffers_in_queue,
4055 stats.buffers_in_idle,
4056 stats.buffers_in_ready,
4057 stats.buffers_processed,
4058 stats.buffers_failed);
4059 }
Mike Isely681c7392007-11-26 01:48:52 -03004060 default: break;
4061 }
4062 return 0;
4063}
4064
4065
4066unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
4067 char *buf,unsigned int acnt)
4068{
4069 unsigned int bcnt,ccnt,idx;
4070 bcnt = 0;
4071 LOCK_TAKE(hdw->big_lock);
4072 for (idx = 0; ; idx++) {
4073 ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,acnt);
4074 if (!ccnt) break;
4075 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
4076 if (!acnt) break;
4077 buf[0] = '\n'; ccnt = 1;
4078 bcnt += ccnt; acnt -= ccnt; buf += ccnt;
4079 }
4080 LOCK_GIVE(hdw->big_lock);
4081 return bcnt;
4082}
4083
4084
4085static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
4086{
4087 char buf[128];
4088 unsigned int idx,ccnt;
4089
4090 for (idx = 0; ; idx++) {
4091 ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
4092 if (!ccnt) break;
4093 printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
4094 }
4095}
4096
4097
4098/* Evaluate and update the driver's current state, taking various actions
4099 as appropriate for the update. */
4100static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw)
4101{
4102 unsigned int st;
4103 int state_updated = 0;
4104 int callback_flag = 0;
Mike Isely1b9c18c2008-04-22 14:45:41 -03004105 int analog_mode;
Mike Isely681c7392007-11-26 01:48:52 -03004106
4107 pvr2_trace(PVR2_TRACE_STBITS,
4108 "Drive state check START");
4109 if (pvrusb2_debug & PVR2_TRACE_STBITS) {
4110 pvr2_hdw_state_log_state(hdw);
4111 }
4112
4113 /* Process all state and get back over disposition */
4114 state_updated = pvr2_hdw_state_update(hdw);
4115
Mike Isely1b9c18c2008-04-22 14:45:41 -03004116 analog_mode = (hdw->pathway_state != PVR2_PATHWAY_DIGITAL);
4117
Mike Isely681c7392007-11-26 01:48:52 -03004118 /* Update master state based upon all other states. */
4119 if (!hdw->flag_ok) {
4120 st = PVR2_STATE_DEAD;
4121 } else if (hdw->fw1_state != FW1_STATE_OK) {
4122 st = PVR2_STATE_COLD;
Mike Isely72998b72008-04-03 04:51:19 -03004123 } else if ((analog_mode ||
4124 hdw->hdw_desc->flag_digital_requires_cx23416) &&
4125 !hdw->state_encoder_ok) {
Mike Isely681c7392007-11-26 01:48:52 -03004126 st = PVR2_STATE_WARM;
Mike Isely1b9c18c2008-04-22 14:45:41 -03004127 } else if (hdw->flag_tripped ||
4128 (analog_mode && hdw->flag_decoder_missed)) {
Mike Isely681c7392007-11-26 01:48:52 -03004129 st = PVR2_STATE_ERROR;
Mike Isely62433e32008-04-22 14:45:40 -03004130 } else if (hdw->state_usbstream_run &&
Mike Isely1b9c18c2008-04-22 14:45:41 -03004131 (!analog_mode ||
Mike Isely62433e32008-04-22 14:45:40 -03004132 (hdw->state_encoder_run && hdw->state_decoder_run))) {
Mike Isely681c7392007-11-26 01:48:52 -03004133 st = PVR2_STATE_RUN;
4134 } else {
4135 st = PVR2_STATE_READY;
4136 }
4137 if (hdw->master_state != st) {
4138 pvr2_trace(PVR2_TRACE_STATE,
4139 "Device state change from %s to %s",
4140 pvr2_get_state_name(hdw->master_state),
4141 pvr2_get_state_name(st));
Mike Isely40381cb2008-04-22 14:45:42 -03004142 pvr2_led_ctrl(hdw,st == PVR2_STATE_RUN);
Mike Isely681c7392007-11-26 01:48:52 -03004143 hdw->master_state = st;
4144 state_updated = !0;
4145 callback_flag = !0;
4146 }
4147 if (state_updated) {
4148 /* Trigger anyone waiting on any state changes here. */
4149 wake_up(&hdw->state_wait_data);
4150 }
4151
4152 if (pvrusb2_debug & PVR2_TRACE_STBITS) {
4153 pvr2_hdw_state_log_state(hdw);
4154 }
4155 pvr2_trace(PVR2_TRACE_STBITS,
4156 "Drive state check DONE callback=%d",callback_flag);
4157
4158 return callback_flag;
4159}
4160
4161
4162/* Cause kernel thread to check / update driver state */
4163static void pvr2_hdw_state_sched(struct pvr2_hdw *hdw)
4164{
4165 if (hdw->state_stale) return;
4166 hdw->state_stale = !0;
4167 trace_stbit("state_stale",hdw->state_stale);
4168 queue_work(hdw->workqueue,&hdw->workpoll);
4169}
4170
4171
Mike Iselyd8554972006-06-26 20:58:46 -03004172int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp)
4173{
4174 return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp);
4175}
4176
4177
4178int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp)
4179{
4180 return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp);
4181}
4182
4183
4184int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp)
4185{
4186 return pvr2_read_register(hdw,PVR2_GPIO_IN,dp);
4187}
4188
4189
4190int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val)
4191{
4192 u32 cval,nval;
4193 int ret;
4194 if (~msk) {
4195 ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval);
4196 if (ret) return ret;
4197 nval = (cval & ~msk) | (val & msk);
4198 pvr2_trace(PVR2_TRACE_GPIO,
4199 "GPIO direction changing 0x%x:0x%x"
4200 " from 0x%x to 0x%x",
4201 msk,val,cval,nval);
4202 } else {
4203 nval = val;
4204 pvr2_trace(PVR2_TRACE_GPIO,
4205 "GPIO direction changing to 0x%x",nval);
4206 }
4207 return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval);
4208}
4209
4210
4211int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
4212{
4213 u32 cval,nval;
4214 int ret;
4215 if (~msk) {
4216 ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval);
4217 if (ret) return ret;
4218 nval = (cval & ~msk) | (val & msk);
4219 pvr2_trace(PVR2_TRACE_GPIO,
4220 "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x",
4221 msk,val,cval,nval);
4222 } else {
4223 nval = val;
4224 pvr2_trace(PVR2_TRACE_GPIO,
4225 "GPIO output changing to 0x%x",nval);
4226 }
4227 return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval);
4228}
4229
4230
Mike Isely7fb20fa2008-04-22 14:45:37 -03004231unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
4232{
4233 return hdw->input_avail_mask;
4234}
4235
4236
Mike Isely1cb03b72008-04-21 03:47:43 -03004237unsigned int pvr2_hdw_get_input_allowed(struct pvr2_hdw *hdw)
4238{
4239 return hdw->input_allowed_mask;
4240}
4241
4242
4243static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v)
4244{
4245 if (hdw->input_val != v) {
4246 hdw->input_val = v;
4247 hdw->input_dirty = !0;
4248 }
4249
4250 /* Handle side effects - if we switch to a mode that needs the RF
4251 tuner, then select the right frequency choice as well and mark
4252 it dirty. */
4253 if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
4254 hdw->freqSelector = 0;
4255 hdw->freqDirty = !0;
4256 } else if ((hdw->input_val == PVR2_CVAL_INPUT_TV) ||
4257 (hdw->input_val == PVR2_CVAL_INPUT_DTV)) {
4258 hdw->freqSelector = 1;
4259 hdw->freqDirty = !0;
4260 }
4261 return 0;
4262}
4263
4264
4265int pvr2_hdw_set_input_allowed(struct pvr2_hdw *hdw,
4266 unsigned int change_mask,
4267 unsigned int change_val)
4268{
4269 int ret = 0;
4270 unsigned int nv,m,idx;
4271 LOCK_TAKE(hdw->big_lock);
4272 do {
4273 nv = hdw->input_allowed_mask & ~change_mask;
4274 nv |= (change_val & change_mask);
4275 nv &= hdw->input_avail_mask;
4276 if (!nv) {
4277 /* No legal modes left; return error instead. */
4278 ret = -EPERM;
4279 break;
4280 }
4281 hdw->input_allowed_mask = nv;
4282 if ((1 << hdw->input_val) & hdw->input_allowed_mask) {
4283 /* Current mode is still in the allowed mask, so
4284 we're done. */
4285 break;
4286 }
4287 /* Select and switch to a mode that is still in the allowed
4288 mask */
4289 if (!hdw->input_allowed_mask) {
4290 /* Nothing legal; give up */
4291 break;
4292 }
4293 m = hdw->input_allowed_mask;
4294 for (idx = 0; idx < (sizeof(m) << 3); idx++) {
4295 if (!((1 << idx) & m)) continue;
4296 pvr2_hdw_set_input(hdw,idx);
4297 break;
4298 }
4299 } while (0);
4300 LOCK_GIVE(hdw->big_lock);
4301 return ret;
4302}
4303
4304
Mike Iselye61b6fc2006-07-18 22:42:18 -03004305/* Find I2C address of eeprom */
Adrian Bunk07e337e2006-06-30 11:30:20 -03004306static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
Mike Iselyd8554972006-06-26 20:58:46 -03004307{
4308 int result;
4309 LOCK_TAKE(hdw->ctl_lock); do {
Michael Krufky8d364362007-01-22 02:17:55 -03004310 hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
Mike Iselyd8554972006-06-26 20:58:46 -03004311 result = pvr2_send_request(hdw,
4312 hdw->cmd_buffer,1,
4313 hdw->cmd_buffer,1);
4314 if (result < 0) break;
4315 result = hdw->cmd_buffer[0];
4316 } while(0); LOCK_GIVE(hdw->ctl_lock);
4317 return result;
4318}
4319
4320
Mike Isely32ffa9a2006-09-23 22:26:52 -03004321int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
Hans Verkuilf3d092b2007-02-23 20:55:14 -03004322 u32 match_type, u32 match_chip, u64 reg_id,
4323 int setFl,u64 *val_ptr)
Mike Isely32ffa9a2006-09-23 22:26:52 -03004324{
4325#ifdef CONFIG_VIDEO_ADV_DEBUG
Mike Isely32ffa9a2006-09-23 22:26:52 -03004326 struct pvr2_i2c_client *cp;
4327 struct v4l2_register req;
Mike Isely6d988162006-09-28 17:53:49 -03004328 int stat = 0;
4329 int okFl = 0;
Mike Isely32ffa9a2006-09-23 22:26:52 -03004330
Mike Isely201f5c92007-01-28 16:08:36 -03004331 if (!capable(CAP_SYS_ADMIN)) return -EPERM;
4332
Hans Verkuilf3d092b2007-02-23 20:55:14 -03004333 req.match_type = match_type;
4334 req.match_chip = match_chip;
Mike Isely32ffa9a2006-09-23 22:26:52 -03004335 req.reg = reg_id;
4336 if (setFl) req.val = *val_ptr;
4337 mutex_lock(&hdw->i2c_list_lock); do {
Trent Piephoe77e2c22007-10-10 05:37:42 -03004338 list_for_each_entry(cp, &hdw->i2c_clients, list) {
Mike Isely8481a752007-04-27 12:31:31 -03004339 if (!v4l2_chip_match_i2c_client(
4340 cp->client,
4341 req.match_type, req.match_chip)) {
Hans Verkuilf3d092b2007-02-23 20:55:14 -03004342 continue;
4343 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03004344 stat = pvr2_i2c_client_cmd(
Trent Piepho52ebc762007-01-23 22:38:13 -03004345 cp,(setFl ? VIDIOC_DBG_S_REGISTER :
4346 VIDIOC_DBG_G_REGISTER),&req);
Mike Isely32ffa9a2006-09-23 22:26:52 -03004347 if (!setFl) *val_ptr = req.val;
Mike Isely6d988162006-09-28 17:53:49 -03004348 okFl = !0;
4349 break;
Mike Isely32ffa9a2006-09-23 22:26:52 -03004350 }
4351 } while (0); mutex_unlock(&hdw->i2c_list_lock);
Mike Isely6d988162006-09-28 17:53:49 -03004352 if (okFl) {
4353 return stat;
4354 }
Mike Isely32ffa9a2006-09-23 22:26:52 -03004355 return -EINVAL;
4356#else
4357 return -ENOSYS;
4358#endif
4359}
4360
4361
Mike Iselyd8554972006-06-26 20:58:46 -03004362/*
4363 Stuff for Emacs to see, in order to encourage consistent editing style:
4364 *** Local Variables: ***
4365 *** mode: c ***
4366 *** fill-column: 75 ***
4367 *** tab-width: 8 ***
4368 *** c-basic-offset: 8 ***
4369 *** End: ***
4370 */