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 
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 
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. */
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 
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. */
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 
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 
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 
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 
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