e7cc80cb3c9bb8ad255360ef95c002b1c22f72b0
[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / pasdk / test_dsp / sio_dev2 / dev2.c
1 /* --COPYRIGHT--,BSD
2 * Copyright (c) $(CPYYEAR), Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * --/COPYRIGHT--*/
32 /*
33 * ======== dev2.c ========
34 */
36 #include <xdc/std.h>
37 #include <xdc/runtime/Error.h>
38 #include <xdc/runtime/Memory.h>
39 #include <xdc/runtime/Log.h>
40 #include <xdc/runtime/System.h>
41 #include <ti/sysbios/hal/Hwi.h>
42 #include <ti/sysbios/knl/Task.h>
44 #include "dev2.h"
46 #include <string.h>
48 Queue_Elem devList = {NULL, NULL};
50 DEV2_Attrs DEV2_ATTRS = {
51 NULL, /* dev ID */
52 NULL, /* params */
53 DEV2_SIOTYPE, /* TODO: Default was set to IOM(fxns) */
54 NULL /* devp */
55 };
57 static Bool devInit = FALSE;
59 /*
60 * ======== DEV2_createDevice ========
61 * Create a device(DEV2_Device) entry and add it to the list of devices.
62 * This API is not reentrant
63 */
64 Int DEV2_createDevice (String name, Void *fxns, Fxn initFxn,
65 DEV2_Attrs *attrs)
66 {
67 // DEV2_TableElem *objDevHead = (DEV2_TableElem*) &DEV2_table;
68 DEV2_TableElem *objDevHead = (DEV2_TableElem*) &devList;
69 DEV2_TableElem *objDev, *objEntry;
70 DEV2_Device *dptr, *entry;
71 // IOM_Fxns *iomfxns;
72 // Int status;
73 UInt key;
74 UInt taskKey;
75 Error_Block eb;
77 DEV2_init();
79 /* Crate a device entry */
80 Error_init(&eb);
81 objEntry = Memory_calloc(0, sizeof(DEV2_TableElem), 0, &eb);
83 if (objEntry == NULL) {
84 return(DEV2_ENOMEM);
85 }
87 taskKey = Task_disable();
89 /*
90 * Return error if device already exists in the Device table, or has
91 * already been created.
92 */
93 DEV2_find(name, &entry);
95 if (entry != NULL) {
96 Task_restore(taskKey);
97 Memory_free(0, objEntry, sizeof(DEV2_TableElem));
98 Log_error1("DEV2_createDevice: Device %s alread in table", (IArg)name);
99 return (DEV2_EINVAL);
100 }
102 /*
103 * Initialize new device entry(DEV2_Device) in the OBJ table with
104 * the parameters passed to API
105 */
106 entry = &objEntry->device;
107 entry->name = name;
108 entry->fxns = fxns;
110 if (attrs == NULL) {
111 attrs = &DEV2_ATTRS;
112 }
113 entry->devid = attrs->devid;
114 entry->params = attrs->params;
115 entry->type = attrs->type;
116 entry->devp = attrs->devp;
118 /*
119 * Call the Device init function if its not NULL, with interrupts
120 * disabled.
121 */
122 if (initFxn != NULL) {
123 key = Hwi_disable();
124 (*initFxn)();
125 Hwi_restore(key);
126 }
127 #if 0 // TODO
129 /*
130 * If device created is of type IOM then call mini driver function
131 * mdBindDev with interrupts disabled.
132 */
133 if (entry->type == DEV2_IOMTYPE) {
134 iomfxns = (IOM_Fxns *)entry->fxns;
136 key = HWI_disable();
137 status = iomfxns->mdBindDev(&entry->devp, entry->devid,
138 entry->params);
139 HWI_restore(key);
141 if (status != IOM_COMPLETED) {
143 TSK_enable();
145 /* Delete the just created device entry in device table */
146 Memory_free(NULL, objEntry, sizeof(DEV2_TableElem));
148 Log_error1("DEV2_createDevice: mdBindDev() failed (%d)",
149 (IArg)status);
151 return(status);
152 }
154 }
155 #endif // TODO
156 /*
157 * Device is ready for addition into the device. Check new device
158 * name length against existing device name lengths. If length of
159 * new device is greater than one in the table, mark the location
160 * and insert device ahead of device whose name length is shorter
161 * else add it to the end.
162 *
163 * This will keep all the devices sorted in descending order, which is
164 * required to pass additional parameters along with device name in
165 * DEV2_open()
166 */
168 objDev = (DEV2_TableElem *)Queue_next((Ptr)objDevHead);
169 while (objDev != objDevHead) {
170 dptr = &objDev->device;
171 if (strlen(name) > strlen(dptr->name)) {
172 break;
173 }
174 objDev = (DEV2_TableElem *)Queue_next((Ptr)objDev);
175 }
177 /* Insert objEntry ahead of objDev */
178 Queue_insert((Queue_Elem *)objDev, (Queue_Elem *)objEntry);
180 Task_restore(taskKey);
182 return (DEV2_OK);
183 }
185 /*
186 * DEV2_deleteDevice deletes device(DEV2_Device) entry in the OBJ table
187 * if device by that name exist in the system.
188 * This API is not reentrant
189 */
190 Int DEV2_deleteDevice (String name)
191 {
192 DEV2_TableElem *objDev;
193 DEV2_Device *entry;
194 // TODO IOM_Fxns *iomfxns;
195 Int status = DEV2_OK;
196 // Uns key;
198 DEV2_init();
200 /* Check if device exists in the Device table, if not return FALSE */
201 DEV2_find(name, &entry);
202 if (entry == NULL) {
203 Log_error1("DEV2_deleteDevice: Device %s not found", (IArg)name);
204 return (DEV2_ENODEV);
205 }
207 #if 0 // TODO
208 /*
209 * If device to be deleted is of type IOM call mdUnBindDev with
210 * interrupts disabled
211 */
212 if (entry->type == DEV2_IOMTYPE) {
213 iomfxns = (IOM_Fxns *)entry->fxns;
215 key = Hwi_disable();
216 status = iomfxns->mdUnBindDev(entry->devp);
217 Hwi_restore(key);
219 if (status != IOM_COMPLETED) {
220 Log_error1("DEV2_deleteDevice: mdUnBindDev failed (%d) ", status);
221 }
222 else {
223 status = DEV2_OK;
224 }
226 }
227 #endif // TODO
229 /* Free Device entry in the device table */
230 objDev = (DEV2_TableElem *)((char *)entry - sizeof(Queue_Elem));
231 Queue_remove((Queue_Elem *)objDev);
232 Memory_free(NULL, objDev, sizeof(DEV2_TableElem));
234 return (status);
235 }
237 /*
238 * ======== DEV2_ebadio ========
239 */
240 Int DEV2_ebadio(DEV2_Handle device)
241 {
242 Log_error1("DEV2_ebadio (0x%x)", (IArg)device);
244 return (DEV2_EBADIO);
245 }
247 /*
248 * ======== DEV2_find ========
249 */
250 Void DEV2_find(String name, DEV2_Device **driver)
251 {
252 DEV2_TableElem *objDevHead = (DEV2_TableElem*) &devList;
253 // DEV2_TableElem *objDevHead = (DEV2_TableElem*) &DEV2_table;
254 DEV2_TableElem *objDev;
255 DEV2_Device *dptr;
257 DEV2_init();
259 /*
260 * Do the exact match, return device entry if successfull.
261 */
262 for (objDev = (DEV2_TableElem *)Queue_next((Ptr)objDevHead);
263 objDev != objDevHead;
264 objDev = (DEV2_TableElem *)Queue_next((Ptr)objDev)) {
265 dptr = &objDev->device;
266 if (strcmp(name,dptr->name) == 0) {
267 /* If driver exists in the devicetable, point the *driver
268 to corresponding device entry */
269 *driver = dptr;
270 return;
271 }
272 }
274 *driver = NULL;
275 return;
276 }
278 /*
279 * ======== DEV2_init ========
280 */
281 Void DEV2_init()
282 {
283 UInt taskKey;
284 UInt numEntries = 0;
285 Int i;
287 if (!devInit) {
288 taskKey = Task_disable();
290 /* Count the number of devices and initialize next, prev pointers */
291 for (i = 0; DEV2_table[i].device.name != NULL; i++) {
292 DEV2_table[i].qElem.next = (Queue_Elem *)&DEV2_table[i + 1];
293 DEV2_table[i + 1].qElem.prev = (Queue_Elem *)&DEV2_table[i];
294 }
295 numEntries = i;
297 if (numEntries > 0) {
298 devList.next = (Queue_Elem *)&DEV2_table[0];
299 devList.prev = (Queue_Elem *)&DEV2_table[numEntries - 1];
300 DEV2_table[numEntries - 1].qElem.next = &devList;
301 }
302 else {
303 devList.next = devList.prev = &devList;
304 }
305 devInit = TRUE;
306 Task_restore(taskKey);
307 }
308 }
310 /*
311 * ======== DEV2_match ========
312 */
313 String DEV2_match(String name, DEV2_Device **driver)
314 {
315 DEV2_TableElem *objDevHead = (DEV2_TableElem*)&devList;
316 // DEV2_TableElem *objDevHead = (DEV2_TableElem*) &DEV2_table;
317 DEV2_TableElem *objDev;
318 DEV2_Device *dptr;
319 Int len;
321 DEV2_init();
323 /*
324 * Trace the existence of device through OBJ_table[OBJ_DEV].
325 * If successfull *dptr points to the device entry.
326 */
327 if(name[0] == '/') name ++;
329 if (strncmp(name, "SAP", 3) == 0)
330 name[0]='D';
332 for (objDev = (DEV2_TableElem *)Queue_next((Ptr)objDevHead);
333 objDev != objDevHead;
334 objDev = (DEV2_TableElem *)Queue_next((Ptr)objDev)) {
335 dptr = &objDev->device;
336 len = strlen(dptr->name);
337 if ((len == 0) || (strncmp(name,dptr->name,len) == 0) ) {
338 /* If driver exists in the devicetable, point the *driver
339 to corresponding device entry */
340 *driver = dptr;
341 return (name + len);
342 }
343 }
345 *driver = NULL;
346 return (name);
348 }
350 /*
351 * ======== DEV2_mkframe ========
352 */
353 DEV2_Frame *DEV2_mkframe(xdc_runtime_IHeap_Handle seg, Uns size, Uns align)
354 {
355 DEV2_Frame *frame;
356 Error_Block eb;
358 Error_init(&eb);
360 if ((frame = Memory_alloc(0, sizeof(DEV2_Frame), 0, &eb)) == NULL) {
361 return (NULL);
362 }
364 /* don't allocate frame buffer if size is zero */
365 if (size > 0) {
366 if ((frame->addr = Memory_alloc(seg, size, align, &eb)) == NULL) {
367 Memory_free(0, frame, sizeof(DEV2_Frame));
368 return (NULL);
369 }
370 }
372 frame->size = size;
374 return (frame);
375 }
377 /*
378 * ======== DEV2_one ========
379 */
380 Int DEV2_one(void)
381 {
382 return (1);
383 }
385 /*
386 * ======== DEV2_rmframe ========
387 */
388 Void DEV2_rmframe(DEV2_Frame *frame, xdc_runtime_IHeap_Handle seg, Uns size)
389 {
390 if (size > 0) {
391 /* free buffer */
392 Memory_free(seg, frame->addr, size);
393 }
395 /* free object */
396 Memory_free(0, frame, sizeof(DEV2_Frame));
397 }
399 /*
400 * ======== DEV2_zero ========
401 */
402 Int DEV2_zero(void)
403 {
404 return (0);
405 }