amstream.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681
  1. /*
  2. * AMLOGIC Audio/Video streaming port driver.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the named License,
  7. * or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  17. *
  18. * Author: Tim Yao <timyao@amlogic.com>
  19. *
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/module.h>
  23. #include <linux/types.h>
  24. #include <linux/fs.h>
  25. #include <linux/init.h>
  26. #include <linux/device.h>
  27. #include <linux/vmalloc.h>
  28. #include <linux/mm.h>
  29. #include <linux/major.h>
  30. #include <linux/sched.h>
  31. #include <linux/interrupt.h>
  32. #include <linux/amports/amstream.h>
  33. #include <linux/amports/vformat.h>
  34. #include <linux/amports/aformat.h>
  35. #include <linux/amports/tsync.h>
  36. #include <linux/amports/ptsserv.h>
  37. #include <linux/amports/timestamp.h>
  38. #include <asm/types.h>
  39. #include <asm/uaccess.h>
  40. #include <asm/sections.h>
  41. #include <asm/io.h>
  42. #include <mach/am_regs.h>
  43. #include <linux/platform_device.h>
  44. #include <linux/mutex.h>
  45. #include <linux/poll.h>
  46. #include <linux/dma-mapping.h>
  47. #include <asm/uaccess.h>
  48. #ifdef CONFIG_ARCH_MESON6
  49. #include <mach/mod_gate.h>
  50. #endif
  51. #include "streambuf.h"
  52. #include "streambuf_reg.h"
  53. #include "tsdemux.h"
  54. #include "psparser.h"
  55. #include "esparser.h"
  56. #include "vdec.h"
  57. #include "adec.h"
  58. #include "rmparser.h"
  59. #define DEVICE_NAME "amstream-dev"
  60. #define DRIVER_NAME "amstream"
  61. #define MODULE_NAME "amstream"
  62. #define MAX_AMSTREAM_PORT_NUM ARRAY_SIZE(ports)
  63. extern void set_real_audio_info(void *arg);
  64. //#define DATA_DEBUG
  65. #ifdef DATA_DEBUG
  66. #include <linux/fs.h>
  67. #define DEBUG_FILE_NAME "/tmp/debug.tmp"
  68. static struct file* debug_filp = NULL;
  69. static loff_t debug_file_pos = 0;
  70. void debug_file_write(const char __user *buf, size_t count)
  71. {
  72. mm_segment_t old_fs;
  73. if (!debug_filp) {
  74. return;
  75. }
  76. old_fs = get_fs();
  77. set_fs(KERNEL_DS);
  78. if (count != vfs_write(debug_filp, buf, count, &debug_file_pos)) {
  79. printk("Failed to write debug file\n");
  80. }
  81. set_fs(old_fs);
  82. return;
  83. }
  84. #endif
  85. #define DEFAULT_VIDEO_BUFFER_SIZE (1024*1024*3)
  86. #define DEFAULT_AUDIO_BUFFER_SIZE (1024*384)
  87. #define DEFAULT_SUBTITLE_BUFFER_SIZE (1024*128)
  88. #if 0
  89. static ulong vbuf_start;
  90. module_param(vbuf_start, ulong, 0644);
  91. MODULE_PARM_DESC(vbuf_start, "Amstreaming ports video buffer start address");
  92. static ulong vbuf_size;
  93. module_param(vbuf_size, ulong, 0644);
  94. MODULE_PARM_DESC(vbuf_size, "Amstreaming ports video buffer size");
  95. static ulong abuf_start;
  96. module_param(abuf_start, ulong, 0644);
  97. MODULE_PARM_DESC(abuf_start, "Amstreaming ports audio buffer start address");
  98. static ulong abuf_size;
  99. module_param(abuf_size, ulong, 0644);
  100. MODULE_PARM_DESC(abuf_size, "Amstreaming ports audio buffer size");
  101. #endif
  102. #if 0
  103. typedef struct stream_port_s {
  104. /* driver info */
  105. const char *name;
  106. struct device *class_dev;
  107. const struct file_operations *fops;
  108. /* ports control */
  109. s32 type;
  110. s32 flag;
  111. /* decoder info */
  112. s32 vformat;
  113. s32 aformat;
  114. s32 achanl;
  115. s32 asamprate;
  116. /* parser info */
  117. u32 vid;
  118. u32 aid;
  119. } stream_port_t;
  120. #endif
  121. static int amstream_open
  122. (struct inode *inode, struct file *file);
  123. static int amstream_release
  124. (struct inode *inode, struct file *file);
  125. static long amstream_ioctl
  126. (struct file *file,
  127. unsigned int cmd, ulong arg);
  128. static ssize_t amstream_vbuf_write
  129. (struct file *file, const char *buf,
  130. size_t count, loff_t * ppos);
  131. static ssize_t amstream_abuf_write
  132. (struct file *file, const char *buf,
  133. size_t count, loff_t * ppos);
  134. static ssize_t amstream_mpts_write
  135. (struct file *file, const char *buf,
  136. size_t count, loff_t * ppos);
  137. static ssize_t amstream_mpps_write
  138. (struct file *file, const char *buf,
  139. size_t count, loff_t * ppos);
  140. static ssize_t amstream_sub_read
  141. (struct file *file, char *buf,
  142. size_t count, loff_t * ppos);
  143. static ssize_t amstream_sub_write
  144. (struct file *file, const char *buf,
  145. size_t count, loff_t * ppos);
  146. static unsigned int amstream_sub_poll
  147. (struct file *file, poll_table *wait_table);
  148. static int (*amstream_vdec_status)
  149. (struct vdec_status *vstatus);
  150. static int (*amstream_adec_status)
  151. (struct adec_status *astatus);
  152. static int (*amstream_vdec_trickmode)
  153. (unsigned long trickmode);
  154. static ssize_t amstream_mprm_write
  155. (struct file *file, const char *buf,
  156. size_t count, loff_t * ppos);
  157. const static struct file_operations vbuf_fops = {
  158. .owner = THIS_MODULE,
  159. .open = amstream_open,
  160. .release = amstream_release,
  161. .write = amstream_vbuf_write,
  162. .unlocked_ioctl = amstream_ioctl,
  163. };
  164. const static struct file_operations abuf_fops = {
  165. .owner = THIS_MODULE,
  166. .open = amstream_open,
  167. .release = amstream_release,
  168. .write = amstream_abuf_write,
  169. .unlocked_ioctl = amstream_ioctl,
  170. };
  171. const static struct file_operations mpts_fops = {
  172. .owner = THIS_MODULE,
  173. .open = amstream_open,
  174. .release = amstream_release,
  175. .write = amstream_mpts_write,
  176. .unlocked_ioctl = amstream_ioctl,
  177. };
  178. const static struct file_operations mpps_fops = {
  179. .owner = THIS_MODULE,
  180. .open = amstream_open,
  181. .release = amstream_release,
  182. .write = amstream_mpps_write,
  183. .unlocked_ioctl = amstream_ioctl,
  184. };
  185. const static struct file_operations mprm_fops = {
  186. .owner = THIS_MODULE,
  187. .open = amstream_open,
  188. .release = amstream_release,
  189. .write = amstream_mprm_write,
  190. .unlocked_ioctl = amstream_ioctl,
  191. };
  192. const static struct file_operations sub_fops = {
  193. .owner = THIS_MODULE,
  194. .open = amstream_open,
  195. .release = amstream_release,
  196. .write = amstream_sub_write,
  197. .unlocked_ioctl = amstream_ioctl,
  198. };
  199. const static struct file_operations sub_read_fops = {
  200. .owner = THIS_MODULE,
  201. .open = amstream_open,
  202. .release = amstream_release,
  203. .read = amstream_sub_read,
  204. .poll = amstream_sub_poll,
  205. .unlocked_ioctl = amstream_ioctl,
  206. };
  207. const static struct file_operations amstream_fops = {
  208. .owner = THIS_MODULE,
  209. .open = amstream_open,
  210. .release = amstream_release,
  211. .unlocked_ioctl = amstream_ioctl,
  212. };
  213. /**************************************************/
  214. static struct audio_info audio_dec_info;
  215. struct dec_sysinfo amstream_dec_info;
  216. static struct class *amstream_dev_class;
  217. static DEFINE_MUTEX(amstream_mutex);
  218. atomic_t subdata_ready = ATOMIC_INIT(0);
  219. static int sub_type;
  220. static int sub_port_inited;
  221. /* wait queue for poll */
  222. static wait_queue_head_t amstream_sub_wait;
  223. static stream_port_t ports[] = {
  224. {
  225. .name = "amstream_vbuf",
  226. .type = PORT_TYPE_ES | PORT_TYPE_VIDEO,
  227. .fops = &vbuf_fops,
  228. },
  229. {
  230. .name = "amstream_abuf",
  231. .type = PORT_TYPE_ES | PORT_TYPE_AUDIO,
  232. .fops = &abuf_fops,
  233. },
  234. {
  235. .name = "amstream_mpts",
  236. .type = PORT_TYPE_MPTS | PORT_TYPE_VIDEO | PORT_TYPE_AUDIO | PORT_TYPE_SUB,
  237. .fops = &mpts_fops,
  238. },
  239. {
  240. .name = "amstream_mpps",
  241. .type = PORT_TYPE_MPPS | PORT_TYPE_VIDEO | PORT_TYPE_AUDIO | PORT_TYPE_SUB,
  242. .fops = &mpps_fops,
  243. },
  244. {
  245. .name = "amstream_rm",
  246. .type = PORT_TYPE_RM | PORT_TYPE_VIDEO | PORT_TYPE_AUDIO,
  247. .fops = &mprm_fops,
  248. },
  249. {
  250. .name = "amstream_sub",
  251. .type = PORT_TYPE_SUB,
  252. .fops = &sub_fops,
  253. },
  254. {
  255. .name = "amstream_sub_read",
  256. .type = PORT_TYPE_SUB_RD,
  257. .fops = &sub_read_fops,
  258. }
  259. };
  260. static stream_buf_t bufs[BUF_MAX_NUM] = {
  261. {
  262. .reg_base = VLD_MEM_VIFIFO_REG_BASE,
  263. .type = BUF_TYPE_VIDEO,
  264. .buf_start = 0,
  265. .buf_size = 0,
  266. .first_tstamp = INVALID_PTS
  267. },
  268. {
  269. .reg_base = AIU_MEM_AIFIFO_REG_BASE,
  270. .type = BUF_TYPE_AUDIO,
  271. .buf_start = 0,
  272. .buf_size = 0,
  273. .first_tstamp = INVALID_PTS
  274. },
  275. {
  276. .reg_base = 0,
  277. .type = BUF_TYPE_SUBTITLE,
  278. .buf_start = 0,
  279. .buf_size = 0,
  280. .first_tstamp = INVALID_PTS
  281. }
  282. };
  283. void set_sample_rate_info(int arg)
  284. {
  285. audio_dec_info.sample_rate = arg;
  286. audio_dec_info.valid = 1;
  287. }
  288. void set_ch_num_info(int arg)
  289. {
  290. audio_dec_info.channels= arg;
  291. }
  292. struct audio_info *get_audio_info(void) {
  293. return &audio_dec_info;
  294. }
  295. EXPORT_SYMBOL(get_audio_info);
  296. static void video_port_release(stream_port_t *port, struct stream_buf_s * pbuf, int release_num)
  297. {
  298. switch (release_num) {
  299. default:
  300. case 0: /*release all*/
  301. /* */
  302. case 4:
  303. esparser_release(pbuf);
  304. case 3:
  305. vdec_release(port->vformat);
  306. case 2:
  307. stbuf_release(pbuf);
  308. case 1:
  309. ;
  310. }
  311. return ;
  312. }
  313. static int video_port_init(stream_port_t *port, struct stream_buf_s * pbuf)
  314. {
  315. int r;
  316. if ((port->flag & PORT_FLAG_VFORMAT) == 0) {
  317. printk("vformat not set\n");
  318. return -EPERM;
  319. }
  320. r = stbuf_init(pbuf);
  321. if (r < 0) {
  322. return r;
  323. }
  324. r = vdec_init(port->vformat);
  325. if (r < 0) {
  326. video_port_release(port, pbuf, 2);
  327. return r;
  328. }
  329. if (port->type & PORT_TYPE_ES) {
  330. r = esparser_init(pbuf);
  331. if (r < 0) {
  332. video_port_release(port, pbuf, 3);
  333. printk("esparser_init() failed\n");
  334. return r;
  335. }
  336. }
  337. pbuf->flag |= BUF_FLAG_IN_USE;
  338. return 0;
  339. }
  340. static void audio_port_release(stream_port_t *port, struct stream_buf_s * pbuf, int release_num)
  341. {
  342. switch (release_num) {
  343. default:
  344. case 0: /*release all*/
  345. /* */
  346. case 4:
  347. esparser_release(pbuf);
  348. case 3:
  349. adec_release(port->vformat);
  350. case 2:
  351. stbuf_release(pbuf);
  352. case 1:
  353. ;
  354. }
  355. return ;
  356. }
  357. static int audio_port_reset(stream_port_t *port, struct stream_buf_s * pbuf)
  358. {
  359. int r;
  360. if ((port->flag & PORT_FLAG_AFORMAT) == 0) {
  361. printk("aformat not set\n");
  362. return 0;
  363. }
  364. pts_stop(PTS_TYPE_AUDIO);
  365. stbuf_release(pbuf);
  366. r = stbuf_init(pbuf);
  367. if (r < 0) {
  368. return r;
  369. }
  370. r = adec_init(port);
  371. if (r < 0) {
  372. audio_port_release(port, pbuf, 2);
  373. return r;
  374. }
  375. if (port->type & PORT_TYPE_ES) {
  376. esparser_audio_reset(pbuf);
  377. }
  378. if (port->type & PORT_TYPE_MPTS) {
  379. tsdemux_audio_reset();
  380. }
  381. if (port->type & PORT_TYPE_MPPS) {
  382. psparser_audio_reset();
  383. }
  384. if (port->type & PORT_TYPE_RM) {
  385. rm_audio_reset();
  386. }
  387. pbuf->flag |= BUF_FLAG_IN_USE;
  388. pts_start(PTS_TYPE_AUDIO);
  389. return 0;
  390. }
  391. static int sub_port_reset(stream_port_t *port, struct stream_buf_s * pbuf)
  392. {
  393. int r;
  394. port->flag &= (~PORT_FLAG_INITED);
  395. stbuf_release(pbuf);
  396. r = stbuf_init(pbuf);
  397. if (r < 0) {
  398. return r;
  399. }
  400. if (port->type & PORT_TYPE_MPTS) {
  401. tsdemux_sub_reset();
  402. }
  403. if (port->type & PORT_TYPE_MPPS) {
  404. psparser_sub_reset();
  405. }
  406. if (port->sid == 0xffff) { // es sub
  407. esparser_sub_reset();
  408. pbuf->flag |= BUF_FLAG_PARSER;
  409. }
  410. pbuf->flag |= BUF_FLAG_IN_USE;
  411. port->flag |= PORT_FLAG_INITED;
  412. return 0;
  413. }
  414. static int audio_port_init(stream_port_t *port, struct stream_buf_s * pbuf)
  415. {
  416. int r;
  417. if ((port->flag & PORT_FLAG_AFORMAT) == 0) {
  418. printk("aformat not set\n");
  419. return 0;
  420. }
  421. r = stbuf_init(pbuf);
  422. if (r < 0) {
  423. return r;
  424. }
  425. r = adec_init(port);
  426. if (r < 0) {
  427. audio_port_release(port, pbuf, 2);
  428. return r;
  429. }
  430. if (port->type & PORT_TYPE_ES) {
  431. r = esparser_init(pbuf);
  432. if (r < 0) {
  433. audio_port_release(port, pbuf, 3);
  434. return r;
  435. }
  436. }
  437. pbuf->flag |= BUF_FLAG_IN_USE;
  438. return 0;
  439. }
  440. static void sub_port_release(stream_port_t *port, struct stream_buf_s * pbuf)
  441. {
  442. if (port->sid == 0xffff) { // this is es sub
  443. esparser_release(pbuf);
  444. }
  445. stbuf_release(pbuf);
  446. sub_port_inited = 0;
  447. return;
  448. }
  449. static int sub_port_init(stream_port_t *port, struct stream_buf_s * pbuf)
  450. {
  451. int r;
  452. if ((port->flag & PORT_FLAG_SID) == 0) {
  453. printk("subtitle id not set\n");
  454. return 0;
  455. }
  456. r = stbuf_init(pbuf);
  457. if (r < 0) {
  458. return r;
  459. }
  460. if (port->sid == 0xffff) { // es sub
  461. r = esparser_init(pbuf);
  462. if (r < 0) {
  463. sub_port_release(port, pbuf);
  464. return r;
  465. }
  466. }
  467. sub_port_inited = 1;
  468. return 0;
  469. }
  470. static int amstream_port_init(stream_port_t *port)
  471. {
  472. int r;
  473. stream_buf_t *pvbuf = &bufs[BUF_TYPE_VIDEO];
  474. stream_buf_t *pabuf = &bufs[BUF_TYPE_AUDIO];
  475. stream_buf_t *psbuf = &bufs[BUF_TYPE_SUBTITLE];
  476. if ((port->type & PORT_TYPE_AUDIO) && (port->flag & PORT_FLAG_AFORMAT)) {
  477. r = audio_port_init(port, pabuf);
  478. if (r < 0) {
  479. printk("audio_port_init failed\n");
  480. goto error1;
  481. }
  482. }
  483. if ((port->type & PORT_TYPE_VIDEO) && (port->flag & PORT_FLAG_VFORMAT)) {
  484. r = video_port_init(port, pvbuf);
  485. if (r < 0) {
  486. printk("video_port_init failed\n");
  487. goto error2;
  488. }
  489. }
  490. if ((port->type & PORT_TYPE_SUB) && (port->flag & PORT_FLAG_SID)) {
  491. r = sub_port_init(port, psbuf);
  492. if (r < 0) {
  493. printk("sub_port_init failed\n");
  494. goto error3;
  495. }
  496. }
  497. if (port->type & PORT_TYPE_MPTS) {
  498. r = tsdemux_init((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
  499. (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff,
  500. (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff);
  501. if (r < 0) {
  502. printk("tsdemux_init failed\n");
  503. goto error4;
  504. }
  505. }
  506. if (port->type & PORT_TYPE_MPPS) {
  507. r = psparser_init((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
  508. (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff,
  509. (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff);
  510. if (r < 0) {
  511. printk("psparser_init failed\n");
  512. goto error5;
  513. }
  514. }
  515. if (port->type & PORT_TYPE_RM) {
  516. rm_set_vasid((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
  517. (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff);
  518. }
  519. tsync_audio_break(0); // clear audio break
  520. port->flag |= PORT_FLAG_INITED;
  521. return 0;
  522. /*errors follow here*/
  523. error5:
  524. tsdemux_release();
  525. error4:
  526. sub_port_release(port, psbuf);
  527. error3:
  528. video_port_release(port, pvbuf, 0);
  529. error2:
  530. audio_port_release(port, pabuf, 0);
  531. error1:
  532. return r;
  533. }
  534. static int amstream_port_release(stream_port_t *port)
  535. {
  536. stream_buf_t *pvbuf = &bufs[BUF_TYPE_VIDEO];
  537. stream_buf_t *pabuf = &bufs[BUF_TYPE_AUDIO];
  538. stream_buf_t *psbuf = &bufs[BUF_TYPE_SUBTITLE];
  539. if (port->type & PORT_TYPE_MPTS) {
  540. tsdemux_release();
  541. }
  542. if (port->type & PORT_TYPE_MPPS) {
  543. psparser_release();
  544. }
  545. if (port->type & PORT_TYPE_RM) {
  546. rmparser_release();
  547. }
  548. if (port->type & PORT_TYPE_VIDEO) {
  549. video_port_release(port, pvbuf, 0);
  550. }
  551. if (port->type & PORT_TYPE_AUDIO) {
  552. audio_port_release(port, pabuf, 0);
  553. }
  554. if (port->type & PORT_TYPE_SUB) {
  555. sub_port_release(port, psbuf);
  556. }
  557. port->flag = 0;
  558. return 0;
  559. }
  560. static void amstream_change_avid(stream_port_t *port)
  561. {
  562. if (port->type & PORT_TYPE_MPTS) {
  563. tsdemux_change_avid((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
  564. (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff);
  565. }
  566. if (port->type & PORT_TYPE_MPPS) {
  567. psparser_change_avid((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
  568. (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff);
  569. }
  570. if (port->type & PORT_TYPE_RM) {
  571. rm_set_vasid((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
  572. (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff);
  573. }
  574. return;
  575. }
  576. static void amstream_change_sid(stream_port_t *port)
  577. {
  578. if (port->type & PORT_TYPE_MPTS) {
  579. tsdemux_change_sid((port->flag & PORT_FLAG_SID) ? port->sid : 0xffff);
  580. }
  581. if (port->type & PORT_TYPE_MPPS) {
  582. psparser_change_sid((port->flag & PORT_FLAG_SID) ? port->sid : 0xffff);
  583. }
  584. return;
  585. }
  586. /**************************************************/
  587. static ssize_t amstream_vbuf_write(struct file *file, const char *buf,
  588. size_t count, loff_t * ppos)
  589. {
  590. stream_port_t *port = (stream_port_t *)file->private_data;
  591. stream_buf_t *pbuf = &bufs[BUF_TYPE_VIDEO];
  592. int r;
  593. if (!(port->flag & PORT_FLAG_INITED)) {
  594. r = amstream_port_init(port);
  595. if (r < 0) {
  596. return r;
  597. }
  598. }
  599. r = esparser_write(file, pbuf, buf, count);
  600. #ifdef DATA_DEBUG
  601. debug_file_write(buf, r);
  602. #endif
  603. return r;
  604. }
  605. static ssize_t amstream_abuf_write(struct file *file, const char *buf,
  606. size_t count, loff_t * ppos)
  607. {
  608. stream_port_t *port = (stream_port_t *)file->private_data;
  609. stream_buf_t *pbuf = &bufs[BUF_TYPE_AUDIO];
  610. int r;
  611. if (!(port->flag & PORT_FLAG_INITED)) {
  612. r = amstream_port_init(port);
  613. if (r < 0) {
  614. return r;
  615. }
  616. }
  617. return esparser_write(file, pbuf, buf, count);
  618. }
  619. static ssize_t amstream_mpts_write(struct file *file, const char *buf,
  620. size_t count, loff_t * ppos)
  621. {
  622. stream_port_t *port = (stream_port_t *)file->private_data;
  623. stream_buf_t *pvbuf = &bufs[BUF_TYPE_VIDEO];
  624. stream_buf_t *pabuf = &bufs[BUF_TYPE_AUDIO];
  625. int r;
  626. if (!(port->flag & PORT_FLAG_INITED)) {
  627. r = amstream_port_init(port);
  628. if (r < 0) {
  629. return r;
  630. }
  631. }
  632. #ifdef DATA_DEBUG
  633. debug_file_write(buf, count);
  634. #endif
  635. return tsdemux_write(file, pvbuf, pabuf, buf, count);
  636. }
  637. static ssize_t amstream_mpps_write(struct file *file, const char *buf,
  638. size_t count, loff_t * ppos)
  639. {
  640. stream_port_t *port = (stream_port_t *)file->private_data;
  641. stream_buf_t *pvbuf = &bufs[BUF_TYPE_VIDEO];
  642. stream_buf_t *pabuf = &bufs[BUF_TYPE_AUDIO];
  643. int r;
  644. if (!(port->flag & PORT_FLAG_INITED)) {
  645. r = amstream_port_init(port);
  646. if (r < 0) {
  647. return r;
  648. }
  649. }
  650. return psparser_write(file, pvbuf, pabuf, buf, count);
  651. }
  652. static ssize_t amstream_mprm_write(struct file *file, const char *buf,
  653. size_t count, loff_t * ppos)
  654. {
  655. stream_port_t *port = (stream_port_t *)file->private_data;
  656. stream_buf_t *pvbuf = &bufs[BUF_TYPE_VIDEO];
  657. stream_buf_t *pabuf = &bufs[BUF_TYPE_AUDIO];
  658. int r;
  659. if (!(port->flag & PORT_FLAG_INITED)) {
  660. r = amstream_port_init(port);
  661. if (r < 0) {
  662. return r;
  663. }
  664. }
  665. return rmparser_write(file, pvbuf, pabuf, buf, count);
  666. }
  667. static ssize_t amstream_sub_read(struct file *file, char __user *buf, size_t count, loff_t * ppos)
  668. {
  669. u32 sub_rp, sub_wp, sub_start, data_size, res;
  670. stream_buf_t *s_buf = &bufs[BUF_TYPE_SUBTITLE];
  671. if (sub_port_inited == 0) {
  672. return 0;
  673. }
  674. sub_rp = stbuf_sub_rp_get();
  675. sub_wp = stbuf_sub_wp_get();
  676. sub_start = stbuf_sub_start_get();
  677. if (sub_wp == sub_rp) {
  678. return 0;
  679. }
  680. if (sub_wp > sub_rp) {
  681. data_size = sub_wp - sub_rp;
  682. } else {
  683. data_size = s_buf->buf_size - sub_rp + sub_wp;
  684. }
  685. if (data_size > count) {
  686. data_size = count;
  687. }
  688. if (sub_wp < sub_rp) {
  689. int first_num = s_buf->buf_size - (sub_rp - sub_start);
  690. if (data_size <= first_num) {
  691. res = copy_to_user((void *)buf, (void *)(phys_to_virt(sub_rp)), data_size);
  692. if (res >= 0) {
  693. stbuf_sub_rp_set(sub_rp + data_size - res);
  694. }
  695. return data_size - res;
  696. } else {
  697. if (first_num > 0) {
  698. res = copy_to_user((void *)buf, (void *)(phys_to_virt(sub_rp)), first_num);
  699. if (res >= 0) {
  700. stbuf_sub_rp_set(sub_rp + first_num - res);
  701. }
  702. return first_num - res;
  703. }
  704. res = copy_to_user((void *)buf, (void *)(phys_to_virt(sub_start)), data_size - first_num);
  705. if (res >= 0) {
  706. stbuf_sub_rp_set(sub_start + data_size - first_num - res);
  707. }
  708. return data_size - first_num - res;
  709. }
  710. } else {
  711. res = copy_to_user((void *)buf, (void *)(phys_to_virt(sub_rp)), data_size);
  712. if (res >= 0) {
  713. stbuf_sub_rp_set(sub_rp + data_size - res);
  714. }
  715. return data_size - res;
  716. }
  717. }
  718. static ssize_t amstream_sub_write(struct file *file, const char *buf,
  719. size_t count, loff_t * ppos)
  720. {
  721. stream_port_t *port = (stream_port_t *)file->private_data;
  722. stream_buf_t *pbuf = &bufs[BUF_TYPE_SUBTITLE];
  723. int r;
  724. if (!(port->flag & PORT_FLAG_INITED)) {
  725. r = amstream_port_init(port);
  726. if (r < 0) {
  727. return r;
  728. }
  729. }
  730. r = esparser_write(file, pbuf, buf, count);
  731. if (r < 0) {
  732. return r;
  733. }
  734. wakeup_sub_poll();
  735. return r;
  736. }
  737. static unsigned int amstream_sub_poll(struct file *file, poll_table *wait_table)
  738. {
  739. poll_wait(file, &amstream_sub_wait, wait_table);
  740. if (atomic_read(&subdata_ready)) {
  741. atomic_set(&subdata_ready, 0);
  742. return POLLOUT | POLLWRNORM;
  743. }
  744. return 0;
  745. }
  746. static int amstream_open(struct inode *inode, struct file *file)
  747. {
  748. s32 i;
  749. stream_port_t *s;
  750. stream_port_t *this = &ports[iminor(inode)];
  751. #ifdef CONFIG_ARCH_MESON6
  752. switch_mod_gate_by_name("audio", 1);
  753. switch_mod_gate_by_name("vdec", 1);
  754. #endif
  755. if (iminor(inode) >= MAX_AMSTREAM_PORT_NUM) {
  756. return (-ENODEV);
  757. }
  758. if (this->flag & PORT_FLAG_IN_USE) {
  759. return (-EBUSY);
  760. }
  761. /* check other ports conflict */
  762. for (s = &ports[0], i = 0; i < MAX_AMSTREAM_PORT_NUM; i++, s++) {
  763. if ((s->flag & PORT_FLAG_IN_USE) &&
  764. ((this->type) & (s->type) & (PORT_TYPE_VIDEO | PORT_TYPE_AUDIO))) {
  765. return (-EBUSY);
  766. }
  767. }
  768. this->vid = 0;
  769. this->aid = 0;
  770. this->sid = 0;
  771. file->f_op = this->fops;
  772. file->private_data = this;
  773. this->flag = PORT_FLAG_IN_USE;
  774. #ifdef DATA_DEBUG
  775. debug_filp = filp_open(DEBUG_FILE_NAME, O_WRONLY, 0);
  776. if (IS_ERR(debug_filp)) {
  777. printk("amstream: open debug file failed\n");
  778. debug_filp = NULL;
  779. }
  780. #endif
  781. return 0;
  782. }
  783. static int amstream_release(struct inode *inode, struct file *file)
  784. {
  785. stream_port_t *this = &ports[iminor(inode)];
  786. if (iminor(inode) >= MAX_AMSTREAM_PORT_NUM) {
  787. return (-ENODEV);
  788. }
  789. if (this->flag & PORT_FLAG_INITED) {
  790. amstream_port_release(this);
  791. }
  792. this->flag = 0;
  793. ///timestamp_pcrscr_set(0);
  794. #ifdef DATA_DEBUG
  795. if (debug_filp) {
  796. filp_close(debug_filp, current->files);
  797. debug_filp = NULL;
  798. debug_file_pos = 0;
  799. }
  800. #endif
  801. #ifdef CONFIG_ARCH_MESON6
  802. switch_mod_gate_by_name("audio", 0);
  803. switch_mod_gate_by_name("vdec", 0);
  804. #endif
  805. return 0;
  806. }
  807. static long amstream_ioctl(struct file *file,
  808. unsigned int cmd, ulong arg)
  809. {
  810. s32 r = 0;
  811. struct inode *inode = file->f_dentry->d_inode;
  812. stream_port_t *this = &ports[iminor(inode)];
  813. switch (cmd) {
  814. case AMSTREAM_IOC_VB_START:
  815. if ((this->type & PORT_TYPE_VIDEO) &&
  816. ((bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_IN_USE) == 0)) {
  817. bufs[BUF_TYPE_VIDEO].buf_start = arg;
  818. } else {
  819. r = -EINVAL;
  820. }
  821. break;
  822. case AMSTREAM_IOC_VB_SIZE:
  823. if ((this->type & PORT_TYPE_VIDEO) &&
  824. ((bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_IN_USE) == 0)) {
  825. if (bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_ALLOC) {
  826. r = stbuf_change_size(&bufs[BUF_TYPE_VIDEO], arg);
  827. }
  828. } else {
  829. r = -EINVAL;
  830. }
  831. break;
  832. case AMSTREAM_IOC_AB_START:
  833. if ((this->type & PORT_TYPE_AUDIO) &&
  834. ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0)) {
  835. bufs[BUF_TYPE_AUDIO].buf_start = arg;
  836. } else {
  837. r = -EINVAL;
  838. }
  839. break;
  840. case AMSTREAM_IOC_AB_SIZE:
  841. if ((this->type & PORT_TYPE_AUDIO) &&
  842. ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0)) {
  843. if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC) {
  844. r = stbuf_change_size(&bufs[BUF_TYPE_AUDIO], arg);
  845. }
  846. } else {
  847. r = -EINVAL;
  848. }
  849. break;
  850. case AMSTREAM_IOC_VFORMAT:
  851. if ((this->type & PORT_TYPE_VIDEO) &&
  852. (arg < VFORMAT_MAX)) {
  853. this->vformat = (vformat_t)arg;
  854. this->flag |= PORT_FLAG_VFORMAT;
  855. } else {
  856. r = -EINVAL;
  857. }
  858. break;
  859. case AMSTREAM_IOC_AFORMAT:
  860. if ((this->type & PORT_TYPE_AUDIO) &&
  861. (arg < AFORMAT_MAX)) {
  862. memset(&audio_dec_info,0,sizeof(struct audio_info));//for new format,reset the audio info.
  863. this->aformat = (aformat_t)arg;
  864. this->flag |= PORT_FLAG_AFORMAT;
  865. } else {
  866. r = -EINVAL;
  867. }
  868. break;
  869. case AMSTREAM_IOC_VID:
  870. if (this->type & PORT_TYPE_VIDEO) {
  871. this->vid = (u32)arg;
  872. this->flag |= PORT_FLAG_VID;
  873. } else {
  874. r = -EINVAL;
  875. }
  876. break;
  877. case AMSTREAM_IOC_AID:
  878. if (this->type & PORT_TYPE_AUDIO) {
  879. this->aid = (u32)arg;
  880. this->flag |= PORT_FLAG_AID;
  881. if (this->flag & PORT_FLAG_INITED) {
  882. tsync_audio_break(1);
  883. amstream_change_avid(this);
  884. }
  885. } else {
  886. r = -EINVAL;
  887. }
  888. break;
  889. case AMSTREAM_IOC_SID:
  890. if (this->type & PORT_TYPE_SUB) {
  891. this->sid = (u32)arg;
  892. this->flag |= PORT_FLAG_SID;
  893. if (this->flag & PORT_FLAG_INITED) {
  894. amstream_change_sid(this);
  895. }
  896. } else {
  897. r = -EINVAL;
  898. }
  899. break;
  900. case AMSTREAM_IOC_VB_STATUS:
  901. if (this->type & PORT_TYPE_VIDEO) {
  902. struct am_io_param *p = (void*)arg;
  903. stream_buf_t *buf = &bufs[BUF_TYPE_VIDEO];
  904. if (p == NULL) {
  905. r = -EINVAL;
  906. }
  907. p->status.size = buf->buf_size;
  908. p->status.data_len = stbuf_level(buf);
  909. p->status.free_len = stbuf_space(buf);
  910. p->status.read_pointer = stbuf_rp(buf);
  911. } else {
  912. r = -EINVAL;
  913. }
  914. break;
  915. case AMSTREAM_IOC_AB_STATUS:
  916. if (this->type & PORT_TYPE_AUDIO) {
  917. struct am_io_param *p = (void*)arg;
  918. stream_buf_t *buf = &bufs[BUF_TYPE_AUDIO];
  919. if (p == NULL) {
  920. r = -EINVAL;
  921. }
  922. p->status.size = buf->buf_size;
  923. p->status.data_len = stbuf_level(buf);
  924. p->status.free_len = stbuf_space(buf);
  925. p->status.read_pointer = stbuf_rp(buf);
  926. } else {
  927. r = -EINVAL;
  928. }
  929. break;
  930. case AMSTREAM_IOC_SYSINFO:
  931. if (this->type & PORT_TYPE_VIDEO) {
  932. if (copy_from_user((void *)&amstream_dec_info, (void *)arg, sizeof(amstream_dec_info))) {
  933. r = -EFAULT;
  934. }
  935. } else {
  936. r = -EINVAL;
  937. }
  938. break;
  939. case AMSTREAM_IOC_ACHANNEL:
  940. if (this->type & PORT_TYPE_AUDIO) {
  941. this->achanl = (u32)arg;
  942. set_ch_num_info( (u32)arg);
  943. } else {
  944. r = -EINVAL;
  945. }
  946. break;
  947. case AMSTREAM_IOC_SAMPLERATE:
  948. if (this->type & PORT_TYPE_AUDIO) {
  949. this->asamprate = (u32)arg;
  950. set_sample_rate_info((u32)arg);
  951. } else {
  952. r = -EINVAL;
  953. }
  954. break;
  955. case AMSTREAM_IOC_DATAWIDTH:
  956. if (this->type & PORT_TYPE_AUDIO) {
  957. this->adatawidth = (u32)arg;
  958. } else {
  959. r = -EINVAL;
  960. }
  961. break;
  962. case AMSTREAM_IOC_TSTAMP:
  963. if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) ==
  964. ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO))) {
  965. r = -EINVAL;
  966. } else if (this->type & PORT_TYPE_VIDEO) {
  967. r = es_vpts_checkin(&bufs[BUF_TYPE_VIDEO], arg);
  968. } else if (this->type & PORT_TYPE_AUDIO) {
  969. r = es_apts_checkin(&bufs[BUF_TYPE_AUDIO], arg);
  970. }
  971. break;
  972. case AMSTREAM_IOC_VDECSTAT:
  973. if ((this->type & PORT_TYPE_VIDEO) == 0) {
  974. return -EINVAL;
  975. }
  976. if (amstream_vdec_status == NULL) {
  977. return -ENODEV;
  978. } else {
  979. struct vdec_status vstatus;
  980. struct am_io_param *p = (void*)arg;
  981. if (p == NULL) {
  982. return -EINVAL;
  983. }
  984. amstream_vdec_status(&vstatus);
  985. p->vstatus.width = vstatus.width;
  986. p->vstatus.height = vstatus.height;
  987. p->vstatus.fps = vstatus.fps;
  988. p->vstatus.error_count = vstatus.error_count;
  989. p->vstatus.status = vstatus.status;
  990. return 0;
  991. }
  992. case AMSTREAM_IOC_ADECSTAT:
  993. if ((this->type & PORT_TYPE_AUDIO) == 0) {
  994. return -EINVAL;
  995. }
  996. if (amstream_adec_status == NULL) {
  997. return -ENODEV;
  998. } else {
  999. struct adec_status astatus;
  1000. struct am_io_param *p = (void*)arg;
  1001. if (p == NULL) {
  1002. return -EINVAL;
  1003. }
  1004. amstream_adec_status(&astatus);
  1005. p->astatus.channels = astatus.channels;
  1006. p->astatus.sample_rate = astatus.sample_rate;
  1007. p->astatus.resolution = astatus.resolution;
  1008. p->astatus.error_count = astatus.error_count;
  1009. p->astatus.status = astatus.status;
  1010. return 0;
  1011. }
  1012. case AMSTREAM_IOC_PORT_INIT:
  1013. r = amstream_port_init(this);
  1014. break;
  1015. case AMSTREAM_IOC_TRICKMODE:
  1016. if ((this->type & PORT_TYPE_VIDEO) == 0) {
  1017. return -EINVAL;
  1018. }
  1019. if (amstream_vdec_trickmode == NULL) {
  1020. return -ENODEV;
  1021. } else {
  1022. amstream_vdec_trickmode(arg);
  1023. }
  1024. break;
  1025. case AMSTREAM_IOC_AUDIO_INFO:
  1026. if ((this->type & PORT_TYPE_VIDEO) || (this->type & PORT_TYPE_AUDIO)) {
  1027. if (copy_from_user(&audio_dec_info, (void __user *)arg, sizeof(audio_dec_info))) {
  1028. r = -EFAULT;
  1029. }
  1030. } else {
  1031. r = -EINVAL;
  1032. }
  1033. break;
  1034. case AMSTREAM_IOC_AUDIO_RESET:
  1035. if (this->type & PORT_TYPE_AUDIO) {
  1036. stream_buf_t *pabuf = &bufs[BUF_TYPE_AUDIO];
  1037. r = audio_port_reset(this, pabuf);
  1038. } else {
  1039. r = -EINVAL;
  1040. }
  1041. break;
  1042. case AMSTREAM_IOC_SUB_RESET:
  1043. if (this->type & PORT_TYPE_SUB) {
  1044. stream_buf_t *psbuf = &bufs[BUF_TYPE_SUBTITLE];
  1045. r = sub_port_reset(this, psbuf);
  1046. } else {
  1047. r = -EINVAL;
  1048. }
  1049. break;
  1050. case AMSTREAM_IOC_SUB_LENGTH:
  1051. if (this->type & PORT_TYPE_SUB || this->type & PORT_TYPE_SUB_RD) {
  1052. u32 sub_wp, sub_rp;
  1053. stream_buf_t *psbuf = &bufs[BUF_TYPE_SUBTITLE];
  1054. sub_wp = stbuf_sub_wp_get();
  1055. sub_rp = stbuf_sub_rp_get();
  1056. if (sub_wp == sub_rp) {
  1057. *((u32 *)arg) = 0;
  1058. } else if (sub_wp > sub_rp) {
  1059. *((u32 *)arg) = sub_wp - sub_rp;
  1060. } else {
  1061. *((u32 *)arg) = psbuf->buf_size - (sub_rp - sub_wp);
  1062. }
  1063. } else {
  1064. r = -EINVAL;
  1065. }
  1066. break;
  1067. case AMSTREAM_IOC_SET_DEC_RESET:
  1068. tsync_set_dec_reset();
  1069. break;
  1070. case AMSTREAM_IOC_TS_SKIPBYTE:
  1071. if ((int)arg >= 0) {
  1072. tsdemux_set_skipbyte(arg);
  1073. } else {
  1074. r = -EINVAL;
  1075. }
  1076. break;
  1077. case AMSTREAM_IOC_SUB_TYPE:
  1078. sub_type = (int)arg;
  1079. break;
  1080. case AMSTREAM_IOC_APTS:
  1081. *((u32 *)arg) = timestamp_apts_get();
  1082. break;
  1083. case AMSTREAM_IOC_VPTS:
  1084. *((u32 *)arg) = timestamp_vpts_get();
  1085. break;
  1086. case AMSTREAM_IOC_PCRSCR:
  1087. *((u32 *)arg) = timestamp_pcrscr_get();
  1088. break;
  1089. case AMSTREAM_IOC_SET_PCRSCR:
  1090. timestamp_pcrscr_set(arg);
  1091. break;
  1092. case AMSTREAM_IOC_SUB_NUM:
  1093. *((u32 *)arg) = psparser_get_sub_found_num();
  1094. break;
  1095. case AMSTREAM_IOC_SUB_INFO:
  1096. if (arg > 0) {
  1097. struct subtitle_info msub_info[MAX_SUB_NUM];
  1098. struct subtitle_info *psub_info[MAX_SUB_NUM];
  1099. int i;
  1100. for (i = 0; i < MAX_SUB_NUM; i ++) {
  1101. psub_info[i] = &msub_info[i];
  1102. }
  1103. r = psparser_get_sub_info(psub_info);
  1104. if(r == 0) {
  1105. if (copy_to_user((void __user *)arg, msub_info, sizeof(struct subtitle_info) * MAX_SUB_NUM)) {
  1106. r = -EFAULT;
  1107. }
  1108. }
  1109. }
  1110. break;
  1111. default:
  1112. r = -ENOIOCTLCMD;
  1113. break;
  1114. }
  1115. return r;
  1116. }
  1117. static ssize_t ports_show(struct class *class, struct class_attribute *attr, char *buf)
  1118. {
  1119. int i;
  1120. char *pbuf = buf;
  1121. stream_port_t *p = NULL;
  1122. for (i = 0; i < sizeof(ports) / sizeof(stream_port_t); i++) {
  1123. p = &ports[i];
  1124. /*name*/
  1125. pbuf += sprintf(pbuf, "%s\t:\n", p->name);
  1126. /*type*/
  1127. pbuf += sprintf(pbuf, "\ttype:%d( ", p->type);
  1128. if (p->type & PORT_TYPE_VIDEO) {
  1129. pbuf += sprintf(pbuf, "%s ", "Video");
  1130. }
  1131. if (p->type & PORT_TYPE_AUDIO) {
  1132. pbuf += sprintf(pbuf, "%s ", "Audio");
  1133. }
  1134. if (p->type & PORT_TYPE_MPTS) {
  1135. pbuf += sprintf(pbuf, "%s ", "TS");
  1136. }
  1137. if (p->type & PORT_TYPE_MPPS) {
  1138. pbuf += sprintf(pbuf, "%s ", "PS");
  1139. }
  1140. if (p->type & PORT_TYPE_ES) {
  1141. pbuf += sprintf(pbuf, "%s ", "ES");
  1142. }
  1143. if (p->type & PORT_TYPE_RM) {
  1144. pbuf += sprintf(pbuf, "%s ", "RM");
  1145. }
  1146. if (p->type & PORT_TYPE_SUB) {
  1147. pbuf += sprintf(pbuf, "%s ", "Subtitle");
  1148. }
  1149. if (p->type & PORT_TYPE_SUB_RD) {
  1150. pbuf += sprintf(pbuf, "%s ", "Subtitle_Read");
  1151. }
  1152. pbuf += sprintf(pbuf, ")\n");
  1153. /*flag*/
  1154. pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag);
  1155. if (p->flag & PORT_FLAG_IN_USE) {
  1156. pbuf += sprintf(pbuf, "%s ", "Used");
  1157. } else {
  1158. pbuf += sprintf(pbuf, "%s ", "Unused");
  1159. }
  1160. if (p->flag & PORT_FLAG_INITED) {
  1161. pbuf += sprintf(pbuf, "%s ", "inited");
  1162. } else {
  1163. pbuf += sprintf(pbuf, "%s ", "uninited");
  1164. }
  1165. pbuf += sprintf(pbuf, ")\n");
  1166. /*others*/
  1167. pbuf += sprintf(pbuf, "\tVformat:%d\n", (p->flag & PORT_FLAG_VFORMAT) ? p->vformat : -1);
  1168. pbuf += sprintf(pbuf, "\tAformat:%d\n", (p->flag & PORT_FLAG_AFORMAT) ? p->aformat : -1);
  1169. pbuf += sprintf(pbuf, "\tVid:%d\n", (p->flag & PORT_FLAG_VID) ? p->vid : -1);
  1170. pbuf += sprintf(pbuf, "\tAid:%d\n", (p->flag & PORT_FLAG_AID) ? p->aid : -1);
  1171. pbuf += sprintf(pbuf, "\tSid:%d\n", (p->flag & PORT_FLAG_SID) ? p->sid : -1);
  1172. pbuf += sprintf(pbuf, "\tachannel:%d\n", p->achanl);
  1173. pbuf += sprintf(pbuf, "\tasamprate:%d\n", p->asamprate);
  1174. pbuf += sprintf(pbuf, "\tadatawidth:%d\n\n", p->adatawidth);
  1175. }
  1176. return pbuf - buf;
  1177. }
  1178. static ssize_t bufs_show(struct class *class, struct class_attribute *attr, char *buf)
  1179. {
  1180. int i;
  1181. char *pbuf = buf;
  1182. stream_buf_t *p = NULL;
  1183. char buf_type[][12] = {"Video", "Audio", "Subtitle", "NA"};
  1184. for (i = 0; i < sizeof(bufs) / sizeof(stream_buf_t); i++) {
  1185. p = &bufs[i];
  1186. /*type*/
  1187. pbuf += sprintf(pbuf, "%s buffer:", buf_type[p->type]);
  1188. /*flag*/
  1189. pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag);
  1190. if (p->flag & BUF_FLAG_ALLOC) {
  1191. pbuf += sprintf(pbuf, "%s ", "Alloc");
  1192. } else {
  1193. pbuf += sprintf(pbuf, "%s ", "Unalloc");
  1194. }
  1195. if (p->flag & BUF_FLAG_IN_USE) {
  1196. pbuf += sprintf(pbuf, "%s ", "Used");
  1197. } else {
  1198. pbuf += sprintf(pbuf, "%s ", "Noused");
  1199. }
  1200. if (p->flag & BUF_FLAG_PARSER) {
  1201. pbuf += sprintf(pbuf, "%s ", "Parser");
  1202. } else {
  1203. pbuf += sprintf(pbuf, "%s ", "noParser");
  1204. }
  1205. if (p->flag & BUF_FLAG_FIRST_TSTAMP) {
  1206. pbuf += sprintf(pbuf, "%s ", "firststamp");
  1207. } else {
  1208. pbuf += sprintf(pbuf, "%s ", "nofirststamp");
  1209. }
  1210. pbuf += sprintf(pbuf, ")\n");
  1211. /*buf stats*/
  1212. pbuf += sprintf(pbuf, "\tbuf addr:%#x\n", p->buf_start);
  1213. if (p->type != BUF_TYPE_SUBTITLE) {
  1214. pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size);
  1215. pbuf += sprintf(pbuf, "\tbuf regbase:%#lx\n", p->reg_base);
  1216. pbuf += sprintf(pbuf, "\tbuf level:%#x\n", stbuf_level(p));
  1217. pbuf += sprintf(pbuf, "\tbuf space:%#x\n", stbuf_space(p));
  1218. pbuf += sprintf(pbuf, "\tbuf read pointer:%#x\n", stbuf_rp(p));
  1219. } else {
  1220. u32 sub_wp, sub_rp, data_size;
  1221. sub_wp = stbuf_sub_wp_get();
  1222. sub_rp = stbuf_sub_rp_get();
  1223. if (sub_wp >= sub_rp) {
  1224. data_size = sub_wp - sub_rp;
  1225. } else {
  1226. data_size = p->buf_size - sub_rp + sub_wp;
  1227. }
  1228. pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size);
  1229. pbuf += sprintf(pbuf, "\tbuf start:%#x\n", stbuf_sub_start_get());
  1230. pbuf += sprintf(pbuf, "\tbuf write pointer:%#x\n", sub_wp);
  1231. pbuf += sprintf(pbuf, "\tbuf read pointer:%#x\n", sub_rp);
  1232. pbuf += sprintf(pbuf, "\tbuf level:%#x\n", data_size);
  1233. }
  1234. pbuf += sprintf(pbuf, "\tbuf first_stamp:%#x\n", p->first_tstamp);
  1235. pbuf += sprintf(pbuf, "\tbuf wcnt:%#x\n\n", p->wcnt);
  1236. }
  1237. return pbuf - buf;
  1238. }
  1239. static ssize_t vcodec_profile_show(struct class *class,
  1240. struct class_attribute *attr,
  1241. char *buf)
  1242. {
  1243. return vcodec_profile_read(buf);
  1244. }
  1245. static struct class_attribute amstream_class_attrs[] = {
  1246. __ATTR_RO(ports),
  1247. __ATTR_RO(bufs),
  1248. __ATTR_RO(vcodec_profile),
  1249. __ATTR_NULL
  1250. };
  1251. static struct class amstream_class = {
  1252. .name = "amstream",
  1253. .class_attrs = amstream_class_attrs,
  1254. };
  1255. static int amstream_probe(struct platform_device *pdev)
  1256. {
  1257. int i;
  1258. int r;
  1259. stream_port_t *st;
  1260. struct resource *res;
  1261. printk("Amlogic A/V streaming port init\n");
  1262. r = class_register(&amstream_class);
  1263. if (r) {
  1264. printk("amstream class create fail.\n");
  1265. return r;
  1266. }
  1267. r = astream_dev_register();
  1268. if (r) {
  1269. return r;
  1270. }
  1271. r = vdec_dev_register();
  1272. if (r) {
  1273. return r;
  1274. }
  1275. r = register_chrdev(AMSTREAM_MAJOR, "amstream", &amstream_fops);
  1276. if (r < 0) {
  1277. printk("Can't allocate major for amstreaming device\n");
  1278. goto error2;
  1279. }
  1280. vdec_set_resource(platform_get_resource(pdev, IORESOURCE_MEM, 0), (void *)&amstream_dec_info);
  1281. amstream_dev_class = class_create(THIS_MODULE, DEVICE_NAME);
  1282. for (st = &ports[0], i = 0; i < MAX_AMSTREAM_PORT_NUM; i++, st++) {
  1283. st->class_dev = device_create(amstream_dev_class, NULL,
  1284. MKDEV(AMSTREAM_MAJOR, i), NULL,
  1285. ports[i].name);
  1286. }
  1287. amstream_vdec_status = NULL;
  1288. amstream_adec_status = NULL;
  1289. if (tsdemux_class_register() != 0) {
  1290. r = (-EIO);
  1291. goto error3;
  1292. }
  1293. res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  1294. if (!res) {
  1295. printk("Can not obtain I/O memory, and will allocate stream buffer!\n");
  1296. if (stbuf_change_size(&bufs[BUF_TYPE_VIDEO], DEFAULT_VIDEO_BUFFER_SIZE) != 0) {
  1297. r = (-ENOMEM);
  1298. goto error4;
  1299. }
  1300. if (stbuf_change_size(&bufs[BUF_TYPE_AUDIO], DEFAULT_AUDIO_BUFFER_SIZE) != 0) {
  1301. r = (-ENOMEM);
  1302. goto error5;
  1303. }
  1304. if (stbuf_change_size(&bufs[BUF_TYPE_SUBTITLE], DEFAULT_SUBTITLE_BUFFER_SIZE) != 0) {
  1305. r = (-ENOMEM);
  1306. goto error6;
  1307. }
  1308. } else {
  1309. bufs[BUF_TYPE_VIDEO].buf_start = res->start;
  1310. bufs[BUF_TYPE_VIDEO].buf_size = resource_size(res) - DEFAULT_AUDIO_BUFFER_SIZE - DEFAULT_SUBTITLE_BUFFER_SIZE;
  1311. bufs[BUF_TYPE_VIDEO].flag |= BUF_FLAG_IOMEM;
  1312. bufs[BUF_TYPE_AUDIO].buf_start = res->start + bufs[BUF_TYPE_VIDEO].buf_size;
  1313. bufs[BUF_TYPE_AUDIO].buf_size = DEFAULT_AUDIO_BUFFER_SIZE;
  1314. bufs[BUF_TYPE_AUDIO].flag |= BUF_FLAG_IOMEM;
  1315. bufs[BUF_TYPE_SUBTITLE].buf_start = res->start + resource_size(res) - DEFAULT_SUBTITLE_BUFFER_SIZE;
  1316. bufs[BUF_TYPE_SUBTITLE].buf_size = DEFAULT_SUBTITLE_BUFFER_SIZE;
  1317. bufs[BUF_TYPE_SUBTITLE].flag = BUF_FLAG_IOMEM;
  1318. }
  1319. if (stbuf_fetch_init() != 0) {
  1320. r = (-ENOMEM);
  1321. goto error7;
  1322. }
  1323. init_waitqueue_head(&amstream_sub_wait);
  1324. return 0;
  1325. error7:
  1326. if (bufs[BUF_TYPE_SUBTITLE].flag & BUF_FLAG_ALLOC) {
  1327. stbuf_change_size(&bufs[BUF_TYPE_SUBTITLE], 0);
  1328. }
  1329. error6:
  1330. if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC) {
  1331. stbuf_change_size(&bufs[BUF_TYPE_AUDIO], 0);
  1332. }
  1333. error5:
  1334. if (bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_ALLOC) {
  1335. stbuf_change_size(&bufs[BUF_TYPE_VIDEO], 0);
  1336. }
  1337. error4:
  1338. tsdemux_class_unregister();
  1339. error3:
  1340. for (st = &ports[0], i = 0; i < MAX_AMSTREAM_PORT_NUM; i++, st++) {
  1341. device_destroy(amstream_dev_class, MKDEV(AMSTREAM_MAJOR, i));
  1342. }
  1343. class_destroy(amstream_dev_class);
  1344. error2:
  1345. unregister_chrdev(AMSTREAM_MAJOR, "amstream");
  1346. //error1:
  1347. astream_dev_unregister();
  1348. return (r);
  1349. }
  1350. static int amstream_remove(struct platform_device *pdev)
  1351. {
  1352. int i;
  1353. stream_port_t *st;
  1354. if (bufs[BUF_TYPE_VIDEO].flag & BUF_FLAG_ALLOC) {
  1355. stbuf_change_size(&bufs[BUF_TYPE_VIDEO], 0);
  1356. }
  1357. if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC) {
  1358. stbuf_change_size(&bufs[BUF_TYPE_AUDIO], 0);
  1359. }
  1360. stbuf_fetch_release();
  1361. tsdemux_class_unregister();
  1362. for (st = &ports[0], i = 0; i < MAX_AMSTREAM_PORT_NUM; i++, st++) {
  1363. device_destroy(amstream_dev_class, MKDEV(AMSTREAM_MAJOR, i));
  1364. }
  1365. class_destroy(amstream_dev_class);
  1366. unregister_chrdev(AMSTREAM_MAJOR, DEVICE_NAME);
  1367. vdec_dev_unregister();
  1368. astream_dev_unregister();
  1369. amstream_vdec_status = NULL;
  1370. amstream_adec_status = NULL;
  1371. amstream_vdec_trickmode = NULL;
  1372. printk("Amlogic A/V streaming port release\n");
  1373. return 0;
  1374. }
  1375. void set_vdec_func(int (*vdec_func)(struct vdec_status *))
  1376. {
  1377. amstream_vdec_status = vdec_func;
  1378. return;
  1379. }
  1380. void set_adec_func(int (*adec_func)(struct adec_status *))
  1381. {
  1382. amstream_adec_status = adec_func;
  1383. return;
  1384. }
  1385. void set_trickmode_func(int (*trickmode_func)(unsigned long trickmode))
  1386. {
  1387. amstream_vdec_trickmode = trickmode_func;
  1388. return;
  1389. }
  1390. void wakeup_sub_poll(void)
  1391. {
  1392. atomic_set(&subdata_ready, 1);
  1393. wake_up_interruptible(&amstream_sub_wait);
  1394. return;
  1395. }
  1396. int get_sub_type(void)
  1397. {
  1398. return sub_type;
  1399. }
  1400. /*get pes buffers */
  1401. stream_buf_t* get_stream_buffer(int id)
  1402. {
  1403. if(id>=BUF_MAX_NUM)
  1404. {
  1405. return 0;
  1406. }
  1407. return &bufs[id];
  1408. }
  1409. EXPORT_SYMBOL(set_vdec_func);
  1410. EXPORT_SYMBOL(set_adec_func);
  1411. EXPORT_SYMBOL(set_trickmode_func);
  1412. EXPORT_SYMBOL(wakeup_sub_poll);
  1413. EXPORT_SYMBOL(get_sub_type);
  1414. static struct platform_driver
  1415. amstream_driver = {
  1416. .probe = amstream_probe,
  1417. .remove = amstream_remove,
  1418. .driver = {
  1419. .name = "mesonstream",
  1420. }
  1421. };
  1422. static int __init amstream_module_init(void)
  1423. {
  1424. if (platform_driver_register(&amstream_driver)) {
  1425. printk("failed to register amstream module\n");
  1426. return -ENODEV;
  1427. }
  1428. return 0;
  1429. }
  1430. static void __exit amstream_module_exit(void)
  1431. {
  1432. platform_driver_unregister(&amstream_driver);
  1433. return ;
  1434. }
  1435. module_init(amstream_module_init);
  1436. module_exit(amstream_module_exit);
  1437. MODULE_DESCRIPTION("AMLOGIC streaming port driver");
  1438. MODULE_LICENSE("GPL");
  1439. MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");