1 /*
2 *
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
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 */
17
18 #include <linux/device.h> // for linux/firmware.h
19 #include <linux/firmware.h>
20 #include "pvrusb2-util.h"
21 #include "pvrusb2-encoder.h"
22 #include "pvrusb2-hdw-internal.h"
23 #include "pvrusb2-debug.h"
24 #include "pvrusb2-fx2-cmd.h"
25
26
27
28 /* Firmware mailbox flags - definitions found from ivtv */
29 #define IVTV_MBOX_FIRMWARE_DONE 0x00000004
30 #define IVTV_MBOX_DRIVER_DONE 0x00000002
31 #define IVTV_MBOX_DRIVER_BUSY 0x00000001
32
33 #define MBOX_BASE 0x44
34
35
pvr2_encoder_write_words(struct pvr2_hdw * hdw,unsigned int offs,const u32 * data,unsigned int dlen)36 static int pvr2_encoder_write_words(struct pvr2_hdw *hdw,
37 unsigned int offs,
38 const u32 *data, unsigned int dlen)
39 {
40 unsigned int idx,addr;
41 unsigned int bAddr;
42 int ret;
43 unsigned int chunkCnt;
44
45 /*
46
47 Format: First byte must be 0x01. Remaining 32 bit words are
48 spread out into chunks of 7 bytes each, with the first 4 bytes
49 being the data word (little endian), and the next 3 bytes
50 being the address where that data word is to be written (big
51 endian). Repeat request for additional words, with offset
52 adjusted accordingly.
53
54 */
55 while (dlen) {
56 chunkCnt = 8;
57 if (chunkCnt > dlen) chunkCnt = dlen;
58 memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
59 bAddr = 0;
60 hdw->cmd_buffer[bAddr++] = FX2CMD_MEM_WRITE_DWORD;
61 for (idx = 0; idx < chunkCnt; idx++) {
62 addr = idx + offs;
63 hdw->cmd_buffer[bAddr+6] = (addr & 0xffu);
64 hdw->cmd_buffer[bAddr+5] = ((addr>>8) & 0xffu);
65 hdw->cmd_buffer[bAddr+4] = ((addr>>16) & 0xffu);
66 PVR2_DECOMPOSE_LE(hdw->cmd_buffer, bAddr,data[idx]);
67 bAddr += 7;
68 }
69 ret = pvr2_send_request(hdw,
70 hdw->cmd_buffer,1+(chunkCnt*7),
71 NULL,0);
72 if (ret) return ret;
73 data += chunkCnt;
74 dlen -= chunkCnt;
75 offs += chunkCnt;
76 }
77
78 return 0;
79 }
80
81
pvr2_encoder_read_words(struct pvr2_hdw * hdw,unsigned int offs,u32 * data,unsigned int dlen)82 static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,
83 unsigned int offs,
84 u32 *data, unsigned int dlen)
85 {
86 unsigned int idx;
87 int ret;
88 unsigned int chunkCnt;
89
90 /*
91
92 Format: First byte must be 0x02 (status check) or 0x28 (read
93 back block of 32 bit words). Next 6 bytes must be zero,
94 followed by a single byte of MBOX_BASE+offset for portion to
95 be read. Returned data is packed set of 32 bits words that
96 were read.
97
98 */
99
100 while (dlen) {
101 chunkCnt = 16;
102 if (chunkCnt > dlen) chunkCnt = dlen;
103 if (chunkCnt < 16) chunkCnt = 1;
104 hdw->cmd_buffer[0] =
105 ((chunkCnt == 1) ?
106 FX2CMD_MEM_READ_DWORD : FX2CMD_MEM_READ_64BYTES);
107 hdw->cmd_buffer[1] = 0;
108 hdw->cmd_buffer[2] = 0;
109 hdw->cmd_buffer[3] = 0;
110 hdw->cmd_buffer[4] = 0;
111 hdw->cmd_buffer[5] = ((offs>>16) & 0xffu);
112 hdw->cmd_buffer[6] = ((offs>>8) & 0xffu);
113 hdw->cmd_buffer[7] = (offs & 0xffu);
114 ret = pvr2_send_request(hdw,
115 hdw->cmd_buffer,8,
116 hdw->cmd_buffer,
117 (chunkCnt == 1 ? 4 : 16 * 4));
118 if (ret) return ret;
119
120 for (idx = 0; idx < chunkCnt; idx++) {
121 data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4);
122 }
123 data += chunkCnt;
124 dlen -= chunkCnt;
125 offs += chunkCnt;
126 }
127
128 return 0;
129 }
130
131
132 /* This prototype is set up to be compatible with the
133 cx2341x_mbox_func prototype in cx2341x.h, which should be in
134 kernels 2.6.18 or later. We do this so that we can enable
135 cx2341x.ko to write to our encoder (by handing it a pointer to this
136 function). For earlier kernels this doesn't really matter. */
pvr2_encoder_cmd(void * ctxt,u32 cmd,int arg_cnt_send,int arg_cnt_recv,u32 * argp)137 static int pvr2_encoder_cmd(void *ctxt,
138 u32 cmd,
139 int arg_cnt_send,
140 int arg_cnt_recv,
141 u32 *argp)
142 {
143 unsigned int poll_count;
144 unsigned int try_count = 0;
145 int retry_flag;
146 int ret = 0;
147 unsigned int idx;
148 /* These sizes look to be limited by the FX2 firmware implementation */
149 u32 wrData[16];
150 u32 rdData[16];
151 struct pvr2_hdw *hdw = (struct pvr2_hdw *)ctxt;
152
153
154 /*
155
156 The encoder seems to speak entirely using blocks 32 bit words.
157 In ivtv driver terms, this is a mailbox at MBOX_BASE which we
158 populate with data and watch what the hardware does with it.
159 The first word is a set of flags used to control the
160 transaction, the second word is the command to execute, the
161 third byte is zero (ivtv driver suggests that this is some
162 kind of return value), and the fourth byte is a specified
163 timeout (windows driver always uses 0x00060000 except for one
164 case when it is zero). All successive words are the argument
165 words for the command.
166
167 First, write out the entire set of words, with the first word
168 being zero.
169
170 Next, write out just the first word again, but set it to
171 IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which
172 probably means "go").
173
174 Next, read back the return count words. Check the first word,
175 which should have IVTV_MBOX_FIRMWARE_DONE set. If however
176 that bit is not set, then the command isn't done so repeat the
177 read until it is set.
178
179 Finally, write out just the first word again, but set it to
180 0x0 this time (which probably means "idle").
181
182 */
183
184 if (arg_cnt_send > (ARRAY_SIZE(wrData) - 4)) {
185 pvr2_trace(
186 PVR2_TRACE_ERROR_LEGS,
187 "Failed to write cx23416 command - too many input arguments (was given %u limit %lu)",
188 arg_cnt_send, (long unsigned) ARRAY_SIZE(wrData) - 4);
189 return -EINVAL;
190 }
191
192 if (arg_cnt_recv > (ARRAY_SIZE(rdData) - 4)) {
193 pvr2_trace(
194 PVR2_TRACE_ERROR_LEGS,
195 "Failed to write cx23416 command - too many return arguments (was given %u limit %lu)",
196 arg_cnt_recv, (long unsigned) ARRAY_SIZE(rdData) - 4);
197 return -EINVAL;
198 }
199
200
201 LOCK_TAKE(hdw->ctl_lock); while (1) {
202
203 if (!hdw->state_encoder_ok) {
204 ret = -EIO;
205 break;
206 }
207
208 retry_flag = 0;
209 try_count++;
210 ret = 0;
211 wrData[0] = 0;
212 wrData[1] = cmd;
213 wrData[2] = 0;
214 wrData[3] = 0x00060000;
215 for (idx = 0; idx < arg_cnt_send; idx++) {
216 wrData[idx+4] = argp[idx];
217 }
218 for (; idx < ARRAY_SIZE(wrData) - 4; idx++) {
219 wrData[idx+4] = 0;
220 }
221
222 ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,idx);
223 if (ret) break;
224 wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY;
225 ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1);
226 if (ret) break;
227 poll_count = 0;
228 while (1) {
229 poll_count++;
230 ret = pvr2_encoder_read_words(hdw,MBOX_BASE,rdData,
231 arg_cnt_recv+4);
232 if (ret) {
233 break;
234 }
235 if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) {
236 break;
237 }
238 if (rdData[0] && (poll_count < 1000)) continue;
239 if (!rdData[0]) {
240 retry_flag = !0;
241 pvr2_trace(
242 PVR2_TRACE_ERROR_LEGS,
243 "Encoder timed out waiting for us; arranging to retry");
244 } else {
245 pvr2_trace(
246 PVR2_TRACE_ERROR_LEGS,
247 "***WARNING*** device's encoder appears to be stuck (status=0x%08x)",
248 rdData[0]);
249 }
250 pvr2_trace(
251 PVR2_TRACE_ERROR_LEGS,
252 "Encoder command: 0x%02x",cmd);
253 for (idx = 4; idx < arg_cnt_send; idx++) {
254 pvr2_trace(
255 PVR2_TRACE_ERROR_LEGS,
256 "Encoder arg%d: 0x%08x",
257 idx-3,wrData[idx]);
258 }
259 ret = -EBUSY;
260 break;
261 }
262 if (retry_flag) {
263 if (try_count < 20) continue;
264 pvr2_trace(
265 PVR2_TRACE_ERROR_LEGS,
266 "Too many retries...");
267 ret = -EBUSY;
268 }
269 if (ret) {
270 del_timer_sync(&hdw->encoder_run_timer);
271 hdw->state_encoder_ok = 0;
272 pvr2_trace(PVR2_TRACE_STBITS,
273 "State bit %s <-- %s",
274 "state_encoder_ok",
275 (hdw->state_encoder_ok ? "true" : "false"));
276 if (hdw->state_encoder_runok) {
277 hdw->state_encoder_runok = 0;
278 pvr2_trace(PVR2_TRACE_STBITS,
279 "State bit %s <-- %s",
280 "state_encoder_runok",
281 (hdw->state_encoder_runok ?
282 "true" : "false"));
283 }
284 pvr2_trace(
285 PVR2_TRACE_ERROR_LEGS,
286 "Giving up on command. This is normally recovered via a firmware reload and re-initialization; concern is only warranted if this happens repeatedly and rapidly.");
287 break;
288 }
289 wrData[0] = 0x7;
290 for (idx = 0; idx < arg_cnt_recv; idx++) {
291 argp[idx] = rdData[idx+4];
292 }
293
294 wrData[0] = 0x0;
295 ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1);
296 break;
297
298 }; LOCK_GIVE(hdw->ctl_lock);
299
300 return ret;
301 }
302
303
pvr2_encoder_vcmd(struct pvr2_hdw * hdw,int cmd,int args,...)304 static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd,
305 int args, ...)
306 {
307 va_list vl;
308 unsigned int idx;
309 u32 data[12];
310
311 if (args > ARRAY_SIZE(data)) {
312 pvr2_trace(
313 PVR2_TRACE_ERROR_LEGS,
314 "Failed to write cx23416 command - too many arguments (was given %u limit %lu)",
315 args, (long unsigned) ARRAY_SIZE(data));
316 return -EINVAL;
317 }
318
319 va_start(vl, args);
320 for (idx = 0; idx < args; idx++) {
321 data[idx] = va_arg(vl, u32);
322 }
323 va_end(vl);
324
325 return pvr2_encoder_cmd(hdw,cmd,args,0,data);
326 }
327
328
329 /* This implements some extra setup for the encoder that seems to be
330 specific to the PVR USB2 hardware. */
pvr2_encoder_prep_config(struct pvr2_hdw * hdw)331 static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
332 {
333 int ret = 0;
334 int encMisc3Arg = 0;
335
336 #if 0
337 /* This inexplicable bit happens in the Hauppauge windows
338 driver (for both 24xxx and 29xxx devices). However I
339 currently see no difference in behavior with or without
340 this stuff. Leave this here as a note of its existence,
341 but don't use it. */
342 LOCK_TAKE(hdw->ctl_lock); do {
343 u32 dat[1];
344 dat[0] = 0x80000640;
345 pvr2_encoder_write_words(hdw,0x01fe,dat,1);
346 pvr2_encoder_write_words(hdw,0x023e,dat,1);
347 } while(0); LOCK_GIVE(hdw->ctl_lock);
348 #endif
349
350 /* Mike Isely <isely@pobox.com> 26-Jan-2006 The windows driver
351 sends the following list of ENC_MISC commands (for both
352 24xxx and 29xxx devices). Meanings are not entirely clear,
353 however without the ENC_MISC(3,1) command then we risk
354 random perpetual video corruption whenever the video input
355 breaks up for a moment (like when switching channels). */
356
357
358 #if 0
359 /* This ENC_MISC(5,0) command seems to hurt 29xxx sync
360 performance on channel changes, but is not a problem on
361 24xxx devices. */
362 ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0);
363 #endif
364
365 /* This ENC_MISC(3,encMisc3Arg) command is critical - without
366 it there will eventually be video corruption. Also, the
367 saa7115 case is strange - the Windows driver is passing 1
368 regardless of device type but if we have 1 for saa7115
369 devices the video turns sluggish. */
370 if (hdw->hdw_desc->flag_has_cx25840) {
371 encMisc3Arg = 1;
372 } else {
373 encMisc3Arg = 0;
374 }
375 ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3,
376 encMisc3Arg,0,0);
377
378 ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0);
379
380 #if 0
381 /* This ENC_MISC(4,1) command is poisonous, so it is commented
382 out. But I'm leaving it here anyway to document its
383 existence in the Windows driver. The effect of this
384 command is that apps displaying the stream become sluggish
385 with stuttering video. */
386 ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0);
387 #endif
388
389 ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0);
390 ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0);
391
392 /* prevent the PTSs from slowly drifting away in the generated
393 MPEG stream */
394 ret |= pvr2_encoder_vcmd(hdw, CX2341X_ENC_MISC, 2, 4, 1);
395
396 return ret;
397 }
398
pvr2_encoder_adjust(struct pvr2_hdw * hdw)399 int pvr2_encoder_adjust(struct pvr2_hdw *hdw)
400 {
401 int ret;
402 ret = cx2341x_update(hdw,pvr2_encoder_cmd,
403 (hdw->enc_cur_valid ? &hdw->enc_cur_state : NULL),
404 &hdw->enc_ctl_state);
405 if (ret) {
406 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
407 "Error from cx2341x module code=%d",ret);
408 } else {
409 hdw->enc_cur_state = hdw->enc_ctl_state;
410 hdw->enc_cur_valid = !0;
411 }
412 return ret;
413 }
414
415
pvr2_encoder_configure(struct pvr2_hdw * hdw)416 int pvr2_encoder_configure(struct pvr2_hdw *hdw)
417 {
418 int ret;
419 int val;
420 pvr2_trace(PVR2_TRACE_ENCODER, "pvr2_encoder_configure (cx2341x module)");
421 hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING;
422 hdw->enc_ctl_state.width = hdw->res_hor_val;
423 hdw->enc_ctl_state.height = hdw->res_ver_val;
424 hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ?
425 0 : 1);
426
427 ret = 0;
428
429 ret |= pvr2_encoder_prep_config(hdw);
430
431 /* saa7115: 0xf0 */
432 val = 0xf0;
433 if (hdw->hdw_desc->flag_has_cx25840) {
434 /* ivtv cx25840: 0x140 */
435 val = 0x140;
436 }
437
438 if (!ret) ret = pvr2_encoder_vcmd(
439 hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
440 val, val);
441
442 /* setup firmware to notify us about some events (don't know why...) */
443 if (!ret) ret = pvr2_encoder_vcmd(
444 hdw,CX2341X_ENC_SET_EVENT_NOTIFICATION, 4,
445 0, 0, 0x10000000, 0xffffffff);
446
447 if (!ret) ret = pvr2_encoder_vcmd(
448 hdw,CX2341X_ENC_SET_VBI_LINE, 5,
449 0xffffffff,0,0,0,0);
450
451 if (ret) {
452 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
453 "Failed to configure cx23416");
454 return ret;
455 }
456
457 ret = pvr2_encoder_adjust(hdw);
458 if (ret) return ret;
459
460 ret = pvr2_encoder_vcmd(
461 hdw, CX2341X_ENC_INITIALIZE_INPUT, 0);
462
463 if (ret) {
464 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
465 "Failed to initialize cx23416 video input");
466 return ret;
467 }
468
469 return 0;
470 }
471
472
pvr2_encoder_start(struct pvr2_hdw * hdw)473 int pvr2_encoder_start(struct pvr2_hdw *hdw)
474 {
475 int status;
476
477 /* unmask some interrupts */
478 pvr2_write_register(hdw, 0x0048, 0xbfffffff);
479
480 pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1,
481 hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0);
482
483 switch (hdw->active_stream_type) {
484 case pvr2_config_vbi:
485 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
486 0x01,0x14);
487 break;
488 case pvr2_config_mpeg:
489 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
490 0,0x13);
491 break;
492 default: /* Unhandled cases for now */
493 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
494 0,0x13);
495 break;
496 }
497 return status;
498 }
499
pvr2_encoder_stop(struct pvr2_hdw * hdw)500 int pvr2_encoder_stop(struct pvr2_hdw *hdw)
501 {
502 int status;
503
504 /* mask all interrupts */
505 pvr2_write_register(hdw, 0x0048, 0xffffffff);
506
507 switch (hdw->active_stream_type) {
508 case pvr2_config_vbi:
509 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
510 0x01,0x01,0x14);
511 break;
512 case pvr2_config_mpeg:
513 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
514 0x01,0,0x13);
515 break;
516 default: /* Unhandled cases for now */
517 status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
518 0x01,0,0x13);
519 break;
520 }
521
522 return status;
523 }
524