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