[32] | 1 | /*
|
---|
| 2 |
|
---|
| 3 | IOCTL funcs
|
---|
| 4 | Written by Vlad Stelmahovsky with help from Stepan Kazakov
|
---|
| 5 |
|
---|
| 6 | */
|
---|
| 7 |
|
---|
[305] | 8 | #include <sound/core.h>
|
---|
[32] | 9 | #include <sound/control.h>
|
---|
| 10 | #include <sound/info.h>
|
---|
| 11 | #include <sound/pcm.h>
|
---|
| 12 | #include <sound/pcm_params.h>
|
---|
| 13 | #include <sound/minors.h>
|
---|
| 14 | #include <linux/file.h>
|
---|
| 15 | #include <linux/soundcard.h>
|
---|
| 16 |
|
---|
| 17 | #define LINUX
|
---|
| 18 | #include <ossidc32.h>
|
---|
| 19 | #include <stacktoflat.h>
|
---|
| 20 | #include <stdlib.h>
|
---|
| 21 | #include "soundoss.h"
|
---|
| 22 |
|
---|
[677] | 23 | #include <kee.h>
|
---|
[675] | 24 | #include <u32ioctl.h>
|
---|
| 25 |
|
---|
[32] | 26 | POSS32_DEVCAPS pcmcaps[8] = {0,0,0,0,0,0,0,0};
|
---|
| 27 | extern int pcm_device;
|
---|
| 28 | extern OpenedHandles opened_handles[8*256];
|
---|
| 29 |
|
---|
| 30 | /*
|
---|
| 31 | * Control ID changed by an external
|
---|
| 32 | * set by snd_ctl_notify()
|
---|
| 33 | */
|
---|
[305] | 34 | struct snd_pcm_substream *substream_int[8*256] = {0}; // interrupted substream
|
---|
[470] | 35 |
|
---|
[32] | 36 | int control_id_changed = 0;
|
---|
| 37 | int card_id_changed = 0;
|
---|
| 38 | int unlock_all = 0;
|
---|
| 39 | int pcm_instances(int card_id);
|
---|
| 40 |
|
---|
[479] | 41 | void uniaud_set_interrupted_substream(struct snd_pcm_substream *substream)
|
---|
[470] | 42 | {
|
---|
[528] | 43 | int i;
|
---|
[470] | 44 |
|
---|
[528] | 45 | for (i=0; i < 8*256; i++)
|
---|
| 46 | {
|
---|
| 47 | if (substream_int[i] == 0)
|
---|
| 48 | {
|
---|
| 49 | substream_int[i] = substream; // interrupted substream
|
---|
| 50 | // printk("added %x to %i\n", substream, i);
|
---|
| 51 | break;
|
---|
| 52 | }
|
---|
| 53 | if (substream_int[i] == substream)
|
---|
| 54 | {
|
---|
| 55 | // printk("already exist %x at %i\n", substream, i);
|
---|
| 56 | break;
|
---|
| 57 | }
|
---|
| 58 | }
|
---|
[470] | 59 | }
|
---|
| 60 |
|
---|
[32] | 61 | int WaitForControlChange(int card_id, int timeout)
|
---|
| 62 | {
|
---|
[528] | 63 | int ctl_id;
|
---|
| 64 | int i = 0;
|
---|
[32] | 65 |
|
---|
[528] | 66 | while (1)
|
---|
| 67 | {
|
---|
| 68 | if (control_id_changed != 0 && card_id_changed == card_id)
|
---|
| 69 | {
|
---|
| 70 | ctl_id = control_id_changed;
|
---|
| 71 | control_id_changed = 0;
|
---|
| 72 | break;
|
---|
| 73 | }
|
---|
| 74 | i++;
|
---|
[32] | 75 |
|
---|
[528] | 76 | if (i > timeout)
|
---|
| 77 | return -ETIME;
|
---|
[32] | 78 |
|
---|
[677] | 79 | KernBlock((ULONG)&WaitForControlChange, 1, 0, 0, 0);
|
---|
[528] | 80 | if (unlock_all)
|
---|
| 81 | {
|
---|
| 82 | unlock_all = 0;
|
---|
| 83 | break;
|
---|
| 84 | }
|
---|
| 85 | }
|
---|
| 86 | return ctl_id;
|
---|
[32] | 87 | }
|
---|
| 88 |
|
---|
| 89 | int WaitForPCMInterrupt(void *handle, int timeout)
|
---|
| 90 | {
|
---|
[528] | 91 | int i = 0;
|
---|
| 92 | int j = 0;
|
---|
| 93 | struct snd_pcm_file *pcm_file = NULL;
|
---|
| 94 | struct snd_pcm_substream *substream;
|
---|
| 95 | struct snd_pcm_runtime *runtime;
|
---|
| 96 | soundhandle *pHandle = (soundhandle *)handle;
|
---|
| 97 | struct file *pfile;
|
---|
[32] | 98 |
|
---|
[528] | 99 | if (handle == NULL)
|
---|
| 100 | return -ENXIO;
|
---|
[32] | 101 |
|
---|
[528] | 102 | pfile = &pHandle->file;
|
---|
[32] | 103 |
|
---|
[528] | 104 | if (pfile == NULL)
|
---|
| 105 | return -ENXIO;
|
---|
[32] | 106 |
|
---|
[528] | 107 | pcm_file = (struct snd_pcm_file *)pfile->private_data;
|
---|
[32] | 108 |
|
---|
[528] | 109 | if (pcm_file == NULL)
|
---|
| 110 | return -ENXIO;
|
---|
[32] | 111 |
|
---|
[528] | 112 | substream = pcm_file->substream;
|
---|
[32] | 113 |
|
---|
[528] | 114 | if (substream == NULL)
|
---|
| 115 | return -ENXIO;
|
---|
[32] | 116 |
|
---|
[528] | 117 | runtime = substream->runtime;
|
---|
[32] | 118 |
|
---|
[528] | 119 | if ((pfile->f_mode == FMODE_WRITE) &&
|
---|
| 120 | (runtime->status->state != SNDRV_PCM_STATE_RUNNING))
|
---|
| 121 | return -EBADFD;
|
---|
[32] | 122 |
|
---|
[598] | 123 | //printk("wait for %x. tout %i\n",substream, timeout);
|
---|
[32] | 124 |
|
---|
[528] | 125 | while (1)
|
---|
| 126 | {
|
---|
| 127 | for (i=0; i < 8*256; i++)
|
---|
| 128 | {
|
---|
| 129 | if (substream_int[i] == substream)
|
---|
| 130 | {
|
---|
| 131 | // printk("found %x at %i\n",substream_int[i], i);
|
---|
| 132 | substream_int[i] = 0;
|
---|
| 133 | //printk("j =%i\n",j);
|
---|
| 134 | return j; /* milliseconds */
|
---|
| 135 | }
|
---|
| 136 | }
|
---|
[32] | 137 |
|
---|
[528] | 138 | if (j++ > timeout)
|
---|
| 139 | {
|
---|
[542] | 140 | dprintf(("WaitForPCMInterrupt: Timeout j=%i handle=%x\n", j, pHandle));
|
---|
[528] | 141 | return -ETIME;
|
---|
| 142 | }
|
---|
[32] | 143 |
|
---|
[677] | 144 | KernBlock((ULONG)&WaitForPCMInterrupt, 1, 0, 0, 0);
|
---|
[528] | 145 | if (unlock_all)
|
---|
| 146 | {
|
---|
| 147 | unlock_all = 0;
|
---|
| 148 | break;
|
---|
| 149 | }
|
---|
| 150 | }
|
---|
| 151 | //printk("j at exit =%i\n",j);
|
---|
| 152 | return j;
|
---|
[32] | 153 | }
|
---|
| 154 |
|
---|
| 155 | /*
|
---|
| 156 | returns number of registered cards
|
---|
| 157 | */
|
---|
| 158 | int GetNumberOfCards(void)
|
---|
| 159 | {
|
---|
[528] | 160 | return nrCardsDetected;
|
---|
[32] | 161 | }
|
---|
| 162 |
|
---|
| 163 | /*
|
---|
| 164 | returns number of registered pcm instances
|
---|
| 165 | */
|
---|
| 166 | int GetNumberOfPcm(int card_id)
|
---|
| 167 | {
|
---|
[528] | 168 | return pcm_instances(card_id);
|
---|
[32] | 169 | }
|
---|
| 170 |
|
---|
| 171 | int SetPCMInstance(int card_id, int pcm)
|
---|
| 172 | {
|
---|
[528] | 173 | if (pcm>=0 && pcm <= pcm_instances(card_id))
|
---|
| 174 | {
|
---|
| 175 | pcm_device = pcm;
|
---|
| 176 | return pcm;
|
---|
| 177 | } else
|
---|
| 178 | return pcm_device;
|
---|
[32] | 179 | }
|
---|
| 180 |
|
---|
[675] | 181 | /*
|
---|
[32] | 182 | int GetPcmForChannels(ULONG deviceid, int type, int channels)
|
---|
| 183 | {
|
---|
[528] | 184 | POSS32_DEVCAPS pcaps = NULL;
|
---|
| 185 | WAVE_CAPS *wc;
|
---|
| 186 | int i;
|
---|
| 187 | int sel_pcm = -1;
|
---|
[32] | 188 |
|
---|
[528] | 189 | if (!pcmcaps[deviceid])
|
---|
| 190 | {
|
---|
| 191 | FillCaps(deviceid);
|
---|
| 192 | if (!pcmcaps[deviceid])
|
---|
| 193 | {
|
---|
| 194 | printk("Error querying caps for device: %i\n", deviceid);
|
---|
| 195 | return -1;
|
---|
| 196 | }
|
---|
| 197 | }
|
---|
[32] | 198 |
|
---|
[528] | 199 | pcaps = pcmcaps[deviceid];
|
---|
[32] | 200 |
|
---|
[528] | 201 | for (i=0; i<pcm_instances(deviceid);i++)
|
---|
| 202 | {
|
---|
| 203 | switch(type)
|
---|
| 204 | {
|
---|
| 205 | case OSS32_CAPS_WAVE_PLAYBACK: // play
|
---|
| 206 | wc = &pcaps->waveOutCaps;
|
---|
| 207 | break;
|
---|
| 208 | case OSS32_CAPS_WAVE_CAPTURE: // record
|
---|
| 209 | wc = &pcaps->waveInCaps;
|
---|
| 210 | break;
|
---|
| 211 | }
|
---|
| 212 | if (wc->ulMaxChannels == channels)
|
---|
| 213 | {
|
---|
| 214 | sel_pcm = i;
|
---|
| 215 | break;
|
---|
| 216 | }
|
---|
| 217 | pcaps++;
|
---|
| 218 | }
|
---|
[32] | 219 |
|
---|
[528] | 220 | return sel_pcm;
|
---|
[32] | 221 | }
|
---|
[675] | 222 | */
|
---|
[32] | 223 |
|
---|
| 224 | int GetMaxChannels(ULONG deviceid, int type)
|
---|
| 225 | {
|
---|
[528] | 226 | POSS32_DEVCAPS pcaps = NULL;
|
---|
| 227 | WAVE_CAPS *wc;
|
---|
| 228 | int i;
|
---|
[598] | 229 | //int sel_pcm = -1;
|
---|
[528] | 230 | int max_ch = 0;
|
---|
[32] | 231 |
|
---|
[528] | 232 | if (!pcmcaps[deviceid])
|
---|
| 233 | {
|
---|
| 234 | FillCaps(deviceid);
|
---|
| 235 | if (!pcmcaps[deviceid])
|
---|
| 236 | {
|
---|
| 237 | printk("Error querying caps for device: %i\n", deviceid);
|
---|
| 238 | return -1;
|
---|
| 239 | }
|
---|
| 240 | }
|
---|
[32] | 241 |
|
---|
[528] | 242 | pcaps = pcmcaps[deviceid];
|
---|
[32] | 243 |
|
---|
[528] | 244 | for (i=0; i<pcm_instances(deviceid);i++)
|
---|
| 245 | {
|
---|
| 246 | switch(type)
|
---|
| 247 | {
|
---|
| 248 | case OSS32_CAPS_WAVE_PLAYBACK: // play
|
---|
| 249 | wc = &pcaps->waveOutCaps;
|
---|
| 250 | break;
|
---|
| 251 | case OSS32_CAPS_WAVE_CAPTURE: // record
|
---|
| 252 | wc = &pcaps->waveInCaps;
|
---|
| 253 | break;
|
---|
| 254 | }
|
---|
| 255 | if (wc->ulMaxChannels > max_ch)
|
---|
| 256 | max_ch = wc->ulMaxChannels;
|
---|
| 257 | pcaps++;
|
---|
| 258 | }
|
---|
| 259 | return max_ch;
|
---|
[32] | 260 | }
|
---|
| 261 |
|
---|
| 262 | /*
|
---|
| 263 | returns pcm caps
|
---|
| 264 | */
|
---|
[675] | 265 | static int GetUniaudPcmCaps1(ULONG deviceid, void *caps)
|
---|
[32] | 266 | {
|
---|
[528] | 267 | POSS32_DEVCAPS pcaps = (POSS32_DEVCAPS)caps;
|
---|
| 268 | int i;
|
---|
| 269 | OSSSTREAMID streamid = 0;
|
---|
| 270 | soundhandle *pHandle;
|
---|
| 271 | struct snd_pcm_info *pcminfo = NULL;
|
---|
| 272 | struct snd_pcm_hw_params *params;
|
---|
| 273 | int ret, fmt, j;
|
---|
| 274 | ULONG format_mask;
|
---|
| 275 | struct snd_mask *mask;
|
---|
| 276 | int pcms = 0;
|
---|
[32] | 277 |
|
---|
[528] | 278 | pcms = pcm_instances(deviceid);
|
---|
[625] | 279 |
|
---|
[528] | 280 | if (!pcaps || !pcms) return -1;
|
---|
[32] | 281 |
|
---|
[479] | 282 |
|
---|
[528] | 283 | //these structures are too big to put on the stack
|
---|
| 284 | pcminfo = (struct snd_pcm_info *)kmalloc(sizeof(struct snd_pcm_info)+sizeof(struct snd_pcm_hw_params), GFP_KERNEL);
|
---|
| 285 | if(pcminfo == NULL) {
|
---|
| 286 | DebugInt3();
|
---|
| 287 | rprintf(("GetUniaudPcmCaps: out of memory"));
|
---|
| 288 | return OSSERR_OUT_OF_MEMORY;
|
---|
| 289 | }
|
---|
| 290 | params = (struct snd_pcm_hw_params *)(pcminfo+1);
|
---|
[32] | 291 |
|
---|
[528] | 292 | for (i=0; i<pcms;i++)
|
---|
| 293 | {
|
---|
| 294 | pcaps->nrDevices = nrCardsDetected;
|
---|
| 295 | pcaps->ulCaps = OSS32_CAPS_WAVE_PLAYBACK | OSS32_CAPS_WAVE_CAPTURE;
|
---|
[32] | 296 |
|
---|
[528] | 297 | //query wave in & out caps
|
---|
| 298 | for(j=0;j<2;j++)
|
---|
| 299 | {
|
---|
| 300 | PWAVE_CAPS pWaveCaps = (j == 0) ? &pcaps->waveOutCaps : &pcaps->waveInCaps;
|
---|
[32] | 301 |
|
---|
[528] | 302 | ret = OSS32_WaveOpen(deviceid, (j == 0) ? OSS32_STREAM_WAVEOUT : OSS32_STREAM_WAVEIN, &streamid, i, 0);
|
---|
| 303 | if(ret != OSSERR_SUCCESS)
|
---|
| 304 | {
|
---|
[615] | 305 | dprintf(("GetUniaudPcmCaps1: wave open error %i %s at pcm %i", ret, (j == 0) ?"PLAY":"REC", i));
|
---|
[528] | 306 | continue;
|
---|
| 307 | //goto fail;
|
---|
| 308 | }
|
---|
| 309 | pHandle = (soundhandle *)streamid;
|
---|
| 310 | if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) {
|
---|
| 311 | rprintf(("GetUniaudPcmCaps: invalid stream id"));
|
---|
| 312 | ret = OSSERR_INVALID_STREAMID;
|
---|
| 313 | //goto fail;
|
---|
| 314 | }
|
---|
[32] | 315 |
|
---|
[528] | 316 | //set operation to non-blocking
|
---|
| 317 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 318 |
|
---|
[615] | 319 | dprintf(("GetUniaudPcmCaps: cp1. pcm %i, phandle %x", i, pHandle));
|
---|
[644] | 320 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo);
|
---|
[528] | 321 | if(ret != 0) {
|
---|
| 322 | rprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_INFO error %i", ret));
|
---|
| 323 | ret = UNIXToOSSError(ret);
|
---|
| 324 | continue;
|
---|
| 325 | }
|
---|
| 326 | if(pcminfo->name[0]) {
|
---|
| 327 | strncpy(pcaps->szDeviceName, pcminfo->name, sizeof(pcaps->szDeviceName));
|
---|
| 328 | }
|
---|
| 329 | else strncpy(pcaps->szDeviceName, pcminfo->id, sizeof(pcaps->szDeviceName));
|
---|
[32] | 330 |
|
---|
[528] | 331 | if(pcminfo->subname[0]) {
|
---|
| 332 | strncpy(pcaps->szMixerName, pcminfo->subname, sizeof(pcaps->szMixerName));
|
---|
| 333 | }
|
---|
[32] | 334 |
|
---|
[528] | 335 | pWaveCaps->nrStreams = pcminfo->subdevices_count;
|
---|
[32] | 336 |
|
---|
[615] | 337 | dprintf(("GetUniaudPcmCaps: pcm %i, cp2. nr of streams: %i", i, pWaveCaps->nrStreams));
|
---|
[528] | 338 | //get all hardware parameters
|
---|
| 339 | _snd_pcm_hw_params_any(params);
|
---|
[644] | 340 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
|
---|
[528] | 341 | if(ret != 0) {
|
---|
| 342 | dprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i", ret));
|
---|
| 343 | ret = UNIXToOSSError(ret);
|
---|
| 344 | //goto fail;
|
---|
| 345 | continue;
|
---|
| 346 | }
|
---|
| 347 | //dprintf("GetUniaudPcmCaps: cp3"));
|
---|
[32] | 348 |
|
---|
[528] | 349 | pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min;
|
---|
| 350 | pWaveCaps->ulMaxChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
|
---|
| 351 | dprintf(("chan: from %i to %i\n", pWaveCaps->ulMinChannels,pWaveCaps->ulMaxChannels));
|
---|
| 352 | pWaveCaps->ulChanFlags = 0;
|
---|
| 353 | if(pWaveCaps->ulMinChannels == 1) {
|
---|
| 354 | pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_MONO;
|
---|
| 355 | }
|
---|
| 356 | if(pWaveCaps->ulMaxChannels >= 2) {
|
---|
| 357 | pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_STEREO;
|
---|
| 358 | }
|
---|
| 359 | if(pWaveCaps->ulMaxChannels >= 4) {
|
---|
| 360 | pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_QUAD;
|
---|
| 361 | }
|
---|
| 362 | if(pWaveCaps->ulMaxChannels >= 6) {
|
---|
| 363 | pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_5_1;
|
---|
| 364 | }
|
---|
| 365 | pWaveCaps->ulMinRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min;
|
---|
| 366 | pWaveCaps->ulMaxRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max;
|
---|
[32] | 367 |
|
---|
[528] | 368 | mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_RATE_MASK);
|
---|
[518] | 369 | //mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
|
---|
[528] | 370 | pWaveCaps->ulRateFlags = mask->bits[0];
|
---|
[32] | 371 |
|
---|
[528] | 372 | pWaveCaps->ulRateFlags = ALSAToOSSRateFlags(pWaveCaps->ulRateFlags);
|
---|
[32] | 373 |
|
---|
[528] | 374 | pWaveCaps->ulDataFormats = 0;
|
---|
[32] | 375 |
|
---|
[528] | 376 | mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
|
---|
| 377 | format_mask = mask->bits[0];
|
---|
| 378 | for(fmt=0;fmt<32;fmt++)
|
---|
| 379 | {
|
---|
| 380 | if(format_mask & (1 << fmt))
|
---|
| 381 | {
|
---|
| 382 | int f = ALSAToOSSDataType(fmt);
|
---|
| 383 | if (f >= 0)
|
---|
| 384 | pWaveCaps->ulDataFormats |= f;
|
---|
| 385 | }
|
---|
| 386 | }
|
---|
[32] | 387 |
|
---|
[528] | 388 | OSS32_WaveClose(streamid);
|
---|
| 389 | streamid = 0;
|
---|
| 390 | } // for j
|
---|
| 391 | pcaps++; // next pcm
|
---|
| 392 | } // for i
|
---|
[32] | 393 |
|
---|
[528] | 394 | if (pcminfo) kfree(pcminfo);
|
---|
| 395 | return OSSERR_SUCCESS;
|
---|
[32] | 396 | }
|
---|
| 397 |
|
---|
[479] | 398 | void FillCaps(ULONG deviceid)
|
---|
| 399 | {
|
---|
[528] | 400 | int pcms = 0;
|
---|
[479] | 401 |
|
---|
[528] | 402 | pcms = pcm_instances(deviceid);
|
---|
[479] | 403 |
|
---|
[549] | 404 | //dprintf(("FillCaps: pcms=%i\n", pcms));
|
---|
[528] | 405 | if (!pcmcaps[deviceid])
|
---|
| 406 | {
|
---|
| 407 | pcmcaps[deviceid] = (POSS32_DEVCAPS)kmalloc(sizeof(OSS32_DEVCAPS)*pcms, GFP_KERNEL);
|
---|
| 408 | if (pcmcaps[deviceid])
|
---|
| 409 | {
|
---|
| 410 | memset(pcmcaps[deviceid], 0, sizeof(OSS32_DEVCAPS)*pcms);
|
---|
| 411 | GetUniaudPcmCaps1(deviceid, (void *)pcmcaps[deviceid]);
|
---|
| 412 | }
|
---|
| 413 | }
|
---|
| 414 | return;
|
---|
[479] | 415 | }
|
---|
| 416 |
|
---|
| 417 | int GetUniaudPcmCaps(ULONG deviceid, void *caps)
|
---|
| 418 | {
|
---|
[528] | 419 | int pcms = 0;
|
---|
[479] | 420 |
|
---|
[528] | 421 | pcms = pcm_instances(deviceid);
|
---|
[479] | 422 |
|
---|
[528] | 423 | // printk("pcms = %i\n", pcms);
|
---|
| 424 | if (pcmcaps[deviceid])
|
---|
| 425 | {
|
---|
| 426 | memcpy((unsigned char*)caps,(unsigned char*)pcmcaps[deviceid],sizeof(OSS32_DEVCAPS)*pcms);
|
---|
| 427 | return 0;
|
---|
| 428 | }
|
---|
| 429 | else
|
---|
| 430 | {
|
---|
| 431 | return -1;
|
---|
| 432 | }
|
---|
[479] | 433 | }
|
---|
| 434 |
|
---|
[32] | 435 | /*
|
---|
| 436 | returns power state of given card
|
---|
| 437 | */
|
---|
| 438 | int UniaudCtlGetPowerState(ULONG deviceid, void *state)
|
---|
| 439 | {
|
---|
[528] | 440 | mixerhandle *pHandle = NULL;
|
---|
[598] | 441 | int ret;
|
---|
| 442 | //int i, j;
|
---|
[32] | 443 |
|
---|
[528] | 444 | if(alsa_fops == NULL) {
|
---|
| 445 | ret = OSSERR_NO_DEVICE_AVAILABLE;
|
---|
| 446 | goto failure;
|
---|
| 447 | }
|
---|
[32] | 448 |
|
---|
[528] | 449 | pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
|
---|
| 450 | if(pHandle == NULL) {
|
---|
| 451 | ret = OSSERR_OUT_OF_MEMORY;
|
---|
| 452 | goto failure;
|
---|
| 453 | }
|
---|
| 454 | memset(pHandle, 0, sizeof(mixerhandle));
|
---|
[32] | 455 |
|
---|
[528] | 456 | //set operation to non-blocking
|
---|
| 457 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 458 |
|
---|
[528] | 459 | //setup pointers in file structure (used internally by ALSA)
|
---|
| 460 | pHandle->file.f_dentry = &pHandle->d_entry;
|
---|
| 461 | pHandle->file.f_dentry->d_inode = &pHandle->inode;
|
---|
[32] | 462 |
|
---|
[528] | 463 | pHandle->file.f_mode = FMODE_WRITE;
|
---|
| 464 | pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
|
---|
[32] | 465 |
|
---|
[528] | 466 | ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
|
---|
| 467 | if(ret) {
|
---|
| 468 | goto failure;
|
---|
| 469 | }
|
---|
| 470 | //retrieve mixer information
|
---|
[644] | 471 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
|
---|
[528] | 472 | SNDRV_CTL_IOCTL_POWER_STATE,
|
---|
| 473 | (ULONG)state);
|
---|
[32] | 474 |
|
---|
[528] | 475 | pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
[32] | 476 |
|
---|
[528] | 477 | kfree(pHandle);
|
---|
[32] | 478 |
|
---|
[528] | 479 | if(ret) {
|
---|
| 480 | goto failure;
|
---|
| 481 | }
|
---|
[32] | 482 |
|
---|
[528] | 483 | return OSSERR_SUCCESS;
|
---|
[32] | 484 | failure:
|
---|
[528] | 485 | DebugInt3();
|
---|
| 486 | return ret;
|
---|
[32] | 487 | }
|
---|
| 488 |
|
---|
| 489 | /*
|
---|
| 490 | sets power state for given card
|
---|
| 491 | */
|
---|
| 492 | int UniaudCtlSetPowerState(ULONG deviceid, void *state)
|
---|
| 493 | {
|
---|
[528] | 494 | mixerhandle *pHandle = NULL;
|
---|
[598] | 495 | int ret;
|
---|
| 496 | //int i, j;
|
---|
[32] | 497 |
|
---|
[528] | 498 | if(alsa_fops == NULL) {
|
---|
| 499 | ret = OSSERR_NO_DEVICE_AVAILABLE;
|
---|
| 500 | goto failure;
|
---|
| 501 | }
|
---|
[32] | 502 |
|
---|
[528] | 503 | pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
|
---|
| 504 | if(pHandle == NULL) {
|
---|
| 505 | ret = OSSERR_OUT_OF_MEMORY;
|
---|
| 506 | goto failure;
|
---|
| 507 | }
|
---|
| 508 | memset(pHandle, 0, sizeof(mixerhandle));
|
---|
[32] | 509 |
|
---|
[528] | 510 | //set operation to non-blocking
|
---|
| 511 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 512 |
|
---|
[528] | 513 | //setup pointers in file structure (used internally by ALSA)
|
---|
| 514 | pHandle->file.f_dentry = &pHandle->d_entry;
|
---|
| 515 | pHandle->file.f_dentry->d_inode = &pHandle->inode;
|
---|
[32] | 516 |
|
---|
[528] | 517 | pHandle->file.f_mode = FMODE_WRITE;
|
---|
| 518 | pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
|
---|
[32] | 519 |
|
---|
[528] | 520 | ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
|
---|
| 521 | if(ret) {
|
---|
| 522 | goto failure;
|
---|
| 523 | }
|
---|
| 524 | //retrieve mixer information
|
---|
[644] | 525 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
|
---|
[528] | 526 | SNDRV_CTL_IOCTL_POWER,
|
---|
| 527 | (ULONG)state);
|
---|
[32] | 528 |
|
---|
[528] | 529 | pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
[32] | 530 |
|
---|
[528] | 531 | kfree(pHandle);
|
---|
[32] | 532 |
|
---|
[528] | 533 | if(ret) {
|
---|
| 534 | goto failure;
|
---|
| 535 | }
|
---|
[32] | 536 |
|
---|
[528] | 537 | return OSSERR_SUCCESS;
|
---|
[32] | 538 | failure:
|
---|
[528] | 539 | DebugInt3();
|
---|
| 540 | return ret;
|
---|
[32] | 541 | }
|
---|
| 542 |
|
---|
| 543 | /*
|
---|
| 544 | returns card info
|
---|
| 545 | */
|
---|
| 546 | int GetUniaudCardInfo(ULONG deviceid, void *info)
|
---|
| 547 | {
|
---|
[528] | 548 | mixerhandle *pHandle = NULL;
|
---|
[598] | 549 | int ret;
|
---|
| 550 | //int i, j;
|
---|
[32] | 551 |
|
---|
[549] | 552 | //dprintf(("GetUniaudCardInfo"));
|
---|
[542] | 553 |
|
---|
[528] | 554 | if(alsa_fops == NULL) {
|
---|
| 555 | ret = OSSERR_NO_DEVICE_AVAILABLE;
|
---|
| 556 | goto failure;
|
---|
| 557 | }
|
---|
[32] | 558 |
|
---|
[528] | 559 | pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
|
---|
| 560 | if(pHandle == NULL) {
|
---|
| 561 | ret = OSSERR_OUT_OF_MEMORY;
|
---|
| 562 | goto failure;
|
---|
| 563 | }
|
---|
| 564 | memset(pHandle, 0, sizeof(mixerhandle));
|
---|
[32] | 565 |
|
---|
[528] | 566 | //set operation to non-blocking
|
---|
| 567 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 568 |
|
---|
[528] | 569 | //setup pointers in file structure (used internally by ALSA)
|
---|
| 570 | pHandle->file.f_dentry = &pHandle->d_entry;
|
---|
| 571 | pHandle->file.f_dentry->d_inode = &pHandle->inode;
|
---|
[32] | 572 |
|
---|
[528] | 573 | pHandle->file.f_mode = FMODE_WRITE;
|
---|
| 574 | pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
|
---|
[32] | 575 |
|
---|
[528] | 576 | ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
|
---|
| 577 | if(ret) {
|
---|
| 578 | goto failure;
|
---|
| 579 | }
|
---|
| 580 | //retrieve mixer information
|
---|
[644] | 581 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
|
---|
[528] | 582 | SNDRV_CTL_IOCTL_CARD_INFO,
|
---|
| 583 | (ULONG)(struct snd_ctl_card_info *)info);
|
---|
| 584 | if(ret) {
|
---|
| 585 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 586 | goto failure;
|
---|
| 587 | }
|
---|
| 588 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
[32] | 589 |
|
---|
[528] | 590 | if(pHandle) {
|
---|
| 591 | kfree(pHandle);
|
---|
| 592 | }
|
---|
| 593 | return OSSERR_SUCCESS;
|
---|
[32] | 594 | failure:
|
---|
[528] | 595 | if(pHandle) {
|
---|
| 596 | kfree(pHandle);
|
---|
| 597 | }
|
---|
| 598 | DebugInt3();
|
---|
| 599 | return OSSERR_OUT_OF_MEMORY;
|
---|
[32] | 600 | }
|
---|
| 601 |
|
---|
| 602 | int GetUniaudControlNum(ULONG deviceid)
|
---|
| 603 | {
|
---|
[528] | 604 | mixerhandle *pHandle = NULL;
|
---|
[598] | 605 | int ret, sz;
|
---|
| 606 | //int i, j;
|
---|
[32] | 607 |
|
---|
[549] | 608 | //dprintf(("GetUniaudControlNum"));
|
---|
[542] | 609 |
|
---|
[528] | 610 | if(alsa_fops == NULL) {
|
---|
| 611 | ret = OSSERR_NO_DEVICE_AVAILABLE;
|
---|
| 612 | goto failure;
|
---|
| 613 | }
|
---|
[32] | 614 |
|
---|
[528] | 615 | sz = sizeof(mixerhandle);
|
---|
| 616 | pHandle = kmalloc(sz, GFP_KERNEL);
|
---|
| 617 | if(pHandle == NULL) {
|
---|
| 618 | ret = OSSERR_OUT_OF_MEMORY;
|
---|
| 619 | goto failure;
|
---|
| 620 | }
|
---|
| 621 | memset(pHandle, 0, sizeof(mixerhandle));
|
---|
[32] | 622 |
|
---|
[528] | 623 | //set operation to non-blocking
|
---|
| 624 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 625 |
|
---|
[528] | 626 | //setup pointers in file structure (used internally by ALSA)
|
---|
| 627 | pHandle->file.f_dentry = &pHandle->d_entry;
|
---|
| 628 | pHandle->file.f_dentry->d_inode = &pHandle->inode;
|
---|
[32] | 629 |
|
---|
[528] | 630 | pHandle->file.f_mode = FMODE_WRITE;
|
---|
| 631 | pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
|
---|
[32] | 632 |
|
---|
[528] | 633 | ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
|
---|
| 634 | if(ret) {
|
---|
| 635 | goto failure;
|
---|
| 636 | }
|
---|
| 637 | //retrieve mixer information
|
---|
[644] | 638 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
|
---|
[528] | 639 | SNDRV_CTL_IOCTL_CARD_INFO,
|
---|
| 640 | (ULONG)&pHandle->info);
|
---|
| 641 | if(ret) {
|
---|
| 642 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 643 | goto failure;
|
---|
| 644 | }
|
---|
| 645 | //get the number of mixer elements
|
---|
| 646 | pHandle->list.offset = 0;
|
---|
| 647 | pHandle->list.space = 0;
|
---|
[644] | 648 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
|
---|
[528] | 649 | SNDRV_CTL_IOCTL_ELEM_LIST,
|
---|
| 650 | (ULONG)&pHandle->list);
|
---|
| 651 | if(ret) {
|
---|
| 652 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 653 | goto failure;
|
---|
| 654 | }
|
---|
| 655 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 656 | if(pHandle) {
|
---|
| 657 | if(pHandle->pids) kfree(pHandle->pids);
|
---|
| 658 | kfree(pHandle);
|
---|
| 659 | }
|
---|
| 660 | return pHandle->list.count;
|
---|
[32] | 661 | failure:
|
---|
[528] | 662 | if(pHandle) {
|
---|
| 663 | if(pHandle->pids) kfree(pHandle->pids);
|
---|
| 664 | kfree(pHandle);
|
---|
| 665 | }
|
---|
| 666 | DebugInt3();
|
---|
| 667 | return OSSERR_OUT_OF_MEMORY;
|
---|
[32] | 668 | }
|
---|
| 669 |
|
---|
| 670 | int GetUniaudControls(ULONG deviceid, void *pids)
|
---|
| 671 | {
|
---|
[528] | 672 | mixerhandle *pHandle = NULL;
|
---|
[598] | 673 | int ret, sz;
|
---|
| 674 | //int i, j;
|
---|
[32] | 675 |
|
---|
[549] | 676 | //dprintf(("GetUniaudControls"));
|
---|
[542] | 677 |
|
---|
[528] | 678 | if(alsa_fops == NULL) {
|
---|
| 679 | ret = OSSERR_NO_DEVICE_AVAILABLE;
|
---|
| 680 | goto failure;
|
---|
| 681 | }
|
---|
[32] | 682 |
|
---|
[528] | 683 | sz = sizeof(mixerhandle);
|
---|
| 684 | pHandle = kmalloc(sz, GFP_KERNEL);
|
---|
| 685 | if(pHandle == NULL) {
|
---|
| 686 | ret = OSSERR_OUT_OF_MEMORY;
|
---|
| 687 | goto failure;
|
---|
| 688 | }
|
---|
| 689 | memset(pHandle, 0, sizeof(mixerhandle));
|
---|
[32] | 690 |
|
---|
[528] | 691 | //set operation to non-blocking
|
---|
| 692 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 693 |
|
---|
[528] | 694 | //setup pointers in file structure (used internally by ALSA)
|
---|
| 695 | pHandle->file.f_dentry = &pHandle->d_entry;
|
---|
| 696 | pHandle->file.f_dentry->d_inode = &pHandle->inode;
|
---|
[32] | 697 |
|
---|
[528] | 698 | pHandle->file.f_mode = FMODE_WRITE;
|
---|
| 699 | pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
|
---|
[32] | 700 |
|
---|
[528] | 701 | ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
|
---|
| 702 | if(ret) {
|
---|
| 703 | goto failure;
|
---|
| 704 | }
|
---|
| 705 | //retrieve mixer information
|
---|
[644] | 706 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
|
---|
[528] | 707 | SNDRV_CTL_IOCTL_CARD_INFO,
|
---|
| 708 | (ULONG)&pHandle->info);
|
---|
| 709 | if(ret) {
|
---|
| 710 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 711 | goto failure;
|
---|
| 712 | }
|
---|
| 713 | //get the number of mixer elements
|
---|
| 714 | pHandle->list.offset = 0;
|
---|
| 715 | pHandle->list.space = 0;
|
---|
[644] | 716 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
|
---|
[528] | 717 | SNDRV_CTL_IOCTL_ELEM_LIST,
|
---|
| 718 | (ULONG)&pHandle->list);
|
---|
| 719 | if(ret) {
|
---|
| 720 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 721 | goto failure;
|
---|
| 722 | }
|
---|
[32] | 723 |
|
---|
[528] | 724 | //allocate memory for all mixer elements
|
---|
| 725 | pHandle->pids = (struct snd_ctl_elem_id *)pids;
|
---|
| 726 | //kmalloc(sizeof(struct snd_ctl_elem_id)*pHandle->list.count, GFP_KERNEL);
|
---|
| 727 | if(pHandle->pids == NULL) {
|
---|
| 728 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 729 | goto failure;
|
---|
| 730 | }
|
---|
| 731 | //and retrieve all mixer elements
|
---|
| 732 | pHandle->list.offset = 0;
|
---|
| 733 | pHandle->list.space = pHandle->list.count;
|
---|
| 734 | pHandle->list.pids = pHandle->pids;
|
---|
[644] | 735 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file,
|
---|
[528] | 736 | SNDRV_CTL_IOCTL_ELEM_LIST,
|
---|
| 737 | (ULONG)&pHandle->list);
|
---|
| 738 | if(ret) {
|
---|
| 739 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 740 | goto failure;
|
---|
| 741 | }
|
---|
| 742 | // if (pids)
|
---|
| 743 | // memcpy(pids, pHandle->pids,
|
---|
| 744 | // sizeof(struct snd_ctl_elem_id)*pHandle->list.count);
|
---|
[32] | 745 |
|
---|
[528] | 746 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 747 | if(pHandle) {
|
---|
| 748 | // if(pHandle->pids) kfree(pHandle->pids);
|
---|
| 749 | kfree(pHandle);
|
---|
| 750 | }
|
---|
| 751 | return pHandle->list.count;
|
---|
[32] | 752 | failure:
|
---|
[528] | 753 | if(pHandle) {
|
---|
| 754 | // if(pHandle->pids) kfree(pHandle->pids);
|
---|
| 755 | kfree(pHandle);
|
---|
| 756 | }
|
---|
| 757 | DebugInt3();
|
---|
| 758 | return OSSERR_OUT_OF_MEMORY;
|
---|
[32] | 759 | }
|
---|
| 760 |
|
---|
| 761 | int GetUniaudControlInfo(ULONG deviceid, ULONG id, void *info)
|
---|
| 762 | {
|
---|
[598] | 763 | //struct snd_ctl_elem_value *pElem = NULL;
|
---|
[528] | 764 | struct snd_ctl_elem_info *pElemInfo = NULL;
|
---|
| 765 | mixerhandle *pHandle = NULL;
|
---|
[598] | 766 | int ret, sz;
|
---|
| 767 | //int i, j;
|
---|
[32] | 768 |
|
---|
[549] | 769 | //dprintf(("GetUniaudControlInfo"));
|
---|
[542] | 770 |
|
---|
[528] | 771 | if(alsa_fops == NULL) {
|
---|
| 772 | ret = OSSERR_NO_DEVICE_AVAILABLE;
|
---|
| 773 | goto failure;
|
---|
| 774 | }
|
---|
[32] | 775 |
|
---|
[528] | 776 | sz = sizeof(mixerhandle);
|
---|
| 777 | pHandle = kmalloc(sz, GFP_KERNEL);
|
---|
| 778 | if(pHandle == NULL) {
|
---|
| 779 | ret = OSSERR_OUT_OF_MEMORY;
|
---|
| 780 | goto failure;
|
---|
| 781 | }
|
---|
| 782 | memset(pHandle, 0, sizeof(mixerhandle));
|
---|
[32] | 783 |
|
---|
[528] | 784 | //set operation to non-blocking
|
---|
| 785 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 786 |
|
---|
[528] | 787 | //setup pointers in file structure (used internally by ALSA)
|
---|
| 788 | pHandle->file.f_dentry = &pHandle->d_entry;
|
---|
| 789 | pHandle->file.f_dentry->d_inode = &pHandle->inode;
|
---|
[32] | 790 |
|
---|
[528] | 791 | pHandle->file.f_mode = FMODE_WRITE;
|
---|
| 792 | pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
|
---|
[32] | 793 |
|
---|
[528] | 794 | ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
|
---|
| 795 | if(ret) {
|
---|
| 796 | goto failure;
|
---|
| 797 | }
|
---|
[32] | 798 |
|
---|
[528] | 799 | //allocate memory for info element
|
---|
| 800 | pElemInfo = (struct snd_ctl_elem_info *)info;
|
---|
| 801 | if(pElemInfo == NULL) {
|
---|
| 802 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 803 | goto failure;
|
---|
| 804 | }
|
---|
[32] | 805 |
|
---|
[528] | 806 | // printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info));
|
---|
[32] | 807 |
|
---|
[528] | 808 | pElemInfo->id.numid = id;
|
---|
[644] | 809 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
|
---|
[528] | 810 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 811 | if(pHandle) kfree(pHandle);
|
---|
| 812 | // printk("elem type: %i, id: %i, card: %i\n", pElemInfo->type, pElemInfo->id.numid, deviceid);
|
---|
| 813 | return OSSERR_SUCCESS;
|
---|
[32] | 814 |
|
---|
| 815 | failure:
|
---|
[528] | 816 | if(pHandle) {
|
---|
| 817 | kfree(pHandle);
|
---|
| 818 | }
|
---|
| 819 | DebugInt3();
|
---|
| 820 | return OSSERR_OUT_OF_MEMORY;
|
---|
[32] | 821 | }
|
---|
| 822 |
|
---|
| 823 | int GetUniaudControlValueGet(ULONG deviceid, ULONG id, void *value)
|
---|
| 824 | {
|
---|
[528] | 825 | struct snd_ctl_elem_value *pElem = NULL;
|
---|
[542] | 826 | //struct snd_ctl_elem_info *pElemInfo = NULL;
|
---|
[528] | 827 | mixerhandle *pHandle = NULL;
|
---|
[598] | 828 | int ret, sz;
|
---|
| 829 | //int i, j;
|
---|
[32] | 830 |
|
---|
[528] | 831 | if(alsa_fops == NULL) {
|
---|
| 832 | ret = OSSERR_NO_DEVICE_AVAILABLE;
|
---|
| 833 | goto failure;
|
---|
| 834 | }
|
---|
[32] | 835 |
|
---|
[528] | 836 | sz = sizeof(mixerhandle);
|
---|
| 837 | pHandle = kmalloc(sz, GFP_KERNEL);
|
---|
| 838 | if(pHandle == NULL) {
|
---|
| 839 | ret = OSSERR_OUT_OF_MEMORY;
|
---|
| 840 | goto failure;
|
---|
| 841 | }
|
---|
| 842 | memset(pHandle, 0, sizeof(mixerhandle));
|
---|
[32] | 843 |
|
---|
[528] | 844 | //set operation to non-blocking
|
---|
| 845 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 846 |
|
---|
[528] | 847 | //setup pointers in file structure (used internally by ALSA)
|
---|
| 848 | pHandle->file.f_dentry = &pHandle->d_entry;
|
---|
| 849 | pHandle->file.f_dentry->d_inode = &pHandle->inode;
|
---|
[32] | 850 |
|
---|
[528] | 851 | pHandle->file.f_mode = FMODE_WRITE;
|
---|
| 852 | pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
|
---|
[32] | 853 |
|
---|
[528] | 854 | ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
|
---|
| 855 | if(ret) {
|
---|
| 856 | goto failure;
|
---|
| 857 | }
|
---|
[32] | 858 |
|
---|
[528] | 859 | pElem = (struct snd_ctl_elem_value *)value;
|
---|
| 860 | if(pElem == NULL) {
|
---|
| 861 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 862 | goto failure;
|
---|
| 863 | }
|
---|
[32] | 864 |
|
---|
[528] | 865 | pElem->id.numid = id;
|
---|
| 866 | pElem->indirect = 0;
|
---|
[644] | 867 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_CTL_IOCTL_ELEM_READ, (ULONG)pElem);
|
---|
[528] | 868 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 869 | if(pHandle) kfree(pHandle);
|
---|
[32] | 870 |
|
---|
[549] | 871 | //dprintf(("GetUniaudControlValueGet: id=%x 0=%x 1=%x", pElem->id.numid, pElem->value.integer.value[0], pElem->value.integer.value[1]));
|
---|
[542] | 872 |
|
---|
[528] | 873 | return OSSERR_SUCCESS;
|
---|
[32] | 874 | failure:
|
---|
[528] | 875 | if(pHandle) {
|
---|
| 876 | kfree(pHandle);
|
---|
| 877 | }
|
---|
| 878 | DebugInt3();
|
---|
| 879 | return OSSERR_OUT_OF_MEMORY;
|
---|
[32] | 880 | }
|
---|
| 881 |
|
---|
| 882 | int GetUniaudControlValuePut(ULONG deviceid, ULONG id, void *value)
|
---|
| 883 | {
|
---|
[528] | 884 | struct snd_ctl_elem_value *pElem = NULL;
|
---|
[542] | 885 | //struct snd_ctl_elem_info *pElemInfo = NULL;
|
---|
[528] | 886 | mixerhandle *pHandle = NULL;
|
---|
[598] | 887 | int ret, sz;
|
---|
| 888 | //int i, j;
|
---|
[32] | 889 |
|
---|
[528] | 890 | if(alsa_fops == NULL) {
|
---|
| 891 | ret = OSSERR_NO_DEVICE_AVAILABLE;
|
---|
| 892 | goto failure;
|
---|
| 893 | }
|
---|
[32] | 894 |
|
---|
[528] | 895 | sz = sizeof(mixerhandle);
|
---|
| 896 | pHandle = kmalloc(sz, GFP_KERNEL);
|
---|
| 897 | if(pHandle == NULL) {
|
---|
| 898 | ret = OSSERR_OUT_OF_MEMORY;
|
---|
| 899 | goto failure;
|
---|
| 900 | }
|
---|
| 901 | memset(pHandle, 0, sizeof(mixerhandle));
|
---|
[32] | 902 |
|
---|
[528] | 903 | //set operation to non-blocking
|
---|
| 904 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 905 |
|
---|
[528] | 906 | //setup pointers in file structure (used internally by ALSA)
|
---|
| 907 | pHandle->file.f_dentry = &pHandle->d_entry;
|
---|
| 908 | pHandle->file.f_dentry->d_inode = &pHandle->inode;
|
---|
[32] | 909 |
|
---|
[528] | 910 | pHandle->file.f_mode = FMODE_WRITE;
|
---|
| 911 | pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
|
---|
[32] | 912 |
|
---|
[528] | 913 | ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
|
---|
| 914 | if(ret) {
|
---|
| 915 | goto failure;
|
---|
| 916 | }
|
---|
[32] | 917 |
|
---|
[528] | 918 | pElem = (struct snd_ctl_elem_value *)value;
|
---|
| 919 | if(pElem == NULL) {
|
---|
| 920 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 921 | goto failure;
|
---|
| 922 | }
|
---|
[32] | 923 |
|
---|
[528] | 924 | pElem->id.numid = id;
|
---|
| 925 | pElem->indirect = 0;
|
---|
[542] | 926 |
|
---|
[644] | 927 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
|
---|
[528] | 928 | ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
|
---|
| 929 | if(pHandle) kfree(pHandle);
|
---|
[32] | 930 |
|
---|
[528] | 931 | return OSSERR_SUCCESS;
|
---|
[32] | 932 |
|
---|
| 933 | failure:
|
---|
[528] | 934 | if(pHandle) {
|
---|
| 935 | kfree(pHandle);
|
---|
| 936 | }
|
---|
| 937 | DebugInt3();
|
---|
| 938 | return OSSERR_OUT_OF_MEMORY;
|
---|
[32] | 939 | }
|
---|
| 940 |
|
---|
| 941 | int UniaudIoctlHWRefine(OSSSTREAMID streamid, void *pHwParams)
|
---|
| 942 | {
|
---|
[528] | 943 | int ret;
|
---|
| 944 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
| 945 | struct snd_pcm_hw_params *params = NULL;
|
---|
| 946 | params = (struct snd_pcm_hw_params *)pHwParams;
|
---|
[32] | 947 |
|
---|
[549] | 948 | //dprintf(("UniaudIoctlHWRefine"));
|
---|
[542] | 949 |
|
---|
[528] | 950 | if (!params) return -1001;
|
---|
[32] | 951 |
|
---|
[528] | 952 | if (!pHandle) return -1002;
|
---|
[32] | 953 |
|
---|
[528] | 954 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[644] | 955 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params);
|
---|
[528] | 956 | return ret;
|
---|
[32] | 957 | }
|
---|
| 958 |
|
---|
| 959 | int UniaudIoctlHWParamSet(OSSSTREAMID streamid, void *pHwParams)
|
---|
| 960 | {
|
---|
[528] | 961 | int ret;
|
---|
| 962 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
| 963 | struct snd_pcm_hw_params *params = NULL;
|
---|
| 964 | params = (struct snd_pcm_hw_params *)pHwParams;
|
---|
[32] | 965 |
|
---|
[549] | 966 | //dprintf(("UniaudIoctlHWParamSet"));
|
---|
[542] | 967 |
|
---|
[528] | 968 | if (!params) return -1001;
|
---|
| 969 | if (!pHandle) return -1002;
|
---|
[32] | 970 |
|
---|
[528] | 971 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[644] | 972 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)params);
|
---|
[528] | 973 | return ret;
|
---|
[32] | 974 | }
|
---|
| 975 |
|
---|
| 976 | int UniaudIoctlSWParamSet(OSSSTREAMID streamid, void *pSwParams)
|
---|
| 977 | {
|
---|
[528] | 978 | int ret;
|
---|
| 979 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
| 980 | struct snd_pcm_sw_params *params = NULL;
|
---|
[542] | 981 |
|
---|
[528] | 982 | params = (struct snd_pcm_sw_params *)pSwParams;
|
---|
[32] | 983 |
|
---|
[549] | 984 | //dprintf(("UniaudIoctlSWParamSet"));
|
---|
[542] | 985 |
|
---|
[528] | 986 | if (!params) return -1001;
|
---|
| 987 | if (!pHandle) return -1002;
|
---|
[32] | 988 |
|
---|
[528] | 989 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 990 |
|
---|
[644] | 991 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)params);
|
---|
[528] | 992 | return ret;
|
---|
[32] | 993 | }
|
---|
| 994 |
|
---|
| 995 | int UniaudIoctlPCMStatus(OSSSTREAMID streamid, void *pstatus)
|
---|
| 996 | {
|
---|
[528] | 997 | int ret;
|
---|
| 998 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
| 999 | struct snd_pcm_status *status = (struct snd_pcm_status *)pstatus;
|
---|
[32] | 1000 |
|
---|
[549] | 1001 | //dprintf(("UniaudIoctlPCMStatus"));
|
---|
[542] | 1002 |
|
---|
[528] | 1003 | if (!status) return -1001;
|
---|
| 1004 | if (!pHandle) return -1002;
|
---|
[32] | 1005 |
|
---|
[528] | 1006 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 1007 |
|
---|
[644] | 1008 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)status);
|
---|
[528] | 1009 | return ret;
|
---|
[32] | 1010 | }
|
---|
| 1011 |
|
---|
| 1012 | int UniaudIoctlPCMWrite(OSSSTREAMID streamid, char *buf, int size)
|
---|
| 1013 | {
|
---|
[528] | 1014 | int ret;
|
---|
| 1015 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
[32] | 1016 |
|
---|
[549] | 1017 | //dprintf(("UniaudIoctlPCMWrite"));
|
---|
[542] | 1018 |
|
---|
[528] | 1019 | if (!buf) return -1001;
|
---|
| 1020 | if (!pHandle) return -1002;
|
---|
[32] | 1021 |
|
---|
[528] | 1022 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 1023 |
|
---|
[528] | 1024 | ret = pHandle->file.f_op->write(&pHandle->file, buf, size, &pHandle->file.f_pos);
|
---|
[32] | 1025 |
|
---|
[528] | 1026 | return ret;
|
---|
[32] | 1027 | }
|
---|
| 1028 |
|
---|
| 1029 | int UniaudIoctlPCMRead(OSSSTREAMID streamid, char *buf, int size)
|
---|
| 1030 | {
|
---|
[528] | 1031 | int ret;
|
---|
| 1032 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
[32] | 1033 |
|
---|
[528] | 1034 | if (!buf) return -1001;
|
---|
| 1035 | if (!pHandle) return -1002;
|
---|
[32] | 1036 |
|
---|
[549] | 1037 | //dprintf(("UniaudIoctlPCMRead"));
|
---|
[542] | 1038 |
|
---|
[528] | 1039 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 1040 |
|
---|
[528] | 1041 | ret = pHandle->file.f_op->read(&pHandle->file, buf, size, &pHandle->file.f_pos);
|
---|
[32] | 1042 |
|
---|
[528] | 1043 | return ret;
|
---|
[32] | 1044 | }
|
---|
| 1045 |
|
---|
| 1046 | int UniaudIoctlPCMPrepare(OSSSTREAMID streamid)
|
---|
| 1047 | {
|
---|
[528] | 1048 | int ret;
|
---|
| 1049 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
[32] | 1050 |
|
---|
[549] | 1051 | //dprintf(("UniaudIoctlPCMPrepare"));
|
---|
[542] | 1052 |
|
---|
[528] | 1053 | if (!pHandle) return -1002;
|
---|
[32] | 1054 |
|
---|
[528] | 1055 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 1056 |
|
---|
[644] | 1057 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0);
|
---|
[528] | 1058 | return ret;
|
---|
[32] | 1059 | }
|
---|
| 1060 |
|
---|
| 1061 | int UniaudIoctlPCMResume(OSSSTREAMID streamid, int pause)
|
---|
| 1062 | {
|
---|
[528] | 1063 | int ret;
|
---|
| 1064 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
[32] | 1065 |
|
---|
[549] | 1066 | //dprintf(("UniaudIoctlPCMResume: %x", pause));
|
---|
[542] | 1067 |
|
---|
[528] | 1068 | if (!pHandle) return -1002;
|
---|
[32] | 1069 |
|
---|
[528] | 1070 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 1071 |
|
---|
[644] | 1072 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_PAUSE, pause);
|
---|
[32] | 1073 |
|
---|
[528] | 1074 | return ret;
|
---|
[32] | 1075 | }
|
---|
| 1076 |
|
---|
| 1077 | int UniaudIoctlPCMStart(OSSSTREAMID streamid)
|
---|
| 1078 | {
|
---|
[528] | 1079 | int ret;
|
---|
| 1080 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
[32] | 1081 |
|
---|
[549] | 1082 | //dprintf(("UniaudIoctlPCMStart"));
|
---|
[542] | 1083 |
|
---|
[528] | 1084 | if (!pHandle) return -1002;
|
---|
[32] | 1085 |
|
---|
[528] | 1086 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 1087 |
|
---|
[644] | 1088 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_START, 0);
|
---|
[32] | 1089 |
|
---|
[528] | 1090 | return ret;
|
---|
[32] | 1091 | }
|
---|
| 1092 |
|
---|
| 1093 | int UniaudIoctlPCMDrop(OSSSTREAMID streamid)
|
---|
| 1094 | {
|
---|
[528] | 1095 | int ret;
|
---|
| 1096 | soundhandle *pHandle = (soundhandle *)streamid;
|
---|
[32] | 1097 |
|
---|
[549] | 1098 | //dprintf(("UniaudIoctlPCMDrop"));
|
---|
[542] | 1099 |
|
---|
[528] | 1100 | if (!pHandle) return -1002;
|
---|
[32] | 1101 |
|
---|
[528] | 1102 | pHandle->file.f_flags = O_NONBLOCK;
|
---|
[32] | 1103 |
|
---|
[644] | 1104 | ret = pHandle->file.f_op->unlocked_ioctl(&pHandle->file, SNDRV_PCM_IOCTL_DROP, 0);
|
---|
[32] | 1105 |
|
---|
[528] | 1106 | return ret;
|
---|
[32] | 1107 | }
|
---|
| 1108 |
|
---|
| 1109 | void UniaudCloseAll(USHORT fileid)
|
---|
| 1110 | {
|
---|
[528] | 1111 | int i;
|
---|
[32] | 1112 |
|
---|
[528] | 1113 | for (i=0; i < 8*256; i++)
|
---|
| 1114 | {
|
---|
| 1115 | if (opened_handles[i].handle != 0)
|
---|
| 1116 | {
|
---|
| 1117 | if (fileid)
|
---|
| 1118 | {
|
---|
| 1119 | if (fileid == opened_handles[i].FileId)
|
---|
| 1120 | {
|
---|
| 1121 | opened_handles[i].reuse = 0;
|
---|
| 1122 | if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
|
---|
| 1123 | opened_handles[i].handle = 0;
|
---|
| 1124 | }
|
---|
| 1125 | }
|
---|
| 1126 | else
|
---|
| 1127 | {
|
---|
| 1128 | opened_handles[i].reuse = 0;
|
---|
| 1129 | if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0)
|
---|
| 1130 | opened_handles[i].handle = 0;
|
---|
| 1131 | }
|
---|
| 1132 | }
|
---|
| 1133 | }
|
---|
| 1134 | return;
|
---|
[32] | 1135 | }
|
---|