saa7164-vbi.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375
  1. /*
  2. * Driver for the NXP SAA7164 PCIe bridge
  3. *
  4. * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. *
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include "saa7164.h"
  22. static struct saa7164_tvnorm saa7164_tvnorms[] = {
  23. {
  24. .name = "NTSC-M",
  25. .id = V4L2_STD_NTSC_M,
  26. }, {
  27. .name = "NTSC-JP",
  28. .id = V4L2_STD_NTSC_M_JP,
  29. }
  30. };
  31. static const u32 saa7164_v4l2_ctrls[] = {
  32. 0
  33. };
  34. /* Take the encoder configuration from the port struct and
  35. * flush it to the hardware.
  36. */
  37. static void saa7164_vbi_configure(struct saa7164_port *port)
  38. {
  39. struct saa7164_dev *dev = port->dev;
  40. dprintk(DBGLVL_VBI, "%s()\n", __func__);
  41. port->vbi_params.width = port->width;
  42. port->vbi_params.height = port->height;
  43. port->vbi_params.is_50hz =
  44. (port->encodernorm.id & V4L2_STD_625_50) != 0;
  45. /* Set up the DIF (enable it) for analog mode by default */
  46. saa7164_api_initialize_dif(port);
  47. // /* Configure the correct video standard */
  48. // saa7164_api_configure_dif(port, port->encodernorm.id);
  49. // /* Ensure the audio decoder is correct configured */
  50. // saa7164_api_set_audio_std(port);
  51. dprintk(DBGLVL_VBI, "%s() ends\n", __func__);
  52. }
  53. static int saa7164_vbi_buffers_dealloc(struct saa7164_port *port)
  54. {
  55. struct list_head *c, *n, *p, *q, *l, *v;
  56. struct saa7164_dev *dev = port->dev;
  57. struct saa7164_buffer *buf;
  58. struct saa7164_user_buffer *ubuf;
  59. /* Remove any allocated buffers */
  60. mutex_lock(&port->dmaqueue_lock);
  61. dprintk(DBGLVL_VBI, "%s(port=%d) dmaqueue\n", __func__, port->nr);
  62. list_for_each_safe(c, n, &port->dmaqueue.list) {
  63. buf = list_entry(c, struct saa7164_buffer, list);
  64. list_del(c);
  65. saa7164_buffer_dealloc(buf);
  66. }
  67. dprintk(DBGLVL_VBI, "%s(port=%d) used\n", __func__, port->nr);
  68. list_for_each_safe(p, q, &port->list_buf_used.list) {
  69. ubuf = list_entry(p, struct saa7164_user_buffer, list);
  70. list_del(p);
  71. saa7164_buffer_dealloc_user(ubuf);
  72. }
  73. dprintk(DBGLVL_VBI, "%s(port=%d) free\n", __func__, port->nr);
  74. list_for_each_safe(l, v, &port->list_buf_free.list) {
  75. ubuf = list_entry(l, struct saa7164_user_buffer, list);
  76. list_del(l);
  77. saa7164_buffer_dealloc_user(ubuf);
  78. }
  79. mutex_unlock(&port->dmaqueue_lock);
  80. dprintk(DBGLVL_VBI, "%s(port=%d) done\n", __func__, port->nr);
  81. return 0;
  82. }
  83. /* Dynamic buffer switch at vbi start time */
  84. static int saa7164_vbi_buffers_alloc(struct saa7164_port *port)
  85. {
  86. struct saa7164_dev *dev = port->dev;
  87. struct saa7164_buffer *buf;
  88. struct saa7164_user_buffer *ubuf;
  89. struct tmHWStreamParameters *params = &port->hw_streamingparams;
  90. int result = -ENODEV, i;
  91. int len = 0;
  92. dprintk(DBGLVL_VBI, "%s()\n", __func__);
  93. /* TODO: NTSC SPECIFIC */
  94. /* Init and establish defaults */
  95. params->samplesperline = 1440;
  96. params->numberoflines = 12;
  97. params->numberoflines = 18;
  98. params->pitch = 1600;
  99. params->pitch = 1440;
  100. params->numpagetables = 2 +
  101. ((params->numberoflines * params->pitch) / PAGE_SIZE);
  102. params->bitspersample = 8;
  103. params->linethreshold = 0;
  104. params->pagetablelistvirt = 0;
  105. params->pagetablelistphys = 0;
  106. params->numpagetableentries = port->hwcfg.buffercount;
  107. /* Allocate the PCI resources, buffers (hard) */
  108. for (i = 0; i < port->hwcfg.buffercount; i++) {
  109. buf = saa7164_buffer_alloc(port,
  110. params->numberoflines *
  111. params->pitch);
  112. if (!buf) {
  113. printk(KERN_ERR "%s() failed "
  114. "(errno = %d), unable to allocate buffer\n",
  115. __func__, result);
  116. result = -ENOMEM;
  117. goto failed;
  118. } else {
  119. mutex_lock(&port->dmaqueue_lock);
  120. list_add_tail(&buf->list, &port->dmaqueue.list);
  121. mutex_unlock(&port->dmaqueue_lock);
  122. }
  123. }
  124. /* Allocate some kenrel kernel buffers for copying
  125. * to userpsace.
  126. */
  127. len = params->numberoflines * params->pitch;
  128. if (vbi_buffers < 16)
  129. vbi_buffers = 16;
  130. if (vbi_buffers > 512)
  131. vbi_buffers = 512;
  132. for (i = 0; i < vbi_buffers; i++) {
  133. ubuf = saa7164_buffer_alloc_user(dev, len);
  134. if (ubuf) {
  135. mutex_lock(&port->dmaqueue_lock);
  136. list_add_tail(&ubuf->list, &port->list_buf_free.list);
  137. mutex_unlock(&port->dmaqueue_lock);
  138. }
  139. }
  140. result = 0;
  141. failed:
  142. return result;
  143. }
  144. static int saa7164_vbi_initialize(struct saa7164_port *port)
  145. {
  146. saa7164_vbi_configure(port);
  147. return 0;
  148. }
  149. /* -- V4L2 --------------------------------------------------------- */
  150. static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
  151. {
  152. struct saa7164_vbi_fh *fh = file->private_data;
  153. struct saa7164_port *port = fh->port;
  154. struct saa7164_dev *dev = port->dev;
  155. unsigned int i;
  156. dprintk(DBGLVL_VBI, "%s(id=0x%x)\n", __func__, (u32)*id);
  157. for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
  158. if (*id & saa7164_tvnorms[i].id)
  159. break;
  160. }
  161. if (i == ARRAY_SIZE(saa7164_tvnorms))
  162. return -EINVAL;
  163. port->encodernorm = saa7164_tvnorms[i];
  164. /* Update the audio decoder while is not running in
  165. * auto detect mode.
  166. */
  167. saa7164_api_set_audio_std(port);
  168. dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)*id);
  169. return 0;
  170. }
  171. static int vidioc_enum_input(struct file *file, void *priv,
  172. struct v4l2_input *i)
  173. {
  174. int n;
  175. char *inputs[] = { "tuner", "composite", "svideo", "aux",
  176. "composite 2", "svideo 2", "aux 2" };
  177. if (i->index >= 7)
  178. return -EINVAL;
  179. strcpy(i->name, inputs[i->index]);
  180. if (i->index == 0)
  181. i->type = V4L2_INPUT_TYPE_TUNER;
  182. else
  183. i->type = V4L2_INPUT_TYPE_CAMERA;
  184. for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
  185. i->std |= saa7164_tvnorms[n].id;
  186. return 0;
  187. }
  188. static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
  189. {
  190. struct saa7164_vbi_fh *fh = file->private_data;
  191. struct saa7164_port *port = fh->port;
  192. struct saa7164_dev *dev = port->dev;
  193. if (saa7164_api_get_videomux(port) != SAA_OK)
  194. return -EIO;
  195. *i = (port->mux_input - 1);
  196. dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, *i);
  197. return 0;
  198. }
  199. static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
  200. {
  201. struct saa7164_vbi_fh *fh = file->private_data;
  202. struct saa7164_port *port = fh->port;
  203. struct saa7164_dev *dev = port->dev;
  204. dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, i);
  205. if (i >= 7)
  206. return -EINVAL;
  207. port->mux_input = i + 1;
  208. if (saa7164_api_set_videomux(port) != SAA_OK)
  209. return -EIO;
  210. return 0;
  211. }
  212. static int vidioc_g_tuner(struct file *file, void *priv,
  213. struct v4l2_tuner *t)
  214. {
  215. struct saa7164_vbi_fh *fh = file->private_data;
  216. struct saa7164_port *port = fh->port;
  217. struct saa7164_dev *dev = port->dev;
  218. if (0 != t->index)
  219. return -EINVAL;
  220. strcpy(t->name, "tuner");
  221. t->type = V4L2_TUNER_ANALOG_TV;
  222. t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
  223. dprintk(DBGLVL_VBI, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
  224. return 0;
  225. }
  226. static int vidioc_s_tuner(struct file *file, void *priv,
  227. struct v4l2_tuner *t)
  228. {
  229. /* Update the A/V core */
  230. return 0;
  231. }
  232. static int vidioc_g_frequency(struct file *file, void *priv,
  233. struct v4l2_frequency *f)
  234. {
  235. struct saa7164_vbi_fh *fh = file->private_data;
  236. struct saa7164_port *port = fh->port;
  237. f->type = V4L2_TUNER_ANALOG_TV;
  238. f->frequency = port->freq;
  239. return 0;
  240. }
  241. static int vidioc_s_frequency(struct file *file, void *priv,
  242. struct v4l2_frequency *f)
  243. {
  244. struct saa7164_vbi_fh *fh = file->private_data;
  245. struct saa7164_port *port = fh->port;
  246. struct saa7164_dev *dev = port->dev;
  247. struct saa7164_port *tsport;
  248. struct dvb_frontend *fe;
  249. /* TODO: Pull this for the std */
  250. struct analog_parameters params = {
  251. .mode = V4L2_TUNER_ANALOG_TV,
  252. .audmode = V4L2_TUNER_MODE_STEREO,
  253. .std = port->encodernorm.id,
  254. .frequency = f->frequency
  255. };
  256. /* Stop the encoder */
  257. dprintk(DBGLVL_VBI, "%s() frequency=%d tuner=%d\n", __func__,
  258. f->frequency, f->tuner);
  259. if (f->tuner != 0)
  260. return -EINVAL;
  261. if (f->type != V4L2_TUNER_ANALOG_TV)
  262. return -EINVAL;
  263. port->freq = f->frequency;
  264. /* Update the hardware */
  265. if (port->nr == SAA7164_PORT_VBI1)
  266. tsport = &dev->ports[SAA7164_PORT_TS1];
  267. else
  268. if (port->nr == SAA7164_PORT_VBI2)
  269. tsport = &dev->ports[SAA7164_PORT_TS2];
  270. else
  271. BUG();
  272. fe = tsport->dvb.frontend;
  273. if (fe && fe->ops.tuner_ops.set_analog_params)
  274. fe->ops.tuner_ops.set_analog_params(fe, &params);
  275. else
  276. printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
  277. saa7164_vbi_initialize(port);
  278. return 0;
  279. }
  280. static int vidioc_g_ctrl(struct file *file, void *priv,
  281. struct v4l2_control *ctl)
  282. {
  283. struct saa7164_vbi_fh *fh = file->private_data;
  284. struct saa7164_port *port = fh->port;
  285. struct saa7164_dev *dev = port->dev;
  286. dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
  287. ctl->id, ctl->value);
  288. switch (ctl->id) {
  289. case V4L2_CID_BRIGHTNESS:
  290. ctl->value = port->ctl_brightness;
  291. break;
  292. case V4L2_CID_CONTRAST:
  293. ctl->value = port->ctl_contrast;
  294. break;
  295. case V4L2_CID_SATURATION:
  296. ctl->value = port->ctl_saturation;
  297. break;
  298. case V4L2_CID_HUE:
  299. ctl->value = port->ctl_hue;
  300. break;
  301. case V4L2_CID_SHARPNESS:
  302. ctl->value = port->ctl_sharpness;
  303. break;
  304. case V4L2_CID_AUDIO_VOLUME:
  305. ctl->value = port->ctl_volume;
  306. break;
  307. default:
  308. return -EINVAL;
  309. }
  310. return 0;
  311. }
  312. static int vidioc_s_ctrl(struct file *file, void *priv,
  313. struct v4l2_control *ctl)
  314. {
  315. struct saa7164_vbi_fh *fh = file->private_data;
  316. struct saa7164_port *port = fh->port;
  317. struct saa7164_dev *dev = port->dev;
  318. int ret = 0;
  319. dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
  320. ctl->id, ctl->value);
  321. switch (ctl->id) {
  322. case V4L2_CID_BRIGHTNESS:
  323. if ((ctl->value >= 0) && (ctl->value <= 255)) {
  324. port->ctl_brightness = ctl->value;
  325. saa7164_api_set_usercontrol(port,
  326. PU_BRIGHTNESS_CONTROL);
  327. } else
  328. ret = -EINVAL;
  329. break;
  330. case V4L2_CID_CONTRAST:
  331. if ((ctl->value >= 0) && (ctl->value <= 255)) {
  332. port->ctl_contrast = ctl->value;
  333. saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
  334. } else
  335. ret = -EINVAL;
  336. break;
  337. case V4L2_CID_SATURATION:
  338. if ((ctl->value >= 0) && (ctl->value <= 255)) {
  339. port->ctl_saturation = ctl->value;
  340. saa7164_api_set_usercontrol(port,
  341. PU_SATURATION_CONTROL);
  342. } else
  343. ret = -EINVAL;
  344. break;
  345. case V4L2_CID_HUE:
  346. if ((ctl->value >= 0) && (ctl->value <= 255)) {
  347. port->ctl_hue = ctl->value;
  348. saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
  349. } else
  350. ret = -EINVAL;
  351. break;
  352. case V4L2_CID_SHARPNESS:
  353. if ((ctl->value >= 0) && (ctl->value <= 255)) {
  354. port->ctl_sharpness = ctl->value;
  355. saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
  356. } else
  357. ret = -EINVAL;
  358. break;
  359. case V4L2_CID_AUDIO_VOLUME:
  360. if ((ctl->value >= -83) && (ctl->value <= 24)) {
  361. port->ctl_volume = ctl->value;
  362. saa7164_api_set_audio_volume(port, port->ctl_volume);
  363. } else
  364. ret = -EINVAL;
  365. break;
  366. default:
  367. ret = -EINVAL;
  368. }
  369. return ret;
  370. }
  371. static int saa7164_get_ctrl(struct saa7164_port *port,
  372. struct v4l2_ext_control *ctrl)
  373. {
  374. struct saa7164_vbi_params *params = &port->vbi_params;
  375. switch (ctrl->id) {
  376. case V4L2_CID_MPEG_STREAM_TYPE:
  377. ctrl->value = params->stream_type;
  378. break;
  379. case V4L2_CID_MPEG_AUDIO_MUTE:
  380. ctrl->value = params->ctl_mute;
  381. break;
  382. case V4L2_CID_MPEG_VIDEO_ASPECT:
  383. ctrl->value = params->ctl_aspect;
  384. break;
  385. case V4L2_CID_MPEG_VIDEO_B_FRAMES:
  386. ctrl->value = params->refdist;
  387. break;
  388. case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
  389. ctrl->value = params->gop_size;
  390. break;
  391. default:
  392. return -EINVAL;
  393. }
  394. return 0;
  395. }
  396. static int vidioc_g_ext_ctrls(struct file *file, void *priv,
  397. struct v4l2_ext_controls *ctrls)
  398. {
  399. struct saa7164_vbi_fh *fh = file->private_data;
  400. struct saa7164_port *port = fh->port;
  401. int i, err = 0;
  402. if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
  403. for (i = 0; i < ctrls->count; i++) {
  404. struct v4l2_ext_control *ctrl = ctrls->controls + i;
  405. err = saa7164_get_ctrl(port, ctrl);
  406. if (err) {
  407. ctrls->error_idx = i;
  408. break;
  409. }
  410. }
  411. return err;
  412. }
  413. return -EINVAL;
  414. }
  415. static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
  416. {
  417. int ret = -EINVAL;
  418. switch (ctrl->id) {
  419. case V4L2_CID_MPEG_STREAM_TYPE:
  420. if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
  421. (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
  422. ret = 0;
  423. break;
  424. case V4L2_CID_MPEG_AUDIO_MUTE:
  425. if ((ctrl->value >= 0) &&
  426. (ctrl->value <= 1))
  427. ret = 0;
  428. break;
  429. case V4L2_CID_MPEG_VIDEO_ASPECT:
  430. if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
  431. (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
  432. ret = 0;
  433. break;
  434. case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
  435. if ((ctrl->value >= 0) &&
  436. (ctrl->value <= 255))
  437. ret = 0;
  438. break;
  439. case V4L2_CID_MPEG_VIDEO_B_FRAMES:
  440. if ((ctrl->value >= 1) &&
  441. (ctrl->value <= 3))
  442. ret = 0;
  443. break;
  444. default:
  445. ret = -EINVAL;
  446. }
  447. return ret;
  448. }
  449. static int vidioc_try_ext_ctrls(struct file *file, void *priv,
  450. struct v4l2_ext_controls *ctrls)
  451. {
  452. int i, err = 0;
  453. if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
  454. for (i = 0; i < ctrls->count; i++) {
  455. struct v4l2_ext_control *ctrl = ctrls->controls + i;
  456. err = saa7164_try_ctrl(ctrl, 0);
  457. if (err) {
  458. ctrls->error_idx = i;
  459. break;
  460. }
  461. }
  462. return err;
  463. }
  464. return -EINVAL;
  465. }
  466. static int saa7164_set_ctrl(struct saa7164_port *port,
  467. struct v4l2_ext_control *ctrl)
  468. {
  469. struct saa7164_vbi_params *params = &port->vbi_params;
  470. int ret = 0;
  471. switch (ctrl->id) {
  472. case V4L2_CID_MPEG_STREAM_TYPE:
  473. params->stream_type = ctrl->value;
  474. break;
  475. case V4L2_CID_MPEG_AUDIO_MUTE:
  476. params->ctl_mute = ctrl->value;
  477. ret = saa7164_api_audio_mute(port, params->ctl_mute);
  478. if (ret != SAA_OK) {
  479. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
  480. ret);
  481. ret = -EIO;
  482. }
  483. break;
  484. case V4L2_CID_MPEG_VIDEO_ASPECT:
  485. params->ctl_aspect = ctrl->value;
  486. ret = saa7164_api_set_aspect_ratio(port);
  487. if (ret != SAA_OK) {
  488. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
  489. ret);
  490. ret = -EIO;
  491. }
  492. break;
  493. case V4L2_CID_MPEG_VIDEO_B_FRAMES:
  494. params->refdist = ctrl->value;
  495. break;
  496. case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
  497. params->gop_size = ctrl->value;
  498. break;
  499. default:
  500. return -EINVAL;
  501. }
  502. /* TODO: Update the hardware */
  503. return ret;
  504. }
  505. static int vidioc_s_ext_ctrls(struct file *file, void *priv,
  506. struct v4l2_ext_controls *ctrls)
  507. {
  508. struct saa7164_vbi_fh *fh = file->private_data;
  509. struct saa7164_port *port = fh->port;
  510. int i, err = 0;
  511. if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
  512. for (i = 0; i < ctrls->count; i++) {
  513. struct v4l2_ext_control *ctrl = ctrls->controls + i;
  514. err = saa7164_try_ctrl(ctrl, 0);
  515. if (err) {
  516. ctrls->error_idx = i;
  517. break;
  518. }
  519. err = saa7164_set_ctrl(port, ctrl);
  520. if (err) {
  521. ctrls->error_idx = i;
  522. break;
  523. }
  524. }
  525. return err;
  526. }
  527. return -EINVAL;
  528. }
  529. static int vidioc_querycap(struct file *file, void *priv,
  530. struct v4l2_capability *cap)
  531. {
  532. struct saa7164_vbi_fh *fh = file->private_data;
  533. struct saa7164_port *port = fh->port;
  534. struct saa7164_dev *dev = port->dev;
  535. strcpy(cap->driver, dev->name);
  536. strlcpy(cap->card, saa7164_boards[dev->board].name,
  537. sizeof(cap->card));
  538. sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
  539. cap->capabilities =
  540. V4L2_CAP_VBI_CAPTURE |
  541. V4L2_CAP_READWRITE |
  542. 0;
  543. cap->capabilities |= V4L2_CAP_TUNER;
  544. cap->version = 0;
  545. return 0;
  546. }
  547. static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
  548. struct v4l2_fmtdesc *f)
  549. {
  550. if (f->index != 0)
  551. return -EINVAL;
  552. strlcpy(f->description, "VBI", sizeof(f->description));
  553. f->pixelformat = V4L2_PIX_FMT_MPEG;
  554. return 0;
  555. }
  556. static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
  557. struct v4l2_format *f)
  558. {
  559. struct saa7164_vbi_fh *fh = file->private_data;
  560. struct saa7164_port *port = fh->port;
  561. struct saa7164_dev *dev = port->dev;
  562. f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
  563. f->fmt.pix.bytesperline = 0;
  564. f->fmt.pix.sizeimage =
  565. port->ts_packet_size * port->ts_packet_count;
  566. f->fmt.pix.colorspace = 0;
  567. f->fmt.pix.width = port->width;
  568. f->fmt.pix.height = port->height;
  569. dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n",
  570. port->width, port->height);
  571. return 0;
  572. }
  573. static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
  574. struct v4l2_format *f)
  575. {
  576. struct saa7164_vbi_fh *fh = file->private_data;
  577. struct saa7164_port *port = fh->port;
  578. struct saa7164_dev *dev = port->dev;
  579. f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
  580. f->fmt.pix.bytesperline = 0;
  581. f->fmt.pix.sizeimage =
  582. port->ts_packet_size * port->ts_packet_count;
  583. f->fmt.pix.colorspace = 0;
  584. dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
  585. port->width, port->height);
  586. return 0;
  587. }
  588. static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
  589. struct v4l2_format *f)
  590. {
  591. struct saa7164_vbi_fh *fh = file->private_data;
  592. struct saa7164_port *port = fh->port;
  593. struct saa7164_dev *dev = port->dev;
  594. f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
  595. f->fmt.pix.bytesperline = 0;
  596. f->fmt.pix.sizeimage =
  597. port->ts_packet_size * port->ts_packet_count;
  598. f->fmt.pix.colorspace = 0;
  599. dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
  600. f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
  601. return 0;
  602. }
  603. static int vidioc_log_status(struct file *file, void *priv)
  604. {
  605. return 0;
  606. }
  607. static int fill_queryctrl(struct saa7164_vbi_params *params,
  608. struct v4l2_queryctrl *c)
  609. {
  610. switch (c->id) {
  611. case V4L2_CID_BRIGHTNESS:
  612. return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
  613. case V4L2_CID_CONTRAST:
  614. return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
  615. case V4L2_CID_SATURATION:
  616. return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
  617. case V4L2_CID_HUE:
  618. return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
  619. case V4L2_CID_SHARPNESS:
  620. return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
  621. case V4L2_CID_MPEG_AUDIO_MUTE:
  622. return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
  623. case V4L2_CID_AUDIO_VOLUME:
  624. return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
  625. case V4L2_CID_MPEG_STREAM_TYPE:
  626. return v4l2_ctrl_query_fill(c,
  627. V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
  628. V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
  629. 1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
  630. case V4L2_CID_MPEG_VIDEO_ASPECT:
  631. return v4l2_ctrl_query_fill(c,
  632. V4L2_MPEG_VIDEO_ASPECT_1x1,
  633. V4L2_MPEG_VIDEO_ASPECT_221x100,
  634. 1, V4L2_MPEG_VIDEO_ASPECT_4x3);
  635. case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
  636. return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
  637. case V4L2_CID_MPEG_VIDEO_B_FRAMES:
  638. return v4l2_ctrl_query_fill(c,
  639. 1, 3, 1, 1);
  640. default:
  641. return -EINVAL;
  642. }
  643. }
  644. static int vidioc_queryctrl(struct file *file, void *priv,
  645. struct v4l2_queryctrl *c)
  646. {
  647. struct saa7164_vbi_fh *fh = priv;
  648. struct saa7164_port *port = fh->port;
  649. int i, next;
  650. u32 id = c->id;
  651. memset(c, 0, sizeof(*c));
  652. next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
  653. c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
  654. for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
  655. if (next) {
  656. if (c->id < saa7164_v4l2_ctrls[i])
  657. c->id = saa7164_v4l2_ctrls[i];
  658. else
  659. continue;
  660. }
  661. if (c->id == saa7164_v4l2_ctrls[i])
  662. return fill_queryctrl(&port->vbi_params, c);
  663. if (c->id < saa7164_v4l2_ctrls[i])
  664. break;
  665. }
  666. return -EINVAL;
  667. }
  668. static int saa7164_vbi_stop_port(struct saa7164_port *port)
  669. {
  670. struct saa7164_dev *dev = port->dev;
  671. int ret;
  672. ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
  673. if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
  674. printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
  675. __func__, ret);
  676. ret = -EIO;
  677. } else {
  678. dprintk(DBGLVL_VBI, "%s() Stopped\n", __func__);
  679. ret = 0;
  680. }
  681. return ret;
  682. }
  683. static int saa7164_vbi_acquire_port(struct saa7164_port *port)
  684. {
  685. struct saa7164_dev *dev = port->dev;
  686. int ret;
  687. ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
  688. if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
  689. printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
  690. __func__, ret);
  691. ret = -EIO;
  692. } else {
  693. dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
  694. ret = 0;
  695. }
  696. return ret;
  697. }
  698. static int saa7164_vbi_pause_port(struct saa7164_port *port)
  699. {
  700. struct saa7164_dev *dev = port->dev;
  701. int ret;
  702. ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
  703. if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
  704. printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
  705. __func__, ret);
  706. ret = -EIO;
  707. } else {
  708. dprintk(DBGLVL_VBI, "%s() Paused\n", __func__);
  709. ret = 0;
  710. }
  711. return ret;
  712. }
  713. /* Firmware is very windows centric, meaning you have to transition
  714. * the part through AVStream / KS Windows stages, forwards or backwards.
  715. * States are: stopped, acquired (h/w), paused, started.
  716. * We have to leave here will all of the soft buffers on the free list,
  717. * else the cfg_post() func won't have soft buffers to correctly configure.
  718. */
  719. static int saa7164_vbi_stop_streaming(struct saa7164_port *port)
  720. {
  721. struct saa7164_dev *dev = port->dev;
  722. struct saa7164_buffer *buf;
  723. struct saa7164_user_buffer *ubuf;
  724. struct list_head *c, *n;
  725. int ret;
  726. dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
  727. ret = saa7164_vbi_pause_port(port);
  728. ret = saa7164_vbi_acquire_port(port);
  729. ret = saa7164_vbi_stop_port(port);
  730. dprintk(DBGLVL_VBI, "%s(port=%d) Hardware stopped\n", __func__,
  731. port->nr);
  732. /* Reset the state of any allocated buffer resources */
  733. mutex_lock(&port->dmaqueue_lock);
  734. /* Reset the hard and soft buffer state */
  735. list_for_each_safe(c, n, &port->dmaqueue.list) {
  736. buf = list_entry(c, struct saa7164_buffer, list);
  737. buf->flags = SAA7164_BUFFER_FREE;
  738. buf->pos = 0;
  739. }
  740. list_for_each_safe(c, n, &port->list_buf_used.list) {
  741. ubuf = list_entry(c, struct saa7164_user_buffer, list);
  742. ubuf->pos = 0;
  743. list_move_tail(&ubuf->list, &port->list_buf_free.list);
  744. }
  745. mutex_unlock(&port->dmaqueue_lock);
  746. /* Free any allocated resources */
  747. saa7164_vbi_buffers_dealloc(port);
  748. dprintk(DBGLVL_VBI, "%s(port=%d) Released\n", __func__, port->nr);
  749. return ret;
  750. }
  751. static int saa7164_vbi_start_streaming(struct saa7164_port *port)
  752. {
  753. struct saa7164_dev *dev = port->dev;
  754. int result, ret = 0;
  755. dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
  756. port->done_first_interrupt = 0;
  757. /* allocate all of the PCIe DMA buffer resources on the fly,
  758. * allowing switching between TS and PS payloads without
  759. * requiring a complete driver reload.
  760. */
  761. saa7164_vbi_buffers_alloc(port);
  762. /* Configure the encoder with any cache values */
  763. // saa7164_api_set_encoder(port);
  764. // saa7164_api_get_encoder(port);
  765. /* Place the empty buffers on the hardware */
  766. saa7164_buffer_cfg_port(port);
  767. /* Negotiate format */
  768. if (saa7164_api_set_vbi_format(port) != SAA_OK) {
  769. printk(KERN_ERR "%s() No supported VBI format\n", __func__);
  770. ret = -EIO;
  771. goto out;
  772. }
  773. /* Acquire the hardware */
  774. result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
  775. if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
  776. printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
  777. __func__, result);
  778. ret = -EIO;
  779. goto out;
  780. } else
  781. dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
  782. /* Pause the hardware */
  783. result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
  784. if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
  785. printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
  786. __func__, result);
  787. /* Stop the hardware, regardless */
  788. result = saa7164_vbi_stop_port(port);
  789. if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
  790. printk(KERN_ERR "%s() pause/forced stop transition "
  791. "failed, res = 0x%x\n", __func__, result);
  792. }
  793. ret = -EIO;
  794. goto out;
  795. } else
  796. dprintk(DBGLVL_VBI, "%s() Paused\n", __func__);
  797. /* Start the hardware */
  798. result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
  799. if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
  800. printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
  801. __func__, result);
  802. /* Stop the hardware, regardless */
  803. result = saa7164_vbi_acquire_port(port);
  804. result = saa7164_vbi_stop_port(port);
  805. if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
  806. printk(KERN_ERR "%s() run/forced stop transition "
  807. "failed, res = 0x%x\n", __func__, result);
  808. }
  809. ret = -EIO;
  810. } else
  811. dprintk(DBGLVL_VBI, "%s() Running\n", __func__);
  812. out:
  813. return ret;
  814. }
  815. int saa7164_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f)
  816. {
  817. /* ntsc */
  818. f->fmt.vbi.samples_per_line = 1600;
  819. f->fmt.vbi.samples_per_line = 1440;
  820. f->fmt.vbi.sampling_rate = 27000000;
  821. f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
  822. f->fmt.vbi.offset = 0;
  823. f->fmt.vbi.flags = 0;
  824. f->fmt.vbi.start[0] = 10;
  825. f->fmt.vbi.count[0] = 18;
  826. f->fmt.vbi.start[1] = 263 + 10 + 1;
  827. f->fmt.vbi.count[1] = 18;
  828. return 0;
  829. }
  830. static int fops_open(struct file *file)
  831. {
  832. struct saa7164_dev *dev;
  833. struct saa7164_port *port;
  834. struct saa7164_vbi_fh *fh;
  835. port = (struct saa7164_port *)video_get_drvdata(video_devdata(file));
  836. if (!port)
  837. return -ENODEV;
  838. dev = port->dev;
  839. dprintk(DBGLVL_VBI, "%s()\n", __func__);
  840. /* allocate + initialize per filehandle data */
  841. fh = kzalloc(sizeof(*fh), GFP_KERNEL);
  842. if (NULL == fh)
  843. return -ENOMEM;
  844. file->private_data = fh;
  845. fh->port = port;
  846. return 0;
  847. }
  848. static int fops_release(struct file *file)
  849. {
  850. struct saa7164_vbi_fh *fh = file->private_data;
  851. struct saa7164_port *port = fh->port;
  852. struct saa7164_dev *dev = port->dev;
  853. dprintk(DBGLVL_VBI, "%s()\n", __func__);
  854. /* Shut device down on last close */
  855. if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
  856. if (atomic_dec_return(&port->v4l_reader_count) == 0) {
  857. /* stop vbi capture then cancel buffers */
  858. saa7164_vbi_stop_streaming(port);
  859. }
  860. }
  861. file->private_data = NULL;
  862. kfree(fh);
  863. return 0;
  864. }
  865. struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
  866. {
  867. struct saa7164_user_buffer *ubuf = 0;
  868. struct saa7164_dev *dev = port->dev;
  869. u32 crc;
  870. mutex_lock(&port->dmaqueue_lock);
  871. if (!list_empty(&port->list_buf_used.list)) {
  872. ubuf = list_first_entry(&port->list_buf_used.list,
  873. struct saa7164_user_buffer, list);
  874. if (crc_checking) {
  875. crc = crc32(0, ubuf->data, ubuf->actual_size);
  876. if (crc != ubuf->crc) {
  877. printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,
  878. ubuf, ubuf->crc, crc);
  879. }
  880. }
  881. }
  882. mutex_unlock(&port->dmaqueue_lock);
  883. dprintk(DBGLVL_VBI, "%s() returns %p\n", __func__, ubuf);
  884. return ubuf;
  885. }
  886. static ssize_t fops_read(struct file *file, char __user *buffer,
  887. size_t count, loff_t *pos)
  888. {
  889. struct saa7164_vbi_fh *fh = file->private_data;
  890. struct saa7164_port *port = fh->port;
  891. struct saa7164_user_buffer *ubuf = NULL;
  892. struct saa7164_dev *dev = port->dev;
  893. int ret = 0;
  894. int rem, cnt;
  895. u8 *p;
  896. port->last_read_msecs_diff = port->last_read_msecs;
  897. port->last_read_msecs = jiffies_to_msecs(jiffies);
  898. port->last_read_msecs_diff = port->last_read_msecs -
  899. port->last_read_msecs_diff;
  900. saa7164_histogram_update(&port->read_interval,
  901. port->last_read_msecs_diff);
  902. if (*pos) {
  903. printk(KERN_ERR "%s() ESPIPE\n", __func__);
  904. return -ESPIPE;
  905. }
  906. if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
  907. if (atomic_inc_return(&port->v4l_reader_count) == 1) {
  908. if (saa7164_vbi_initialize(port) < 0) {
  909. printk(KERN_ERR "%s() EINVAL\n", __func__);
  910. return -EINVAL;
  911. }
  912. saa7164_vbi_start_streaming(port);
  913. msleep(200);
  914. }
  915. }
  916. /* blocking wait for buffer */
  917. if ((file->f_flags & O_NONBLOCK) == 0) {
  918. if (wait_event_interruptible(port->wait_read,
  919. saa7164_vbi_next_buf(port))) {
  920. printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
  921. return -ERESTARTSYS;
  922. }
  923. }
  924. /* Pull the first buffer from the used list */
  925. ubuf = saa7164_vbi_next_buf(port);
  926. while ((count > 0) && ubuf) {
  927. /* set remaining bytes to copy */
  928. rem = ubuf->actual_size - ubuf->pos;
  929. cnt = rem > count ? count : rem;
  930. p = ubuf->data + ubuf->pos;
  931. dprintk(DBGLVL_VBI,
  932. "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
  933. __func__, (int)count, cnt, rem, ubuf, ubuf->pos);
  934. if (copy_to_user(buffer, p, cnt)) {
  935. printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
  936. if (!ret) {
  937. printk(KERN_ERR "%s() EFAULT\n", __func__);
  938. ret = -EFAULT;
  939. }
  940. goto err;
  941. }
  942. ubuf->pos += cnt;
  943. count -= cnt;
  944. buffer += cnt;
  945. ret += cnt;
  946. if (ubuf->pos > ubuf->actual_size) {
  947. printk(KERN_ERR "read() pos > actual, huh?\n");
  948. }
  949. if (ubuf->pos == ubuf->actual_size) {
  950. /* finished with current buffer, take next buffer */
  951. /* Requeue the buffer on the free list */
  952. ubuf->pos = 0;
  953. mutex_lock(&port->dmaqueue_lock);
  954. list_move_tail(&ubuf->list, &port->list_buf_free.list);
  955. mutex_unlock(&port->dmaqueue_lock);
  956. /* Dequeue next */
  957. if ((file->f_flags & O_NONBLOCK) == 0) {
  958. if (wait_event_interruptible(port->wait_read,
  959. saa7164_vbi_next_buf(port))) {
  960. break;
  961. }
  962. }
  963. ubuf = saa7164_vbi_next_buf(port);
  964. }
  965. }
  966. err:
  967. if (!ret && !ubuf) {
  968. printk(KERN_ERR "%s() EAGAIN\n", __func__);
  969. ret = -EAGAIN;
  970. }
  971. return ret;
  972. }
  973. static unsigned int fops_poll(struct file *file, poll_table *wait)
  974. {
  975. struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data;
  976. struct saa7164_port *port = fh->port;
  977. struct saa7164_user_buffer *ubuf;
  978. unsigned int mask = 0;
  979. port->last_poll_msecs_diff = port->last_poll_msecs;
  980. port->last_poll_msecs = jiffies_to_msecs(jiffies);
  981. port->last_poll_msecs_diff = port->last_poll_msecs -
  982. port->last_poll_msecs_diff;
  983. saa7164_histogram_update(&port->poll_interval,
  984. port->last_poll_msecs_diff);
  985. if (!video_is_registered(port->v4l_device)) {
  986. return -EIO;
  987. }
  988. if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
  989. if (atomic_inc_return(&port->v4l_reader_count) == 1) {
  990. if (saa7164_vbi_initialize(port) < 0)
  991. return -EINVAL;
  992. saa7164_vbi_start_streaming(port);
  993. msleep(200);
  994. }
  995. }
  996. /* blocking wait for buffer */
  997. if ((file->f_flags & O_NONBLOCK) == 0) {
  998. if (wait_event_interruptible(port->wait_read,
  999. saa7164_vbi_next_buf(port))) {
  1000. return -ERESTARTSYS;
  1001. }
  1002. }
  1003. /* Pull the first buffer from the used list */
  1004. ubuf = list_first_entry(&port->list_buf_used.list,
  1005. struct saa7164_user_buffer, list);
  1006. if (ubuf)
  1007. mask |= POLLIN | POLLRDNORM;
  1008. return mask;
  1009. }
  1010. static const struct v4l2_file_operations vbi_fops = {
  1011. .owner = THIS_MODULE,
  1012. .open = fops_open,
  1013. .release = fops_release,
  1014. .read = fops_read,
  1015. .poll = fops_poll,
  1016. .unlocked_ioctl = video_ioctl2,
  1017. };
  1018. static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
  1019. .vidioc_s_std = vidioc_s_std,
  1020. .vidioc_enum_input = vidioc_enum_input,
  1021. .vidioc_g_input = vidioc_g_input,
  1022. .vidioc_s_input = vidioc_s_input,
  1023. .vidioc_g_tuner = vidioc_g_tuner,
  1024. .vidioc_s_tuner = vidioc_s_tuner,
  1025. .vidioc_g_frequency = vidioc_g_frequency,
  1026. .vidioc_s_frequency = vidioc_s_frequency,
  1027. .vidioc_s_ctrl = vidioc_s_ctrl,
  1028. .vidioc_g_ctrl = vidioc_g_ctrl,
  1029. .vidioc_querycap = vidioc_querycap,
  1030. .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
  1031. .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
  1032. .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
  1033. .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
  1034. .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
  1035. .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
  1036. .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
  1037. .vidioc_log_status = vidioc_log_status,
  1038. .vidioc_queryctrl = vidioc_queryctrl,
  1039. // .vidioc_g_chip_ident = saa7164_g_chip_ident,
  1040. #ifdef CONFIG_VIDEO_ADV_DEBUG
  1041. // .vidioc_g_register = saa7164_g_register,
  1042. // .vidioc_s_register = saa7164_s_register,
  1043. #endif
  1044. .vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt,
  1045. .vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt,
  1046. .vidioc_s_fmt_vbi_cap = saa7164_vbi_fmt,
  1047. };
  1048. static struct video_device saa7164_vbi_template = {
  1049. .name = "saa7164",
  1050. .fops = &vbi_fops,
  1051. .ioctl_ops = &vbi_ioctl_ops,
  1052. .minor = -1,
  1053. .tvnorms = SAA7164_NORMS,
  1054. .current_norm = V4L2_STD_NTSC_M,
  1055. };
  1056. static struct video_device *saa7164_vbi_alloc(
  1057. struct saa7164_port *port,
  1058. struct pci_dev *pci,
  1059. struct video_device *template,
  1060. char *type)
  1061. {
  1062. struct video_device *vfd;
  1063. struct saa7164_dev *dev = port->dev;
  1064. dprintk(DBGLVL_VBI, "%s()\n", __func__);
  1065. vfd = video_device_alloc();
  1066. if (NULL == vfd)
  1067. return NULL;
  1068. *vfd = *template;
  1069. snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
  1070. type, saa7164_boards[dev->board].name);
  1071. vfd->parent = &pci->dev;
  1072. vfd->release = video_device_release;
  1073. return vfd;
  1074. }
  1075. int saa7164_vbi_register(struct saa7164_port *port)
  1076. {
  1077. struct saa7164_dev *dev = port->dev;
  1078. int result = -ENODEV;
  1079. dprintk(DBGLVL_VBI, "%s()\n", __func__);
  1080. if (port->type != SAA7164_MPEG_VBI)
  1081. BUG();
  1082. /* Sanity check that the PCI configuration space is active */
  1083. if (port->hwcfg.BARLocation == 0) {
  1084. printk(KERN_ERR "%s() failed "
  1085. "(errno = %d), NO PCI configuration\n",
  1086. __func__, result);
  1087. result = -ENOMEM;
  1088. goto failed;
  1089. }
  1090. /* Establish VBI defaults here */
  1091. /* Allocate and register the video device node */
  1092. port->v4l_device = saa7164_vbi_alloc(port,
  1093. dev->pci, &saa7164_vbi_template, "vbi");
  1094. if (port->v4l_device == NULL) {
  1095. printk(KERN_INFO "%s: can't allocate vbi device\n",
  1096. dev->name);
  1097. result = -ENOMEM;
  1098. goto failed;
  1099. }
  1100. video_set_drvdata(port->v4l_device, port);
  1101. result = video_register_device(port->v4l_device,
  1102. VFL_TYPE_VBI, -1);
  1103. if (result < 0) {
  1104. printk(KERN_INFO "%s: can't register vbi device\n",
  1105. dev->name);
  1106. /* TODO: We're going to leak here if we don't dealloc
  1107. The buffers above. The unreg function can't deal wit it.
  1108. */
  1109. goto failed;
  1110. }
  1111. printk(KERN_INFO "%s: registered device vbi%d [vbi]\n",
  1112. dev->name, port->v4l_device->num);
  1113. /* Configure the hardware defaults */
  1114. result = 0;
  1115. failed:
  1116. return result;
  1117. }
  1118. void saa7164_vbi_unregister(struct saa7164_port *port)
  1119. {
  1120. struct saa7164_dev *dev = port->dev;
  1121. dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
  1122. if (port->type != SAA7164_MPEG_VBI)
  1123. BUG();
  1124. if (port->v4l_device) {
  1125. if (port->v4l_device->minor != -1)
  1126. video_unregister_device(port->v4l_device);
  1127. else
  1128. video_device_release(port->v4l_device);
  1129. port->v4l_device = NULL;
  1130. }
  1131. }