Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cx88-blackbird.c
Go to the documentation of this file.
1 /*
2  *
3  * Support for a cx23416 mpeg encoder via cx2388x host port.
4  * "blackbird" reference design.
5  *
6  * (c) 2004 Jelle Foks <[email protected]>
7  * (c) 2004 Gerd Knorr <[email protected]>
8  *
9  * (c) 2005-2006 Mauro Carvalho Chehab <[email protected]>
10  * - video_ioctl2 conversion
11  *
12  * Includes parts from the ivtv driver <http://sourceforge.net/projects/ivtv/>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28 
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/fs.h>
33 #include <linux/delay.h>
34 #include <linux/device.h>
35 #include <linux/firmware.h>
36 #include <media/v4l2-common.h>
37 #include <media/v4l2-ioctl.h>
38 #include <media/v4l2-event.h>
39 #include <media/cx2341x.h>
40 
41 #include "cx88.h"
42 
43 MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
44 MODULE_AUTHOR("Jelle Foks <[email protected]>, Gerd Knorr <[email protected]> [SuSE Labs]");
45 MODULE_LICENSE("GPL");
47 
48 static unsigned int mpegbufs = 32;
49 module_param(mpegbufs,int,0644);
50 MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
51 
52 static unsigned int debug;
53 module_param(debug,int,0644);
54 MODULE_PARM_DESC(debug,"enable debug messages [blackbird]");
55 
56 #define dprintk(level,fmt, arg...) if (debug >= level) \
57  printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg)
58 
59 
60 /* ------------------------------------------------------------------ */
61 
62 #define BLACKBIRD_FIRM_IMAGE_SIZE 376836
63 
64 /* defines below are from ivtv-driver.h */
65 
66 #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
67 
68 /* Firmware API commands */
69 #define IVTV_API_STD_TIMEOUT 500
70 
75 };
83 };
85  BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */
86  BLACKBIRD_END_NOW, /* stop immediately, no irq */
87 };
89  BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */
90  BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */
91 };
96 };
100 };
106 };
110 };
117 };
121 };
126 };
130 };
134 };
137 };
141 };
144 };
146  BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */
147  BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */
148  BLACKBIRD_FIELD1_MICRONAS = 0x0105, /* 261 */
149 };
151  BLACKBIRD_FIELD2_SAA7114 = 0x00EF, /* 239 */
152  BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */
153  BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */
154 };
158 };
162 };
167 };
172 };
173 
174 /* Registers */
175 #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
176 #define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC /*| IVTV_REG_OFFSET*/)
177 #define IVTV_REG_SPU (0x9050 /*| IVTV_REG_OFFSET*/)
178 #define IVTV_REG_HW_BLOCKS (0x9054 /*| IVTV_REG_OFFSET*/)
179 #define IVTV_REG_VPU (0x9058 /*| IVTV_REG_OFFSET*/)
180 #define IVTV_REG_APU (0xA064 /*| IVTV_REG_OFFSET*/)
181 
182 /* ------------------------------------------------------------------ */
183 
184 static void host_setup(struct cx88_core *core)
185 {
186  /* toggle reset of the host */
188  udelay(100);
190  udelay(100);
191 
192  /* host port setup */
193  cx_write(MO_GPHST_WSC, 0x44444444U);
195  cx_write(MO_GPHST_WDTH, 15);
197  cx_write(MO_GPHST_MUX16, 0x44448888U);
199 }
200 
201 /* ------------------------------------------------------------------ */
202 
203 #define P1_MDATA0 0x390000
204 #define P1_MDATA1 0x390001
205 #define P1_MDATA2 0x390002
206 #define P1_MDATA3 0x390003
207 #define P1_MADDR2 0x390004
208 #define P1_MADDR1 0x390005
209 #define P1_MADDR0 0x390006
210 #define P1_RDATA0 0x390008
211 #define P1_RDATA1 0x390009
212 #define P1_RDATA2 0x39000A
213 #define P1_RDATA3 0x39000B
214 #define P1_RADDR0 0x39000C
215 #define P1_RADDR1 0x39000D
216 #define P1_RRDWR 0x39000E
217 
218 static int wait_ready_gpio0_bit1(struct cx88_core *core, u32 state)
219 {
220  unsigned long timeout = jiffies + msecs_to_jiffies(1);
221  u32 gpio0,need;
222 
223  need = state ? 2 : 0;
224  for (;;) {
225  gpio0 = cx_read(MO_GP0_IO) & 2;
226  if (need == gpio0)
227  return 0;
228  if (time_after(jiffies,timeout))
229  return -1;
230  udelay(1);
231  }
232 }
233 
234 static int memory_write(struct cx88_core *core, u32 address, u32 value)
235 {
236  /* Warning: address is dword address (4 bytes) */
237  cx_writeb(P1_MDATA0, (unsigned int)value);
238  cx_writeb(P1_MDATA1, (unsigned int)(value >> 8));
239  cx_writeb(P1_MDATA2, (unsigned int)(value >> 16));
240  cx_writeb(P1_MDATA3, (unsigned int)(value >> 24));
241  cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) | 0x40);
242  cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
243  cx_writeb(P1_MADDR0, (unsigned int)address);
246 
247  return wait_ready_gpio0_bit1(core,1);
248 }
249 
250 static int memory_read(struct cx88_core *core, u32 address, u32 *value)
251 {
252  int retval;
253  u32 val;
254 
255  /* Warning: address is dword address (4 bytes) */
256  cx_writeb(P1_MADDR2, (unsigned int)(address >> 16) & ~0xC0);
257  cx_writeb(P1_MADDR1, (unsigned int)(address >> 8));
258  cx_writeb(P1_MADDR0, (unsigned int)address);
260 
261  retval = wait_ready_gpio0_bit1(core,1);
262 
263  cx_writeb(P1_MDATA3, 0);
264  val = (unsigned char)cx_read(P1_MDATA3) << 24;
265  cx_writeb(P1_MDATA2, 0);
266  val |= (unsigned char)cx_read(P1_MDATA2) << 16;
267  cx_writeb(P1_MDATA1, 0);
268  val |= (unsigned char)cx_read(P1_MDATA1) << 8;
269  cx_writeb(P1_MDATA0, 0);
270  val |= (unsigned char)cx_read(P1_MDATA0);
271 
272  *value = val;
273  return retval;
274 }
275 
276 static int register_write(struct cx88_core *core, u32 address, u32 value)
277 {
278  cx_writeb(P1_RDATA0, (unsigned int)value);
279  cx_writeb(P1_RDATA1, (unsigned int)(value >> 8));
280  cx_writeb(P1_RDATA2, (unsigned int)(value >> 16));
281  cx_writeb(P1_RDATA3, (unsigned int)(value >> 24));
282  cx_writeb(P1_RADDR0, (unsigned int)address);
283  cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
284  cx_writeb(P1_RRDWR, 1);
287 
288  return wait_ready_gpio0_bit1(core,1);
289 }
290 
291 
292 static int register_read(struct cx88_core *core, u32 address, u32 *value)
293 {
294  int retval;
295  u32 val;
296 
297  cx_writeb(P1_RADDR0, (unsigned int)address);
298  cx_writeb(P1_RADDR1, (unsigned int)(address >> 8));
299  cx_writeb(P1_RRDWR, 0);
301 
302  retval = wait_ready_gpio0_bit1(core,1);
303  val = (unsigned char)cx_read(P1_RDATA0);
304  val |= (unsigned char)cx_read(P1_RDATA1) << 8;
305  val |= (unsigned char)cx_read(P1_RDATA2) << 16;
306  val |= (unsigned char)cx_read(P1_RDATA3) << 24;
307 
308  *value = val;
309  return retval;
310 }
311 
312 /* ------------------------------------------------------------------ */
313 
314 static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
315 {
316  struct cx8802_dev *dev = priv;
317  unsigned long timeout;
318  u32 value, flag, retval;
319  int i;
320 
321  dprintk(1,"%s: 0x%X\n", __func__, command);
322 
323  /* this may not be 100% safe if we can't read any memory location
324  without side effects */
325  memory_read(dev->core, dev->mailbox - 4, &value);
326  if (value != 0x12345678) {
327  dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n");
328  return -1;
329  }
330 
331  memory_read(dev->core, dev->mailbox, &flag);
332  if (flag) {
333  dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag);
334  return -1;
335  }
336 
337  flag |= 1; /* tell 'em we're working on it */
338  memory_write(dev->core, dev->mailbox, flag);
339 
340  /* write command + args + fill remaining with zeros */
341  memory_write(dev->core, dev->mailbox + 1, command); /* command code */
342  memory_write(dev->core, dev->mailbox + 3, IVTV_API_STD_TIMEOUT); /* timeout */
343  for (i = 0; i < in; i++) {
344  memory_write(dev->core, dev->mailbox + 4 + i, data[i]);
345  dprintk(1, "API Input %d = %d\n", i, data[i]);
346  }
347  for (; i < CX2341X_MBOX_MAX_DATA; i++)
348  memory_write(dev->core, dev->mailbox + 4 + i, 0);
349 
350  flag |= 3; /* tell 'em we're done writing */
351  memory_write(dev->core, dev->mailbox, flag);
352 
353  /* wait for firmware to handle the API command */
354  timeout = jiffies + msecs_to_jiffies(10);
355  for (;;) {
356  memory_read(dev->core, dev->mailbox, &flag);
357  if (0 != (flag & 4))
358  break;
359  if (time_after(jiffies,timeout)) {
360  dprintk(0, "ERROR: API Mailbox timeout\n");
361  return -1;
362  }
363  udelay(10);
364  }
365 
366  /* read output values */
367  for (i = 0; i < out; i++) {
368  memory_read(dev->core, dev->mailbox + 4 + i, data + i);
369  dprintk(1, "API Output %d = %d\n", i, data[i]);
370  }
371 
372  memory_read(dev->core, dev->mailbox + 2, &retval);
373  dprintk(1, "API result = %d\n",retval);
374 
375  flag = 0;
376  memory_write(dev->core, dev->mailbox, flag);
377  return retval;
378 }
379 /* ------------------------------------------------------------------ */
380 
381 /* We don't need to call the API often, so using just one mailbox will probably suffice */
382 static int blackbird_api_cmd(struct cx8802_dev *dev, u32 command,
383  u32 inputcnt, u32 outputcnt, ...)
384 {
386  va_list vargs;
387  int i, err;
388 
389  va_start(vargs, outputcnt);
390 
391  for (i = 0; i < inputcnt; i++) {
392  data[i] = va_arg(vargs, int);
393  }
394  err = blackbird_mbox_func(dev, command, inputcnt, outputcnt, data);
395  for (i = 0; i < outputcnt; i++) {
396  int *vptr = va_arg(vargs, int *);
397  *vptr = data[i];
398  }
399  va_end(vargs);
400  return err;
401 }
402 
403 static int blackbird_find_mailbox(struct cx8802_dev *dev)
404 {
405  u32 signature[4]={0x12345678, 0x34567812, 0x56781234, 0x78123456};
406  int signaturecnt=0;
407  u32 value;
408  int i;
409 
410  for (i = 0; i < BLACKBIRD_FIRM_IMAGE_SIZE; i++) {
411  memory_read(dev->core, i, &value);
412  if (value == signature[signaturecnt])
413  signaturecnt++;
414  else
415  signaturecnt = 0;
416  if (4 == signaturecnt) {
417  dprintk(1, "Mailbox signature found\n");
418  return i+1;
419  }
420  }
421  dprintk(0, "Mailbox signature values not found!\n");
422  return -1;
423 }
424 
425 static int blackbird_load_firmware(struct cx8802_dev *dev)
426 {
427  static const unsigned char magic[8] = {
428  0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa
429  };
430  const struct firmware *firmware;
431  int i, retval = 0;
432  u32 value = 0;
433  u32 checksum = 0;
434  u32 *dataptr;
435 
436  retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
438  retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
439  retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
440  msleep(1);
441  retval |= register_write(dev->core, IVTV_REG_APU, 0);
442 
443  if (retval < 0)
444  dprintk(0, "Error with register_write\n");
445 
446  retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME,
447  &dev->pci->dev);
448 
449 
450  if (retval != 0) {
451  dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n",
453  dprintk(0, "Please fix your hotplug setup, the board will "
454  "not work without firmware loaded!\n");
455  return -1;
456  }
457 
458  if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
459  dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n",
460  firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
461  release_firmware(firmware);
462  return -1;
463  }
464 
465  if (0 != memcmp(firmware->data, magic, 8)) {
466  dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n");
467  release_firmware(firmware);
468  return -1;
469  }
470 
471  /* transfer to the chip */
472  dprintk(1,"Loading firmware ...\n");
473  dataptr = (u32*)firmware->data;
474  for (i = 0; i < (firmware->size >> 2); i++) {
475  value = le32_to_cpu(*dataptr);
476  checksum += ~value;
477  memory_write(dev->core, i, value);
478  dataptr++;
479  }
480 
481  /* read back to verify with the checksum */
482  for (i--; i >= 0; i--) {
483  memory_read(dev->core, i, &value);
484  checksum -= ~value;
485  }
486  if (checksum) {
487  dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n");
488  release_firmware(firmware);
489  return -1;
490  }
491  release_firmware(firmware);
492  dprintk(0, "Firmware upload successful.\n");
493 
495  retval |= register_read(dev->core, IVTV_REG_SPU, &value);
496  retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
497  msleep(1);
498 
499  retval |= register_read(dev->core, IVTV_REG_VPU, &value);
500  retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
501 
502  if (retval < 0)
503  dprintk(0, "Error with register_write\n");
504  return 0;
505 }
506 
521 static void blackbird_codec_settings(struct cx8802_dev *dev)
522 {
523  /* assign frame size */
524  blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
525  dev->height, dev->width);
526 
527  dev->cxhdl.width = dev->width;
528  dev->cxhdl.height = dev->height;
529  cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50);
530  cx2341x_handler_setup(&dev->cxhdl);
531 }
532 
533 static int blackbird_initialize_codec(struct cx8802_dev *dev)
534 {
535  struct cx88_core *core = dev->core;
536  int version;
537  int retval;
538 
539  dprintk(1,"Initialize codec\n");
540  retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
541  if (retval < 0) {
542 
543  dev->mpeg_active = 0;
544 
545  /* ping was not successful, reset and upload firmware */
546  cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
547  cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */
548  retval = blackbird_load_firmware(dev);
549  if (retval < 0)
550  return retval;
551 
552  retval = blackbird_find_mailbox(dev);
553  if (retval < 0)
554  return -1;
555 
556  dev->mailbox = retval;
557 
558  retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
559  if (retval < 0) {
560  dprintk(0, "ERROR: Firmware ping failed!\n");
561  return -1;
562  }
563 
564  retval = blackbird_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version);
565  if (retval < 0) {
566  dprintk(0, "ERROR: Firmware get encoder version failed!\n");
567  return -1;
568  }
569  dprintk(0, "Firmware version is 0x%08x\n", version);
570  }
571 
572  cx_write(MO_PINMUX_IO, 0x88); /* 656-8bit IO and enable MPEG parallel IO */
573  cx_clear(MO_INPUT_FORMAT, 0x100); /* chroma subcarrier lock to normal? */
574  cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
575  cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
576 
577  blackbird_codec_settings(dev);
578 
579  blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
582  );
583 
584  blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
586  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
587 
588  return 0;
589 }
590 
591 static int blackbird_start_codec(struct file *file, void *priv)
592 {
593  struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
594  struct cx88_core *core = dev->core;
595  /* start capturing to the host interface */
596  u32 reg;
597 
598  int i;
599  int lastchange = -1;
600  int lastval = 0;
601 
602  for (i = 0; (i < 10) && (i < (lastchange + 4)); i++) {
603  reg = cx_read(AUD_STATUS);
604 
605  dprintk(1, "AUD_STATUS:%dL: 0x%x\n", i, reg);
606  if ((reg & 0x0F) != lastval) {
607  lastval = reg & 0x0F;
608  lastchange = i;
609  }
610  msleep(100);
611  }
612 
613  /* unmute audio source */
614  cx_clear(AUD_VOL_CTL, (1 << 6));
615 
616  blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0, 0);
617 
618  /* initialize the video input */
619  blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
620 
621  cx2341x_handler_set_busy(&dev->cxhdl, 1);
622 
623  /* start capturing to the host interface */
624  blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
627  );
628 
629  dev->mpeg_active = 1;
630  return 0;
631 }
632 
633 static int blackbird_stop_codec(struct cx8802_dev *dev)
634 {
635  blackbird_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
639  );
640 
641  cx2341x_handler_set_busy(&dev->cxhdl, 0);
642 
643  dev->mpeg_active = 0;
644  return 0;
645 }
646 
647 /* ------------------------------------------------------------------ */
648 
649 static int bb_buf_setup(struct videobuf_queue *q,
650  unsigned int *count, unsigned int *size)
651 {
652  struct cx8802_fh *fh = q->priv_data;
653 
654  fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
655  fh->dev->ts_packet_count = mpegbufs; /* was: 100 */
656 
657  *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
658  *count = fh->dev->ts_packet_count;
659  return 0;
660 }
661 
662 static int
663 bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
664  enum v4l2_field field)
665 {
666  struct cx8802_fh *fh = q->priv_data;
667  return cx8802_buf_prepare(q, fh->dev, (struct cx88_buffer*)vb, field);
668 }
669 
670 static void
671 bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
672 {
673  struct cx8802_fh *fh = q->priv_data;
674  cx8802_buf_queue(fh->dev, (struct cx88_buffer*)vb);
675 }
676 
677 static void
678 bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
679 {
680  cx88_free_buffer(q, (struct cx88_buffer*)vb);
681 }
682 
683 static struct videobuf_queue_ops blackbird_qops = {
684  .buf_setup = bb_buf_setup,
685  .buf_prepare = bb_buf_prepare,
686  .buf_queue = bb_buf_queue,
687  .buf_release = bb_buf_release,
688 };
689 
690 /* ------------------------------------------------------------------ */
691 
692 static int vidioc_querycap(struct file *file, void *priv,
693  struct v4l2_capability *cap)
694 {
695  struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
696  struct cx88_core *core = dev->core;
697 
698  strcpy(cap->driver, "cx88_blackbird");
699  sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
700  cx88_querycap(file, core, cap);
701  return 0;
702 }
703 
704 static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
705  struct v4l2_fmtdesc *f)
706 {
707  if (f->index != 0)
708  return -EINVAL;
709 
710  strlcpy(f->description, "MPEG", sizeof(f->description));
713  return 0;
714 }
715 
716 static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
717  struct v4l2_format *f)
718 {
719  struct cx8802_fh *fh = priv;
720  struct cx8802_dev *dev = fh->dev;
721 
722  f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
723  f->fmt.pix.bytesperline = 0;
724  f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */
725  f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
726  f->fmt.pix.width = dev->width;
727  f->fmt.pix.height = dev->height;
728  f->fmt.pix.field = fh->mpegq.field;
729  dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
730  dev->width, dev->height, fh->mpegq.field );
731  return 0;
732 }
733 
734 static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
735  struct v4l2_format *f)
736 {
737  struct cx8802_fh *fh = priv;
738  struct cx8802_dev *dev = fh->dev;
739 
740  f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
741  f->fmt.pix.bytesperline = 0;
742  f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */
743  f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
744  dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
745  dev->width, dev->height, fh->mpegq.field );
746  return 0;
747 }
748 
749 static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
750  struct v4l2_format *f)
751 {
752  struct cx8802_fh *fh = priv;
753  struct cx8802_dev *dev = fh->dev;
754  struct cx88_core *core = dev->core;
755 
756  f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
757  f->fmt.pix.bytesperline = 0;
758  f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */
759  f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
760  dev->width = f->fmt.pix.width;
761  dev->height = f->fmt.pix.height;
762  fh->mpegq.field = f->fmt.pix.field;
763  cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
764  blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
765  f->fmt.pix.height, f->fmt.pix.width);
766  dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
767  f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
768  return 0;
769 }
770 
771 static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p)
772 {
773  struct cx8802_fh *fh = priv;
774  return (videobuf_reqbufs(&fh->mpegq, p));
775 }
776 
777 static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p)
778 {
779  struct cx8802_fh *fh = priv;
780  return (videobuf_querybuf(&fh->mpegq, p));
781 }
782 
783 static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
784 {
785  struct cx8802_fh *fh = priv;
786  return (videobuf_qbuf(&fh->mpegq, p));
787 }
788 
789 static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
790 {
791  struct cx8802_fh *fh = priv;
792  return (videobuf_dqbuf(&fh->mpegq, p,
793  file->f_flags & O_NONBLOCK));
794 }
795 
796 static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
797 {
798  struct cx8802_fh *fh = priv;
799  struct cx8802_dev *dev = fh->dev;
800 
801  if (!dev->mpeg_active)
802  blackbird_start_codec(file, fh);
803  return videobuf_streamon(&fh->mpegq);
804 }
805 
806 static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
807 {
808  struct cx8802_fh *fh = priv;
809  struct cx8802_dev *dev = fh->dev;
810 
811  if (dev->mpeg_active)
812  blackbird_stop_codec(dev);
813  return videobuf_streamoff(&fh->mpegq);
814 }
815 
816 static int vidioc_s_frequency (struct file *file, void *priv,
817  struct v4l2_frequency *f)
818 {
819  struct cx8802_fh *fh = priv;
820  struct cx8802_dev *dev = fh->dev;
821  struct cx88_core *core = dev->core;
822 
823  if (unlikely(UNSET == core->board.tuner_type))
824  return -EINVAL;
825  if (unlikely(f->tuner != 0))
826  return -EINVAL;
827  if (dev->mpeg_active)
828  blackbird_stop_codec(dev);
829 
830  cx88_set_freq (core,f);
831  blackbird_initialize_codec(dev);
832  cx88_set_scale(dev->core, dev->width, dev->height,
833  fh->mpegq.field);
834  return 0;
835 }
836 
837 static int vidioc_log_status (struct file *file, void *priv)
838 {
839  struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
840  struct cx88_core *core = dev->core;
841  char name[32 + 2];
842 
843  snprintf(name, sizeof(name), "%s/2", core->name);
844  call_all(core, core, log_status);
845  v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name);
846  return 0;
847 }
848 
849 static int vidioc_enum_input (struct file *file, void *priv,
850  struct v4l2_input *i)
851 {
852  struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
853  return cx88_enum_input (core,i);
854 }
855 
856 static int vidioc_g_frequency (struct file *file, void *priv,
857  struct v4l2_frequency *f)
858 {
859  struct cx8802_fh *fh = priv;
860  struct cx88_core *core = fh->dev->core;
861 
862  if (unlikely(UNSET == core->board.tuner_type))
863  return -EINVAL;
864  if (unlikely(f->tuner != 0))
865  return -EINVAL;
866 
867  f->frequency = core->freq;
868  call_all(core, tuner, g_frequency, f);
869 
870  return 0;
871 }
872 
873 static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
874 {
875  struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
876 
877  *i = core->input;
878  return 0;
879 }
880 
881 static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
882 {
883  struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
884 
885  if (i >= 4)
886  return -EINVAL;
887  if (0 == INPUT(i).type)
888  return -EINVAL;
889 
890  mutex_lock(&core->lock);
891  cx88_newstation(core);
892  cx88_video_mux(core,i);
893  mutex_unlock(&core->lock);
894  return 0;
895 }
896 
897 static int vidioc_g_tuner (struct file *file, void *priv,
898  struct v4l2_tuner *t)
899 {
900  struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
901  u32 reg;
902 
903  if (unlikely(UNSET == core->board.tuner_type))
904  return -EINVAL;
905  if (0 != t->index)
906  return -EINVAL;
907 
908  strcpy(t->name, "Television");
910  t->rangehigh = 0xffffffffUL;
911  call_all(core, tuner, g_tuner, t);
912 
913  cx88_get_stereo(core ,t);
914  reg = cx_read(MO_DEVICE_STATUS);
915  t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
916  return 0;
917 }
918 
919 static int vidioc_s_tuner (struct file *file, void *priv,
920  struct v4l2_tuner *t)
921 {
922  struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
923 
924  if (UNSET == core->board.tuner_type)
925  return -EINVAL;
926  if (0 != t->index)
927  return -EINVAL;
928 
929  cx88_set_stereo(core, t->audmode, 1);
930  return 0;
931 }
932 
933 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)
934 {
935  struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
936 
937  *tvnorm = core->tvnorm;
938  return 0;
939 }
940 
941 static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
942 {
943  struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
944 
945  mutex_lock(&core->lock);
946  cx88_set_tvnorm(core,*id);
947  mutex_unlock(&core->lock);
948  return 0;
949 }
950 
951 /* FIXME: cx88_ioctl_hook not implemented */
952 
953 static int mpeg_open(struct file *file)
954 {
955  struct video_device *vdev = video_devdata(file);
956  struct cx8802_dev *dev = video_drvdata(file);
957  struct cx8802_fh *fh;
958  struct cx8802_driver *drv = NULL;
959  int err;
960 
961  dprintk( 1, "%s\n", __func__);
962 
963  mutex_lock(&dev->core->lock);
964 
965  /* Make sure we can acquire the hardware */
967  if (!drv) {
968  dprintk(1, "%s: blackbird driver is not loaded\n", __func__);
969  mutex_unlock(&dev->core->lock);
970  return -ENODEV;
971  }
972 
973  err = drv->request_acquire(drv);
974  if (err != 0) {
975  dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
976  mutex_unlock(&dev->core->lock);
977  return err;
978  }
979 
980  if (!dev->core->mpeg_users && blackbird_initialize_codec(dev) < 0) {
981  drv->request_release(drv);
982  mutex_unlock(&dev->core->lock);
983  return -EINVAL;
984  }
985  dprintk(1, "open dev=%s\n", video_device_node_name(vdev));
986 
987  /* allocate + initialize per filehandle data */
988  fh = kzalloc(sizeof(*fh),GFP_KERNEL);
989  if (NULL == fh) {
990  drv->request_release(drv);
991  mutex_unlock(&dev->core->lock);
992  return -ENOMEM;
993  }
994  v4l2_fh_init(&fh->fh, vdev);
995  file->private_data = fh;
996  fh->dev = dev;
997 
998  videobuf_queue_sg_init(&fh->mpegq, &blackbird_qops,
999  &dev->pci->dev, &dev->slock,
1002  sizeof(struct cx88_buffer),
1003  fh, NULL);
1004 
1005  /* FIXME: locking against other video device */
1006  cx88_set_scale(dev->core, dev->width, dev->height,
1007  fh->mpegq.field);
1008 
1009  dev->core->mpeg_users++;
1010  mutex_unlock(&dev->core->lock);
1011  v4l2_fh_add(&fh->fh);
1012  return 0;
1013 }
1014 
1015 static int mpeg_release(struct file *file)
1016 {
1017  struct cx8802_fh *fh = file->private_data;
1018  struct cx8802_dev *dev = fh->dev;
1019  struct cx8802_driver *drv = NULL;
1020 
1021  mutex_lock(&dev->core->lock);
1022 
1023  if (dev->mpeg_active && dev->core->mpeg_users == 1)
1024  blackbird_stop_codec(dev);
1025 
1027  /* stop mpeg capture */
1028  videobuf_stop(&fh->mpegq);
1029 
1030  videobuf_mmap_free(&fh->mpegq);
1031 
1032  v4l2_fh_del(&fh->fh);
1033  v4l2_fh_exit(&fh->fh);
1034  file->private_data = NULL;
1035  kfree(fh);
1036 
1037  /* Make sure we release the hardware */
1039  WARN_ON(!drv);
1040  if (drv)
1041  drv->request_release(drv);
1042 
1043  dev->core->mpeg_users--;
1044 
1045  mutex_unlock(&dev->core->lock);
1046 
1047  return 0;
1048 }
1049 
1050 static ssize_t
1051 mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1052 {
1053  struct cx8802_fh *fh = file->private_data;
1054  struct cx8802_dev *dev = fh->dev;
1055 
1056  if (!dev->mpeg_active)
1057  blackbird_start_codec(file, fh);
1058 
1059  return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
1060  file->f_flags & O_NONBLOCK);
1061 }
1062 
1063 static unsigned int
1064 mpeg_poll(struct file *file, struct poll_table_struct *wait)
1065 {
1066  unsigned long req_events = poll_requested_events(wait);
1067  struct cx8802_fh *fh = file->private_data;
1068  struct cx8802_dev *dev = fh->dev;
1069 
1070  if (!dev->mpeg_active && (req_events & (POLLIN | POLLRDNORM)))
1071  blackbird_start_codec(file, fh);
1072 
1073  return v4l2_ctrl_poll(file, wait) | videobuf_poll_stream(file, &fh->mpegq, wait);
1074 }
1075 
1076 static int
1077 mpeg_mmap(struct file *file, struct vm_area_struct * vma)
1078 {
1079  struct cx8802_fh *fh = file->private_data;
1080 
1081  return videobuf_mmap_mapper(&fh->mpegq, vma);
1082 }
1083 
1084 static const struct v4l2_file_operations mpeg_fops =
1085 {
1086  .owner = THIS_MODULE,
1087  .open = mpeg_open,
1088  .release = mpeg_release,
1089  .read = mpeg_read,
1090  .poll = mpeg_poll,
1091  .mmap = mpeg_mmap,
1092  .unlocked_ioctl = video_ioctl2,
1093 };
1094 
1095 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
1096  .vidioc_querycap = vidioc_querycap,
1097  .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1098  .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1099  .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1100  .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1101  .vidioc_reqbufs = vidioc_reqbufs,
1102  .vidioc_querybuf = vidioc_querybuf,
1103  .vidioc_qbuf = vidioc_qbuf,
1104  .vidioc_dqbuf = vidioc_dqbuf,
1105  .vidioc_streamon = vidioc_streamon,
1106  .vidioc_streamoff = vidioc_streamoff,
1107  .vidioc_s_frequency = vidioc_s_frequency,
1108  .vidioc_log_status = vidioc_log_status,
1109  .vidioc_enum_input = vidioc_enum_input,
1110  .vidioc_g_frequency = vidioc_g_frequency,
1111  .vidioc_g_input = vidioc_g_input,
1112  .vidioc_s_input = vidioc_s_input,
1113  .vidioc_g_tuner = vidioc_g_tuner,
1114  .vidioc_s_tuner = vidioc_s_tuner,
1115  .vidioc_g_std = vidioc_g_std,
1116  .vidioc_s_std = vidioc_s_std,
1117  .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1118  .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1119 };
1120 
1121 static struct video_device cx8802_mpeg_template = {
1122  .name = "cx8802",
1123  .fops = &mpeg_fops,
1124  .ioctl_ops = &mpeg_ioctl_ops,
1125  .tvnorms = CX88_NORMS,
1126 };
1127 
1128 /* ------------------------------------------------------------------ */
1129 
1130 /* The CX8802 MPEG API will call this when we can use the hardware */
1131 static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv)
1132 {
1133  struct cx88_core *core = drv->core;
1134  int err = 0;
1135 
1136  switch (core->boardnr) {
1138  /* By default, core setup will leave the cx22702 out of reset, on the bus.
1139  * We left the hardware on power up with the cx22702 active.
1140  * We're being given access to re-arrange the GPIOs.
1141  * Take the bus off the cx22702 and put the cx23416 on it.
1142  */
1143  /* Toggle reset on cx22702 leaving i2c active */
1144  cx_set(MO_GP0_IO, 0x00000080);
1145  udelay(1000);
1146  cx_clear(MO_GP0_IO, 0x00000080);
1147  udelay(50);
1148  cx_set(MO_GP0_IO, 0x00000080);
1149  udelay(1000);
1150  /* tri-state the cx22702 pins */
1151  cx_set(MO_GP0_IO, 0x00000004);
1152  udelay(1000);
1153  break;
1154  default:
1155  err = -ENODEV;
1156  }
1157  return err;
1158 }
1159 
1160 /* The CX8802 MPEG API will call this when we need to release the hardware */
1161 static int cx8802_blackbird_advise_release(struct cx8802_driver *drv)
1162 {
1163  struct cx88_core *core = drv->core;
1164  int err = 0;
1165 
1166  switch (core->boardnr) {
1168  /* Exit leaving the cx23416 on the bus */
1169  break;
1170  default:
1171  err = -ENODEV;
1172  }
1173  return err;
1174 }
1175 
1176 static void blackbird_unregister_video(struct cx8802_dev *dev)
1177 {
1178  if (dev->mpeg_dev) {
1179  if (video_is_registered(dev->mpeg_dev))
1180  video_unregister_device(dev->mpeg_dev);
1181  else
1182  video_device_release(dev->mpeg_dev);
1183  dev->mpeg_dev = NULL;
1184  }
1185 }
1186 
1187 static int blackbird_register_video(struct cx8802_dev *dev)
1188 {
1189  int err;
1190 
1191  dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci,
1192  &cx8802_mpeg_template,"mpeg");
1193  dev->mpeg_dev->ctrl_handler = &dev->cxhdl.hdl;
1194  video_set_drvdata(dev->mpeg_dev, dev);
1195  err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1);
1196  if (err < 0) {
1197  printk(KERN_INFO "%s/2: can't register mpeg device\n",
1198  dev->core->name);
1199  return err;
1200  }
1201  printk(KERN_INFO "%s/2: registered device %s [mpeg]\n",
1202  dev->core->name, video_device_node_name(dev->mpeg_dev));
1203  return 0;
1204 }
1205 
1206 /* ----------------------------------------------------------- */
1207 
1208 static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1209 {
1210  struct cx88_core *core = drv->core;
1211  struct cx8802_dev *dev = core->dvbdev;
1212  int err;
1213 
1214  dprintk( 1, "%s\n", __func__);
1215  dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1216  core->boardnr,
1217  core->name,
1218  core->pci_bus,
1219  core->pci_slot);
1220 
1221  err = -ENODEV;
1222  if (!(core->board.mpeg & CX88_MPEG_BLACKBIRD))
1223  goto fail_core;
1224 
1225  dev->width = 720;
1226  if (core->tvnorm & V4L2_STD_525_60) {
1227  dev->height = 480;
1228  } else {
1229  dev->height = 576;
1230  }
1231  dev->cxhdl.port = CX2341X_PORT_STREAMING;
1232  dev->cxhdl.width = dev->width;
1233  dev->cxhdl.height = dev->height;
1234  dev->cxhdl.func = blackbird_mbox_func;
1235  dev->cxhdl.priv = dev;
1236  err = cx2341x_handler_init(&dev->cxhdl, 36);
1237  if (err)
1238  goto fail_core;
1239  v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl, NULL);
1240 
1241  /* blackbird stuff */
1242  printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
1243  core->name);
1244  host_setup(dev->core);
1245 
1246  blackbird_initialize_codec(dev);
1247 
1248  /* initial device configuration: needed ? */
1249 // init_controls(core);
1250  cx88_set_tvnorm(core,core->tvnorm);
1251  cx88_video_mux(core,0);
1252  cx2341x_handler_set_50hz(&dev->cxhdl, dev->height == 576);
1253  cx2341x_handler_setup(&dev->cxhdl);
1254  blackbird_register_video(dev);
1255 
1256  return 0;
1257 
1258  fail_core:
1259  return err;
1260 }
1261 
1262 static int cx8802_blackbird_remove(struct cx8802_driver *drv)
1263 {
1264  struct cx88_core *core = drv->core;
1265  struct cx8802_dev *dev = core->dvbdev;
1266 
1267  /* blackbird */
1268  blackbird_unregister_video(drv->core->dvbdev);
1269  v4l2_ctrl_handler_free(&dev->cxhdl.hdl);
1270 
1271  return 0;
1272 }
1273 
1274 static struct cx8802_driver cx8802_blackbird_driver = {
1275  .type_id = CX88_MPEG_BLACKBIRD,
1276  .hw_access = CX8802_DRVCTL_SHARED,
1277  .probe = cx8802_blackbird_probe,
1278  .remove = cx8802_blackbird_remove,
1279  .advise_acquire = cx8802_blackbird_advise_acquire,
1280  .advise_release = cx8802_blackbird_advise_release,
1281 };
1282 
1283 static int __init blackbird_init(void)
1284 {
1285  printk(KERN_INFO "cx2388x blackbird driver version %s loaded\n",
1286  CX88_VERSION);
1287  return cx8802_register_driver(&cx8802_blackbird_driver);
1288 }
1289 
1290 static void __exit blackbird_fini(void)
1291 {
1292  cx8802_unregister_driver(&cx8802_blackbird_driver);
1293 }
1294 
1295 module_init(blackbird_init);
1296 module_exit(blackbird_fini);
1297 
1298 module_param_named(video_debug,cx8802_mpeg_template.debug, int, 0644);
1299 MODULE_PARM_DESC(debug,"enable debug messages [video]");