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