msm_vidc_v4l2.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. */
  5. #include "msm_vidc_v4l2.h"
  6. #include "msm_vidc_internal.h"
  7. #include "msm_vidc_core.h"
  8. #include "msm_vidc_inst.h"
  9. #include "msm_vidc_debug.h"
  10. #include "msm_vidc_driver.h"
  11. #include "msm_vidc.h"
  12. extern struct msm_vidc_core *g_core;
  13. static struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
  14. {
  15. if (!filp || !filp->private_data)
  16. return NULL;
  17. return container_of(filp->private_data,
  18. struct msm_vidc_inst, event_handler);
  19. }
  20. unsigned int msm_v4l2_poll(struct file *filp, struct poll_table_struct *pt)
  21. {
  22. struct msm_vidc_inst *inst = get_vidc_inst(filp, NULL);
  23. return msm_vidc_poll((void *)inst, filp, pt);
  24. }
  25. int msm_v4l2_open(struct file *filp)
  26. {
  27. struct video_device *vdev = video_devdata(filp);
  28. struct msm_video_device *vid_dev =
  29. container_of(vdev, struct msm_video_device, vdev);
  30. struct msm_vidc_core *core = video_drvdata(filp);
  31. struct msm_vidc_inst *inst;
  32. inst = msm_vidc_open(core, vid_dev->type);
  33. if (!inst) {
  34. d_vpr_e("Failed to create instance, type = %d\n",
  35. vid_dev->type);
  36. return -ENOMEM;
  37. }
  38. clear_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags);
  39. filp->private_data = &(inst->event_handler);
  40. return 0;
  41. }
  42. int msm_v4l2_close(struct file *filp)
  43. {
  44. int rc = 0;
  45. struct msm_vidc_inst *inst;
  46. inst = get_vidc_inst(filp, NULL);
  47. rc = msm_vidc_close(inst);
  48. filp->private_data = NULL;
  49. return rc;
  50. }
  51. int msm_v4l2_querycap(struct file *filp, void *fh,
  52. struct v4l2_capability *cap)
  53. {
  54. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  55. int rc = 0;
  56. inst = get_inst_ref(g_core, inst);
  57. if (!inst) {
  58. d_vpr_e("%s: invalid instance\n", __func__);
  59. return -EINVAL;
  60. }
  61. inst_lock(inst, __func__);
  62. rc = msm_vidc_querycap((void *)inst, cap);
  63. if (rc)
  64. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  65. inst_unlock(inst, __func__);
  66. put_inst(inst);
  67. return rc;
  68. }
  69. int msm_v4l2_enum_fmt(struct file *filp, void *fh,
  70. struct v4l2_fmtdesc *f)
  71. {
  72. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  73. int rc = 0;
  74. inst = get_inst_ref(g_core, inst);
  75. if (!inst) {
  76. d_vpr_e("%s: invalid instance\n", __func__);
  77. return -EINVAL;
  78. }
  79. inst_lock(inst, __func__);
  80. rc = msm_vidc_enum_fmt((void *)inst, f);
  81. if (rc)
  82. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  83. inst_unlock(inst, __func__);
  84. put_inst(inst);
  85. return rc;
  86. }
  87. int msm_v4l2_s_fmt(struct file *filp, void *fh,
  88. struct v4l2_format *f)
  89. {
  90. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  91. int rc = 0;
  92. inst = get_inst_ref(g_core, inst);
  93. if (!inst) {
  94. d_vpr_e("%s: invalid instance\n", __func__);
  95. return -EINVAL;
  96. }
  97. inst_lock(inst, __func__);
  98. rc = msm_vidc_s_fmt((void *)inst, f);
  99. if (rc)
  100. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  101. inst_unlock(inst, __func__);
  102. put_inst(inst);
  103. return rc;
  104. }
  105. int msm_v4l2_g_fmt(struct file *filp, void *fh,
  106. struct v4l2_format *f)
  107. {
  108. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  109. int rc = 0;
  110. inst = get_inst_ref(g_core, inst);
  111. if (!inst) {
  112. d_vpr_e("%s: invalid instance\n", __func__);
  113. return -EINVAL;
  114. }
  115. inst_lock(inst, __func__);
  116. rc = msm_vidc_g_fmt((void *)inst, f);
  117. if (rc)
  118. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  119. inst_unlock(inst, __func__);
  120. put_inst(inst);
  121. return rc;
  122. }
  123. int msm_v4l2_s_selection(struct file *filp, void *fh,
  124. struct v4l2_selection *s)
  125. {
  126. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  127. int rc = 0;
  128. inst = get_inst_ref(g_core, inst);
  129. if (!inst) {
  130. d_vpr_e("%s: invalid instance\n", __func__);
  131. return -EINVAL;
  132. }
  133. inst_lock(inst, __func__);
  134. rc = msm_vidc_s_selection((void *)inst, s);
  135. if (rc)
  136. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  137. inst_unlock(inst, __func__);
  138. put_inst(inst);
  139. return rc;
  140. }
  141. int msm_v4l2_g_selection(struct file *filp, void *fh,
  142. struct v4l2_selection *s)
  143. {
  144. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  145. int rc = 0;
  146. inst = get_inst_ref(g_core, inst);
  147. if (!inst) {
  148. d_vpr_e("%s: invalid instance\n", __func__);
  149. return -EINVAL;
  150. }
  151. inst_lock(inst, __func__);
  152. rc = msm_vidc_g_selection((void *)inst, s);
  153. if (rc)
  154. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  155. inst_unlock(inst, __func__);
  156. put_inst(inst);
  157. return rc;
  158. }
  159. int msm_v4l2_s_parm(struct file *filp, void *fh,
  160. struct v4l2_streamparm *a)
  161. {
  162. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  163. int rc = 0;
  164. inst = get_inst_ref(g_core, inst);
  165. if (!inst) {
  166. d_vpr_e("%s: invalid instance\n", __func__);
  167. return -EINVAL;
  168. }
  169. inst_lock(inst, __func__);
  170. rc = msm_vidc_s_param((void *)inst, a);
  171. if (rc)
  172. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  173. inst_unlock(inst, __func__);
  174. put_inst(inst);
  175. return rc;
  176. }
  177. int msm_v4l2_g_parm(struct file *filp, void *fh,
  178. struct v4l2_streamparm *a)
  179. {
  180. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  181. int rc = 0;
  182. inst = get_inst_ref(g_core, inst);
  183. if (!inst) {
  184. d_vpr_e("%s: invalid instance\n", __func__);
  185. return -EINVAL;
  186. }
  187. inst_lock(inst, __func__);
  188. rc = msm_vidc_g_param((void *)inst, a);
  189. if (rc)
  190. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  191. inst_unlock(inst, __func__);
  192. put_inst(inst);
  193. return rc;
  194. }
  195. int msm_v4l2_s_ctrl(struct file *filp, void *fh,
  196. struct v4l2_control *a)
  197. {
  198. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  199. int rc = 0;
  200. inst = get_inst_ref(g_core, inst);
  201. if (!inst) {
  202. d_vpr_e("%s: invalid instance\n", __func__);
  203. return -EINVAL;
  204. }
  205. inst_lock(inst, __func__);
  206. rc = msm_vidc_s_ctrl((void *)inst, a);
  207. if (rc)
  208. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  209. inst_unlock(inst, __func__);
  210. put_inst(inst);
  211. return rc;
  212. }
  213. int msm_v4l2_g_ctrl(struct file *filp, void *fh,
  214. struct v4l2_control *a)
  215. {
  216. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  217. int rc = 0;
  218. inst = get_inst_ref(g_core, inst);
  219. if (!inst) {
  220. d_vpr_e("%s: invalid instance\n", __func__);
  221. return -EINVAL;
  222. }
  223. inst_lock(inst, __func__);
  224. rc = msm_vidc_g_ctrl((void *)inst, a);
  225. if (rc)
  226. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  227. inst_unlock(inst, __func__);
  228. put_inst(inst);
  229. return rc;
  230. }
  231. int msm_v4l2_reqbufs(struct file *filp, void *fh,
  232. struct v4l2_requestbuffers *b)
  233. {
  234. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  235. int rc = 0;
  236. inst = get_inst_ref(g_core, inst);
  237. if (!inst) {
  238. d_vpr_e("%s: invalid instance\n", __func__);
  239. return -EINVAL;
  240. }
  241. inst_lock(inst, __func__);
  242. rc = msm_vidc_reqbufs((void *)inst, b);
  243. if (rc)
  244. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  245. inst_unlock(inst, __func__);
  246. put_inst(inst);
  247. return rc;
  248. }
  249. int msm_v4l2_qbuf(struct file *filp, void *fh,
  250. struct v4l2_buffer *b)
  251. {
  252. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  253. struct video_device *vdev = video_devdata(filp);
  254. int rc = 0;
  255. inst = get_inst_ref(g_core, inst);
  256. if (!inst) {
  257. d_vpr_e("%s: invalid instance\n", __func__);
  258. return -EINVAL;
  259. }
  260. inst_lock(inst, __func__);
  261. rc = msm_vidc_qbuf(inst, vdev->v4l2_dev->mdev, b);
  262. if (rc)
  263. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  264. inst_unlock(inst, __func__);
  265. put_inst(inst);
  266. return rc;
  267. }
  268. int msm_v4l2_dqbuf(struct file *filp, void *fh,
  269. struct v4l2_buffer *b)
  270. {
  271. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  272. int rc = 0;
  273. inst = get_inst_ref(g_core, inst);
  274. if (!inst) {
  275. d_vpr_e("%s: invalid instance\n", __func__);
  276. return -EINVAL;
  277. }
  278. inst_lock(inst, __func__);
  279. rc = msm_vidc_dqbuf(inst, b);
  280. inst_unlock(inst, __func__);
  281. put_inst(inst);
  282. return rc;
  283. }
  284. int msm_v4l2_streamon(struct file *filp, void *fh,
  285. enum v4l2_buf_type i)
  286. {
  287. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  288. int rc = 0;
  289. inst = get_inst_ref(g_core, inst);
  290. if (!inst) {
  291. d_vpr_e("%s: invalid instance\n", __func__);
  292. return -EINVAL;
  293. }
  294. inst_lock(inst, __func__);
  295. rc = msm_vidc_streamon((void *)inst, i);
  296. if (rc)
  297. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  298. inst_unlock(inst, __func__);
  299. put_inst(inst);
  300. return rc;
  301. }
  302. int msm_v4l2_streamoff(struct file *filp, void *fh,
  303. enum v4l2_buf_type i)
  304. {
  305. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  306. int rc = 0;
  307. inst = get_inst_ref(g_core, inst);
  308. if (!inst) {
  309. d_vpr_e("%s: invalid instance\n", __func__);
  310. return -EINVAL;
  311. }
  312. inst_lock(inst, __func__);
  313. rc = msm_vidc_streamoff((void *)inst, i);
  314. if (rc)
  315. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  316. inst_unlock(inst, __func__);
  317. put_inst(inst);
  318. return rc;
  319. }
  320. int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
  321. const struct v4l2_event_subscription *sub)
  322. {
  323. struct msm_vidc_inst *inst;
  324. int rc = 0;
  325. inst = container_of(fh, struct msm_vidc_inst, event_handler);
  326. inst = get_inst_ref(g_core, inst);
  327. if (!inst) {
  328. d_vpr_e("%s: invalid instance\n", __func__);
  329. return -EINVAL;
  330. }
  331. inst_lock(inst, __func__);
  332. rc = msm_vidc_subscribe_event((void *)inst, sub);
  333. if (rc)
  334. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  335. inst_unlock(inst, __func__);
  336. put_inst(inst);
  337. return rc;
  338. }
  339. int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
  340. const struct v4l2_event_subscription *sub)
  341. {
  342. struct msm_vidc_inst *inst;
  343. int rc = 0;
  344. inst = container_of(fh, struct msm_vidc_inst, event_handler);
  345. inst = get_inst_ref(g_core, inst);
  346. if (!inst) {
  347. d_vpr_e("%s: invalid instance\n", __func__);
  348. return -EINVAL;
  349. }
  350. inst_lock(inst, __func__);
  351. rc = msm_vidc_unsubscribe_event((void *)inst, sub);
  352. if (rc)
  353. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  354. inst_unlock(inst, __func__);
  355. put_inst(inst);
  356. return rc;
  357. }
  358. int msm_v4l2_decoder_cmd(struct file *filp, void *fh,
  359. struct v4l2_decoder_cmd *dec)
  360. {
  361. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  362. int rc = 0;
  363. inst = get_inst_ref(g_core, inst);
  364. if (!inst) {
  365. d_vpr_e("%s: invalid instance\n", __func__);
  366. return -EINVAL;
  367. }
  368. inst_lock(inst, __func__);
  369. rc = msm_vidc_cmd((void *)inst, (union msm_v4l2_cmd *)dec);
  370. if (rc)
  371. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  372. inst_unlock(inst, __func__);
  373. put_inst(inst);
  374. return rc;
  375. }
  376. int msm_v4l2_encoder_cmd(struct file *filp, void *fh,
  377. struct v4l2_encoder_cmd *enc)
  378. {
  379. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  380. int rc = 0;
  381. inst = get_inst_ref(g_core, inst);
  382. if (!inst) {
  383. d_vpr_e("%s: invalid instance\n", __func__);
  384. return -EINVAL;
  385. }
  386. inst_lock(inst, __func__);
  387. rc = msm_vidc_cmd((void *)inst, (union msm_v4l2_cmd *)enc);
  388. if (rc)
  389. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  390. inst_unlock(inst, __func__);
  391. put_inst(inst);
  392. return rc;
  393. }
  394. int msm_v4l2_enum_framesizes(struct file *filp, void *fh,
  395. struct v4l2_frmsizeenum *fsize)
  396. {
  397. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  398. int rc = 0;
  399. inst = get_inst_ref(g_core, inst);
  400. if (!inst) {
  401. d_vpr_e("%s: invalid instance\n", __func__);
  402. return -EINVAL;
  403. }
  404. inst_lock(inst, __func__);
  405. rc = msm_vidc_enum_framesizes((void *)inst, fsize);
  406. if (rc)
  407. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  408. inst_unlock(inst, __func__);
  409. put_inst(inst);
  410. return rc;
  411. }
  412. int msm_v4l2_enum_frameintervals(struct file *filp, void *fh,
  413. struct v4l2_frmivalenum *fival)
  414. {
  415. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  416. int rc = 0;
  417. inst = get_inst_ref(g_core, inst);
  418. if (!inst) {
  419. d_vpr_e("%s: invalid instance\n", __func__);
  420. return -EINVAL;
  421. }
  422. inst_lock(inst, __func__);
  423. rc = msm_vidc_enum_frameintervals((void *)inst, fival);
  424. if (rc)
  425. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  426. inst_unlock(inst, __func__);
  427. put_inst(inst);
  428. return rc;
  429. }
  430. int msm_v4l2_queryctrl(struct file *filp, void *fh,
  431. struct v4l2_queryctrl *ctrl)
  432. {
  433. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  434. int rc = 0;
  435. inst = get_inst_ref(g_core, inst);
  436. if (!inst) {
  437. d_vpr_e("%s: invalid instance\n", __func__);
  438. return -EINVAL;
  439. }
  440. inst_lock(inst, __func__);
  441. rc = msm_vidc_query_ctrl((void *)inst, ctrl);
  442. if (rc)
  443. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  444. inst_unlock(inst, __func__);
  445. put_inst(inst);
  446. return rc;
  447. }
  448. int msm_v4l2_querymenu(struct file *filp, void *fh,
  449. struct v4l2_querymenu *qmenu)
  450. {
  451. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  452. int rc = 0;
  453. inst = get_inst_ref(g_core, inst);
  454. if (!inst) {
  455. d_vpr_e("%s: invalid instance\n", __func__);
  456. return -EINVAL;
  457. }
  458. inst_lock(inst, __func__);
  459. rc = msm_vidc_query_menu((void *)inst, qmenu);
  460. if (rc)
  461. i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
  462. inst_unlock(inst, __func__);
  463. put_inst(inst);
  464. return rc;
  465. }