tw686x-video.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  1. /*
  2. * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
  3. *
  4. * Based on original driver by Krzysztof Ha?asa:
  5. * Copyright (C) 2015 Industrial Research Institute for Automation
  6. * and Measurements PIAP
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of version 2 of the GNU General Public License
  10. * as published by the Free Software Foundation.
  11. *
  12. */
  13. #include <linux/init.h>
  14. #include <linux/delay.h>
  15. #include <linux/list.h>
  16. #include <linux/module.h>
  17. #include <linux/kernel.h>
  18. #include <linux/slab.h>
  19. #include <media/v4l2-common.h>
  20. #include <media/v4l2-event.h>
  21. #include <media/videobuf2-dma-contig.h>
  22. #include <media/videobuf2-dma-sg.h>
  23. #include <media/videobuf2-vmalloc.h>
  24. #include "tw686x.h"
  25. #include "tw686x-regs.h"
  26. #define TW686X_INPUTS_PER_CH 4
  27. #define TW686X_VIDEO_WIDTH 720
  28. #define TW686X_VIDEO_HEIGHT(id) ((id & V4L2_STD_525_60) ? 480 : 576)
  29. #define TW686X_MAX_SG_ENTRY_SIZE 4096
  30. #define TW686X_MAX_SG_DESC_COUNT 256 /* PAL 720x576 needs 203 4-KB pages */
  31. #define TW686X_SG_TABLE_SIZE (TW686X_MAX_SG_DESC_COUNT * sizeof(struct tw686x_sg_desc))
  32. static const struct tw686x_format formats[] = {
  33. {
  34. .fourcc = V4L2_PIX_FMT_UYVY,
  35. .mode = 0,
  36. .depth = 16,
  37. }, {
  38. .fourcc = V4L2_PIX_FMT_RGB565,
  39. .mode = 5,
  40. .depth = 16,
  41. }, {
  42. .fourcc = V4L2_PIX_FMT_YUYV,
  43. .mode = 6,
  44. .depth = 16,
  45. }
  46. };
  47. static void tw686x_buf_done(struct tw686x_video_channel *vc,
  48. unsigned int pb)
  49. {
  50. struct tw686x_dma_desc *desc = &vc->dma_descs[pb];
  51. struct tw686x_dev *dev = vc->dev;
  52. struct vb2_v4l2_buffer *vb;
  53. struct vb2_buffer *vb2_buf;
  54. if (vc->curr_bufs[pb]) {
  55. vb = &vc->curr_bufs[pb]->vb;
  56. vb->field = dev->dma_ops->field;
  57. vb->sequence = vc->sequence++;
  58. vb2_buf = &vb->vb2_buf;
  59. if (dev->dma_mode == TW686X_DMA_MODE_MEMCPY)
  60. memcpy(vb2_plane_vaddr(vb2_buf, 0), desc->virt,
  61. desc->size);
  62. vb2_buf->timestamp = ktime_get_ns();
  63. vb2_buffer_done(vb2_buf, VB2_BUF_STATE_DONE);
  64. }
  65. vc->pb = !pb;
  66. }
  67. /*
  68. * We can call this even when alloc_dma failed for the given channel
  69. */
  70. static void tw686x_memcpy_dma_free(struct tw686x_video_channel *vc,
  71. unsigned int pb)
  72. {
  73. struct tw686x_dma_desc *desc = &vc->dma_descs[pb];
  74. struct tw686x_dev *dev = vc->dev;
  75. struct pci_dev *pci_dev;
  76. unsigned long flags;
  77. /* Check device presence. Shouldn't really happen! */
  78. spin_lock_irqsave(&dev->lock, flags);
  79. pci_dev = dev->pci_dev;
  80. spin_unlock_irqrestore(&dev->lock, flags);
  81. if (!pci_dev) {
  82. WARN(1, "trying to deallocate on missing device\n");
  83. return;
  84. }
  85. if (desc->virt) {
  86. pci_free_consistent(dev->pci_dev, desc->size,
  87. desc->virt, desc->phys);
  88. desc->virt = NULL;
  89. }
  90. }
  91. static int tw686x_memcpy_dma_alloc(struct tw686x_video_channel *vc,
  92. unsigned int pb)
  93. {
  94. struct tw686x_dev *dev = vc->dev;
  95. u32 reg = pb ? VDMA_B_ADDR[vc->ch] : VDMA_P_ADDR[vc->ch];
  96. unsigned int len;
  97. void *virt;
  98. WARN(vc->dma_descs[pb].virt,
  99. "Allocating buffer but previous still here\n");
  100. len = (vc->width * vc->height * vc->format->depth) >> 3;
  101. virt = pci_alloc_consistent(dev->pci_dev, len,
  102. &vc->dma_descs[pb].phys);
  103. if (!virt) {
  104. v4l2_err(&dev->v4l2_dev,
  105. "dma%d: unable to allocate %s-buffer\n",
  106. vc->ch, pb ? "B" : "P");
  107. return -ENOMEM;
  108. }
  109. vc->dma_descs[pb].size = len;
  110. vc->dma_descs[pb].virt = virt;
  111. reg_write(dev, reg, vc->dma_descs[pb].phys);
  112. return 0;
  113. }
  114. static void tw686x_memcpy_buf_refill(struct tw686x_video_channel *vc,
  115. unsigned int pb)
  116. {
  117. struct tw686x_v4l2_buf *buf;
  118. while (!list_empty(&vc->vidq_queued)) {
  119. buf = list_first_entry(&vc->vidq_queued,
  120. struct tw686x_v4l2_buf, list);
  121. list_del(&buf->list);
  122. vc->curr_bufs[pb] = buf;
  123. return;
  124. }
  125. vc->curr_bufs[pb] = NULL;
  126. }
  127. const struct tw686x_dma_ops memcpy_dma_ops = {
  128. .alloc = tw686x_memcpy_dma_alloc,
  129. .free = tw686x_memcpy_dma_free,
  130. .buf_refill = tw686x_memcpy_buf_refill,
  131. .mem_ops = &vb2_vmalloc_memops,
  132. .hw_dma_mode = TW686X_FRAME_MODE,
  133. .field = V4L2_FIELD_INTERLACED,
  134. };
  135. static void tw686x_contig_buf_refill(struct tw686x_video_channel *vc,
  136. unsigned int pb)
  137. {
  138. struct tw686x_v4l2_buf *buf;
  139. while (!list_empty(&vc->vidq_queued)) {
  140. u32 reg = pb ? VDMA_B_ADDR[vc->ch] : VDMA_P_ADDR[vc->ch];
  141. dma_addr_t phys;
  142. buf = list_first_entry(&vc->vidq_queued,
  143. struct tw686x_v4l2_buf, list);
  144. list_del(&buf->list);
  145. phys = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
  146. reg_write(vc->dev, reg, phys);
  147. buf->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
  148. vc->curr_bufs[pb] = buf;
  149. return;
  150. }
  151. vc->curr_bufs[pb] = NULL;
  152. }
  153. const struct tw686x_dma_ops contig_dma_ops = {
  154. .buf_refill = tw686x_contig_buf_refill,
  155. .mem_ops = &vb2_dma_contig_memops,
  156. .hw_dma_mode = TW686X_FRAME_MODE,
  157. .field = V4L2_FIELD_INTERLACED,
  158. };
  159. static int tw686x_sg_desc_fill(struct tw686x_sg_desc *descs,
  160. struct tw686x_v4l2_buf *buf,
  161. unsigned int buf_len)
  162. {
  163. struct sg_table *vbuf = vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0);
  164. unsigned int len, entry_len;
  165. struct scatterlist *sg;
  166. int i, count;
  167. /* Clear the scatter-gather table */
  168. memset(descs, 0, TW686X_SG_TABLE_SIZE);
  169. count = 0;
  170. for_each_sg(vbuf->sgl, sg, vbuf->nents, i) {
  171. dma_addr_t phys = sg_dma_address(sg);
  172. len = sg_dma_len(sg);
  173. while (len && buf_len) {
  174. if (count == TW686X_MAX_SG_DESC_COUNT)
  175. return -ENOMEM;
  176. entry_len = min_t(unsigned int, len,
  177. TW686X_MAX_SG_ENTRY_SIZE);
  178. entry_len = min_t(unsigned int, entry_len, buf_len);
  179. descs[count].phys = cpu_to_le32(phys);
  180. descs[count++].flags_length =
  181. cpu_to_le32(BIT(30) | entry_len);
  182. phys += entry_len;
  183. len -= entry_len;
  184. buf_len -= entry_len;
  185. }
  186. if (!buf_len)
  187. return 0;
  188. }
  189. return -ENOMEM;
  190. }
  191. static void tw686x_sg_buf_refill(struct tw686x_video_channel *vc,
  192. unsigned int pb)
  193. {
  194. struct tw686x_dev *dev = vc->dev;
  195. struct tw686x_v4l2_buf *buf;
  196. while (!list_empty(&vc->vidq_queued)) {
  197. unsigned int buf_len;
  198. buf = list_first_entry(&vc->vidq_queued,
  199. struct tw686x_v4l2_buf, list);
  200. list_del(&buf->list);
  201. buf_len = (vc->width * vc->height * vc->format->depth) >> 3;
  202. if (tw686x_sg_desc_fill(vc->sg_descs[pb], buf, buf_len)) {
  203. v4l2_err(&dev->v4l2_dev,
  204. "dma%d: unable to fill %s-buffer\n",
  205. vc->ch, pb ? "B" : "P");
  206. vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
  207. continue;
  208. }
  209. buf->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
  210. vc->curr_bufs[pb] = buf;
  211. return;
  212. }
  213. vc->curr_bufs[pb] = NULL;
  214. }
  215. static void tw686x_sg_dma_free(struct tw686x_video_channel *vc,
  216. unsigned int pb)
  217. {
  218. struct tw686x_dma_desc *desc = &vc->dma_descs[pb];
  219. struct tw686x_dev *dev = vc->dev;
  220. if (desc->size) {
  221. pci_free_consistent(dev->pci_dev, desc->size,
  222. desc->virt, desc->phys);
  223. desc->virt = NULL;
  224. }
  225. vc->sg_descs[pb] = NULL;
  226. }
  227. static int tw686x_sg_dma_alloc(struct tw686x_video_channel *vc,
  228. unsigned int pb)
  229. {
  230. struct tw686x_dma_desc *desc = &vc->dma_descs[pb];
  231. struct tw686x_dev *dev = vc->dev;
  232. u32 reg = pb ? DMA_PAGE_TABLE1_ADDR[vc->ch] :
  233. DMA_PAGE_TABLE0_ADDR[vc->ch];
  234. void *virt;
  235. if (desc->size) {
  236. virt = pci_alloc_consistent(dev->pci_dev, desc->size,
  237. &desc->phys);
  238. if (!virt) {
  239. v4l2_err(&dev->v4l2_dev,
  240. "dma%d: unable to allocate %s-buffer\n",
  241. vc->ch, pb ? "B" : "P");
  242. return -ENOMEM;
  243. }
  244. desc->virt = virt;
  245. reg_write(dev, reg, desc->phys);
  246. } else {
  247. virt = dev->video_channels[0].dma_descs[pb].virt +
  248. vc->ch * TW686X_SG_TABLE_SIZE;
  249. }
  250. vc->sg_descs[pb] = virt;
  251. return 0;
  252. }
  253. static int tw686x_sg_setup(struct tw686x_dev *dev)
  254. {
  255. unsigned int sg_table_size, pb, ch, channels;
  256. if (is_second_gen(dev)) {
  257. /*
  258. * TW6865/TW6869: each channel needs a pair of
  259. * P-B descriptor tables.
  260. */
  261. channels = max_channels(dev);
  262. sg_table_size = TW686X_SG_TABLE_SIZE;
  263. } else {
  264. /*
  265. * TW6864/TW6868: we need to allocate a pair of
  266. * P-B descriptor tables, common for all channels.
  267. * Each table will be bigger than 4 KB.
  268. */
  269. channels = 1;
  270. sg_table_size = max_channels(dev) * TW686X_SG_TABLE_SIZE;
  271. }
  272. for (ch = 0; ch < channels; ch++) {
  273. struct tw686x_video_channel *vc = &dev->video_channels[ch];
  274. for (pb = 0; pb < 2; pb++)
  275. vc->dma_descs[pb].size = sg_table_size;
  276. }
  277. return 0;
  278. }
  279. const struct tw686x_dma_ops sg_dma_ops = {
  280. .setup = tw686x_sg_setup,
  281. .alloc = tw686x_sg_dma_alloc,
  282. .free = tw686x_sg_dma_free,
  283. .buf_refill = tw686x_sg_buf_refill,
  284. .mem_ops = &vb2_dma_sg_memops,
  285. .hw_dma_mode = TW686X_SG_MODE,
  286. .field = V4L2_FIELD_SEQ_TB,
  287. };
  288. static unsigned int tw686x_fields_map(v4l2_std_id std, unsigned int fps)
  289. {
  290. static const unsigned int map[15] = {
  291. 0x00000000, 0x00000001, 0x00004001, 0x00104001, 0x00404041,
  292. 0x01041041, 0x01104411, 0x01111111, 0x04444445, 0x04511445,
  293. 0x05145145, 0x05151515, 0x05515455, 0x05551555, 0x05555555
  294. };
  295. static const unsigned int std_625_50[26] = {
  296. 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7,
  297. 8, 8, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 0
  298. };
  299. static const unsigned int std_525_60[31] = {
  300. 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
  301. 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 0, 0
  302. };
  303. unsigned int i;
  304. if (std & V4L2_STD_525_60) {
  305. if (fps >= ARRAY_SIZE(std_525_60))
  306. fps = 30;
  307. i = std_525_60[fps];
  308. } else {
  309. if (fps >= ARRAY_SIZE(std_625_50))
  310. fps = 25;
  311. i = std_625_50[fps];
  312. }
  313. return map[i];
  314. }
  315. static void tw686x_set_framerate(struct tw686x_video_channel *vc,
  316. unsigned int fps)
  317. {
  318. unsigned int map;
  319. if (vc->fps == fps)
  320. return;
  321. map = tw686x_fields_map(vc->video_standard, fps) << 1;
  322. map |= map << 1;
  323. if (map > 0)
  324. map |= BIT(31);
  325. reg_write(vc->dev, VIDEO_FIELD_CTRL[vc->ch], map);
  326. vc->fps = fps;
  327. }
  328. static const struct tw686x_format *format_by_fourcc(unsigned int fourcc)
  329. {
  330. unsigned int cnt;
  331. for (cnt = 0; cnt < ARRAY_SIZE(formats); cnt++)
  332. if (formats[cnt].fourcc == fourcc)
  333. return &formats[cnt];
  334. return NULL;
  335. }
  336. static int tw686x_queue_setup(struct vb2_queue *vq,
  337. unsigned int *nbuffers, unsigned int *nplanes,
  338. unsigned int sizes[], void *alloc_ctxs[])
  339. {
  340. struct tw686x_video_channel *vc = vb2_get_drv_priv(vq);
  341. unsigned int szimage =
  342. (vc->width * vc->height * vc->format->depth) >> 3;
  343. /*
  344. * Let's request at least three buffers: two for the
  345. * DMA engine and one for userspace.
  346. */
  347. if (vq->num_buffers + *nbuffers < 3)
  348. *nbuffers = 3 - vq->num_buffers;
  349. if (*nplanes) {
  350. if (*nplanes != 1 || sizes[0] < szimage)
  351. return -EINVAL;
  352. return 0;
  353. }
  354. sizes[0] = szimage;
  355. *nplanes = 1;
  356. return 0;
  357. }
  358. static void tw686x_buf_queue(struct vb2_buffer *vb)
  359. {
  360. struct tw686x_video_channel *vc = vb2_get_drv_priv(vb->vb2_queue);
  361. struct tw686x_dev *dev = vc->dev;
  362. struct pci_dev *pci_dev;
  363. unsigned long flags;
  364. struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
  365. struct tw686x_v4l2_buf *buf =
  366. container_of(vbuf, struct tw686x_v4l2_buf, vb);
  367. /* Check device presence */
  368. spin_lock_irqsave(&dev->lock, flags);
  369. pci_dev = dev->pci_dev;
  370. spin_unlock_irqrestore(&dev->lock, flags);
  371. if (!pci_dev) {
  372. vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
  373. return;
  374. }
  375. spin_lock_irqsave(&vc->qlock, flags);
  376. list_add_tail(&buf->list, &vc->vidq_queued);
  377. spin_unlock_irqrestore(&vc->qlock, flags);
  378. }
  379. static void tw686x_clear_queue(struct tw686x_video_channel *vc,
  380. enum vb2_buffer_state state)
  381. {
  382. unsigned int pb;
  383. while (!list_empty(&vc->vidq_queued)) {
  384. struct tw686x_v4l2_buf *buf;
  385. buf = list_first_entry(&vc->vidq_queued,
  386. struct tw686x_v4l2_buf, list);
  387. list_del(&buf->list);
  388. vb2_buffer_done(&buf->vb.vb2_buf, state);
  389. }
  390. for (pb = 0; pb < 2; pb++) {
  391. if (vc->curr_bufs[pb])
  392. vb2_buffer_done(&vc->curr_bufs[pb]->vb.vb2_buf, state);
  393. vc->curr_bufs[pb] = NULL;
  394. }
  395. }
  396. static int tw686x_start_streaming(struct vb2_queue *vq, unsigned int count)
  397. {
  398. struct tw686x_video_channel *vc = vb2_get_drv_priv(vq);
  399. struct tw686x_dev *dev = vc->dev;
  400. struct pci_dev *pci_dev;
  401. unsigned long flags;
  402. int pb, err;
  403. /* Check device presence */
  404. spin_lock_irqsave(&dev->lock, flags);
  405. pci_dev = dev->pci_dev;
  406. spin_unlock_irqrestore(&dev->lock, flags);
  407. if (!pci_dev) {
  408. err = -ENODEV;
  409. goto err_clear_queue;
  410. }
  411. spin_lock_irqsave(&vc->qlock, flags);
  412. /* Sanity check */
  413. if (dev->dma_mode == TW686X_DMA_MODE_MEMCPY &&
  414. (!vc->dma_descs[0].virt || !vc->dma_descs[1].virt)) {
  415. spin_unlock_irqrestore(&vc->qlock, flags);
  416. v4l2_err(&dev->v4l2_dev,
  417. "video%d: refusing to start without DMA buffers\n",
  418. vc->num);
  419. err = -ENOMEM;
  420. goto err_clear_queue;
  421. }
  422. for (pb = 0; pb < 2; pb++)
  423. dev->dma_ops->buf_refill(vc, pb);
  424. spin_unlock_irqrestore(&vc->qlock, flags);
  425. vc->sequence = 0;
  426. vc->pb = 0;
  427. spin_lock_irqsave(&dev->lock, flags);
  428. tw686x_enable_channel(dev, vc->ch);
  429. spin_unlock_irqrestore(&dev->lock, flags);
  430. mod_timer(&dev->dma_delay_timer, jiffies + msecs_to_jiffies(100));
  431. return 0;
  432. err_clear_queue:
  433. spin_lock_irqsave(&vc->qlock, flags);
  434. tw686x_clear_queue(vc, VB2_BUF_STATE_QUEUED);
  435. spin_unlock_irqrestore(&vc->qlock, flags);
  436. return err;
  437. }
  438. static void tw686x_stop_streaming(struct vb2_queue *vq)
  439. {
  440. struct tw686x_video_channel *vc = vb2_get_drv_priv(vq);
  441. struct tw686x_dev *dev = vc->dev;
  442. struct pci_dev *pci_dev;
  443. unsigned long flags;
  444. /* Check device presence */
  445. spin_lock_irqsave(&dev->lock, flags);
  446. pci_dev = dev->pci_dev;
  447. spin_unlock_irqrestore(&dev->lock, flags);
  448. if (pci_dev)
  449. tw686x_disable_channel(dev, vc->ch);
  450. spin_lock_irqsave(&vc->qlock, flags);
  451. tw686x_clear_queue(vc, VB2_BUF_STATE_ERROR);
  452. spin_unlock_irqrestore(&vc->qlock, flags);
  453. }
  454. static int tw686x_buf_prepare(struct vb2_buffer *vb)
  455. {
  456. struct tw686x_video_channel *vc = vb2_get_drv_priv(vb->vb2_queue);
  457. unsigned int size =
  458. (vc->width * vc->height * vc->format->depth) >> 3;
  459. if (vb2_plane_size(vb, 0) < size)
  460. return -EINVAL;
  461. vb2_set_plane_payload(vb, 0, size);
  462. return 0;
  463. }
  464. static struct vb2_ops tw686x_video_qops = {
  465. .queue_setup = tw686x_queue_setup,
  466. .buf_queue = tw686x_buf_queue,
  467. .buf_prepare = tw686x_buf_prepare,
  468. .start_streaming = tw686x_start_streaming,
  469. .stop_streaming = tw686x_stop_streaming,
  470. .wait_prepare = vb2_ops_wait_prepare,
  471. .wait_finish = vb2_ops_wait_finish,
  472. };
  473. static int tw686x_s_ctrl(struct v4l2_ctrl *ctrl)
  474. {
  475. struct tw686x_video_channel *vc;
  476. struct tw686x_dev *dev;
  477. unsigned int ch;
  478. vc = container_of(ctrl->handler, struct tw686x_video_channel,
  479. ctrl_handler);
  480. dev = vc->dev;
  481. ch = vc->ch;
  482. switch (ctrl->id) {
  483. case V4L2_CID_BRIGHTNESS:
  484. reg_write(dev, BRIGHT[ch], ctrl->val & 0xff);
  485. return 0;
  486. case V4L2_CID_CONTRAST:
  487. reg_write(dev, CONTRAST[ch], ctrl->val);
  488. return 0;
  489. case V4L2_CID_SATURATION:
  490. reg_write(dev, SAT_U[ch], ctrl->val);
  491. reg_write(dev, SAT_V[ch], ctrl->val);
  492. return 0;
  493. case V4L2_CID_HUE:
  494. reg_write(dev, HUE[ch], ctrl->val & 0xff);
  495. return 0;
  496. }
  497. return -EINVAL;
  498. }
  499. static const struct v4l2_ctrl_ops ctrl_ops = {
  500. .s_ctrl = tw686x_s_ctrl,
  501. };
  502. static int tw686x_g_fmt_vid_cap(struct file *file, void *priv,
  503. struct v4l2_format *f)
  504. {
  505. struct tw686x_video_channel *vc = video_drvdata(file);
  506. struct tw686x_dev *dev = vc->dev;
  507. f->fmt.pix.width = vc->width;
  508. f->fmt.pix.height = vc->height;
  509. f->fmt.pix.field = dev->dma_ops->field;
  510. f->fmt.pix.pixelformat = vc->format->fourcc;
  511. f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
  512. f->fmt.pix.bytesperline = (f->fmt.pix.width * vc->format->depth) / 8;
  513. f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
  514. return 0;
  515. }
  516. static int tw686x_try_fmt_vid_cap(struct file *file, void *priv,
  517. struct v4l2_format *f)
  518. {
  519. struct tw686x_video_channel *vc = video_drvdata(file);
  520. struct tw686x_dev *dev = vc->dev;
  521. unsigned int video_height = TW686X_VIDEO_HEIGHT(vc->video_standard);
  522. const struct tw686x_format *format;
  523. format = format_by_fourcc(f->fmt.pix.pixelformat);
  524. if (!format) {
  525. format = &formats[0];
  526. f->fmt.pix.pixelformat = format->fourcc;
  527. }
  528. if (f->fmt.pix.width <= TW686X_VIDEO_WIDTH / 2)
  529. f->fmt.pix.width = TW686X_VIDEO_WIDTH / 2;
  530. else
  531. f->fmt.pix.width = TW686X_VIDEO_WIDTH;
  532. if (f->fmt.pix.height <= video_height / 2)
  533. f->fmt.pix.height = video_height / 2;
  534. else
  535. f->fmt.pix.height = video_height;
  536. f->fmt.pix.bytesperline = (f->fmt.pix.width * format->depth) / 8;
  537. f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
  538. f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
  539. f->fmt.pix.field = dev->dma_ops->field;
  540. return 0;
  541. }
  542. static int tw686x_s_fmt_vid_cap(struct file *file, void *priv,
  543. struct v4l2_format *f)
  544. {
  545. struct tw686x_video_channel *vc = video_drvdata(file);
  546. struct tw686x_dev *dev = vc->dev;
  547. u32 val, width, line_width, height;
  548. unsigned long bitsperframe;
  549. int err, pb;
  550. if (vb2_is_busy(&vc->vidq))
  551. return -EBUSY;
  552. bitsperframe = vc->width * vc->height * vc->format->depth;
  553. err = tw686x_try_fmt_vid_cap(file, priv, f);
  554. if (err)
  555. return err;
  556. vc->format = format_by_fourcc(f->fmt.pix.pixelformat);
  557. vc->width = f->fmt.pix.width;
  558. vc->height = f->fmt.pix.height;
  559. /* We need new DMA buffers if the framesize has changed */
  560. if (dev->dma_ops->alloc &&
  561. bitsperframe != vc->width * vc->height * vc->format->depth) {
  562. for (pb = 0; pb < 2; pb++)
  563. dev->dma_ops->free(vc, pb);
  564. for (pb = 0; pb < 2; pb++) {
  565. err = dev->dma_ops->alloc(vc, pb);
  566. if (err) {
  567. if (pb > 0)
  568. dev->dma_ops->free(vc, 0);
  569. return err;
  570. }
  571. }
  572. }
  573. val = reg_read(vc->dev, VDMA_CHANNEL_CONFIG[vc->ch]);
  574. if (vc->width <= TW686X_VIDEO_WIDTH / 2)
  575. val |= BIT(23);
  576. else
  577. val &= ~BIT(23);
  578. if (vc->height <= TW686X_VIDEO_HEIGHT(vc->video_standard) / 2)
  579. val |= BIT(24);
  580. else
  581. val &= ~BIT(24);
  582. val &= ~0x7ffff;
  583. /* Program the DMA scatter-gather */
  584. if (dev->dma_mode == TW686X_DMA_MODE_SG) {
  585. u32 start_idx, end_idx;
  586. start_idx = is_second_gen(dev) ?
  587. 0 : vc->ch * TW686X_MAX_SG_DESC_COUNT;
  588. end_idx = start_idx + TW686X_MAX_SG_DESC_COUNT - 1;
  589. val |= (end_idx << 10) | start_idx;
  590. }
  591. val &= ~(0x7 << 20);
  592. val |= vc->format->mode << 20;
  593. reg_write(vc->dev, VDMA_CHANNEL_CONFIG[vc->ch], val);
  594. /* Program the DMA frame size */
  595. width = (vc->width * 2) & 0x7ff;
  596. height = vc->height / 2;
  597. line_width = (vc->width * 2) & 0x7ff;
  598. val = (height << 22) | (line_width << 11) | width;
  599. reg_write(vc->dev, VDMA_WHP[vc->ch], val);
  600. return 0;
  601. }
  602. static int tw686x_querycap(struct file *file, void *priv,
  603. struct v4l2_capability *cap)
  604. {
  605. struct tw686x_video_channel *vc = video_drvdata(file);
  606. struct tw686x_dev *dev = vc->dev;
  607. strlcpy(cap->driver, "tw686x", sizeof(cap->driver));
  608. strlcpy(cap->card, dev->name, sizeof(cap->card));
  609. snprintf(cap->bus_info, sizeof(cap->bus_info),
  610. "PCI:%s", pci_name(dev->pci_dev));
  611. cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
  612. V4L2_CAP_READWRITE;
  613. cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
  614. return 0;
  615. }
  616. static int tw686x_s_std(struct file *file, void *priv, v4l2_std_id id)
  617. {
  618. struct tw686x_video_channel *vc = video_drvdata(file);
  619. struct v4l2_format f;
  620. u32 val, ret;
  621. if (vc->video_standard == id)
  622. return 0;
  623. if (vb2_is_busy(&vc->vidq))
  624. return -EBUSY;
  625. if (id & V4L2_STD_NTSC)
  626. val = 0;
  627. else if (id & V4L2_STD_PAL)
  628. val = 1;
  629. else if (id & V4L2_STD_SECAM)
  630. val = 2;
  631. else if (id & V4L2_STD_NTSC_443)
  632. val = 3;
  633. else if (id & V4L2_STD_PAL_M)
  634. val = 4;
  635. else if (id & V4L2_STD_PAL_Nc)
  636. val = 5;
  637. else if (id & V4L2_STD_PAL_60)
  638. val = 6;
  639. else
  640. return -EINVAL;
  641. vc->video_standard = id;
  642. reg_write(vc->dev, SDT[vc->ch], val);
  643. val = reg_read(vc->dev, VIDEO_CONTROL1);
  644. if (id & V4L2_STD_525_60)
  645. val &= ~(1 << (SYS_MODE_DMA_SHIFT + vc->ch));
  646. else
  647. val |= (1 << (SYS_MODE_DMA_SHIFT + vc->ch));
  648. reg_write(vc->dev, VIDEO_CONTROL1, val);
  649. /*
  650. * Adjust format after V4L2_STD_525_60/V4L2_STD_625_50 change,
  651. * calling g_fmt and s_fmt will sanitize the height
  652. * according to the standard.
  653. */
  654. ret = tw686x_g_fmt_vid_cap(file, priv, &f);
  655. if (!ret)
  656. tw686x_s_fmt_vid_cap(file, priv, &f);
  657. return 0;
  658. }
  659. static int tw686x_querystd(struct file *file, void *priv, v4l2_std_id *std)
  660. {
  661. struct tw686x_video_channel *vc = video_drvdata(file);
  662. struct tw686x_dev *dev = vc->dev;
  663. unsigned int old_std, detected_std = 0;
  664. unsigned long end;
  665. if (vb2_is_streaming(&vc->vidq))
  666. return -EBUSY;
  667. /* Enable and start standard detection */
  668. old_std = reg_read(dev, SDT[vc->ch]);
  669. reg_write(dev, SDT[vc->ch], 0x7);
  670. reg_write(dev, SDT_EN[vc->ch], 0xff);
  671. end = jiffies + msecs_to_jiffies(500);
  672. while (time_is_after_jiffies(end)) {
  673. detected_std = reg_read(dev, SDT[vc->ch]);
  674. if (!(detected_std & BIT(7)))
  675. break;
  676. msleep(100);
  677. }
  678. reg_write(dev, SDT[vc->ch], old_std);
  679. /* Exit if still busy */
  680. if (detected_std & BIT(7))
  681. return 0;
  682. detected_std = (detected_std >> 4) & 0x7;
  683. switch (detected_std) {
  684. case TW686X_STD_NTSC_M:
  685. *std &= V4L2_STD_NTSC;
  686. break;
  687. case TW686X_STD_NTSC_443:
  688. *std &= V4L2_STD_NTSC_443;
  689. break;
  690. case TW686X_STD_PAL_M:
  691. *std &= V4L2_STD_PAL_M;
  692. break;
  693. case TW686X_STD_PAL_60:
  694. *std &= V4L2_STD_PAL_60;
  695. break;
  696. case TW686X_STD_PAL:
  697. *std &= V4L2_STD_PAL;
  698. break;
  699. case TW686X_STD_PAL_CN:
  700. *std &= V4L2_STD_PAL_Nc;
  701. break;
  702. case TW686X_STD_SECAM:
  703. *std &= V4L2_STD_SECAM;
  704. break;
  705. default:
  706. *std = 0;
  707. }
  708. return 0;
  709. }
  710. static int tw686x_g_std(struct file *file, void *priv, v4l2_std_id *id)
  711. {
  712. struct tw686x_video_channel *vc = video_drvdata(file);
  713. *id = vc->video_standard;
  714. return 0;
  715. }
  716. static int tw686x_enum_fmt_vid_cap(struct file *file, void *priv,
  717. struct v4l2_fmtdesc *f)
  718. {
  719. if (f->index >= ARRAY_SIZE(formats))
  720. return -EINVAL;
  721. f->pixelformat = formats[f->index].fourcc;
  722. return 0;
  723. }
  724. static int tw686x_s_input(struct file *file, void *priv, unsigned int i)
  725. {
  726. struct tw686x_video_channel *vc = video_drvdata(file);
  727. u32 val;
  728. if (i >= TW686X_INPUTS_PER_CH)
  729. return -EINVAL;
  730. if (i == vc->input)
  731. return 0;
  732. /*
  733. * Not sure we are able to support on the fly input change
  734. */
  735. if (vb2_is_busy(&vc->vidq))
  736. return -EBUSY;
  737. vc->input = i;
  738. val = reg_read(vc->dev, VDMA_CHANNEL_CONFIG[vc->ch]);
  739. val &= ~(0x3 << 30);
  740. val |= i << 30;
  741. reg_write(vc->dev, VDMA_CHANNEL_CONFIG[vc->ch], val);
  742. return 0;
  743. }
  744. static int tw686x_g_input(struct file *file, void *priv, unsigned int *i)
  745. {
  746. struct tw686x_video_channel *vc = video_drvdata(file);
  747. *i = vc->input;
  748. return 0;
  749. }
  750. static int tw686x_enum_input(struct file *file, void *priv,
  751. struct v4l2_input *i)
  752. {
  753. struct tw686x_video_channel *vc = video_drvdata(file);
  754. unsigned int vidstat;
  755. if (i->index >= TW686X_INPUTS_PER_CH)
  756. return -EINVAL;
  757. snprintf(i->name, sizeof(i->name), "Composite%d", i->index);
  758. i->type = V4L2_INPUT_TYPE_CAMERA;
  759. i->std = vc->device->tvnorms;
  760. i->capabilities = V4L2_IN_CAP_STD;
  761. vidstat = reg_read(vc->dev, VIDSTAT[vc->ch]);
  762. i->status = 0;
  763. if (vidstat & TW686X_VIDSTAT_VDLOSS)
  764. i->status |= V4L2_IN_ST_NO_SIGNAL;
  765. if (!(vidstat & TW686X_VIDSTAT_HLOCK))
  766. i->status |= V4L2_IN_ST_NO_H_LOCK;
  767. return 0;
  768. }
  769. static const struct v4l2_file_operations tw686x_video_fops = {
  770. .owner = THIS_MODULE,
  771. .open = v4l2_fh_open,
  772. .unlocked_ioctl = video_ioctl2,
  773. .release = vb2_fop_release,
  774. .poll = vb2_fop_poll,
  775. .read = vb2_fop_read,
  776. .mmap = vb2_fop_mmap,
  777. };
  778. static const struct v4l2_ioctl_ops tw686x_video_ioctl_ops = {
  779. .vidioc_querycap = tw686x_querycap,
  780. .vidioc_g_fmt_vid_cap = tw686x_g_fmt_vid_cap,
  781. .vidioc_s_fmt_vid_cap = tw686x_s_fmt_vid_cap,
  782. .vidioc_enum_fmt_vid_cap = tw686x_enum_fmt_vid_cap,
  783. .vidioc_try_fmt_vid_cap = tw686x_try_fmt_vid_cap,
  784. .vidioc_querystd = tw686x_querystd,
  785. .vidioc_g_std = tw686x_g_std,
  786. .vidioc_s_std = tw686x_s_std,
  787. .vidioc_enum_input = tw686x_enum_input,
  788. .vidioc_g_input = tw686x_g_input,
  789. .vidioc_s_input = tw686x_s_input,
  790. .vidioc_reqbufs = vb2_ioctl_reqbufs,
  791. .vidioc_querybuf = vb2_ioctl_querybuf,
  792. .vidioc_qbuf = vb2_ioctl_qbuf,
  793. .vidioc_dqbuf = vb2_ioctl_dqbuf,
  794. .vidioc_create_bufs = vb2_ioctl_create_bufs,
  795. .vidioc_streamon = vb2_ioctl_streamon,
  796. .vidioc_streamoff = vb2_ioctl_streamoff,
  797. .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
  798. .vidioc_log_status = v4l2_ctrl_log_status,
  799. .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
  800. .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
  801. };
  802. void tw686x_video_irq(struct tw686x_dev *dev, unsigned long requests,
  803. unsigned int pb_status, unsigned int fifo_status,
  804. unsigned int *reset_ch)
  805. {
  806. struct tw686x_video_channel *vc;
  807. unsigned long flags;
  808. unsigned int ch, pb;
  809. for_each_set_bit(ch, &requests, max_channels(dev)) {
  810. vc = &dev->video_channels[ch];
  811. /*
  812. * This can either be a blue frame (with signal-lost bit set)
  813. * or a good frame (with signal-lost bit clear). If we have just
  814. * got signal, then this channel needs resetting.
  815. */
  816. if (vc->no_signal && !(fifo_status & BIT(ch))) {
  817. v4l2_printk(KERN_DEBUG, &dev->v4l2_dev,
  818. "video%d: signal recovered\n", vc->num);
  819. vc->no_signal = false;
  820. *reset_ch |= BIT(ch);
  821. vc->pb = 0;
  822. continue;
  823. }
  824. vc->no_signal = !!(fifo_status & BIT(ch));
  825. /* Check FIFO errors only if there's signal */
  826. if (!vc->no_signal) {
  827. u32 fifo_ov, fifo_bad;
  828. fifo_ov = (fifo_status >> 24) & BIT(ch);
  829. fifo_bad = (fifo_status >> 16) & BIT(ch);
  830. if (fifo_ov || fifo_bad) {
  831. /* Mark this channel for reset */
  832. v4l2_printk(KERN_DEBUG, &dev->v4l2_dev,
  833. "video%d: FIFO error\n", vc->num);
  834. *reset_ch |= BIT(ch);
  835. vc->pb = 0;
  836. continue;
  837. }
  838. }
  839. pb = !!(pb_status & BIT(ch));
  840. if (vc->pb != pb) {
  841. /* Mark this channel for reset */
  842. v4l2_printk(KERN_DEBUG, &dev->v4l2_dev,
  843. "video%d: unexpected p-b buffer!\n",
  844. vc->num);
  845. *reset_ch |= BIT(ch);
  846. vc->pb = 0;
  847. continue;
  848. }
  849. spin_lock_irqsave(&vc->qlock, flags);
  850. tw686x_buf_done(vc, pb);
  851. dev->dma_ops->buf_refill(vc, pb);
  852. spin_unlock_irqrestore(&vc->qlock, flags);
  853. }
  854. }
  855. void tw686x_video_free(struct tw686x_dev *dev)
  856. {
  857. unsigned int ch, pb;
  858. for (ch = 0; ch < max_channels(dev); ch++) {
  859. struct tw686x_video_channel *vc = &dev->video_channels[ch];
  860. if (vc->device)
  861. video_unregister_device(vc->device);
  862. if (dev->dma_ops->free)
  863. for (pb = 0; pb < 2; pb++)
  864. dev->dma_ops->free(vc, pb);
  865. }
  866. }
  867. int tw686x_video_init(struct tw686x_dev *dev)
  868. {
  869. unsigned int ch, val, pb;
  870. int err;
  871. if (dev->dma_mode == TW686X_DMA_MODE_MEMCPY)
  872. dev->dma_ops = &memcpy_dma_ops;
  873. else if (dev->dma_mode == TW686X_DMA_MODE_CONTIG)
  874. dev->dma_ops = &contig_dma_ops;
  875. else if (dev->dma_mode == TW686X_DMA_MODE_SG)
  876. dev->dma_ops = &sg_dma_ops;
  877. else
  878. return -EINVAL;
  879. err = v4l2_device_register(&dev->pci_dev->dev, &dev->v4l2_dev);
  880. if (err)
  881. return err;
  882. if (dev->dma_ops->setup) {
  883. err = dev->dma_ops->setup(dev);
  884. if (err)
  885. return err;
  886. }
  887. for (ch = 0; ch < max_channels(dev); ch++) {
  888. struct tw686x_video_channel *vc = &dev->video_channels[ch];
  889. struct video_device *vdev;
  890. mutex_init(&vc->vb_mutex);
  891. spin_lock_init(&vc->qlock);
  892. INIT_LIST_HEAD(&vc->vidq_queued);
  893. vc->dev = dev;
  894. vc->ch = ch;
  895. /* default settings */
  896. vc->format = &formats[0];
  897. vc->video_standard = V4L2_STD_NTSC;
  898. vc->width = TW686X_VIDEO_WIDTH;
  899. vc->height = TW686X_VIDEO_HEIGHT(vc->video_standard);
  900. vc->input = 0;
  901. reg_write(vc->dev, SDT[ch], 0);
  902. tw686x_set_framerate(vc, 30);
  903. reg_write(dev, VDELAY_LO[ch], 0x14);
  904. reg_write(dev, HACTIVE_LO[ch], 0xd0);
  905. reg_write(dev, VIDEO_SIZE[ch], 0);
  906. if (dev->dma_ops->alloc) {
  907. for (pb = 0; pb < 2; pb++) {
  908. err = dev->dma_ops->alloc(vc, pb);
  909. if (err)
  910. goto error;
  911. }
  912. }
  913. vc->vidq.io_modes = VB2_READ | VB2_MMAP | VB2_DMABUF;
  914. vc->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  915. vc->vidq.drv_priv = vc;
  916. vc->vidq.buf_struct_size = sizeof(struct tw686x_v4l2_buf);
  917. vc->vidq.ops = &tw686x_video_qops;
  918. vc->vidq.mem_ops = dev->dma_ops->mem_ops;
  919. vc->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
  920. vc->vidq.min_buffers_needed = 2;
  921. vc->vidq.lock = &vc->vb_mutex;
  922. vc->vidq.gfp_flags = GFP_DMA32;
  923. vc->vidq.dev = &dev->pci_dev->dev;
  924. err = vb2_queue_init(&vc->vidq);
  925. if (err) {
  926. v4l2_err(&dev->v4l2_dev,
  927. "dma%d: cannot init vb2 queue\n", ch);
  928. goto error;
  929. }
  930. err = v4l2_ctrl_handler_init(&vc->ctrl_handler, 4);
  931. if (err) {
  932. v4l2_err(&dev->v4l2_dev,
  933. "dma%d: cannot init ctrl handler\n", ch);
  934. goto error;
  935. }
  936. v4l2_ctrl_new_std(&vc->ctrl_handler, &ctrl_ops,
  937. V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
  938. v4l2_ctrl_new_std(&vc->ctrl_handler, &ctrl_ops,
  939. V4L2_CID_CONTRAST, 0, 255, 1, 100);
  940. v4l2_ctrl_new_std(&vc->ctrl_handler, &ctrl_ops,
  941. V4L2_CID_SATURATION, 0, 255, 1, 128);
  942. v4l2_ctrl_new_std(&vc->ctrl_handler, &ctrl_ops,
  943. V4L2_CID_HUE, -128, 127, 1, 0);
  944. err = vc->ctrl_handler.error;
  945. if (err)
  946. goto error;
  947. err = v4l2_ctrl_handler_setup(&vc->ctrl_handler);
  948. if (err)
  949. goto error;
  950. vdev = video_device_alloc();
  951. if (!vdev) {
  952. v4l2_err(&dev->v4l2_dev,
  953. "dma%d: unable to allocate device\n", ch);
  954. err = -ENOMEM;
  955. goto error;
  956. }
  957. snprintf(vdev->name, sizeof(vdev->name), "%s video", dev->name);
  958. vdev->fops = &tw686x_video_fops;
  959. vdev->ioctl_ops = &tw686x_video_ioctl_ops;
  960. vdev->release = video_device_release;
  961. vdev->v4l2_dev = &dev->v4l2_dev;
  962. vdev->queue = &vc->vidq;
  963. vdev->tvnorms = V4L2_STD_525_60 | V4L2_STD_625_50;
  964. vdev->minor = -1;
  965. vdev->lock = &vc->vb_mutex;
  966. vdev->ctrl_handler = &vc->ctrl_handler;
  967. vc->device = vdev;
  968. video_set_drvdata(vdev, vc);
  969. err = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
  970. if (err < 0)
  971. goto error;
  972. vc->num = vdev->num;
  973. }
  974. val = TW686X_DEF_PHASE_REF;
  975. for (ch = 0; ch < max_channels(dev); ch++)
  976. val |= dev->dma_ops->hw_dma_mode << (16 + ch * 2);
  977. reg_write(dev, PHASE_REF, val);
  978. reg_write(dev, MISC2[0], 0xe7);
  979. reg_write(dev, VCTRL1[0], 0xcc);
  980. reg_write(dev, LOOP[0], 0xa5);
  981. if (max_channels(dev) > 4) {
  982. reg_write(dev, VCTRL1[1], 0xcc);
  983. reg_write(dev, LOOP[1], 0xa5);
  984. reg_write(dev, MISC2[1], 0xe7);
  985. }
  986. return 0;
  987. error:
  988. tw686x_video_free(dev);
  989. return err;
  990. }