00001
00002
00011
00012
00013
00014
00015
00025
00026 #include <l4/env/errno.h>
00027
00028 #include <l4/dde_linux/dde.h>
00029 #include <l4/dde_linux/sound.h>
00030
00031
00032 #include <linux/kernel.h>
00033 #include <linux/fs.h>
00034 #include <linux/soundcard.h>
00035
00036
00037 #include "__config.h"
00038 #include "internal.h"
00039
00040 #include "soundcore.h"
00041
00043 static int _initialized = 0;
00044
00046 static struct devs
00047 {
00048 struct file file;
00049 struct inode inode;
00050 struct file_operations *fops;
00051 } devs[TYPE_MAX][NUM_MAX];
00052
00054 static inline void show_fops(struct file_operations* f)
00055 {
00056 LOGd(DEBUG_MSG, " open @ %p\n", f->open);
00057 LOGd(DEBUG_MSG, " close @ %p\n", f->release);
00058 LOGd(DEBUG_MSG, " read @ %p\n", f->read);
00059 LOGd(DEBUG_MSG, " write @ %p\n", f->write);
00060 LOGd(DEBUG_MSG, " ioctl @ %p\n", f->ioctl);
00061 }
00062
00063
00064
00066 static int snd_open_dev(int type, int num)
00067 {
00068 int ret;
00069 struct file_operations* fops;
00070 struct file *file;
00071 struct inode *inode;
00072
00073 fops = soundcore_req_fops(type, num);
00074 if (!fops)
00075 return -L4_ENOTFOUND;
00076
00077 devs[type][num].fops = fops;
00078 file = &devs[type][num].file;
00079 inode = &devs[type][num].inode;
00080
00081 file->f_mode = FMODE_READ | FMODE_WRITE;
00082 file->f_flags = O_RDWR;
00083 file->f_pos = 0;
00084
00085 if ((ret=fops->open(inode, file)))
00086 {
00087 LOGdL(DEBUG_ERRORS, "Error: fops->open returned %d", ret);
00088 return -L4_EOPEN;
00089 }
00090
00091 #if DEBUG_SOUND
00092 LOGd(DEBUG_MSG, "%s%d opened", type ? "mixer" : "dsp", num);
00093 show_fops(fops);
00094 #endif
00095
00096 return (type*NUM_MAX + num);
00097 }
00098
00102 int l4dde_snd_open_dsp(int num)
00103 {
00104 return snd_open_dev(TYPE_DSP, num);
00105 }
00106
00110 int l4dde_snd_open_mixer(int num)
00111 {
00112 return snd_open_dev(TYPE_MIXER, num);
00113 }
00114
00118 int l4dde_snd_close(int dev)
00119 {
00120 int ret=0;
00121 struct devs *d = (struct devs *) devs;
00122 struct file_operations* fops = d[dev].fops;
00123 struct file *file;
00124 struct inode *inode;
00125
00126 Assert(fops);
00127 if (!fops)
00128 return -L4_ESKIPPED;
00129
00130 file = &d[dev].file;
00131 inode = &d[dev].inode;
00132
00133
00134 if (fops->release)
00135 ret = fops->release(inode, file);
00136
00137 LOGd(DEBUG_SOUND, "device closed (%d)", ret);
00138
00139 return 0;
00140 }
00141
00145 int l4dde_snd_read(int dev, void *buf, int count)
00146 {
00147 int ret;
00148 struct devs *d = (struct devs *) devs;
00149 struct file_operations* fops = d[dev].fops;
00150 struct file *file;
00151
00152 Assert(fops);
00153 if (!fops)
00154 return -L4_ESKIPPED;
00155
00156 file = &d[dev].file;
00157
00158 if (fops->read)
00159 ret = fops->read(file, buf, count, &file->f_pos);
00160 else
00161 ret = -L4_EINVAL;
00162
00163 LOGd(DEBUG_SOUND_READ, "read from device (%d)", ret);
00164
00165 return ret;
00166 }
00167
00171 int l4dde_snd_write(int dev, const void *buf, int count)
00172 {
00173 int ret;
00174 struct devs *d = (struct devs *) devs;
00175 struct file_operations* fops = d[dev].fops;
00176 struct file *file;
00177
00178 Assert(fops);
00179 if (!fops)
00180 return -L4_ESKIPPED;
00181
00182 file = &d[dev].file;
00183
00184 if (fops->write)
00185 ret = fops->write(file, buf, count, &file->f_pos);
00186 else
00187 ret = -L4_EINVAL;
00188
00189 LOGd(DEBUG_SOUND_WRITE, "write on device (%d)", ret);
00190
00191 return ret;
00192 }
00193
00197 int l4dde_snd_ioctl(int dev, int req, l4_addr_t arg)
00198 {
00199 int ret;
00200 struct devs *d = (struct devs *) devs;
00201 struct file_operations* fops = d[dev].fops;
00202 struct file *file;
00203 struct inode *inode;
00204
00205 Assert(fops);
00206 if (!fops)
00207 return -L4_ESKIPPED;
00208
00209 file = &d[dev].file;
00210 inode = &d[dev].inode;
00211
00212 if (fops->ioctl)
00213 ret = fops->ioctl(inode, file, req, arg);
00214 else
00215 ret = -L4_EINVAL;
00216
00217 LOGd(DEBUG_SOUND, "ioctl on device (%d)", ret);
00218
00219 return ret;
00220 }
00221
00225 int l4dde_snd_init()
00226 {
00227 if (_initialized)
00228 return -L4_ESKIPPED;
00229
00230 ++_initialized;
00231 return 0;
00232 }
00233
00237 int l4dde_snd_exit()
00238 {
00239 if (!_initialized)
00240 return -L4_ESKIPPED;
00241
00242 --_initialized;
00243 return 0;
00244 }