msm_vidc_v4l2.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include "msm_vidc_v4l2.h"
  7. #include "msm_vidc_internal.h"
  8. #include "msm_vidc_core.h"
  9. #include "msm_vidc_inst.h"
  10. #include "msm_vidc_driver.h"
  11. #include "msm_vidc_debug.h"
  12. #include "msm_vidc.h"
  13. #include "msm_vidc_events.h"
  14. extern struct msm_vidc_core *g_core;
  15. static struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
  16. {
  17. if (!filp || !filp->private_data)
  18. return NULL;
  19. return container_of(filp->private_data,
  20. struct msm_vidc_inst, event_handler);
  21. }
  22. unsigned int msm_v4l2_poll(struct file *filp, struct poll_table_struct *pt)
  23. {
  24. struct msm_vidc_inst *inst = get_vidc_inst(filp, NULL);
  25. return msm_vidc_poll((void *)inst, filp, pt);
  26. }
  27. int msm_v4l2_open(struct file *filp)
  28. {
  29. struct video_device *vdev = video_devdata(filp);
  30. struct msm_video_device *vid_dev =
  31. container_of(vdev, struct msm_video_device, vdev);
  32. struct msm_vidc_core *core = video_drvdata(filp);
  33. struct msm_vidc_inst *inst;
  34. trace_msm_v4l2_vidc_open("START", NULL);
  35. inst = msm_vidc_open(core, vid_dev->type);
  36. if (!inst) {
  37. d_vpr_e("Failed to create instance, type = %d\n",
  38. vid_dev->type);
  39. trace_msm_v4l2_vidc_open("END", NULL);
  40. return -ENOMEM;
  41. }
  42. filp->private_data = &(inst->event_handler);
  43. trace_msm_v4l2_vidc_open("END", inst);
  44. return 0;
  45. }
  46. int msm_v4l2_close(struct file *filp)
  47. {
  48. int rc = 0;
  49. struct msm_vidc_inst *inst;
  50. inst = get_vidc_inst(filp, NULL);
  51. trace_msm_v4l2_vidc_close("START", inst);
  52. rc = msm_vidc_close(inst);
  53. filp->private_data = NULL;
  54. trace_msm_v4l2_vidc_close("END", NULL);
  55. return rc;
  56. }
  57. int msm_v4l2_querycap(struct file *filp, void *fh,
  58. struct v4l2_capability *cap)
  59. {
  60. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  61. int rc = 0;
  62. inst = get_inst_ref(g_core, inst);
  63. if (!inst) {
  64. d_vpr_e("%s: invalid instance\n", __func__);
  65. return -EINVAL;
  66. }
  67. client_lock(inst, __func__);
  68. inst_lock(inst, __func__);
  69. rc = msm_vidc_querycap((void *)inst, cap);
  70. if (rc)
  71. goto unlock;
  72. unlock:
  73. inst_unlock(inst, __func__);
  74. client_unlock(inst, __func__);
  75. put_inst(inst);
  76. return rc;
  77. }
  78. int msm_v4l2_enum_fmt(struct file *filp, void *fh,
  79. struct v4l2_fmtdesc *f)
  80. {
  81. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  82. int rc = 0;
  83. inst = get_inst_ref(g_core, inst);
  84. if (!inst) {
  85. d_vpr_e("%s: invalid instance\n", __func__);
  86. return -EINVAL;
  87. }
  88. client_lock(inst, __func__);
  89. inst_lock(inst, __func__);
  90. rc = msm_vidc_enum_fmt((void *)inst, f);
  91. if (rc)
  92. goto unlock;
  93. unlock:
  94. inst_unlock(inst, __func__);
  95. client_unlock(inst, __func__);
  96. put_inst(inst);
  97. return rc;
  98. }
  99. int msm_v4l2_try_fmt(struct file *filp, void *fh, struct v4l2_format *f)
  100. {
  101. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  102. int rc = 0;
  103. inst = get_inst_ref(g_core, inst);
  104. if (!inst) {
  105. d_vpr_e("%s: invalid instance\n", __func__);
  106. return -EINVAL;
  107. }
  108. client_lock(inst, __func__);
  109. inst_lock(inst, __func__);
  110. if (is_session_error(inst)) {
  111. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  112. rc = -EBUSY;
  113. goto unlock;
  114. }
  115. rc = msm_vidc_try_fmt((void *)inst, f);
  116. if (rc)
  117. goto unlock;
  118. unlock:
  119. inst_unlock(inst, __func__);
  120. client_unlock(inst, __func__);
  121. put_inst(inst);
  122. return rc;
  123. }
  124. int msm_v4l2_s_fmt(struct file *filp, void *fh,
  125. struct v4l2_format *f)
  126. {
  127. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  128. int rc = 0;
  129. inst = get_inst_ref(g_core, inst);
  130. if (!inst) {
  131. d_vpr_e("%s: invalid instance\n", __func__);
  132. return -EINVAL;
  133. }
  134. client_lock(inst, __func__);
  135. inst_lock(inst, __func__);
  136. if (is_session_error(inst)) {
  137. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  138. rc = -EBUSY;
  139. goto unlock;
  140. }
  141. rc = inst->event_handle(inst, MSM_VIDC_S_FMT, f);
  142. if (rc)
  143. goto unlock;
  144. unlock:
  145. inst_unlock(inst, __func__);
  146. client_unlock(inst, __func__);
  147. put_inst(inst);
  148. return rc;
  149. }
  150. int msm_v4l2_g_fmt(struct file *filp, void *fh,
  151. struct v4l2_format *f)
  152. {
  153. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  154. int rc = 0;
  155. inst = get_inst_ref(g_core, inst);
  156. if (!inst) {
  157. d_vpr_e("%s: invalid instance\n", __func__);
  158. return -EINVAL;
  159. }
  160. client_lock(inst, __func__);
  161. inst_lock(inst, __func__);
  162. rc = msm_vidc_g_fmt((void *)inst, f);
  163. if (rc)
  164. goto unlock;
  165. unlock:
  166. inst_unlock(inst, __func__);
  167. client_unlock(inst, __func__);
  168. put_inst(inst);
  169. return rc;
  170. }
  171. int msm_v4l2_s_selection(struct file *filp, void *fh,
  172. struct v4l2_selection *s)
  173. {
  174. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  175. int rc = 0;
  176. inst = get_inst_ref(g_core, inst);
  177. if (!inst) {
  178. d_vpr_e("%s: invalid instance\n", __func__);
  179. return -EINVAL;
  180. }
  181. client_lock(inst, __func__);
  182. inst_lock(inst, __func__);
  183. if (is_session_error(inst)) {
  184. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  185. rc = -EBUSY;
  186. goto unlock;
  187. }
  188. rc = msm_vidc_s_selection((void *)inst, s);
  189. if (rc)
  190. goto unlock;
  191. unlock:
  192. inst_unlock(inst, __func__);
  193. client_unlock(inst, __func__);
  194. put_inst(inst);
  195. return rc;
  196. }
  197. int msm_v4l2_g_selection(struct file *filp, void *fh,
  198. struct v4l2_selection *s)
  199. {
  200. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  201. int rc = 0;
  202. inst = get_inst_ref(g_core, inst);
  203. if (!inst) {
  204. d_vpr_e("%s: invalid instance\n", __func__);
  205. return -EINVAL;
  206. }
  207. client_lock(inst, __func__);
  208. inst_lock(inst, __func__);
  209. rc = msm_vidc_g_selection((void *)inst, s);
  210. if (rc)
  211. goto unlock;
  212. unlock:
  213. inst_unlock(inst, __func__);
  214. client_unlock(inst, __func__);
  215. put_inst(inst);
  216. return rc;
  217. }
  218. int msm_v4l2_s_parm(struct file *filp, void *fh,
  219. struct v4l2_streamparm *a)
  220. {
  221. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  222. int rc = 0;
  223. inst = get_inst_ref(g_core, inst);
  224. if (!inst) {
  225. d_vpr_e("%s: invalid instance\n", __func__);
  226. return -EINVAL;
  227. }
  228. client_lock(inst, __func__);
  229. inst_lock(inst, __func__);
  230. if (is_session_error(inst)) {
  231. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  232. rc = -EBUSY;
  233. goto unlock;
  234. }
  235. rc = msm_vidc_s_param((void *)inst, a);
  236. if (rc)
  237. goto unlock;
  238. unlock:
  239. inst_unlock(inst, __func__);
  240. client_unlock(inst, __func__);
  241. put_inst(inst);
  242. return rc;
  243. }
  244. int msm_v4l2_g_parm(struct file *filp, void *fh,
  245. struct v4l2_streamparm *a)
  246. {
  247. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  248. int rc = 0;
  249. inst = get_inst_ref(g_core, inst);
  250. if (!inst) {
  251. d_vpr_e("%s: invalid instance\n", __func__);
  252. return -EINVAL;
  253. }
  254. client_lock(inst, __func__);
  255. inst_lock(inst, __func__);
  256. rc = msm_vidc_g_param((void *)inst, a);
  257. if (rc)
  258. goto unlock;
  259. unlock:
  260. inst_unlock(inst, __func__);
  261. client_unlock(inst, __func__);
  262. put_inst(inst);
  263. return rc;
  264. }
  265. int msm_v4l2_reqbufs(struct file *filp, void *fh,
  266. struct v4l2_requestbuffers *b)
  267. {
  268. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  269. int rc = 0;
  270. inst = get_inst_ref(g_core, inst);
  271. if (!inst) {
  272. d_vpr_e("%s: invalid instance\n", __func__);
  273. return -EINVAL;
  274. }
  275. client_lock(inst, __func__);
  276. inst_lock(inst, __func__);
  277. rc = inst->event_handle(inst, MSM_VIDC_REQBUFS, b);
  278. if (rc)
  279. goto unlock;
  280. unlock:
  281. inst_unlock(inst, __func__);
  282. client_unlock(inst, __func__);
  283. put_inst(inst);
  284. return rc;
  285. }
  286. int msm_v4l2_querybuf(struct file *filp, void *fh,
  287. struct v4l2_buffer *b)
  288. {
  289. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  290. int rc = 0;
  291. inst = get_inst_ref(g_core, inst);
  292. if (!inst) {
  293. d_vpr_e("%s: invalid instance\n", __func__);
  294. return -EINVAL;
  295. }
  296. client_lock(inst, __func__);
  297. inst_lock(inst, __func__);
  298. rc = msm_vidc_querybuf((void *)inst, b);
  299. if (rc)
  300. goto unlock;
  301. unlock:
  302. inst_unlock(inst, __func__);
  303. client_unlock(inst, __func__);
  304. put_inst(inst);
  305. return rc;
  306. }
  307. int msm_v4l2_create_bufs(struct file *filp, void *fh,
  308. struct v4l2_create_buffers *b)
  309. {
  310. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  311. int rc = 0;
  312. inst = get_inst_ref(g_core, inst);
  313. if (!inst) {
  314. d_vpr_e("%s: invalid instance\n", __func__);
  315. return -EINVAL;
  316. }
  317. client_lock(inst, __func__);
  318. inst_lock(inst, __func__);
  319. rc = msm_vidc_create_bufs((void *)inst, b);
  320. if (rc)
  321. goto unlock;
  322. unlock:
  323. inst_unlock(inst, __func__);
  324. client_unlock(inst, __func__);
  325. put_inst(inst);
  326. return rc;
  327. }
  328. int msm_v4l2_prepare_buf(struct file *filp, void *fh,
  329. struct v4l2_buffer *b)
  330. {
  331. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  332. struct video_device *vdev = video_devdata(filp);
  333. int rc = 0;
  334. inst = get_inst_ref(g_core, inst);
  335. if (!inst) {
  336. d_vpr_e("%s: invalid instance\n", __func__);
  337. return -EINVAL;
  338. }
  339. client_lock(inst, __func__);
  340. inst_lock(inst, __func__);
  341. rc = msm_vidc_prepare_buf((void *)inst, vdev->v4l2_dev->mdev, b);
  342. if (rc)
  343. goto unlock;
  344. unlock:
  345. inst_unlock(inst, __func__);
  346. client_unlock(inst, __func__);
  347. put_inst(inst);
  348. return rc;
  349. }
  350. int msm_v4l2_qbuf(struct file *filp, void *fh,
  351. struct v4l2_buffer *b)
  352. {
  353. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  354. struct video_device *vdev = video_devdata(filp);
  355. int rc = 0;
  356. inst = get_inst_ref(g_core, inst);
  357. if (!inst) {
  358. d_vpr_e("%s: invalid instance\n", __func__);
  359. return -EINVAL;
  360. }
  361. /*
  362. * do not acquire inst lock here. acquire it in msm_vb2_buf_queue.
  363. * for requests, msm_vb2_buf_queue() is not called from here.
  364. * instead it's called as part of msm_v4l2_request_queue().
  365. * hence acquire the inst lock in common function i.e
  366. * msm_vb2_buf_queue, to handle both requests and non-request
  367. * scenarios.
  368. */
  369. rc = msm_vidc_qbuf(inst, vdev->v4l2_dev->mdev, b);
  370. if (rc)
  371. goto exit;
  372. exit:
  373. put_inst(inst);
  374. return rc;
  375. }
  376. int msm_v4l2_dqbuf(struct file *filp, void *fh,
  377. struct v4l2_buffer *b)
  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. client_lock(inst, __func__);
  387. inst_lock(inst, __func__);
  388. rc = msm_vidc_dqbuf(inst, b);
  389. if (rc)
  390. goto unlock;
  391. unlock:
  392. inst_unlock(inst, __func__);
  393. client_unlock(inst, __func__);
  394. put_inst(inst);
  395. return rc;
  396. }
  397. int msm_v4l2_streamon(struct file *filp, void *fh,
  398. enum v4l2_buf_type i)
  399. {
  400. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  401. int rc = 0;
  402. inst = get_inst_ref(g_core, inst);
  403. if (!inst) {
  404. d_vpr_e("%s: invalid instance\n", __func__);
  405. return -EINVAL;
  406. }
  407. rc = msm_vidc_streamon((void *)inst, i);
  408. if (rc)
  409. goto exit;
  410. exit:
  411. put_inst(inst);
  412. return rc;
  413. }
  414. int msm_v4l2_streamoff(struct file *filp, void *fh,
  415. enum v4l2_buf_type i)
  416. {
  417. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  418. int rc = 0;
  419. inst = get_inst_ref(g_core, inst);
  420. if (!inst) {
  421. d_vpr_e("%s: invalid instance\n", __func__);
  422. return -EINVAL;
  423. }
  424. rc = msm_vidc_streamoff((void *)inst, i);
  425. if (rc)
  426. goto exit;
  427. exit:
  428. put_inst(inst);
  429. return rc;
  430. }
  431. int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
  432. const struct v4l2_event_subscription *sub)
  433. {
  434. struct msm_vidc_inst *inst;
  435. int rc = 0;
  436. inst = container_of(fh, struct msm_vidc_inst, event_handler);
  437. inst = get_inst_ref(g_core, inst);
  438. if (!inst) {
  439. d_vpr_e("%s: invalid instance\n", __func__);
  440. return -EINVAL;
  441. }
  442. client_lock(inst, __func__);
  443. inst_lock(inst, __func__);
  444. if (is_session_error(inst)) {
  445. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  446. rc = -EBUSY;
  447. goto unlock;
  448. }
  449. rc = msm_vidc_subscribe_event((void *)inst, sub);
  450. if (rc)
  451. goto unlock;
  452. unlock:
  453. inst_unlock(inst, __func__);
  454. client_unlock(inst, __func__);
  455. put_inst(inst);
  456. return rc;
  457. }
  458. int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
  459. const struct v4l2_event_subscription *sub)
  460. {
  461. struct msm_vidc_inst *inst;
  462. int rc = 0;
  463. inst = container_of(fh, struct msm_vidc_inst, event_handler);
  464. inst = get_inst_ref(g_core, inst);
  465. if (!inst) {
  466. d_vpr_e("%s: invalid instance\n", __func__);
  467. return -EINVAL;
  468. }
  469. client_lock(inst, __func__);
  470. inst_lock(inst, __func__);
  471. rc = msm_vidc_unsubscribe_event((void *)inst, sub);
  472. if (rc)
  473. goto unlock;
  474. unlock:
  475. inst_unlock(inst, __func__);
  476. client_unlock(inst, __func__);
  477. put_inst(inst);
  478. return rc;
  479. }
  480. int msm_v4l2_try_decoder_cmd(struct file *filp, void *fh,
  481. struct v4l2_decoder_cmd *dec)
  482. {
  483. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  484. int rc = 0;
  485. inst = get_inst_ref(g_core, inst);
  486. if (!inst) {
  487. d_vpr_e("%s: invalid instance\n", __func__);
  488. return -EINVAL;
  489. }
  490. client_lock(inst, __func__);
  491. inst_lock(inst, __func__);
  492. if (is_session_error(inst)) {
  493. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  494. rc = -EBUSY;
  495. goto unlock;
  496. }
  497. rc = msm_vidc_try_cmd(inst, (union msm_v4l2_cmd *)dec);
  498. if (rc)
  499. goto unlock;
  500. unlock:
  501. inst_unlock(inst, __func__);
  502. client_unlock(inst, __func__);
  503. put_inst(inst);
  504. return rc;
  505. }
  506. int msm_v4l2_decoder_cmd(struct file *filp, void *fh,
  507. struct v4l2_decoder_cmd *dec)
  508. {
  509. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  510. enum msm_vidc_event event;
  511. int rc = 0;
  512. inst = get_inst_ref(g_core, inst);
  513. if (!inst) {
  514. d_vpr_e("%s: invalid instance\n", __func__);
  515. return -EINVAL;
  516. }
  517. client_lock(inst, __func__);
  518. inst_lock(inst, __func__);
  519. if (is_session_error(inst)) {
  520. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  521. rc = -EBUSY;
  522. goto unlock;
  523. }
  524. if (!dec) {
  525. i_vpr_e(inst, "%s: invalid params\n", __func__);
  526. rc = -EINVAL;
  527. goto unlock;
  528. }
  529. if (dec->cmd != V4L2_DEC_CMD_START &&
  530. dec->cmd != V4L2_DEC_CMD_STOP) {
  531. i_vpr_e(inst, "%s: invalid cmd %#x\n", __func__, dec->cmd);
  532. rc = -EINVAL;
  533. goto unlock;
  534. }
  535. event = (dec->cmd == V4L2_DEC_CMD_START ? MSM_VIDC_CMD_START : MSM_VIDC_CMD_STOP);
  536. rc = inst->event_handle(inst, event, NULL);
  537. if (rc)
  538. goto unlock;
  539. unlock:
  540. inst_unlock(inst, __func__);
  541. client_unlock(inst, __func__);
  542. put_inst(inst);
  543. return rc;
  544. }
  545. int msm_v4l2_try_encoder_cmd(struct file *filp, void *fh,
  546. struct v4l2_encoder_cmd *enc)
  547. {
  548. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  549. int rc = 0;
  550. inst = get_inst_ref(g_core, inst);
  551. if (!inst) {
  552. d_vpr_e("%s: invalid instance\n", __func__);
  553. return -EINVAL;
  554. }
  555. client_lock(inst, __func__);
  556. inst_lock(inst, __func__);
  557. if (is_session_error(inst)) {
  558. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  559. rc = -EBUSY;
  560. goto unlock;
  561. }
  562. rc = msm_vidc_try_cmd(inst, (union msm_v4l2_cmd *)enc);
  563. if (rc)
  564. goto unlock;
  565. unlock:
  566. inst_unlock(inst, __func__);
  567. client_unlock(inst, __func__);
  568. put_inst(inst);
  569. return rc;
  570. }
  571. int msm_v4l2_encoder_cmd(struct file *filp, void *fh,
  572. struct v4l2_encoder_cmd *enc)
  573. {
  574. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  575. enum msm_vidc_event event;
  576. int rc = 0;
  577. inst = get_inst_ref(g_core, inst);
  578. if (!inst) {
  579. d_vpr_e("%s: invalid instance\n", __func__);
  580. return -EINVAL;
  581. }
  582. client_lock(inst, __func__);
  583. inst_lock(inst, __func__);
  584. if (is_session_error(inst)) {
  585. i_vpr_e(inst, "%s: inst in error state\n", __func__);
  586. rc = -EBUSY;
  587. goto unlock;
  588. }
  589. if (!enc) {
  590. i_vpr_e(inst, "%s: invalid params\n", __func__);
  591. rc = -EINVAL;
  592. goto unlock;
  593. }
  594. if (enc->cmd != V4L2_ENC_CMD_START &&
  595. enc->cmd != V4L2_ENC_CMD_STOP) {
  596. i_vpr_e(inst, "%s: invalid cmd %#x\n", __func__, enc->cmd);
  597. rc = -EINVAL;
  598. goto unlock;
  599. }
  600. event = (enc->cmd == V4L2_ENC_CMD_START ? MSM_VIDC_CMD_START : MSM_VIDC_CMD_STOP);
  601. rc = inst->event_handle(inst, event, NULL);
  602. if (rc)
  603. goto unlock;
  604. unlock:
  605. inst_unlock(inst, __func__);
  606. client_unlock(inst, __func__);
  607. put_inst(inst);
  608. return rc;
  609. }
  610. int msm_v4l2_enum_framesizes(struct file *filp, void *fh,
  611. struct v4l2_frmsizeenum *fsize)
  612. {
  613. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  614. int rc = 0;
  615. inst = get_inst_ref(g_core, inst);
  616. if (!inst) {
  617. d_vpr_e("%s: invalid instance\n", __func__);
  618. return -EINVAL;
  619. }
  620. client_lock(inst, __func__);
  621. inst_lock(inst, __func__);
  622. rc = msm_vidc_enum_framesizes((void *)inst, fsize);
  623. if (rc)
  624. goto unlock;
  625. unlock:
  626. inst_unlock(inst, __func__);
  627. client_unlock(inst, __func__);
  628. put_inst(inst);
  629. return rc;
  630. }
  631. int msm_v4l2_enum_frameintervals(struct file *filp, void *fh,
  632. struct v4l2_frmivalenum *fival)
  633. {
  634. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  635. int rc = 0;
  636. inst = get_inst_ref(g_core, inst);
  637. if (!inst) {
  638. d_vpr_e("%s: invalid instance\n", __func__);
  639. return -EINVAL;
  640. }
  641. client_lock(inst, __func__);
  642. inst_lock(inst, __func__);
  643. rc = msm_vidc_enum_frameintervals((void *)inst, fival);
  644. if (rc)
  645. goto unlock;
  646. unlock:
  647. inst_unlock(inst, __func__);
  648. client_unlock(inst, __func__);
  649. put_inst(inst);
  650. return rc;
  651. }
  652. int msm_v4l2_queryctrl(struct file *filp, void *fh,
  653. struct v4l2_queryctrl *ctrl)
  654. {
  655. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  656. int rc = 0;
  657. inst = get_inst_ref(g_core, inst);
  658. if (!inst) {
  659. d_vpr_e("%s: invalid instance\n", __func__);
  660. return -EINVAL;
  661. }
  662. client_lock(inst, __func__);
  663. inst_lock(inst, __func__);
  664. rc = msm_vidc_query_ctrl((void *)inst, ctrl);
  665. if (rc)
  666. goto unlock;
  667. unlock:
  668. inst_unlock(inst, __func__);
  669. client_unlock(inst, __func__);
  670. put_inst(inst);
  671. return rc;
  672. }
  673. int msm_v4l2_querymenu(struct file *filp, void *fh,
  674. struct v4l2_querymenu *qmenu)
  675. {
  676. struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
  677. int rc = 0;
  678. inst = get_inst_ref(g_core, inst);
  679. if (!inst) {
  680. d_vpr_e("%s: invalid instance\n", __func__);
  681. return -EINVAL;
  682. }
  683. client_lock(inst, __func__);
  684. inst_lock(inst, __func__);
  685. rc = msm_vidc_query_menu((void *)inst, qmenu);
  686. if (rc)
  687. goto unlock;
  688. unlock:
  689. inst_unlock(inst, __func__);
  690. client_unlock(inst, __func__);
  691. put_inst(inst);
  692. return rc;
  693. }
  694. int msm_v4l2_request_validate(struct media_request *req)
  695. {
  696. d_vpr_l("%s()\n", __func__);
  697. return vb2_request_validate(req);
  698. }
  699. void msm_v4l2_request_queue(struct media_request *req)
  700. {
  701. d_vpr_l("%s()\n", __func__);
  702. v4l2_m2m_request_queue(req);
  703. }
  704. void msm_v4l2_m2m_device_run(void *priv)
  705. {
  706. d_vpr_l("%s()\n", __func__);
  707. }
  708. void msm_v4l2_m2m_job_abort(void *priv)
  709. {
  710. struct msm_vidc_inst *inst = priv;
  711. if (!inst) {
  712. d_vpr_e("%s: invalid params\n", __func__);
  713. return;
  714. }
  715. i_vpr_h(inst, "%s: m2m job aborted\n", __func__);
  716. v4l2_m2m_job_finish(inst->m2m_dev, inst->m2m_ctx);
  717. }