Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
saa7134-go7007.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2006 Micronas USA Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License (Version 2) as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software Foundation,
15  * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16  */
17 
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/spinlock.h>
22 #include <linux/wait.h>
23 #include <linux/list.h>
24 #include <linux/slab.h>
25 #include <linux/time.h>
26 #include <linux/mm.h>
27 #include <linux/usb.h>
28 #include <linux/i2c.h>
29 #include <asm/byteorder.h>
30 #include <media/v4l2-common.h>
31 
32 #include "saa7134-reg.h"
33 #include "saa7134.h"
34 #include "go7007-priv.h"
35 
36 #define GO7007_HPI_DEBUG
37 
46 };
47 
49  GPIO_COMMAND_RESET = 0x00, /* 000b */
50  GPIO_COMMAND_REQ1 = 0x04, /* 001b */
51  GPIO_COMMAND_WRITE = 0x20, /* 010b */
52  GPIO_COMMAND_REQ2 = 0x24, /* 011b */
53  GPIO_COMMAND_READ = 0x80, /* 100b */
54  GPIO_COMMAND_VIDEO = 0x84, /* 101b */
55  GPIO_COMMAND_IDLE = 0xA0, /* 110b */
56  GPIO_COMMAND_ADDR = 0xA4, /* 111b */
57 };
58 
60  struct saa7134_dev *dev;
61  u8 *top;
65 };
66 
67 static struct go7007_board_info board_voyager = {
68  .firmware = "go7007tv.bin",
69  .flags = 0,
70  .sensor_flags = GO7007_SENSOR_656 |
74  .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
76  .audio_rate = 48000,
77  .audio_bclk_div = 8,
78  .audio_main_div = 2,
79  .hpi_buffer_cap = 7,
80  .num_inputs = 1,
81  .inputs = {
82  {
83  .name = "SAA7134",
84  },
85  },
86 };
87 MODULE_FIRMWARE("go7007tv.bin");
88 
89 /********************* Driver for GPIO HPI interface *********************/
90 
91 static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
92 {
94 
95  /* Write HPI address */
99 
100  /* Write low byte */
101  saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
104 
105  /* Write high byte */
109 
110  return 0;
111 }
112 
113 static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
114 {
116 
117  /* Write HPI address */
121 
123 
124  /* Read low byte */
130 
131  /* Read high byte */
135  *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
137 
138  return 0;
139 }
140 
141 static int saa7134_go7007_interface_reset(struct go7007 *go)
142 {
143  struct saa7134_go7007 *saa = go->hpi_context;
144  struct saa7134_dev *dev = saa->dev;
145  u32 status;
146  u16 intr_val, intr_data;
147  int count = 20;
148 
149  saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
152 
155  msleep(1);
158  msleep(10);
159 
162 
164  /*printk(KERN_DEBUG "status is %s\n", status & 0x40 ? "OK" : "not OK"); */
165 
166  /* enter command mode...(?) */
169 
170  do {
174  /*printk(KERN_INFO "gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
175  } while (--count > 0);
176 
177  /* Wait for an interrupt to indicate successful hardware reset */
178  if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
179  (intr_val & ~0x1) != 0x55aa) {
181  "saa7134-go7007: unable to reset the GO7007\n");
182  return -1;
183  }
184  return 0;
185 }
186 
187 static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
188 {
189  struct saa7134_go7007 *saa = go->hpi_context;
190  struct saa7134_dev *dev = saa->dev;
191  int i;
192  u16 status_reg;
193 
194 #ifdef GO7007_HPI_DEBUG
196  "saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
197 #endif
198 
199  for (i = 0; i < 100; ++i) {
200  gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
201  if (!(status_reg & 0x0010))
202  break;
203  msleep(10);
204  }
205  if (i == 100) {
207  "saa7134-go7007: device is hung, status reg = 0x%04x\n",
208  status_reg);
209  return -1;
210  }
213 
214  return 0;
215 }
216 
217 static int saa7134_go7007_read_interrupt(struct go7007 *go)
218 {
219  struct saa7134_go7007 *saa = go->hpi_context;
220  struct saa7134_dev *dev = saa->dev;
221 
222  /* XXX we need to wait if there is no interrupt available */
223  go->interrupt_available = 1;
226 #ifdef GO7007_HPI_DEBUG
227  printk(KERN_DEBUG "saa7134-go7007: ReadInterrupt: %04x %04x\n",
229 #endif
230  return 0;
231 }
232 
233 static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
234  unsigned long status)
235 {
236  struct go7007 *go = video_get_drvdata(dev->empress_dev);
237  struct saa7134_go7007 *saa = go->hpi_context;
238 
239  if (!go->streaming)
240  return;
241  if (0 != (status & 0x000f0000))
242  printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n",
243  (status >> 16) & 0x0f);
244  if (status & 0x100000) {
245  dma_sync_single_for_cpu(&dev->pci->dev,
249  } else {
250  dma_sync_single_for_cpu(&dev->pci->dev,
254  }
255 }
256 
257 static int saa7134_go7007_stream_start(struct go7007 *go)
258 {
259  struct saa7134_go7007 *saa = go->hpi_context;
260  struct saa7134_dev *dev = saa->dev;
261 
262  saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
264  if (!saa->top_dma)
265  return -ENOMEM;
266  saa->bottom_dma = dma_map_page(&dev->pci->dev,
267  virt_to_page(saa->bottom),
269  if (!saa->bottom_dma) {
270  dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
272  return -ENOMEM;
273  }
274 
275  saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
276  saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
277 
278  /* Set HPI interface for video */
283 
284  /* Enable TS interface */
286 
287  /* Reset TS interface */
290 
291  /* Set up transfer block size */
293  saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1);
296 
297  /* Enable video streaming mode */
299 
302  saa_writel(SAA7134_RS_PITCH(5), 128);
304 
305  /* Enable TS FIFO */
307 
308  /* Enable DMA IRQ */
311 
312  return 0;
313 }
314 
315 static int saa7134_go7007_stream_stop(struct go7007 *go)
316 {
317  struct saa7134_go7007 *saa = go->hpi_context;
318  struct saa7134_dev *dev;
319 
320  if (!saa)
321  return -EINVAL;
322  dev = saa->dev;
323  if (!dev)
324  return -EINVAL;
325 
326  /* Shut down TS FIFO */
328 
329  /* Disable DMA IRQ */
332 
333  /* Disable TS interface */
335 
336  dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
338  dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
340 
341  return 0;
342 }
343 
344 static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
345 {
346  struct saa7134_go7007 *saa = go->hpi_context;
347  struct saa7134_dev *dev = saa->dev;
348  u16 status_reg;
349  int i;
350 
351 #ifdef GO7007_HPI_DEBUG
352  printk(KERN_DEBUG "saa7134-go7007: DownloadBuffer "
353  "sending %d bytes\n", len);
354 #endif
355 
356  while (len > 0) {
357  i = len > 64 ? 64 : len;
362  while (i-- > 0) {
366  ++data;
367  --len;
368  }
369  for (i = 0; i < 100; ++i) {
370  gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
371  if (!(status_reg & 0x0002))
372  break;
373  }
374  if (i == 100) {
375  printk(KERN_ERR "saa7134-go7007: device is hung, "
376  "status reg = 0x%04x\n", status_reg);
377  return -1;
378  }
379  }
380  return 0;
381 }
382 
383 static int saa7134_go7007_send_command(struct go7007 *go, unsigned int cmd,
384  void *arg)
385 {
386  struct saa7134_go7007 *saa = go->hpi_context;
387  struct saa7134_dev *dev = saa->dev;
388 
389  switch (cmd) {
390  case VIDIOC_S_STD:
391  {
392  v4l2_std_id *std = arg;
393  return saa7134_s_std_internal(dev, NULL, std);
394  }
395  case VIDIOC_G_STD:
396  {
397  v4l2_std_id *std = arg;
398  *std = dev->tvnorm->id;
399  return 0;
400  }
401  case VIDIOC_QUERYCTRL:
402  {
403  struct v4l2_queryctrl *ctrl = arg;
405  return saa7134_queryctrl(NULL, NULL, ctrl);
406  }
407  case VIDIOC_G_CTRL:
408  {
409  struct v4l2_control *ctrl = arg;
411  return saa7134_g_ctrl_internal(dev, NULL, ctrl);
412  }
413  case VIDIOC_S_CTRL:
414  {
415  struct v4l2_control *ctrl = arg;
417  return saa7134_s_ctrl_internal(dev, NULL, ctrl);
418  }
419  }
420  return -EINVAL;
421 
422 }
423 
424 static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
425  .interface_reset = saa7134_go7007_interface_reset,
426  .write_interrupt = saa7134_go7007_write_interrupt,
427  .read_interrupt = saa7134_go7007_read_interrupt,
428  .stream_start = saa7134_go7007_stream_start,
429  .stream_stop = saa7134_go7007_stream_stop,
430  .send_firmware = saa7134_go7007_send_firmware,
431  .send_command = saa7134_go7007_send_command,
432 };
433 
434 /********************* Add/remove functions *********************/
435 
436 static int saa7134_go7007_init(struct saa7134_dev *dev)
437 {
438  struct go7007 *go;
439  struct saa7134_go7007 *saa;
440 
441  printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n");
442 
443  saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
444  if (saa == NULL)
445  return -ENOMEM;
446 
447  /* Allocate a couple pages for receiving the compressed stream */
448  saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
449  if (!saa->top)
450  goto allocfail;
451  saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
452  if (!saa->bottom)
453  goto allocfail;
454 
455  go = go7007_alloc(&board_voyager, &dev->pci->dev);
456  if (go == NULL)
457  goto allocfail;
459  strncpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
460  go->hpi_ops = &saa7134_go7007_hpi_ops;
461  go->hpi_context = saa;
462  saa->dev = dev;
463 
464  /* Boot the GO7007 */
465  if (go7007_boot_encoder(go, go->board_info->flags &
467  goto initfail;
468 
469  /* Do any final GO7007 initialization, then register the
470  * V4L2 and ALSA interfaces */
471  if (go7007_register_encoder(go) < 0)
472  goto initfail;
473  dev->empress_dev = go->video_dev;
474  video_set_drvdata(dev->empress_dev, go);
475 
476  go->status = STATUS_ONLINE;
477  return 0;
478 
479 initfail:
480  go->status = STATUS_SHUTDOWN;
481  return 0;
482 
483 allocfail:
484  if (saa->top)
485  free_page((unsigned long)saa->top);
486  if (saa->bottom)
487  free_page((unsigned long)saa->bottom);
488  kfree(saa);
489  return -ENOMEM;
490 }
491 
492 static int saa7134_go7007_fini(struct saa7134_dev *dev)
493 {
494  struct go7007 *go;
495  struct saa7134_go7007 *saa;
496 
497  if (NULL == dev->empress_dev)
498  return 0;
499 
500  go = video_get_drvdata(dev->empress_dev);
501  saa = go->hpi_context;
502  go->status = STATUS_SHUTDOWN;
503  free_page((unsigned long)saa->top);
504  free_page((unsigned long)saa->bottom);
505  kfree(saa);
506  go7007_remove(go);
507  dev->empress_dev = NULL;
508 
509  return 0;
510 }
511 
512 static struct saa7134_mpeg_ops saa7134_go7007_ops = {
513  .type = SAA7134_MPEG_GO7007,
514  .init = saa7134_go7007_init,
515  .fini = saa7134_go7007_fini,
516  .irq_ts_done = saa7134_go7007_irq_ts_done,
517 };
518 
519 static int __init saa7134_go7007_mod_init(void)
520 {
521  return saa7134_ts_register(&saa7134_go7007_ops);
522 }
523 
524 static void __exit saa7134_go7007_mod_cleanup(void)
525 {
526  saa7134_ts_unregister(&saa7134_go7007_ops);
527 }
528 
529 module_init(saa7134_go7007_mod_init);
530 module_exit(saa7134_go7007_mod_cleanup);
531 
532 MODULE_LICENSE("GPL v2");