summaryrefslogtreecommitdiff
path: root/drivers/stream_input/amports/adec.c (plain)
blob: 220c888c9a48726fc4cd5362dd4ad76d39cc6914
1/*
2 * drivers/amlogic/media/stream_input/amports/adec.c
3 *
4 * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16*/
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include <linux/errno.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/uio_driver.h>
24
25#include <linux/amlogic/media/utils/aformat.h>
26#include <linux/amlogic/media/frame_sync/ptsserv.h>
27
28#include <linux/amlogic/media/registers/register.h>
29
30#include "../parser/streambuf.h"
31#include <linux/module.h>
32#include "amports_priv.h"
33
34#define INFO_VALID ((astream_dev) && (astream_dev->format))
35
36struct astream_device_s {
37 char *name;
38 char *format;
39 s32 channum;
40 s32 samplerate;
41 s32 datawidth;
42
43 struct device dev;
44};
45
46static char *astream_format[] = {
47 "amadec_mpeg",
48 "amadec_pcm_s16le",
49 "amadec_aac",
50 "amadec_ac3",
51 "amadec_alaw",
52 "amadec_mulaw",
53 "amadec_dts",
54 "amadec_pcm_s16be",
55 "amadec_flac",
56 "amadec_cook",
57 "amadec_pcm_u8",
58 "amadec_adpcm",
59 "amadec_amr",
60 "amadec_raac",
61 "amadec_wma",
62 "amadec_wmapro",
63 "amadec_pcm_bluray",
64 "amadec_alac",
65 "amadec_vorbis",
66 "amadec_aac_latm",
67 "amadec_ape",
68 "amadec_eac3",
69 "amadec_pcm_widi",
70 "amadec_wmavoi"
71};
72
73static const char *na_string = "NA";
74static struct astream_device_s *astream_dev;
75
76static ssize_t format_show(struct class *class, struct class_attribute *attr,
77 char *buf)
78{
79 if (INFO_VALID && astream_dev->format)
80 return sprintf(buf, "%s\n", astream_dev->format);
81 else
82 return sprintf(buf, "%s\n", na_string);
83}
84
85static ssize_t channum_show(struct class *class, struct class_attribute *attr,
86 char *buf)
87{
88 if (INFO_VALID)
89 return sprintf(buf, "%u\n", astream_dev->channum);
90 else
91 return sprintf(buf, "%s\n", na_string);
92}
93
94static ssize_t samplerate_show(struct class *class,
95 struct class_attribute *attr, char *buf)
96{
97 if (INFO_VALID)
98 return sprintf(buf, "%u\n", astream_dev->samplerate);
99 else
100 return sprintf(buf, "%s\n", na_string);
101}
102
103static ssize_t datawidth_show(struct class *class,
104 struct class_attribute *attr,
105 char *buf)
106{
107 if (INFO_VALID)
108 return sprintf(buf, "%u\n", astream_dev->datawidth);
109 else
110 return sprintf(buf, "%s\n", na_string);
111}
112
113static ssize_t pts_show(struct class *class, struct class_attribute *attr,
114 char *buf)
115{
116 u32 pts;
117 u32 pts_margin = 0;
118
119 if (astream_dev->samplerate <= 12000)
120 pts_margin = 512;
121
122 if (INFO_VALID && (pts_lookup(PTS_TYPE_AUDIO, &pts, pts_margin) >= 0))
123 return sprintf(buf, "0x%x\n", pts);
124 else
125 return sprintf(buf, "%s\n", na_string);
126}
127
128static struct class_attribute astream_class_attrs[] = {
129 __ATTR_RO(format),
130 __ATTR_RO(samplerate),
131 __ATTR_RO(channum),
132 __ATTR_RO(datawidth),
133 __ATTR_RO(pts),
134 __ATTR_NULL
135};
136
137static struct class astream_class = {
138 .name = "astream",
139 .class_attrs = astream_class_attrs,
140 };
141
142#if 1
143#define IO_CBUS_PHY_BASE 0xc1100000
144#define CBUS_REG_OFFSET(reg) ((reg) << 2)
145#define IO_SECBUS_PHY_BASE 0xda000000
146
147static struct uio_info astream_uio_info = {
148 .name = "astream_uio",
149 .version = "0.1",
150 .irq = UIO_IRQ_NONE,
151
152 .mem = {
153 [0] = {
154 .name = "AIFIFO",
155 .memtype = UIO_MEM_PHYS,
156 .addr =
157 (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(AIU_AIFIFO_CTRL))
158 &(PAGE_MASK),
159 .size = PAGE_SIZE,
160 },
161 [1] = {
162 .memtype = UIO_MEM_PHYS,
163 .addr =
164 (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(VCOP_CTRL_REG)),
165 .size = PAGE_SIZE,
166 },
167 [2] = {
168 .name = "SECBUS",
169 .memtype = UIO_MEM_PHYS,
170 .addr = (IO_SECBUS_PHY_BASE),
171 .size = PAGE_SIZE,
172 },
173 [3] = {
174 .name = "CBUS",
175 .memtype = UIO_MEM_PHYS,
176 .addr =
177 (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(ASSIST_HW_REV))
178 &(PAGE_MASK),
179 .size = PAGE_SIZE,
180 },
181 [4] = {
182 .name = "CBUS-START",
183 .memtype = UIO_MEM_PHYS,
184 .addr = (IO_CBUS_PHY_BASE + CBUS_REG_OFFSET(0x1000)),
185 .size = PAGE_SIZE * 4,
186 },
187 },
188};
189#endif
190
191static void astream_release(struct device *dev)
192{
193 kfree(astream_dev);
194
195 astream_dev = NULL;
196}
197
198s32 adec_init(struct stream_port_s *port)
199{
200 enum aformat_e af;
201
202 if (!astream_dev)
203 return -ENODEV;
204
205 af = port->aformat;
206
207 astream_dev->channum = port->achanl;
208 astream_dev->samplerate = port->asamprate;
209 astream_dev->datawidth = port->adatawidth;
210
211 /*wmb();don't need it...*/
212 if (af <= ARRAY_SIZE(astream_format))
213 astream_dev->format = astream_format[af];
214 else
215 astream_dev->format = NULL;
216 return 0;
217}
218
219s32 adec_release(enum aformat_e vf)
220{
221 pr_info("adec_release\n");
222
223 if (!astream_dev)
224 return -ENODEV;
225
226 astream_dev->format = NULL;
227
228 return 0;
229}
230
231s32 astream_dev_register(void)
232{
233 s32 r;
234
235 r = class_register(&astream_class);
236 if (r) {
237 pr_info("astream class create fail.\n");
238 return r;
239 }
240
241 astream_dev = kzalloc(sizeof(struct astream_device_s), GFP_KERNEL);
242
243 if (!astream_dev) {
244 r = -ENOMEM;
245 goto err_3;
246 }
247
248 astream_dev->dev.class = &astream_class;
249 astream_dev->dev.release = astream_release;
250
251 dev_set_name(&astream_dev->dev, "astream-dev");
252
253 dev_set_drvdata(&astream_dev->dev, astream_dev);
254
255 r = device_register(&astream_dev->dev);
256 if (r) {
257 pr_info("astream device register fail.\n");
258 goto err_2;
259 }
260
261#if 1
262 if (uio_register_device(&astream_dev->dev, &astream_uio_info)) {
263 pr_info("astream UIO device register fail.\n");
264 r = -ENODEV;
265 goto err_1;
266 }
267#endif
268
269 return 0;
270
271err_1:
272 device_unregister(&astream_dev->dev);
273
274err_2:
275 kfree(astream_dev);
276 astream_dev = NULL;
277
278err_3:
279 class_unregister(&astream_class);
280
281 return r;
282}
283
284void astream_dev_unregister(void)
285{
286 if (astream_dev) {
287#if 1
288 uio_unregister_device(&astream_uio_info);
289#endif
290
291 device_unregister(&astream_dev->dev);
292
293 class_unregister(&astream_class);
294 }
295}
296