saa7134-go7007.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  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. #include "saa7134.h"
  14. #include "saa7134-reg.h"
  15. #include <linux/module.h>
  16. #include <linux/kernel.h>
  17. #include <linux/init.h>
  18. #include <linux/spinlock.h>
  19. #include <linux/wait.h>
  20. #include <linux/list.h>
  21. #include <linux/slab.h>
  22. #include <linux/time.h>
  23. #include <linux/mm.h>
  24. #include <linux/usb.h>
  25. #include <linux/i2c.h>
  26. #include <asm/byteorder.h>
  27. #include <media/v4l2-common.h>
  28. #include <media/v4l2-device.h>
  29. #include <media/v4l2-subdev.h>
  30. #include "go7007-priv.h"
  31. /*#define GO7007_HPI_DEBUG*/
  32. enum hpi_address {
  33. HPI_ADDR_VIDEO_BUFFER = 0xe4,
  34. HPI_ADDR_INIT_BUFFER = 0xea,
  35. HPI_ADDR_INTR_RET_VALUE = 0xee,
  36. HPI_ADDR_INTR_RET_DATA = 0xec,
  37. HPI_ADDR_INTR_STATUS = 0xf4,
  38. HPI_ADDR_INTR_WR_PARAM = 0xf6,
  39. HPI_ADDR_INTR_WR_INDEX = 0xf8,
  40. };
  41. enum gpio_command {
  42. GPIO_COMMAND_RESET = 0x00, /* 000b */
  43. GPIO_COMMAND_REQ1 = 0x04, /* 001b */
  44. GPIO_COMMAND_WRITE = 0x20, /* 010b */
  45. GPIO_COMMAND_REQ2 = 0x24, /* 011b */
  46. GPIO_COMMAND_READ = 0x80, /* 100b */
  47. GPIO_COMMAND_VIDEO = 0x84, /* 101b */
  48. GPIO_COMMAND_IDLE = 0xA0, /* 110b */
  49. GPIO_COMMAND_ADDR = 0xA4, /* 111b */
  50. };
  51. struct saa7134_go7007 {
  52. struct v4l2_subdev sd;
  53. struct saa7134_dev *dev;
  54. u8 *top;
  55. u8 *bottom;
  56. dma_addr_t top_dma;
  57. dma_addr_t bottom_dma;
  58. };
  59. static inline struct saa7134_go7007 *to_state(struct v4l2_subdev *sd)
  60. {
  61. return container_of(sd, struct saa7134_go7007, sd);
  62. }
  63. static const struct go7007_board_info board_voyager = {
  64. .flags = 0,
  65. .sensor_flags = GO7007_SENSOR_656 |
  66. GO7007_SENSOR_VALID_ENABLE |
  67. GO7007_SENSOR_TV |
  68. GO7007_SENSOR_VBI,
  69. .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
  70. GO7007_AUDIO_WORD_16,
  71. .audio_rate = 48000,
  72. .audio_bclk_div = 8,
  73. .audio_main_div = 2,
  74. .hpi_buffer_cap = 7,
  75. .num_inputs = 1,
  76. .inputs = {
  77. {
  78. .name = "SAA7134",
  79. },
  80. },
  81. };
  82. /********************* Driver for GPIO HPI interface *********************/
  83. static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
  84. {
  85. saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
  86. /* Write HPI address */
  87. saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
  88. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
  89. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
  90. /* Write low byte */
  91. saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
  92. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
  93. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
  94. /* Write high byte */
  95. saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8);
  96. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
  97. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
  98. return 0;
  99. }
  100. static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
  101. {
  102. saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
  103. /* Write HPI address */
  104. saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
  105. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
  106. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
  107. saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
  108. /* Read low byte */
  109. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
  110. saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
  111. saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
  112. *data = saa_readb(SAA7134_GPIO_GPSTATUS0);
  113. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
  114. /* Read high byte */
  115. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
  116. saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
  117. saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
  118. *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
  119. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
  120. return 0;
  121. }
  122. static int saa7134_go7007_interface_reset(struct go7007 *go)
  123. {
  124. struct saa7134_go7007 *saa = go->hpi_context;
  125. struct saa7134_dev *dev = saa->dev;
  126. u16 intr_val, intr_data;
  127. int count = 20;
  128. saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
  129. saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4);
  130. saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
  131. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
  132. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET);
  133. msleep(1);
  134. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
  135. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
  136. msleep(10);
  137. saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
  138. saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
  139. saa_readb(SAA7134_GPIO_GPSTATUS2);
  140. /*pr_debug("status is %s\n", saa_readb(SAA7134_GPIO_GPSTATUS2) & 0x40 ? "OK" : "not OK"); */
  141. /* enter command mode...(?) */
  142. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
  143. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
  144. do {
  145. saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
  146. saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
  147. saa_readb(SAA7134_GPIO_GPSTATUS2);
  148. /*pr_info("gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
  149. } while (--count > 0);
  150. /* Wait for an interrupt to indicate successful hardware reset */
  151. if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
  152. (intr_val & ~0x1) != 0x55aa) {
  153. pr_err("saa7134-go7007: unable to reset the GO7007\n");
  154. return -1;
  155. }
  156. return 0;
  157. }
  158. static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
  159. {
  160. struct saa7134_go7007 *saa = go->hpi_context;
  161. struct saa7134_dev *dev = saa->dev;
  162. int i;
  163. u16 status_reg;
  164. #ifdef GO7007_HPI_DEBUG
  165. pr_debug("saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
  166. #endif
  167. for (i = 0; i < 100; ++i) {
  168. gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
  169. if (!(status_reg & 0x0010))
  170. break;
  171. msleep(10);
  172. }
  173. if (i == 100) {
  174. pr_err("saa7134-go7007: device is hung, status reg = 0x%04x\n",
  175. status_reg);
  176. return -1;
  177. }
  178. gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data);
  179. gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr);
  180. return 0;
  181. }
  182. static int saa7134_go7007_read_interrupt(struct go7007 *go)
  183. {
  184. struct saa7134_go7007 *saa = go->hpi_context;
  185. struct saa7134_dev *dev = saa->dev;
  186. /* XXX we need to wait if there is no interrupt available */
  187. go->interrupt_available = 1;
  188. gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value);
  189. gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data);
  190. #ifdef GO7007_HPI_DEBUG
  191. pr_debug("saa7134-go7007: ReadInterrupt: %04x %04x\n",
  192. go->interrupt_value, go->interrupt_data);
  193. #endif
  194. return 0;
  195. }
  196. static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
  197. unsigned long status)
  198. {
  199. struct go7007 *go = video_get_drvdata(dev->empress_dev);
  200. struct saa7134_go7007 *saa = go->hpi_context;
  201. if (!vb2_is_streaming(&go->vidq))
  202. return;
  203. if (0 != (status & 0x000f0000))
  204. pr_debug("saa7134-go7007: irq: lost %ld\n",
  205. (status >> 16) & 0x0f);
  206. if (status & 0x100000) {
  207. dma_sync_single_for_cpu(&dev->pci->dev,
  208. saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE);
  209. go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE);
  210. saa_writel(SAA7134_RS_BA2(5), saa->bottom_dma);
  211. } else {
  212. dma_sync_single_for_cpu(&dev->pci->dev,
  213. saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE);
  214. go7007_parse_video_stream(go, saa->top, PAGE_SIZE);
  215. saa_writel(SAA7134_RS_BA1(5), saa->top_dma);
  216. }
  217. }
  218. static int saa7134_go7007_stream_start(struct go7007 *go)
  219. {
  220. struct saa7134_go7007 *saa = go->hpi_context;
  221. struct saa7134_dev *dev = saa->dev;
  222. saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
  223. 0, PAGE_SIZE, DMA_FROM_DEVICE);
  224. if (dma_mapping_error(&dev->pci->dev, saa->top_dma))
  225. return -ENOMEM;
  226. saa->bottom_dma = dma_map_page(&dev->pci->dev,
  227. virt_to_page(saa->bottom),
  228. 0, PAGE_SIZE, DMA_FROM_DEVICE);
  229. if (dma_mapping_error(&dev->pci->dev, saa->bottom_dma)) {
  230. dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
  231. DMA_FROM_DEVICE);
  232. return -ENOMEM;
  233. }
  234. saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
  235. saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
  236. /* Set HPI interface for video */
  237. saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
  238. saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER);
  239. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
  240. saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
  241. /* Enable TS interface */
  242. saa_writeb(SAA7134_TS_PARALLEL, 0xe6);
  243. /* Reset TS interface */
  244. saa_setb(SAA7134_TS_SERIAL1, 0x01);
  245. saa_clearb(SAA7134_TS_SERIAL1, 0x01);
  246. /* Set up transfer block size */
  247. saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1);
  248. saa_writeb(SAA7134_TS_DMA0, ((PAGE_SIZE >> 7) - 1) & 0xff);
  249. saa_writeb(SAA7134_TS_DMA1, (PAGE_SIZE >> 15) & 0xff);
  250. saa_writeb(SAA7134_TS_DMA2, (PAGE_SIZE >> 31) & 0x3f);
  251. /* Enable video streaming mode */
  252. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO);
  253. saa_writel(SAA7134_RS_BA1(5), saa->top_dma);
  254. saa_writel(SAA7134_RS_BA2(5), saa->bottom_dma);
  255. saa_writel(SAA7134_RS_PITCH(5), 128);
  256. saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX);
  257. /* Enable TS FIFO */
  258. saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
  259. /* Enable DMA IRQ */
  260. saa_setl(SAA7134_IRQ1,
  261. SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
  262. return 0;
  263. }
  264. static int saa7134_go7007_stream_stop(struct go7007 *go)
  265. {
  266. struct saa7134_go7007 *saa = go->hpi_context;
  267. struct saa7134_dev *dev;
  268. if (!saa)
  269. return -EINVAL;
  270. dev = saa->dev;
  271. if (!dev)
  272. return -EINVAL;
  273. /* Shut down TS FIFO */
  274. saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
  275. /* Disable DMA IRQ */
  276. saa_clearl(SAA7134_IRQ1,
  277. SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
  278. /* Disable TS interface */
  279. saa_clearb(SAA7134_TS_PARALLEL, 0x80);
  280. dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
  281. DMA_FROM_DEVICE);
  282. dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
  283. DMA_FROM_DEVICE);
  284. return 0;
  285. }
  286. static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
  287. {
  288. struct saa7134_go7007 *saa = go->hpi_context;
  289. struct saa7134_dev *dev = saa->dev;
  290. u16 status_reg;
  291. int i;
  292. #ifdef GO7007_HPI_DEBUG
  293. pr_debug("saa7134-go7007: DownloadBuffer sending %d bytes\n", len);
  294. #endif
  295. while (len > 0) {
  296. i = len > 64 ? 64 : len;
  297. saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
  298. saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER);
  299. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
  300. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
  301. while (i-- > 0) {
  302. saa_writeb(SAA7134_GPIO_GPSTATUS0, *data);
  303. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
  304. saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
  305. ++data;
  306. --len;
  307. }
  308. for (i = 0; i < 100; ++i) {
  309. gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
  310. if (!(status_reg & 0x0002))
  311. break;
  312. }
  313. if (i == 100) {
  314. pr_err("saa7134-go7007: device is hung, status reg = 0x%04x\n",
  315. status_reg);
  316. return -1;
  317. }
  318. }
  319. return 0;
  320. }
  321. static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
  322. .interface_reset = saa7134_go7007_interface_reset,
  323. .write_interrupt = saa7134_go7007_write_interrupt,
  324. .read_interrupt = saa7134_go7007_read_interrupt,
  325. .stream_start = saa7134_go7007_stream_start,
  326. .stream_stop = saa7134_go7007_stream_stop,
  327. .send_firmware = saa7134_go7007_send_firmware,
  328. };
  329. MODULE_FIRMWARE("go7007/go7007tv.bin");
  330. /* --------------------------------------------------------------------------*/
  331. static int saa7134_go7007_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
  332. {
  333. #if 0
  334. struct saa7134_go7007 *saa = to_state(sd);
  335. struct saa7134_dev *dev = saa->dev;
  336. return saa7134_s_std_internal(dev, NULL, norm);
  337. #else
  338. return 0;
  339. #endif
  340. }
  341. static const struct v4l2_subdev_video_ops saa7134_go7007_video_ops = {
  342. .s_std = saa7134_go7007_s_std,
  343. };
  344. static const struct v4l2_subdev_ops saa7134_go7007_sd_ops = {
  345. .video = &saa7134_go7007_video_ops,
  346. };
  347. /* --------------------------------------------------------------------------*/
  348. /********************* Add/remove functions *********************/
  349. static int saa7134_go7007_init(struct saa7134_dev *dev)
  350. {
  351. struct go7007 *go;
  352. struct saa7134_go7007 *saa;
  353. struct v4l2_subdev *sd;
  354. pr_debug("saa7134-go7007: probing new SAA713X board\n");
  355. go = go7007_alloc(&board_voyager, &dev->pci->dev);
  356. if (go == NULL)
  357. return -ENOMEM;
  358. saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
  359. if (saa == NULL) {
  360. kfree(go);
  361. return -ENOMEM;
  362. }
  363. go->board_id = GO7007_BOARDID_PCI_VOYAGER;
  364. snprintf(go->bus_info, sizeof(go->bus_info), "PCI:%s", pci_name(dev->pci));
  365. strlcpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
  366. go->hpi_ops = &saa7134_go7007_hpi_ops;
  367. go->hpi_context = saa;
  368. saa->dev = dev;
  369. /* Init the subdevice interface */
  370. sd = &saa->sd;
  371. v4l2_subdev_init(sd, &saa7134_go7007_sd_ops);
  372. v4l2_set_subdevdata(sd, saa);
  373. strncpy(sd->name, "saa7134-go7007", sizeof(sd->name));
  374. /* Allocate a couple pages for receiving the compressed stream */
  375. saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
  376. if (!saa->top)
  377. goto allocfail;
  378. saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
  379. if (!saa->bottom)
  380. goto allocfail;
  381. /* Boot the GO7007 */
  382. if (go7007_boot_encoder(go, go->board_info->flags &
  383. GO7007_BOARD_USE_ONBOARD_I2C) < 0)
  384. goto allocfail;
  385. /* Do any final GO7007 initialization, then register the
  386. * V4L2 and ALSA interfaces */
  387. if (go7007_register_encoder(go, go->board_info->num_i2c_devs) < 0)
  388. goto allocfail;
  389. /* Register the subdevice interface with the go7007 device */
  390. if (v4l2_device_register_subdev(&go->v4l2_dev, sd) < 0)
  391. pr_info("saa7134-go7007: register subdev failed\n");
  392. dev->empress_dev = &go->vdev;
  393. go->status = STATUS_ONLINE;
  394. return 0;
  395. allocfail:
  396. if (saa->top)
  397. free_page((unsigned long)saa->top);
  398. if (saa->bottom)
  399. free_page((unsigned long)saa->bottom);
  400. kfree(saa);
  401. kfree(go);
  402. return -ENOMEM;
  403. }
  404. static int saa7134_go7007_fini(struct saa7134_dev *dev)
  405. {
  406. struct go7007 *go;
  407. struct saa7134_go7007 *saa;
  408. if (NULL == dev->empress_dev)
  409. return 0;
  410. go = video_get_drvdata(dev->empress_dev);
  411. if (go->audio_enabled)
  412. go7007_snd_remove(go);
  413. saa = go->hpi_context;
  414. go->status = STATUS_SHUTDOWN;
  415. free_page((unsigned long)saa->top);
  416. free_page((unsigned long)saa->bottom);
  417. v4l2_device_unregister_subdev(&saa->sd);
  418. kfree(saa);
  419. video_unregister_device(&go->vdev);
  420. v4l2_device_put(&go->v4l2_dev);
  421. dev->empress_dev = NULL;
  422. return 0;
  423. }
  424. static struct saa7134_mpeg_ops saa7134_go7007_ops = {
  425. .type = SAA7134_MPEG_GO7007,
  426. .init = saa7134_go7007_init,
  427. .fini = saa7134_go7007_fini,
  428. .irq_ts_done = saa7134_go7007_irq_ts_done,
  429. };
  430. static int __init saa7134_go7007_mod_init(void)
  431. {
  432. return saa7134_ts_register(&saa7134_go7007_ops);
  433. }
  434. static void __exit saa7134_go7007_mod_cleanup(void)
  435. {
  436. saa7134_ts_unregister(&saa7134_go7007_ops);
  437. }
  438. module_init(saa7134_go7007_mod_init);
  439. module_exit(saa7134_go7007_mod_cleanup);
  440. MODULE_LICENSE("GPL v2");