adec.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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/types.h>
  23. #include <linux/errno.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/slab.h>
  26. #include <linux/uio_driver.h>
  27. #include <linux/amports/aformat.h>
  28. #include <linux/amports/ptsserv.h>
  29. #include <mach/am_regs.h>
  30. #include "streambuf.h"
  31. #define INFO_VALID ((astream_dev) && (astream_dev->format))
  32. typedef struct astream_device_s {
  33. char *name;
  34. char *format;
  35. s32 channum;
  36. s32 samplerate;
  37. s32 datawidth;
  38. struct device dev;
  39. } astream_dev_t;
  40. static char *astream_format[] = {
  41. "amadec_mpeg",
  42. "amadec_pcm_s16le",
  43. "amadec_aac",
  44. "amadec_ac3",
  45. "amadec_alaw",
  46. "amadec_mulaw",
  47. "amadec_dts",
  48. "amadec_pcm_s16be",
  49. "amadec_flac",
  50. "amadec_cook",
  51. "amadec_pcm_u8",
  52. "amadec_adpcm",
  53. "amadec_amr",
  54. "amadec_raac",
  55. "amadec_wma",
  56. "amadec_wmapro",
  57. "amadec_pcm_bluray",
  58. "amadec_alac",
  59. "amadec_vorbis",
  60. "amadec_aac_latm",
  61. "amadec_ape",
  62. };
  63. static const char *na_string = "NA";
  64. static astream_dev_t *astream_dev = NULL;
  65. static ssize_t format_show(struct class *class, struct class_attribute *attr, char *buf)
  66. {
  67. if (INFO_VALID && astream_dev->format) {
  68. return sprintf(buf, "%s\n", astream_dev->format);
  69. } else {
  70. return sprintf(buf, "%s\n", na_string);
  71. }
  72. }
  73. static ssize_t channum_show(struct class *class, struct class_attribute *attr, char *buf)
  74. {
  75. if (INFO_VALID) {
  76. return sprintf(buf, "%u\n", astream_dev->channum);
  77. } else {
  78. return sprintf(buf, "%s\n", na_string);
  79. }
  80. }
  81. static ssize_t samplerate_show(struct class *class, struct class_attribute *attr, char *buf)
  82. {
  83. if (INFO_VALID) {
  84. return sprintf(buf, "%u\n", astream_dev->samplerate);
  85. } else {
  86. return sprintf(buf, "%s\n", na_string);
  87. }
  88. }
  89. static ssize_t datawidth_show(struct class *class, struct class_attribute *attr, char *buf)
  90. {
  91. if (INFO_VALID) {
  92. return sprintf(buf, "%u\n", astream_dev->datawidth);
  93. } else {
  94. return sprintf(buf, "%s\n", na_string);
  95. }
  96. }
  97. static ssize_t pts_show(struct class *class, struct class_attribute *attr, char *buf)
  98. {
  99. u32 pts;
  100. u32 pts_margin = 0;
  101. if (astream_dev->samplerate <= 12000) {
  102. pts_margin = 512;
  103. }
  104. if (INFO_VALID &&
  105. (pts_lookup(PTS_TYPE_AUDIO, &pts, pts_margin) >= 0)) {
  106. return sprintf(buf, "0x%x\n", pts);
  107. } else {
  108. return sprintf(buf, "%s\n", na_string);
  109. }
  110. }
  111. static struct class_attribute astream_class_attrs[] = {
  112. __ATTR_RO(format),
  113. __ATTR_RO(samplerate),
  114. __ATTR_RO(channum),
  115. __ATTR_RO(datawidth),
  116. __ATTR_RO(pts),
  117. __ATTR_NULL
  118. };
  119. static struct class astream_class = {
  120. .name = "astream",
  121. .class_attrs = astream_class_attrs,
  122. };
  123. #if 0
  124. static struct uio_info astream_uio_info = {
  125. .name = "astream_uio",
  126. .version = "0.1",
  127. .irq = UIO_IRQ_NONE,
  128. .mem = {
  129. [0] = {
  130. .memtype = UIO_MEM_PHYS,
  131. .addr = (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(AIU_AIFIFO_CTRL)),
  132. .size = (AIU_MEM_AIFIFO_LEVEL - AIU_AIFIFO_CTRL + 1) * 4,
  133. },
  134. [1] = {
  135. .memtype = UIO_MEM_PHYS,
  136. .addr = (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(VCOP_CTRL_REG)),
  137. .size = (VC1_BITPLANE_CTL - VCOP_CTRL_REG + 1)*4,
  138. },
  139. },
  140. };
  141. #endif
  142. static void astream_release(struct device *dev)
  143. {
  144. kfree(astream_dev);
  145. astream_dev = NULL;
  146. }
  147. s32 adec_init(stream_port_t *port)
  148. {
  149. aformat_t af;
  150. if (!astream_dev) {
  151. return -ENODEV;
  152. }
  153. af = port->aformat;
  154. astream_dev->channum = port->achanl;
  155. astream_dev->samplerate = port->asamprate;
  156. astream_dev->datawidth = port->adatawidth;
  157. wmb();
  158. astream_dev->format = astream_format[af];
  159. return 0;
  160. }
  161. s32 adec_release(aformat_t vf)
  162. {
  163. printk("adec_release\n");
  164. if (!astream_dev) {
  165. return -ENODEV;
  166. }
  167. astream_dev->format = NULL;
  168. return 0;
  169. }
  170. s32 astream_dev_register(void)
  171. {
  172. s32 r;
  173. r = class_register(&astream_class);
  174. if (r) {
  175. printk("astream class create fail.\n");
  176. return r;
  177. }
  178. astream_dev = kzalloc(sizeof(astream_dev_t), GFP_KERNEL);
  179. if (!astream_dev) {
  180. printk("astream device create fail.\n");
  181. r = -ENOMEM;
  182. goto err_3;
  183. }
  184. astream_dev->dev.class = &astream_class;
  185. astream_dev->dev.release = astream_release;
  186. dev_set_name(&astream_dev->dev, "astream-dev");
  187. dev_set_drvdata(&astream_dev->dev, astream_dev);
  188. r = device_register(&astream_dev->dev);
  189. if (r) {
  190. printk("astream device register fail.\n");
  191. goto err_2;
  192. }
  193. #if 0
  194. if (uio_register_device(&astream_dev->dev, &astream_uio_info)) {
  195. printk("astream UIO device register fail.\n");
  196. r = -ENODEV;
  197. goto err_1;
  198. }
  199. #endif
  200. return 0;
  201. //err_1:
  202. device_unregister(&astream_dev->dev);
  203. err_2:
  204. kfree(astream_dev);
  205. astream_dev = NULL;
  206. err_3:
  207. class_unregister(&astream_class);
  208. return r;
  209. }
  210. void astream_dev_unregister(void)
  211. {
  212. if (astream_dev) {
  213. #if 0
  214. uio_unregister_device(&astream_uio_info);
  215. #endif
  216. device_unregister(&astream_dev->dev);
  217. class_unregister(&astream_class);
  218. }
  219. }