00001
00002
00011
00012
00013
00014
00015
00022
00023 #include <l4/env/errno.h>
00024 #include <l4/lock/lock.h>
00025
00026 #include <l4/dde_linux/dde.h>
00027
00028
00029 #include <linux/vmalloc.h>
00030 #include <linux/fs.h>
00031
00032
00033 #include "__config.h"
00034 #include "internal.h"
00035
00036 #include "soundcore.h"
00037
00039 struct sound_unit
00040 {
00041 int type;
00042 int num;
00043 struct file_operations *fops;
00044 struct sound_unit *next;
00045 };
00046
00048 static struct sound_unit *dsp = NULL, *mixer = NULL;
00050 static l4lock_t sound_loader_lock = L4LOCK_UNLOCKED;
00051
00060 static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list,
00061 struct file_operations *fops)
00062 {
00063 int n=0;
00064
00065
00066 while (*list && (*list)->num < n)
00067 list=&((*list)->next);
00068
00069 while(n < NUM_MAX)
00070 {
00071
00072 if(*list == NULL || (*list)->num > n)
00073 break;
00074 list = &((*list)->next);
00075 n++;
00076 }
00077
00078 if(n >= NUM_MAX)
00079 return -ENOENT;
00080
00081
00082 s->num = n;
00083 s->fops = fops;
00084
00085
00086 s->next = *list;
00087 *list = s;
00088
00089 return n;
00090 }
00091
00095 static void __sound_remove_unit(struct sound_unit **list, int unit)
00096 {
00097 while(*list)
00098 {
00099 struct sound_unit *p=*list;
00100 if (p->num == unit)
00101 {
00102 *list = p->next;
00103 vfree(p);
00104 return;
00105 }
00106 list = &(p->next);
00107 }
00108 LOG_Error("Sound device %d went missing!", unit);
00109 }
00110
00112 static struct sound_unit *__look_for_unit(struct sound_unit *s, int unit)
00113 {
00114 while(s && s->num <= unit)
00115 {
00116 if (s->num == unit)
00117 return s;
00118 s = s->next;
00119 }
00120 return NULL;
00121 }
00122
00127 static int sound_insert_unit(struct sound_unit **list,
00128 struct file_operations *fops, const char *name,
00129 int type)
00130 {
00131 int r;
00132 struct sound_unit *s=(struct sound_unit *)vmalloc(sizeof(struct sound_unit));
00133
00134 if(s==NULL)
00135 return -ENOMEM;
00136
00137 spin_lock(&sound_loader_lock);
00138 r = __sound_insert_unit(s, list, fops);
00139 s->type = type;
00140 spin_unlock(&sound_loader_lock);
00141
00142 if (r < 0)
00143 vfree(s);
00144
00145 return r;
00146 }
00147
00152 static void sound_remove_unit(struct sound_unit **list, int unit)
00153 {
00154 struct sound_unit *s;
00155
00156 if (!(s = __look_for_unit(*list, unit)))
00157 return;
00158
00159 spin_lock(&sound_loader_lock);
00160 __sound_remove_unit(list, unit);
00161 spin_unlock(&sound_loader_lock);
00162 }
00163
00175 int register_sound_dsp(struct file_operations *fops, int dev)
00176 {
00177 if (dev != -1)
00178 {
00179 #if DEBUG_SOUND
00180 LOGd(DEBUG_MSG, "dev has to be -1 (dev=%d)\n", dev);
00181 #endif
00182 return -EINVAL;
00183 }
00184
00185 dev = sound_insert_unit(&dsp, fops, "dsp", TYPE_DSP);
00186
00187 #if DEBUG_SOUND
00188 LOGd(DEBUG_MSG, "register dsp node %d\n", dev);
00189 #endif
00190
00191 return dev;
00192 }
00193
00204 int register_sound_mixer(struct file_operations *fops, int dev)
00205 {
00206 if (dev != -1)
00207 {
00208 #if DEBUG_SOUND
00209 LOGd(DEBUG_MSG, "dev has to be -1 (dev=%d)\n", dev);
00210 #endif
00211 return -EINVAL;
00212 }
00213
00214 dev = sound_insert_unit(&mixer, fops, "mixer", TYPE_MIXER);
00215
00216 #if DEBUG_SOUND
00217 LOGd(DEBUG_MSG, "register mixer node %d\n", dev);
00218 #endif
00219
00220 return dev;
00221 }
00222
00231 int register_sound_midi(struct file_operations *fops, int dev)
00232 {
00233 if (dev != -1)
00234 {
00235 #if DEBUG_SOUND
00236 LOGd(DEBUG_MSG, "dev has to be -1 (dev=%d)\n", dev);
00237 #endif
00238 return -EINVAL;
00239 }
00240 #if 0
00241 dev = sound_insert_unit(&midi, fops, "midi", TYPE_MIDI);
00242
00243 #if DEBUG_SOUND
00244 LOGd(DEBUG_MSG, "register midi node %d\n", dev);
00245 #endif
00246
00247 return dev;
00248 #else
00249 return 0;
00250 #endif
00251 }
00252
00264 int register_sound_special(struct file_operations *fops, int unit)
00265 {
00266 char *name;
00267
00268 switch (unit)
00269 {
00270 case 0:
00271 name = "mixer";
00272 break;
00273 case 1:
00274 name = "sequencer";
00275 break;
00276 case 2:
00277 name = "midi00";
00278 break;
00279 case 3:
00280 name = "dsp";
00281 break;
00282 case 4:
00283 name = "audio";
00284 break;
00285 case 5:
00286 name = "unknown5";
00287 break;
00288 case 6:
00289 name = "unknown6";
00290 break;
00291 case 7:
00292 name = "unknown7";
00293 break;
00294 case 8:
00295 name = "sequencer2";
00296 break;
00297 case 9:
00298 name = "dmmidi";
00299 break;
00300 case 10:
00301 name = "dmfm";
00302 break;
00303 case 11:
00304 name = "unknown11";
00305 break;
00306 case 12:
00307 name = "adsp";
00308 break;
00309 case 13:
00310 name = "amidi";
00311 break;
00312 case 14:
00313 name = "admmidi";
00314 break;
00315 default:
00316 name = "unknown";
00317 break;
00318 }
00319 #if DEBUG_SOUND
00320 LOGd(DEBUG_MSG, "register special node \"%s\" not supported\n", name);
00321 #endif
00322 return -ENOENT;
00323 }
00324
00336 int register_sound_synth(struct file_operations *fops, int dev)
00337 {
00338 #if DEBUG_SOUND
00339 LOGd(DEBUG_MSG, "register synth node not supported\n");
00340 #endif
00341 return -ENOENT;
00342 }
00343
00349 void unregister_sound_dsp(int unit)
00350 {
00351 sound_remove_unit(&dsp, unit);
00352
00353 #if DEBUG_SOUND
00354 LOGd(DEBUG_MSG, "unregister dsp node %d\n", unit);
00355 #endif
00356 }
00357
00363 void unregister_sound_mixer(int unit)
00364 {
00365 sound_remove_unit(&mixer, unit);
00366
00367 #if DEBUG_SOUND
00368 LOGd(DEBUG_MSG, "unregister mixer node %d\n", unit);
00369 #endif
00370 }
00371
00377 void unregister_sound_midi(int unit)
00378 {
00379 #if 0
00380 sound_remove_unit(&midi, unit);
00381 #endif
00382
00383 #if DEBUG_SOUND
00384 LOGd(DEBUG_MSG, "unregister midi node %d\n", unit);
00385 #endif
00386 }
00387
00396 void unregister_sound_special(int unit)
00397 {
00398 #if DEBUG_SOUND
00399 LOGd(DEBUG_MSG, "unregister special node %d not supported\n", unit);
00400 #endif
00401 }
00402
00411 void unregister_sound_synth(int unit)
00412 {
00413 #if DEBUG_SOUND
00414 LOGd(DEBUG_MSG, "unregister synth node %d not supported\n", unit);
00415 #endif
00416 }
00417
00418
00427 struct file_operations* soundcore_req_fops(int type, int num)
00428 {
00429 struct sound_unit *s;
00430
00431 switch (type)
00432 {
00433 case TYPE_DSP:
00434 s = __look_for_unit(dsp, num);
00435 break;
00436 case TYPE_MIXER:
00437 s = __look_for_unit(mixer, num);
00438 break;
00439 default:
00440 s = NULL;
00441 }
00442 return s ? s->fops : NULL;
00443 }
00444
00447 void soundcore_rel_fops(int type, int num)
00448 {
00449 }