video.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /*
  2. * V4L2 AIM - V4L2 Application Interface Module for MostCore
  3. *
  4. * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG
  5. *
  6. * This program is distributed in the hope that it will be useful,
  7. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. * GNU General Public License for more details.
  10. *
  11. * This file is licensed under GPLv2.
  12. */
  13. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  14. #include <linux/module.h>
  15. #include <linux/slab.h>
  16. #include <linux/init.h>
  17. #include <linux/device.h>
  18. #include <linux/suspend.h>
  19. #include <linux/videodev2.h>
  20. #include <linux/mutex.h>
  21. #include <media/v4l2-common.h>
  22. #include <media/v4l2-ioctl.h>
  23. #include <media/v4l2-event.h>
  24. #include <media/v4l2-device.h>
  25. #include <media/v4l2-ctrls.h>
  26. #include <media/v4l2-fh.h>
  27. #include "mostcore.h"
  28. #define V4L2_AIM_MAX_INPUT 1
  29. static struct most_aim aim_info;
  30. struct most_video_dev {
  31. struct most_interface *iface;
  32. int ch_idx;
  33. struct list_head list;
  34. bool mute;
  35. struct list_head pending_mbos;
  36. spinlock_t list_lock;
  37. struct v4l2_device v4l2_dev;
  38. atomic_t access_ref;
  39. struct video_device *vdev;
  40. unsigned int ctrl_input;
  41. struct mutex lock;
  42. wait_queue_head_t wait_data;
  43. };
  44. struct aim_fh {
  45. /* must be the first field of this struct! */
  46. struct v4l2_fh fh;
  47. struct most_video_dev *mdev;
  48. u32 offs;
  49. };
  50. static struct list_head video_devices = LIST_HEAD_INIT(video_devices);
  51. static struct spinlock list_lock;
  52. static inline bool data_ready(struct most_video_dev *mdev)
  53. {
  54. return !list_empty(&mdev->pending_mbos);
  55. }
  56. static inline struct mbo *get_top_mbo(struct most_video_dev *mdev)
  57. {
  58. return list_first_entry(&mdev->pending_mbos, struct mbo, list);
  59. }
  60. static int aim_vdev_open(struct file *filp)
  61. {
  62. int ret;
  63. struct video_device *vdev = video_devdata(filp);
  64. struct most_video_dev *mdev = video_drvdata(filp);
  65. struct aim_fh *fh;
  66. pr_info("aim_vdev_open()\n");
  67. switch (vdev->vfl_type) {
  68. case VFL_TYPE_GRABBER:
  69. break;
  70. default:
  71. return -EINVAL;
  72. }
  73. fh = kzalloc(sizeof(*fh), GFP_KERNEL);
  74. if (!fh)
  75. return -ENOMEM;
  76. if (!atomic_inc_and_test(&mdev->access_ref)) {
  77. pr_err("too many clients\n");
  78. ret = -EBUSY;
  79. goto err_dec;
  80. }
  81. fh->mdev = mdev;
  82. v4l2_fh_init(&fh->fh, vdev);
  83. filp->private_data = fh;
  84. v4l2_fh_add(&fh->fh);
  85. ret = most_start_channel(mdev->iface, mdev->ch_idx, &aim_info);
  86. if (ret) {
  87. pr_err("most_start_channel() failed\n");
  88. goto err_rm;
  89. }
  90. return 0;
  91. err_rm:
  92. v4l2_fh_del(&fh->fh);
  93. v4l2_fh_exit(&fh->fh);
  94. err_dec:
  95. atomic_dec(&mdev->access_ref);
  96. kfree(fh);
  97. return ret;
  98. }
  99. static int aim_vdev_close(struct file *filp)
  100. {
  101. struct aim_fh *fh = filp->private_data;
  102. struct most_video_dev *mdev = fh->mdev;
  103. struct mbo *mbo, *tmp;
  104. pr_info("aim_vdev_close()\n");
  105. /*
  106. * We need to put MBOs back before we call most_stop_channel()
  107. * to deallocate MBOs.
  108. * From the other hand mostcore still calling rx_completion()
  109. * to deliver MBOs until most_stop_channel() is called.
  110. * Use mute to work around this issue.
  111. * This must be implemented in core.
  112. */
  113. spin_lock(&mdev->list_lock);
  114. mdev->mute = true;
  115. list_for_each_entry_safe(mbo, tmp, &mdev->pending_mbos, list) {
  116. list_del(&mbo->list);
  117. spin_unlock(&mdev->list_lock);
  118. most_put_mbo(mbo);
  119. spin_lock(&mdev->list_lock);
  120. }
  121. spin_unlock(&mdev->list_lock);
  122. most_stop_channel(mdev->iface, mdev->ch_idx, &aim_info);
  123. mdev->mute = false;
  124. v4l2_fh_del(&fh->fh);
  125. v4l2_fh_exit(&fh->fh);
  126. atomic_dec(&mdev->access_ref);
  127. kfree(fh);
  128. return 0;
  129. }
  130. static ssize_t aim_vdev_read(struct file *filp, char __user *buf,
  131. size_t count, loff_t *pos)
  132. {
  133. struct aim_fh *fh = filp->private_data;
  134. struct most_video_dev *mdev = fh->mdev;
  135. int ret = 0;
  136. if (*pos)
  137. return -ESPIPE;
  138. if (!mdev)
  139. return -ENODEV;
  140. /* wait for the first buffer */
  141. if (!(filp->f_flags & O_NONBLOCK)) {
  142. if (wait_event_interruptible(mdev->wait_data, data_ready(mdev)))
  143. return -ERESTARTSYS;
  144. }
  145. if (!data_ready(mdev))
  146. return -EAGAIN;
  147. while (count > 0 && data_ready(mdev)) {
  148. struct mbo *const mbo = get_top_mbo(mdev);
  149. int const rem = mbo->processed_length - fh->offs;
  150. int const cnt = rem < count ? rem : count;
  151. if (copy_to_user(buf, mbo->virt_address + fh->offs, cnt)) {
  152. pr_err("read: copy_to_user failed\n");
  153. if (!ret)
  154. ret = -EFAULT;
  155. return ret;
  156. }
  157. fh->offs += cnt;
  158. count -= cnt;
  159. buf += cnt;
  160. ret += cnt;
  161. if (cnt >= rem) {
  162. fh->offs = 0;
  163. spin_lock(&mdev->list_lock);
  164. list_del(&mbo->list);
  165. spin_unlock(&mdev->list_lock);
  166. most_put_mbo(mbo);
  167. }
  168. }
  169. return ret;
  170. }
  171. static unsigned int aim_vdev_poll(struct file *filp, poll_table *wait)
  172. {
  173. struct aim_fh *fh = filp->private_data;
  174. struct most_video_dev *mdev = fh->mdev;
  175. unsigned int mask = 0;
  176. /* only wait if no data is available */
  177. if (!data_ready(mdev))
  178. poll_wait(filp, &mdev->wait_data, wait);
  179. if (data_ready(mdev))
  180. mask |= POLLIN | POLLRDNORM;
  181. return mask;
  182. }
  183. static void aim_set_format_struct(struct v4l2_format *f)
  184. {
  185. f->fmt.pix.width = 8;
  186. f->fmt.pix.height = 8;
  187. f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
  188. f->fmt.pix.bytesperline = 0;
  189. f->fmt.pix.sizeimage = 188 * 2;
  190. f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
  191. f->fmt.pix.field = V4L2_FIELD_NONE;
  192. f->fmt.pix.priv = 0;
  193. }
  194. static int aim_set_format(struct most_video_dev *mdev, unsigned int cmd,
  195. struct v4l2_format *format)
  196. {
  197. if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG)
  198. return -EINVAL;
  199. if (cmd == VIDIOC_TRY_FMT)
  200. return 0;
  201. aim_set_format_struct(format);
  202. return 0;
  203. }
  204. static int vidioc_querycap(struct file *file, void *priv,
  205. struct v4l2_capability *cap)
  206. {
  207. struct aim_fh *fh = priv;
  208. struct most_video_dev *mdev = fh->mdev;
  209. pr_info("vidioc_querycap()\n");
  210. strlcpy(cap->driver, "v4l2_most_aim", sizeof(cap->driver));
  211. strlcpy(cap->card, "my_card", sizeof(cap->card));
  212. snprintf(cap->bus_info, sizeof(cap->bus_info),
  213. "%s", mdev->iface->description);
  214. cap->capabilities =
  215. V4L2_CAP_READWRITE |
  216. V4L2_CAP_TUNER |
  217. V4L2_CAP_VIDEO_CAPTURE;
  218. return 0;
  219. }
  220. static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
  221. struct v4l2_fmtdesc *f)
  222. {
  223. pr_info("vidioc_enum_fmt_vid_cap() %d\n", f->index);
  224. if (f->index)
  225. return -EINVAL;
  226. strcpy(f->description, "MPEG");
  227. f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  228. f->flags = V4L2_FMT_FLAG_COMPRESSED;
  229. f->pixelformat = V4L2_PIX_FMT_MPEG;
  230. return 0;
  231. }
  232. static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
  233. struct v4l2_format *f)
  234. {
  235. pr_info("vidioc_g_fmt_vid_cap()\n");
  236. aim_set_format_struct(f);
  237. return 0;
  238. }
  239. static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
  240. struct v4l2_format *f)
  241. {
  242. struct aim_fh *fh = priv;
  243. struct most_video_dev *mdev = fh->mdev;
  244. return aim_set_format(mdev, VIDIOC_TRY_FMT, f);
  245. }
  246. static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
  247. struct v4l2_format *f)
  248. {
  249. struct aim_fh *fh = priv;
  250. struct most_video_dev *mdev = fh->mdev;
  251. return aim_set_format(mdev, VIDIOC_S_FMT, f);
  252. }
  253. static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
  254. {
  255. pr_info("vidioc_g_std()\n");
  256. *norm = V4L2_STD_UNKNOWN;
  257. return 0;
  258. }
  259. static int vidioc_enum_input(struct file *file, void *priv,
  260. struct v4l2_input *input)
  261. {
  262. struct aim_fh *fh = priv;
  263. struct most_video_dev *mdev = fh->mdev;
  264. if (input->index >= V4L2_AIM_MAX_INPUT)
  265. return -EINVAL;
  266. strcpy(input->name, "MOST Video");
  267. input->type |= V4L2_INPUT_TYPE_CAMERA;
  268. input->audioset = 0;
  269. input->std = mdev->vdev->tvnorms;
  270. return 0;
  271. }
  272. static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
  273. {
  274. struct aim_fh *fh = priv;
  275. struct most_video_dev *mdev = fh->mdev;
  276. *i = mdev->ctrl_input;
  277. return 0;
  278. }
  279. static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
  280. {
  281. struct aim_fh *fh = priv;
  282. struct most_video_dev *mdev = fh->mdev;
  283. pr_info("vidioc_s_input(%d)\n", index);
  284. if (index >= V4L2_AIM_MAX_INPUT)
  285. return -EINVAL;
  286. mdev->ctrl_input = index;
  287. return 0;
  288. }
  289. static struct v4l2_file_operations aim_fops = {
  290. .owner = THIS_MODULE,
  291. .open = aim_vdev_open,
  292. .release = aim_vdev_close,
  293. .read = aim_vdev_read,
  294. .poll = aim_vdev_poll,
  295. .unlocked_ioctl = video_ioctl2,
  296. };
  297. static const struct v4l2_ioctl_ops video_ioctl_ops = {
  298. .vidioc_querycap = vidioc_querycap,
  299. .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
  300. .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
  301. .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
  302. .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
  303. .vidioc_g_std = vidioc_g_std,
  304. .vidioc_enum_input = vidioc_enum_input,
  305. .vidioc_g_input = vidioc_g_input,
  306. .vidioc_s_input = vidioc_s_input,
  307. };
  308. static const struct video_device aim_videodev_template = {
  309. .fops = &aim_fops,
  310. .release = video_device_release,
  311. .ioctl_ops = &video_ioctl_ops,
  312. .tvnorms = V4L2_STD_UNKNOWN,
  313. };
  314. /**************************************************************************/
  315. static struct most_video_dev *get_aim_dev(
  316. struct most_interface *iface, int channel_idx)
  317. {
  318. struct most_video_dev *mdev, *tmp;
  319. spin_lock(&list_lock);
  320. list_for_each_entry_safe(mdev, tmp, &video_devices, list) {
  321. if (mdev->iface == iface && mdev->ch_idx == channel_idx) {
  322. spin_unlock(&list_lock);
  323. return mdev;
  324. }
  325. }
  326. spin_unlock(&list_lock);
  327. return NULL;
  328. }
  329. static int aim_rx_data(struct mbo *mbo)
  330. {
  331. struct most_video_dev *mdev =
  332. get_aim_dev(mbo->ifp, mbo->hdm_channel_id);
  333. if (!mdev)
  334. return -EIO;
  335. spin_lock(&mdev->list_lock);
  336. if (unlikely(mdev->mute)) {
  337. spin_unlock(&mdev->list_lock);
  338. return -EIO;
  339. }
  340. list_add_tail(&mbo->list, &mdev->pending_mbos);
  341. spin_unlock(&mdev->list_lock);
  342. wake_up_interruptible(&mdev->wait_data);
  343. return 0;
  344. }
  345. static int aim_register_videodev(struct most_video_dev *mdev)
  346. {
  347. int retval = -ENOMEM;
  348. int ret;
  349. pr_info("aim_register_videodev()\n");
  350. init_waitqueue_head(&mdev->wait_data);
  351. /* allocate and fill v4l2 video struct */
  352. mdev->vdev = video_device_alloc();
  353. if (!mdev->vdev)
  354. return -ENOMEM;
  355. /* Fill the video capture device struct */
  356. *mdev->vdev = aim_videodev_template;
  357. mdev->vdev->v4l2_dev = &mdev->v4l2_dev;
  358. mdev->vdev->lock = &mdev->lock;
  359. strcpy(mdev->vdev->name, "most v4l2 aim video");
  360. /* Register the v4l2 device */
  361. video_set_drvdata(mdev->vdev, mdev);
  362. retval = video_register_device(mdev->vdev, VFL_TYPE_GRABBER, -1);
  363. if (retval != 0) {
  364. pr_err("video_register_device failed (%d)\n", retval);
  365. ret = -ENODEV;
  366. goto err_vbi_dev;
  367. }
  368. return 0;
  369. err_vbi_dev:
  370. video_device_release(mdev->vdev);
  371. return ret;
  372. }
  373. static void aim_unregister_videodev(struct most_video_dev *mdev)
  374. {
  375. pr_info("aim_unregister_videodev()\n");
  376. video_unregister_device(mdev->vdev);
  377. }
  378. static void aim_v4l2_dev_release(struct v4l2_device *v4l2_dev)
  379. {
  380. struct most_video_dev *mdev =
  381. container_of(v4l2_dev, struct most_video_dev, v4l2_dev);
  382. v4l2_device_unregister(v4l2_dev);
  383. kfree(mdev);
  384. }
  385. static int aim_probe_channel(struct most_interface *iface, int channel_idx,
  386. struct most_channel_config *ccfg,
  387. struct kobject *parent, char *name)
  388. {
  389. int ret;
  390. struct most_video_dev *mdev = get_aim_dev(iface, channel_idx);
  391. pr_info("aim_probe_channel()\n");
  392. if (mdev) {
  393. pr_err("channel already linked\n");
  394. return -EEXIST;
  395. }
  396. if (ccfg->direction != MOST_CH_RX) {
  397. pr_err("wrong direction, expect rx\n");
  398. return -EINVAL;
  399. }
  400. if (ccfg->data_type != MOST_CH_SYNC &&
  401. ccfg->data_type != MOST_CH_ISOC_AVP) {
  402. pr_err("wrong channel type, expect sync or isoc_avp\n");
  403. return -EINVAL;
  404. }
  405. mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
  406. if (!mdev)
  407. return -ENOMEM;
  408. mutex_init(&mdev->lock);
  409. atomic_set(&mdev->access_ref, -1);
  410. spin_lock_init(&mdev->list_lock);
  411. INIT_LIST_HEAD(&mdev->pending_mbos);
  412. mdev->iface = iface;
  413. mdev->ch_idx = channel_idx;
  414. mdev->v4l2_dev.release = aim_v4l2_dev_release;
  415. /* Create the v4l2_device */
  416. strlcpy(mdev->v4l2_dev.name, "most_video_device",
  417. sizeof(mdev->v4l2_dev.name));
  418. ret = v4l2_device_register(NULL, &mdev->v4l2_dev);
  419. if (ret) {
  420. pr_err("v4l2_device_register() failed\n");
  421. kfree(mdev);
  422. return ret;
  423. }
  424. ret = aim_register_videodev(mdev);
  425. if (ret)
  426. goto err_unreg;
  427. spin_lock(&list_lock);
  428. list_add(&mdev->list, &video_devices);
  429. spin_unlock(&list_lock);
  430. return 0;
  431. err_unreg:
  432. v4l2_device_disconnect(&mdev->v4l2_dev);
  433. v4l2_device_put(&mdev->v4l2_dev);
  434. return ret;
  435. }
  436. static int aim_disconnect_channel(struct most_interface *iface,
  437. int channel_idx)
  438. {
  439. struct most_video_dev *mdev = get_aim_dev(iface, channel_idx);
  440. pr_info("aim_disconnect_channel()\n");
  441. if (!mdev) {
  442. pr_err("no such channel is linked\n");
  443. return -ENOENT;
  444. }
  445. spin_lock(&list_lock);
  446. list_del(&mdev->list);
  447. spin_unlock(&list_lock);
  448. aim_unregister_videodev(mdev);
  449. v4l2_device_disconnect(&mdev->v4l2_dev);
  450. v4l2_device_put(&mdev->v4l2_dev);
  451. return 0;
  452. }
  453. static struct most_aim aim_info = {
  454. .name = "v4l",
  455. .probe_channel = aim_probe_channel,
  456. .disconnect_channel = aim_disconnect_channel,
  457. .rx_completion = aim_rx_data,
  458. };
  459. static int __init aim_init(void)
  460. {
  461. spin_lock_init(&list_lock);
  462. return most_register_aim(&aim_info);
  463. }
  464. static void __exit aim_exit(void)
  465. {
  466. struct most_video_dev *mdev, *tmp;
  467. /*
  468. * As the mostcore currently doesn't call disconnect_channel()
  469. * for linked channels while we call most_deregister_aim()
  470. * we simulate this call here.
  471. * This must be fixed in core.
  472. */
  473. spin_lock(&list_lock);
  474. list_for_each_entry_safe(mdev, tmp, &video_devices, list) {
  475. list_del(&mdev->list);
  476. spin_unlock(&list_lock);
  477. aim_unregister_videodev(mdev);
  478. v4l2_device_disconnect(&mdev->v4l2_dev);
  479. v4l2_device_put(&mdev->v4l2_dev);
  480. spin_lock(&list_lock);
  481. }
  482. spin_unlock(&list_lock);
  483. most_deregister_aim(&aim_info);
  484. BUG_ON(!list_empty(&video_devices));
  485. }
  486. module_init(aim_init);
  487. module_exit(aim_exit);
  488. MODULE_DESCRIPTION("V4L2 Application Interface Module for MostCore");
  489. MODULE_AUTHOR("Andrey Shvetsov <andrey.shvetsov@k2l.de>");
  490. MODULE_LICENSE("GPL");