V4L/DVB (4228a): pvrusb2 to kernel 2.6.18
[powerpc.git] / drivers / media / video / pvrusb2 / pvrusb2-encoder.c
1 /*
2  *
3  *  $Id$
4  *
5  *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
6  *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22
23 #include <linux/device.h>   // for linux/firmware.h
24 #include <linux/firmware.h>
25 #include <linux/videodev2.h>
26 #include <media/cx2341x.h>
27 #include "pvrusb2-util.h"
28 #include "pvrusb2-encoder.h"
29 #include "pvrusb2-hdw-internal.h"
30 #include "pvrusb2-debug.h"
31
32 static u32 pvr_tbl_emphasis [] = {
33         [PVR2_CVAL_AUDIOEMPHASIS_NONE] = 0x0 << 12,
34         [PVR2_CVAL_AUDIOEMPHASIS_50_15] = 0x1 << 12,
35         [PVR2_CVAL_AUDIOEMPHASIS_CCITT] = 0x3 << 12,
36 };
37
38 static u32 pvr_tbl_srate[] = {
39         [PVR2_CVAL_SRATE_48] =  0x01,
40         [PVR2_CVAL_SRATE_44_1] = 0x00,
41 };
42
43 static u32 pvr_tbl_audiobitrate[] = {
44         [PVR2_CVAL_AUDIOBITRATE_384] = 0xe << 4,
45         [PVR2_CVAL_AUDIOBITRATE_320] = 0xd << 4,
46         [PVR2_CVAL_AUDIOBITRATE_256] = 0xc << 4,
47         [PVR2_CVAL_AUDIOBITRATE_224] = 0xb << 4,
48         [PVR2_CVAL_AUDIOBITRATE_192] = 0xa << 4,
49         [PVR2_CVAL_AUDIOBITRATE_160] = 0x9 << 4,
50         [PVR2_CVAL_AUDIOBITRATE_128] = 0x8 << 4,
51         [PVR2_CVAL_AUDIOBITRATE_112] = 0x7 << 4,
52         [PVR2_CVAL_AUDIOBITRATE_96]  = 0x6 << 4,
53         [PVR2_CVAL_AUDIOBITRATE_80]  = 0x5 << 4,
54         [PVR2_CVAL_AUDIOBITRATE_64]  = 0x4 << 4,
55         [PVR2_CVAL_AUDIOBITRATE_56]  = 0x3 << 4,
56         [PVR2_CVAL_AUDIOBITRATE_48]  = 0x2 << 4,
57         [PVR2_CVAL_AUDIOBITRATE_32]  = 0x1 << 4,
58         [PVR2_CVAL_AUDIOBITRATE_VBR] = 0x0 << 4,
59 };
60
61
62 /* Firmware mailbox flags - definitions found from ivtv */
63 #define IVTV_MBOX_FIRMWARE_DONE 0x00000004
64 #define IVTV_MBOX_DRIVER_DONE 0x00000002
65 #define IVTV_MBOX_DRIVER_BUSY 0x00000001
66
67
68 static int pvr2_write_encoder_words(struct pvr2_hdw *hdw,
69                                     const u32 *data, unsigned int dlen)
70 {
71         unsigned int idx;
72         int ret;
73         unsigned int offs = 0;
74         unsigned int chunkCnt;
75
76         /*
77
78         Format: First byte must be 0x01.  Remaining 32 bit words are
79         spread out into chunks of 7 bytes each, little-endian ordered,
80         offset at zero within each 2 blank bytes following and a
81         single byte that is 0x44 plus the offset of the word.  Repeat
82         request for additional words, with offset adjusted
83         accordingly.
84
85         */
86         while (dlen) {
87                 chunkCnt = 8;
88                 if (chunkCnt > dlen) chunkCnt = dlen;
89                 memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
90                 hdw->cmd_buffer[0] = 0x01;
91                 for (idx = 0; idx < chunkCnt; idx++) {
92                         hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs;
93                         PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7),
94                                           data[idx]);
95                 }
96                 ret = pvr2_send_request(hdw,
97                                         hdw->cmd_buffer,1+(chunkCnt*7),
98                                         0,0);
99                 if (ret) return ret;
100                 data += chunkCnt;
101                 dlen -= chunkCnt;
102                 offs += chunkCnt;
103         }
104
105         return 0;
106 }
107
108
109 static int pvr2_read_encoder_words(struct pvr2_hdw *hdw,int statusFl,
110                                    u32 *data, unsigned int dlen)
111 {
112         unsigned int idx;
113         int ret;
114         unsigned int offs = 0;
115         unsigned int chunkCnt;
116
117         /*
118
119         Format: First byte must be 0x02 (status check) or 0x28 (read
120         back block of 32 bit words).  Next 6 bytes must be zero,
121         followed by a single byte of 0x44+offset for portion to be
122         read.  Returned data is packed set of 32 bits words that were
123         read.
124
125         */
126
127         while (dlen) {
128                 chunkCnt = 16;
129                 if (chunkCnt > dlen) chunkCnt = dlen;
130                 memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer));
131                 hdw->cmd_buffer[0] = statusFl ? 0x02 : 0x28;
132                 hdw->cmd_buffer[7] = 0x44 + offs;
133                 ret = pvr2_send_request(hdw,
134                                         hdw->cmd_buffer,8,
135                                         hdw->cmd_buffer,chunkCnt * 4);
136                 if (ret) return ret;
137
138                 for (idx = 0; idx < chunkCnt; idx++) {
139                         data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4);
140                 }
141                 data += chunkCnt;
142                 dlen -= chunkCnt;
143                 offs += chunkCnt;
144         }
145
146         return 0;
147 }
148
149
150 static int pvr2_write_encoder_vcmd (struct pvr2_hdw *hdw, u8 cmd,
151                                     int args, ...)
152 {
153         unsigned int poll_count;
154         int ret = 0;
155         va_list vl;
156         unsigned int idx;
157         u32 wrData[16];
158         u32 rdData[32];
159
160         /*
161
162         The encoder seems to speak entirely using blocks 32 bit words.
163         In ivtv driver terms, this is a mailbox which we populate with
164         data and watch what the hardware does with it.  The first word
165         is a set of flags used to control the transaction, the second
166         word is the command to execute, the third byte is zero (ivtv
167         driver suggests that this is some kind of return value), and
168         the fourth byte is a specified timeout (windows driver always
169         uses 0x00060000 except for one case when it is zero).  All
170         successive words are the argument words for the command.
171
172         First, write out the entire set of words, with the first word
173         being zero.
174
175         Next, write out just the first word again, but set it to
176         IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which
177         probably means "go").
178
179         Next, read back 16 words as status.  Check the first word,
180         which should have IVTV_MBOX_FIRMWARE_DONE set.  If however
181         that bit is not set, then the command isn't done so repeat the
182         read.
183
184         Next, read back 32 words and compare with the original
185         arugments.  Hopefully they will match.
186
187         Finally, write out just the first word again, but set it to
188         0x0 this time (which probably means "idle").
189
190         */
191
192
193         LOCK_TAKE(hdw->ctl_lock); do {
194
195                 wrData[0] = 0;
196                 wrData[1] = cmd;
197                 wrData[2] = 0;
198                 wrData[3] = 0x00060000;
199                 va_start(vl, args);
200                 for (idx = 0; idx < args; idx++) {
201                         wrData[idx+4] = va_arg(vl, u32);
202                 }
203                 va_end(vl);
204                 args += 4;
205                 while (args < sizeof(wrData)/sizeof(wrData[0])) {
206                         wrData[args++] = 0;
207                 }
208
209                 ret = pvr2_write_encoder_words(hdw,wrData,args);
210                 if (ret) break;
211                 wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY;
212                 ret = pvr2_write_encoder_words(hdw,wrData,1);
213                 if (ret) break;
214                 poll_count = 0;
215                 while (1) {
216                         if (poll_count < 10000000) poll_count++;
217                         ret = pvr2_read_encoder_words(hdw,!0,rdData,1);
218                         if (ret) break;
219                         if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) {
220                                 break;
221                         }
222                         if (poll_count == 100) {
223                                 pvr2_trace(
224                                         PVR2_TRACE_ERROR_LEGS,
225                                         "***WARNING*** device's encoder"
226                                         " appears to be stuck"
227                                         " (status=0%08x)",rdData[0]);
228                                 pvr2_trace(
229                                         PVR2_TRACE_ERROR_LEGS,
230                                         "Encoder command: 0x%02x",cmd);
231                                 for (idx = 4; idx < args; idx++) {
232                                         pvr2_trace(
233                                                 PVR2_TRACE_ERROR_LEGS,
234                                                 "Encoder arg%d: 0x%08x",
235                                                 idx-3,wrData[idx]);
236                                 }
237                                 pvr2_trace(
238                                         PVR2_TRACE_ERROR_LEGS,
239                                         "Giving up waiting."
240                                         "  It is likely that"
241                                         " this is a bad idea...");
242                                 ret = -EBUSY;
243                                 break;
244                         }
245                 }
246                 if (ret) break;
247                 wrData[0] = 0x7;
248                 ret = pvr2_read_encoder_words(hdw,0,rdData,16);
249                 if (ret) break;
250                 for (idx = 0; idx < args; idx++) {
251                         if (rdData[idx] != wrData[idx]) {
252                                 pvr2_trace(
253                                         PVR2_TRACE_DEBUG,
254                                         "pvr2_encoder idx %02x mismatch exp:"
255                                         " %08x got: %08x",
256                                         idx,wrData[idx],rdData[idx]);
257                         }
258                 }
259
260                 wrData[0] = 0x0;
261                 ret = pvr2_write_encoder_words(hdw,wrData,1);
262                 if (ret) break;
263
264         } while(0); LOCK_GIVE(hdw->ctl_lock);
265
266         return ret;
267 }
268
269 int pvr2_encoder_configure(struct pvr2_hdw *hdw)
270 {
271         int ret = 0, audio, i;
272         v4l2_std_id vd_std = hdw->std_mask_cur;
273         int height = hdw->res_ver_val;
274         int width = hdw->res_hor_val;
275         int height_full = !hdw->interlace_val;
276
277         int is_30fps, is_ntsc;
278
279         if (vd_std & V4L2_STD_NTSC) {
280                 is_ntsc=1;
281                 is_30fps=1;
282         } else if (vd_std & V4L2_STD_PAL_M) {
283                 is_ntsc=0;
284                 is_30fps=1;
285         } else {
286                 is_ntsc=0;
287                 is_30fps=0;
288         }
289
290         pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure");
291
292         /* set stream output port.  Some notes here: The ivtv-derived
293            encoder documentation says that this command only gets a
294            single argument.  However the Windows driver for the model
295            29xxx series hardware has been sending 0x01 as a second
296            argument, while the Windows driver for the model 24xxx
297            series hardware has been sending 0x02 as a second argument.
298            Confusing matters further are the observations that 0x01
299            for that second argument simply won't work on the 24xxx
300            hardware, while 0x02 will work on the 29xxx - except that
301            when we use 0x02 then xawtv breaks due to a loss of
302            synchronization with the mpeg packet headers.  While xawtv
303            should be fixed to let it resync better (I did try to
304            contact Gerd about this but he has not answered), it has
305            also been determined that sending 0x00 as this mystery
306            second argument seems to work on both hardware models AND
307            xawtv works again.  So we're going to send 0x00. */
308         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_OUTPUT_PORT, 2,
309                                        0x01, 0x00);
310
311         /* set the Program Index Information. We want I,P,B frames (max 400) */
312         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_PGM_INDEX_INFO, 2,
313                                        0x07, 0x0190);
314
315         /* NOTE : windows driver sends these */
316         /* Mike Isely <isely@pobox.com> 7-Mar-2006 The windows driver
317            sends the following commands but if we do the same then
318            many apps are no longer able to read the video stream.
319            Leaving these out seems to do no harm at all, so they're
320            commented out for that reason. */
321 #ifdef notdef
322         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0);
323         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3,1,0,0);
324         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0);
325         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0);
326         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0);
327         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0);
328 #endif
329
330         /* Strange compared to ivtv data. */
331         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
332                                        0xf0, 0xf0);
333
334         /* setup firmware to notify us about some events (don't know why...) */
335         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4,
336                                        0, 0, 0x10000000, 0xffffffff);
337
338         /* set fps to 25 or 30 (1 or 0)*/
339         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_FRAME_RATE, 1,
340                                        is_30fps ? 0 : 1);
341
342         /* set encoding resolution */
343         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_FRAME_SIZE, 2,
344                                        (height_full ? height : (height / 2)),
345                                        width);
346         /* set encoding aspect ratio to 4:3 */
347         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_ASPECT_RATIO, 1,
348                                        0x02);
349
350         /* VBI */
351
352         if (hdw->config == pvr2_config_vbi) {
353                 int lines = 2 * (is_30fps ? 12 : 18);
354                 int size = (4*((lines*1443+3)/4)) / lines;
355                 ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_VBI_CONFIG, 7,
356                                                0xbd05, 1, 4,
357                                                0x25256262, 0x387f7f7f,
358                                                lines , size);
359 //                                     0x25256262, 0x13135454, lines , size);
360                 /* select vbi lines */
361 #define line_used(l)  (is_30fps ? (l >= 10 && l <= 21) : (l >= 6 && l <= 23))
362                 for (i = 2 ; i <= 24 ; i++){
363                         ret |= pvr2_write_encoder_vcmd(
364                                 hdw,CX2341X_ENC_SET_VBI_LINE, 5,
365                                 i-1,line_used(i), 0, 0, 0);
366                         ret |= pvr2_write_encoder_vcmd(
367                                 hdw,CX2341X_ENC_SET_VBI_LINE, 5,
368                                 (i-1) | (1 << 31),
369                                 line_used(i), 0, 0, 0);
370                 }
371         } else {
372                 ret |= pvr2_write_encoder_vcmd(
373                         hdw,CX2341X_ENC_SET_VBI_LINE, 5,
374                         0xffffffff,0,0,0,0);
375         }
376
377         /* set stream type, depending on resolution. */
378         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_STREAM_TYPE, 1,
379                                        height_full ? 0x0a : 0x0b);
380         /* set video bitrate */
381         ret |= pvr2_write_encoder_vcmd(
382                 hdw, CX2341X_ENC_SET_BIT_RATE, 3,
383                 (hdw->vbr_val ? 1 : 0),
384                 hdw->videobitrate_val,
385                 hdw->videopeak_val / 400);
386         /* setup GOP structure (GOP size = 0f or 0c, 3-1 = 2 B-frames) */
387         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
388                                        is_30fps ?  0x0f : 0x0c, 0x03);
389
390         /* enable 3:2 pulldown */
391         ret |= pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_SET_3_2_PULLDOWN,1,0);
392
393         /* set GOP open/close property (open) */
394         ret |= pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_SET_GOP_CLOSURE,1,0);
395
396         /* set audio stream properties 0x40b9? 0100 0000 1011 1001 */
397         audio = (pvr_tbl_audiobitrate[hdw->audiobitrate_val] |
398                  pvr_tbl_srate[hdw->srate_val] |
399                  hdw->audiolayer_val << 2 |
400                  (hdw->audiocrc_val ? 1 << 14 : 0) |
401                  pvr_tbl_emphasis[hdw->audioemphasis_val]);
402
403         ret |= pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_SET_AUDIO_PROPERTIES,1,
404                                        audio);
405
406         /* set dynamic noise reduction filter to manual, Horiz/Vert */
407         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
408                                        0, 0x03);
409
410         /* dynamic noise reduction filter param */
411         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2
412                                        , 0, 0);
413
414         /* dynamic noise reduction median filter */
415         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_CORING_LEVELS, 4,
416                                        0, 0xff, 0, 0xff);
417
418         /* spacial prefiler parameter */
419         ret |= pvr2_write_encoder_vcmd(hdw,
420                                        CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
421                                        0x01, 0x01);
422
423         /* initialize video input */
424         ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_INITIALIZE_INPUT, 0);
425
426         if (!ret) {
427                 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG);
428         }
429
430         return ret;
431 }
432
433 int pvr2_encoder_start(struct pvr2_hdw *hdw)
434 {
435         int status;
436
437         /* unmask some interrupts */
438         pvr2_write_register(hdw, 0x0048, 0xbfffffff);
439
440         /* change some GPIO data */
441         pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000481);
442         pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000);
443
444         if (hdw->config == pvr2_config_vbi) {
445                 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
446                                                  0x01,0x14);
447         } else if (hdw->config == pvr2_config_mpeg) {
448                 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
449                                                  0,0x13);
450         } else {
451                 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2,
452                                                  0,0x13);
453         }
454         if (!status) {
455                 hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN);
456         }
457         return status;
458 }
459
460 int pvr2_encoder_stop(struct pvr2_hdw *hdw)
461 {
462         int status;
463
464         /* mask all interrupts */
465         pvr2_write_register(hdw, 0x0048, 0xffffffff);
466
467         if (hdw->config == pvr2_config_vbi) {
468                 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
469                                                  0x01,0x01,0x14);
470         } else if (hdw->config == pvr2_config_mpeg) {
471                 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
472                                                  0x01,0,0x13);
473         } else {
474                 status = pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3,
475                                                  0x01,0,0x13);
476         }
477
478         /* change some GPIO data */
479         /* Note: Bit d7 of dir appears to control the LED.  So we shut it
480            off here. */
481         pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401);
482         pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000);
483
484         if (!status) {
485                 hdw->subsys_enabled_mask &= ~(1<<PVR2_SUBSYS_B_ENC_RUN);
486         }
487         return status;
488 }
489
490
491 /*
492   Stuff for Emacs to see, in order to encourage consistent editing style:
493   *** Local Variables: ***
494   *** mode: c ***
495   *** fill-column: 70 ***
496   *** tab-width: 8 ***
497   *** c-basic-offset: 8 ***
498   *** End: ***
499   */