Changeset 528 for GPL/trunk/lib32/soundmixer.c
- Timestamp:
- Jul 25, 2010, 7:16:22 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/lib32/soundmixer.c
r518 r528 41 41 42 42 static struct { 43 44 45 43 char *name; 44 unsigned int index; 45 unsigned int recsrc; 46 46 } ossid[OSS_MIXER_NRDEVICES] = { 47 47 /* OSS_MIXER_VOLUME */ { "Master", 0 , -1}, 48 /* OSS_MIXER_BASS 48 /* OSS_MIXER_BASS */ { "Tone Control - Bass", 0, -1}, 49 49 /* OSS_MIXER_TREBLE */ { "Tone Control - Treble", 0, -1}, 50 /* OSS_MIXER_SYNTH 51 /* OSS_MIXER_PCM 52 /* OSS_MIXER_PCSPEAKER 53 /* OSS_MIXER_LINE 54 /* OSS_MIXER_MIC 55 /* OSS_MIXER_CD 56 /* OSS_MIXER_IMIX 50 /* OSS_MIXER_SYNTH */ { "Synth", 0 , OSS32_MIX_RECSRC_SYNTH}, 51 /* OSS_MIXER_PCM */ { "PCM", 0 , -1}, 52 /* OSS_MIXER_PCSPEAKER */ { "PC Speaker", 0 , -1}, 53 /* OSS_MIXER_LINE */ { "Line", 0 , OSS32_MIX_RECSRC_LINE}, 54 /* OSS_MIXER_MIC */ { "Mic", 0, OSS32_MIX_RECSRC_MIC}, 55 /* OSS_MIXER_CD */ { "CD", 0 , OSS32_MIX_RECSRC_CD}, 56 /* OSS_MIXER_IMIX */ { "Monitor Mix", 0 , OSS32_MIX_RECSRC_MIXER}, 57 57 /* OSS_MIXER_ALTPCM */ { "PCM", 1 , -1}, 58 58 /* OSS_MIXER_RECLEV */ { "-- nothing --", 0 , -1}, 59 /* OSS_MIXER_IGAIN 60 /* OSS_MIXER_OGAIN 61 /* OSS_MIXER_LINE1 62 /* OSS_MIXER_LINE2 63 /* OSS_MIXER_LINE3 59 /* OSS_MIXER_IGAIN */ { "Capture", 0 , -1}, 60 /* OSS_MIXER_OGAIN */ { "Playback", 0 , -1}, 61 /* OSS_MIXER_LINE1 */ { "Aux", 0 , OSS32_MIX_RECSRC_AUX}, 62 /* OSS_MIXER_LINE2 */ { "Aux", 1 , -1}, 63 /* OSS_MIXER_LINE3 */ { "Aux", 2 , -1}, 64 64 /* OSS_MIXER_DIGITAL1 */ { "Digital", 0 , -1}, 65 65 /* OSS_MIXER_DIGITAL2 */ { "Digital", 1 , -1}, … … 67 67 /* OSS_MIXER_PHONEIN */ { "Phone", 0 , OSS32_MIX_RECSRC_PHONE}, 68 68 /* OSS_MIXER_PHONEOUT */ { "Phone", 1 , -1}, 69 /* OSS_MIXER_VIDEO 70 /* OSS_MIXER_RADIO 69 /* OSS_MIXER_VIDEO */ { "Video", 0 , OSS32_MIX_RECSRC_VIDEO}, 70 /* OSS_MIXER_RADIO */ { "Radio", 0 , -1}, 71 71 /* OSS_MIXER_MONITOR */ { "Monitor", 0 , -1}, 72 72 /* OSS_MIXER_3DDEPTH */ { "3D Control - Depth", 0 , -1}, 73 74 /* OSS_MIXER_FRONT 73 /* OSS_MIXER_3DCENTER */ { "3D Control - Center", 0 , -1}, 74 /* OSS_MIXER_FRONT */ { "Front", 0 , -1}, 75 75 /* OSS_MIXER_SPEAKER */ { "Speaker", 0 , -1}, 76 76 /* OSS_MIXER_HEADPHONE */ { "Headphone", 0 , -1}, 77 77 }; 78 78 char *szRecSources[OSS32_MIX_RECSRC_MAX] = { 79 79 "Mic", "CD", "Line", "Video", "Aux", "Mix", "Mix Mono", "Phone", "Synth" 80 80 }; 81 81 82 82 static unsigned char LinToLog[OSS32_MAX_VOLUME+1] = { 83 0, 0, 0, 0, 1, 2, 2,5, 5, 10,84 10, 10, 16, 19, 20, 22, 24,25, 27, 27,85 28, 28, 29, 30, 30, 35, 35,35, 39, 39,86 43, 44, 45, 47, 48, 49, 50,51, 52, 53,87 55, 56, 57, 59, 60, 62, 63,64, 65, 66,88 67, 68, 69, 70, 71, 72, 73,74, 74, 75,89 76, 77, 78, 79, 79, 80, 81,82, 83, 84,90 85, 86, 87, 88, 89, 90, 91,92, 92, 93,91 93, 94, 94, 95, 95, 96, 96,97, 97, 98,92 98, 99, 99, 83 0, 0, 0, 0, 1, 2, 2, 5, 5, 10, 84 10, 10, 16, 19, 20, 22, 24, 25, 27, 27, 85 28, 28, 29, 30, 30, 35, 35, 35, 39, 39, 86 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 87 55, 56, 57, 59, 60, 62, 63, 64, 65, 66, 88 67, 68, 69, 70, 71, 72, 73, 74, 74, 75, 89 76, 77, 78, 79, 79, 80, 81, 82, 83, 84, 90 85, 86, 87, 88, 89, 90, 91, 92, 92, 93, 91 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 92 98, 99, 99, 99, 99, 100, 100, 100, 100, 100, 93 93 100 94 94 }; … … 99 99 ULONG ConvertVolume(ULONG ulLinVolume, ULONG ulLogVolMax) 100 100 { 101 102 103 104 105 106 101 if(ulLinVolume > OSS32_MAX_VOLUME) { 102 ulLinVolume = OSS32_MAX_VOLUME; 103 } 104 ulLinVolume = LinToLog[ulLinVolume]; 105 106 return (ulLinVolume * ulLogVolMax) / OSS32_MAX_VOLUME; 107 107 } 108 108 … … 111 111 OSSRET OSS32_MixOpen(ULONG deviceid, OSSSTREAMID *pStreamId) 112 112 { 113 114 intret, i, j, sz;115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 pHandle->file.f_dentry= &pHandle->d_entry;140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 pHandle->list.pids= pHandle->pids;174 175 176 177 178 179 113 mixerhandle *pHandle = NULL; 114 int ret, i, j, sz; 115 116 if(pStreamId == NULL) { 117 DebugInt3(); 118 return OSSERR_INVALID_PARAMETER; 119 } 120 *pStreamId = 0; 121 122 if(alsa_fops == NULL) { 123 ret = OSSERR_NO_DEVICE_AVAILABLE; 124 goto failure; 125 } 126 127 sz = sizeof(mixerhandle); 128 pHandle = kmalloc(sz, GFP_KERNEL); 129 if(pHandle == NULL) { 130 ret = OSSERR_OUT_OF_MEMORY; 131 goto failure; 132 } 133 memset(pHandle, 0, sizeof(mixerhandle)); 134 135 //set operation to non-blocking 136 pHandle->file.f_flags = O_NONBLOCK; 137 138 //setup pointers in file structure (used internally by ALSA) 139 pHandle->file.f_dentry = &pHandle->d_entry; 140 pHandle->file.f_dentry->d_inode = &pHandle->inode; 141 142 pHandle->file.f_mode = FMODE_WRITE; 143 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 144 145 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 146 if(ret) { 147 goto failure; 148 } 149 //retrieve mixer information 150 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 151 SNDRV_CTL_IOCTL_CARD_INFO, 152 (ULONG)&pHandle->info); 153 if(ret) { 154 goto failure; 155 } 156 //get the number of mixer elements 157 pHandle->list.offset = 0; 158 pHandle->list.space = 0; 159 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 160 SNDRV_CTL_IOCTL_ELEM_LIST, 161 (ULONG)&pHandle->list); 162 if(ret) { 163 goto failure; 164 } 165 //allocate memory for all mixer elements 166 pHandle->pids = (struct snd_ctl_elem_id *)kmalloc(sizeof(struct snd_ctl_elem_id)*pHandle->list.count, GFP_KERNEL); 167 if(pHandle->pids == NULL) { 168 goto failure; 169 } 170 //and retrieve all mixer elements 171 pHandle->list.offset = 0; 172 pHandle->list.space = pHandle->list.count; 173 pHandle->list.pids = pHandle->pids; 174 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 175 SNDRV_CTL_IOCTL_ELEM_LIST, 176 (ULONG)&pHandle->list); 177 if(ret) { 178 goto failure; 179 } 180 180 181 181 #if 0 182 183 184 185 186 182 dprintf(("Mixer name: %s", pHandle->info.mixername)); 183 dprintf(("List of mixer elements:")); 184 for(i=0;i<pHandle->list.count;i++) { 185 dprintf(("index %d name %s id %d device %d subdevice %d", pHandle->pids[i].index, pHandle->pids[i].name, pHandle->pids[i].numid, pHandle->pids[i].device, pHandle->pids[i].subdevice)); 186 } 187 187 #endif 188 188 189 //Extract standard mixer controls from array with control names 190 for(j=0;j<OSS_MIXER_NRDEVICES;j++) 191 { 192 int namelen = strlen(ossid[j].name); 193 194 pHandle->controls[j].idxVolume = -1; 195 pHandle->controls[j].idxMute = -1; 196 pHandle->controls[j].idxCustom = -1; 197 pHandle->controls[j].idxCaptureSwitch = -1; 198 199 for(i=0;i<pHandle->list.count;i++) 200 { 201 if (pHandle->pids[i].index == ossid[j].index && 202 strncmp(pHandle->pids[i].name, ossid[j].name, namelen) == 0) 203 { 204 int controlnamelen = strlen(pHandle->pids[i].name); 205 206 if(namelen == controlnamelen) 207 {//control names are identical; found exact match 208 pHandle->controls[j].idxVolume = i; 209 break; 210 } 211 else 212 {//first part of the control name is correct; now find out what 213 //is it exactly 214 char *nextword = &pHandle->pids[i].name[namelen]; 215 while(*nextword && *nextword == ' ') nextword++; 216 217 if(strncmp(nextword, MIXER_PLAYBACKVOLUME, sizeof(MIXER_PLAYBACKVOLUME)-1) == 0 || 218 strncmp(nextword, MIXER_VOLUME, sizeof(MIXER_VOLUME)-1) == 0) 219 {//volume control 220 pHandle->controls[j].idxVolume = i; 221 } 222 else 223 if(strncmp(nextword, MIXER_PLAYBACKSWITCH, sizeof(MIXER_PLAYBACKSWITCH)-1) == 0 || 224 strncmp(nextword, MIXER_SWITCH, sizeof(MIXER_SWITCH)-1) == 0) 225 {//mute control 226 pHandle->controls[j].idxMute = i; 227 if (pHandle->controls[j].idxVolume == -1) 228 pHandle->controls[j].idxVolume = i; 229 } 230 else 231 if(strncmp(nextword, MIXER_SOURCE, sizeof(MIXER_SOURCE)-1) == 0) 232 {//source control (e.g. recording source) 233 pHandle->controls[j].idxCustom = i; 234 } 235 else 236 if(strncmp(nextword, MIXER_CAPTUREROUTE, sizeof(MIXER_CAPTUREROUTE)-1) == 0 || 237 strncmp(nextword, MIXER_CAPTURESWITCH, sizeof(MIXER_CAPTURESWITCH)-1) == 0) 238 {//source control for recording (per input) 239 pHandle->controls[j].idxCaptureSwitch = i; 240 } 241 else 242 if(i == OSS_MIXER_MIC) { 243 if(strncmp(nextword, MIXER_BOOST, sizeof(MIXER_BOOST)-1) == 0) 244 {//mic boost switch 245 pHandle->controls[j].idxCustom = i; 246 } 247 } 248 } 249 } 250 } 251 } 252 253 pHandle->reccaps = 0; 254 for(j=0;j<OSS32_MIX_RECSRC_MAX;j++) { 255 pHandle->idxRecCaps[j] = -1; 256 } 257 258 //request information about available capture sources 259 if(pHandle->controls[OSS_MIXER_IGAIN].idxCustom != -1) 260 { 261 struct snd_ctl_elem_info *pElemInfo = NULL; 262 int idx, j; 263 264 idx = pHandle->controls[OSS_MIXER_IGAIN].idxCustom; 265 266 //set operation to non-blocking 267 pHandle->file.f_flags = O_NONBLOCK; 268 269 pHandle->rectype = RECTYPE_SELECTOR; 270 271 //too big to put on the stack 272 pElemInfo = (struct snd_ctl_elem_info *)kmalloc(sizeof(struct snd_ctl_elem_info), GFP_KERNEL); 273 if(pElemInfo == NULL) { 274 DebugInt3(); 275 goto failure; 276 } 277 278 pElemInfo->value.enumerated.items = 1; 279 for(i=0;i<pElemInfo->value.enumerated.items;i++) 280 { 281 pElemInfo->value.enumerated.item = i; 282 pElemInfo->id.numid = pHandle->pids[idx].numid; 283 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo); 284 if(ret) { 285 DebugInt3(); 286 break; 287 } 288 if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) { 289 DebugInt3(); 290 break; 291 } 292 for(j=0;j<OSS32_MIX_RECSRC_MAX;j++) { 293 if(!strcmp(pElemInfo->value.enumerated.name, szRecSources[j])) { 294 pHandle->reccaps |= OSS32_MIX_FLAG(j); 295 pHandle->idxRecCaps[j] = i; //save alsa index 296 break; 297 } 298 } 299 } 300 kfree(pElemInfo); 301 } 302 else 303 {//This card has no record source selection, but probably route switches for 304 //each input source (SB mixers (also ALS4000), CMedia) 305 pHandle->rectype = RECTYPE_SWITCH; 306 for(j=0;j<OSS32_MIX_RECSRC_MAX;j++) { 307 pHandle->idxRecCaps[j] = -1; 308 } 309 for(j=0;j<OSS_MIXER_NRDEVICES;j++) 310 { 311 if(pHandle->controls[j].idxCaptureSwitch != -1) { 312 pHandle->reccaps |= OSS32_MIX_FLAG(ossid[j].recsrc); 313 pHandle->idxRecCaps[ossid[j].recsrc] = pHandle->controls[j].idxCaptureSwitch; //save alsa index 314 } 315 } 316 } 317 318 pHandle->magic = MAGIC_MIXER_ALSA32; 319 *pStreamId = (ULONG)pHandle; 320 return OSSERR_SUCCESS; 189 //Extract standard mixer controls from array with control names 190 for(j=0;j<OSS_MIXER_NRDEVICES;j++) 191 { 192 int namelen = strlen(ossid[j].name); 193 194 pHandle->controls[j].idxVolume = -1; 195 pHandle->controls[j].idxMute = -1; 196 pHandle->controls[j].idxCustom = -1; 197 pHandle->controls[j].idxCaptureSwitch = -1; 198 199 for(i=0;i<pHandle->list.count;i++) { 200 if (pHandle->pids[i].index == ossid[j].index && strncmp(pHandle->pids[i].name, ossid[j].name, namelen) == 0) { 201 int controlnamelen = strlen(pHandle->pids[i].name); 202 203 if(namelen == controlnamelen) { //control names are identical; found exact match 204 pHandle->controls[j].idxVolume = i; 205 break; 206 } else { //first part of the control name is correct; now find out what is it exactly 207 char *nextword = &pHandle->pids[i].name[namelen]; 208 while(*nextword && *nextword == ' ') nextword++; 209 210 if(strncmp(nextword, MIXER_PLAYBACKVOLUME, sizeof(MIXER_PLAYBACKVOLUME)-1) == 0 || 211 strncmp(nextword, MIXER_VOLUME, sizeof(MIXER_VOLUME)-1) == 0) 212 { //volume control 213 pHandle->controls[j].idxVolume = i; 214 } 215 else 216 if(strncmp(nextword, MIXER_PLAYBACKSWITCH, sizeof(MIXER_PLAYBACKSWITCH)-1) == 0 || 217 strncmp(nextword, MIXER_SWITCH, sizeof(MIXER_SWITCH)-1) == 0) 218 { //mute control 219 pHandle->controls[j].idxMute = i; 220 if (pHandle->controls[j].idxVolume == -1) pHandle->controls[j].idxVolume = i; 221 } 222 else 223 if(strncmp(nextword, MIXER_SOURCE, sizeof(MIXER_SOURCE)-1) == 0) 224 { //source control (e.g. recording source) 225 pHandle->controls[j].idxCustom = i; 226 } 227 else 228 if(strncmp(nextword, MIXER_CAPTUREROUTE, sizeof(MIXER_CAPTUREROUTE)-1) == 0 || 229 strncmp(nextword, MIXER_CAPTURESWITCH, sizeof(MIXER_CAPTURESWITCH)-1) == 0) 230 { //source control for recording (per input) 231 pHandle->controls[j].idxCaptureSwitch = i; 232 } 233 else 234 if(i == OSS_MIXER_MIC) { 235 if(strncmp(nextword, MIXER_BOOST, sizeof(MIXER_BOOST)-1) == 0) { //mic boost switch 236 pHandle->controls[j].idxCustom = i; 237 } 238 } 239 } 240 } 241 } 242 } 243 244 pHandle->reccaps = 0; 245 for (j=0;j<OSS32_MIX_RECSRC_MAX;j++) { 246 pHandle->idxRecCaps[j] = -1; 247 } 248 249 //request information about available capture sources 250 if (pHandle->controls[OSS_MIXER_IGAIN].idxCustom != -1) { 251 struct snd_ctl_elem_info *pElemInfo = NULL; 252 int idx, j; 253 254 idx = pHandle->controls[OSS_MIXER_IGAIN].idxCustom; 255 256 //set operation to non-blocking 257 pHandle->file.f_flags = O_NONBLOCK; 258 259 pHandle->rectype = RECTYPE_SELECTOR; 260 261 //too big to put on the stack 262 pElemInfo = (struct snd_ctl_elem_info *)kmalloc(sizeof(struct snd_ctl_elem_info), GFP_KERNEL); 263 if(pElemInfo == NULL) { 264 DebugInt3(); 265 goto failure; 266 } 267 268 pElemInfo->value.enumerated.items = 1; 269 for(i=0;i<pElemInfo->value.enumerated.items;i++) 270 { 271 pElemInfo->value.enumerated.item = i; 272 pElemInfo->id.numid = pHandle->pids[idx].numid; 273 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo); 274 if(ret) { 275 DebugInt3(); 276 break; 277 } 278 if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) { 279 DebugInt3(); 280 break; 281 } 282 for(j=0;j<OSS32_MIX_RECSRC_MAX;j++) { 283 if(!strcmp(pElemInfo->value.enumerated.name, szRecSources[j])) { 284 pHandle->reccaps |= OSS32_MIX_FLAG(j); 285 pHandle->idxRecCaps[j] = i; //save alsa index 286 break; 287 } 288 } 289 } 290 kfree(pElemInfo); 291 } 292 else 293 {//This card has no record source selection, but probably route switches for 294 //each input source (SB mixers (also ALS4000), CMedia) 295 pHandle->rectype = RECTYPE_SWITCH; 296 for(j=0;j<OSS32_MIX_RECSRC_MAX;j++) { 297 pHandle->idxRecCaps[j] = -1; 298 } 299 for(j=0;j<OSS_MIXER_NRDEVICES;j++) 300 { 301 if(pHandle->controls[j].idxCaptureSwitch != -1) { 302 pHandle->reccaps |= OSS32_MIX_FLAG(ossid[j].recsrc); 303 pHandle->idxRecCaps[ossid[j].recsrc] = pHandle->controls[j].idxCaptureSwitch; //save alsa index 304 } 305 } 306 } 307 308 pHandle->magic = MAGIC_MIXER_ALSA32; 309 *pStreamId = (ULONG)pHandle; 310 return OSSERR_SUCCESS; 321 311 322 312 failure: 323 324 325 326 327 328 313 if(pHandle) { 314 if(pHandle->pids) kfree(pHandle->pids); 315 kfree(pHandle); 316 } 317 DebugInt3(); 318 return OSSERR_OUT_OF_MEMORY; 329 319 } 330 320 //****************************************************************************** … … 332 322 OSSRET OSS32_MixClose(OSSSTREAMID streamid) 333 323 { 334 335 intret;336 337 338 339 340 341 342 343 344 345 kfree(pHandle);//free handle data346 347 348 349 350 351 324 mixerhandle *pHandle = (mixerhandle *)streamid; 325 int ret; 326 327 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) { 328 DebugInt3(); 329 return OSSERR_INVALID_STREAMID; 330 } 331 //set operation to non-blocking 332 pHandle->file.f_flags = O_NONBLOCK; 333 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 334 kfree(pHandle->pids); //free mixer element array 335 kfree(pHandle); //free handle data 336 337 if(ret) { 338 DebugInt3(); 339 return UNIXToOSSError(ret); 340 } 341 return OSSERR_SUCCESS; 352 342 } 353 343 //****************************************************************************** … … 355 345 OSSRET OSS32_MixGetVolume(OSSSTREAMID streamid, ULONG line, ULONG *pVolume) 356 346 { 357 358 intret;359 360 361 362 363 364 365 366 367 347 mixerhandle *pHandle = (mixerhandle *)streamid; 348 int ret; 349 350 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) { 351 DebugInt3(); 352 return OSSERR_INVALID_STREAMID; 353 } 354 //set operation to non-blocking 355 pHandle->file.f_flags = O_NONBLOCK; 356 357 return OSSERR_NOT_SUPPORTED; 368 358 } 369 359 //****************************************************************************** … … 371 361 OSSRET OSS32_MixSetVolume(OSSSTREAMID streamid, ULONG line, ULONG volume) 372 362 { 373 mixerhandle*pHandle = (mixerhandle *)streamid;374 375 376 intret, idx, lVol, rVol = 0, idxMute, cnt;377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 363 mixerhandle *pHandle = (mixerhandle *)streamid; 364 struct snd_ctl_elem_value *pElem = NULL; 365 struct snd_ctl_elem_info *pElemInfo; 366 int ret, idx, lVol, rVol = 0, idxMute, cnt; 367 368 //dprintf(("OSS32_MixSetVolume line=%d\n", line)); 369 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) { 370 printk("Invalid handle in OSS32_MixSetVolume\n"); 371 DebugInt3(); 372 return OSSERR_INVALID_STREAMID; 373 } 374 //set operation to non-blocking 375 pHandle->file.f_flags = O_NONBLOCK; 376 377 //too big to put on the stack 378 pElem = (struct snd_ctl_elem_value *)kmalloc(sizeof(struct snd_ctl_elem_value) + sizeof(struct snd_ctl_elem_info), GFP_KERNEL); 379 if(pElem == NULL) { 380 printk("Out of memory in OSS32_MixSetVolume\n"); 381 DebugInt3(); 382 return OSSERR_OUT_OF_MEMORY; 383 } 384 pElemInfo = (struct snd_ctl_elem_info *)(pElem+1); 385 386 switch(line) { 387 case OSS32_MIX_VOLUME_MASTER_FRONT: 388 idx = pHandle->controls[OSS_MIXER_VOLUME].idxVolume; 389 idxMute = pHandle->controls[OSS_MIXER_VOLUME].idxMute; 390 if (idx == -1) 391 { 392 /* HDA codecs workaround */ 393 idx = pHandle->controls[OSS_MIXER_FRONT].idxVolume; 394 idxMute = pHandle->controls[OSS_MIXER_FRONT].idxMute; 395 } 396 break; 397 case OSS32_MIX_VOLUME_MASTER_REAR: //TODO: 398 idx = pHandle->controls[OSS_MIXER_VOLUME].idxVolume; 399 idxMute = pHandle->controls[OSS_MIXER_VOLUME].idxMute; 400 break; 401 case OSS32_MIX_VOLUME_PCM: 402 idx = pHandle->controls[OSS_MIXER_PCM].idxVolume; 403 idxMute = pHandle->controls[OSS_MIXER_PCM].idxMute; 404 if (idx == -1) 405 { 406 /* HDA codecs workaround */ 407 idx = pHandle->controls[OSS_MIXER_FRONT].idxVolume; 408 idxMute = pHandle->controls[OSS_MIXER_FRONT].idxMute; 409 } 410 break; 411 case OSS32_MIX_VOLUME_MIDI: 412 idx = pHandle->controls[OSS_MIXER_SYNTH].idxVolume; 413 idxMute = pHandle->controls[OSS_MIXER_SYNTH].idxMute; 414 break; 415 case OSS32_MIX_VOLUME_LINEIN: 416 idx = pHandle->controls[OSS_MIXER_LINE].idxVolume; 417 idxMute = pHandle->controls[OSS_MIXER_LINE].idxMute; 418 break; 419 case OSS32_MIX_VOLUME_MIC: 420 idx = pHandle->controls[OSS_MIXER_MIC].idxVolume; 421 idxMute = pHandle->controls[OSS_MIXER_MIC].idxMute; 422 break; 423 case OSS32_MIX_VOLUME_CD: 424 idx = pHandle->controls[OSS_MIXER_CD].idxVolume; 425 idxMute = pHandle->controls[OSS_MIXER_CD].idxMute; 426 break; 427 case OSS32_MIX_VOLUME_SPDIF: 428 idx = pHandle->controls[OSS_MIXER_DIGITAL1].idxVolume; 429 idxMute = pHandle->controls[OSS_MIXER_DIGITAL1].idxMute; 430 break; 431 case OSS32_MIX_VOLUME_VIDEO: 432 idx = pHandle->controls[OSS_MIXER_VIDEO].idxVolume; 433 idxMute = pHandle->controls[OSS_MIXER_VIDEO].idxMute; 434 break; 435 case OSS32_MIX_VOLUME_PCSPEAKER: 436 idx = pHandle->controls[OSS_MIXER_PCSPEAKER].idxVolume; 437 idxMute = pHandle->controls[OSS_MIXER_PCSPEAKER].idxMute; 438 break; 439 case OSS32_MIX_VOLUME_PHONE: 440 idx = pHandle->controls[OSS_MIXER_PHONEOUT].idxVolume; 441 idxMute = pHandle->controls[OSS_MIXER_PHONEOUT].idxMute; 442 break; 443 case OSS32_MIX_VOLUME_HEADPHONE: 444 idx = pHandle->controls[OSS_MIXER_HEADPHONE].idxVolume; 445 idxMute = pHandle->controls[OSS_MIXER_HEADPHONE].idxMute; 446 break; 447 case OSS32_MIX_VOLUME_SPEAKER: 448 idx = pHandle->controls[OSS_MIXER_SPEAKER].idxVolume; 449 idxMute = pHandle->controls[OSS_MIXER_SPEAKER].idxMute; 450 break; 451 case OSS32_MIX_VOLUME_AUX: 452 idx = pHandle->controls[OSS_MIXER_LINE1].idxVolume; 453 idxMute = pHandle->controls[OSS_MIXER_LINE1].idxMute; 454 break; 455 case OSS32_MIX_VOLUME_CAPTURE: 456 idx = pHandle->controls[OSS_MIXER_IGAIN].idxVolume; 457 idxMute = pHandle->controls[OSS_MIXER_IGAIN].idxMute; 458 break; 459 460 default: 461 DebugInt3(); 462 ret = OSSERR_INVALID_PARAMETER; 463 goto fail; 464 } 465 if(idx == -1) { 466 rprintf(("Unknown control %d", line)); 467 ret = OSSERR_INVALID_PARAMETER; 468 goto fail; 469 } 470 471 if(idxMute != -1 && volume != 0) { 472 //disable mute 473 pElem->id.numid = pHandle->pids[idxMute].numid; 474 pElem->indirect = 0; 475 476 pElem->value.integer.value[0] = TRUE; //switch, not mute control (inversed) 477 pElem->value.integer.value[1] = TRUE; 478 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem); 479 } 480 //request information about mixer control 481 pElemInfo->id.numid = pHandle->pids[idx].numid; 482 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo); 483 if(ret) { 484 ret = UNIXToOSSError(ret); 485 DebugInt3(); 486 goto fail; 487 } 488 if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_INTEGER) { 489 ret = OSSERR_INVALID_PARAMETER; 490 DebugInt3(); 491 goto fail; 492 } 493 pElem->id.numid = pHandle->pids[idx].numid; 494 pElem->indirect = 0; 495 496 lVol = ConvertVolume(GET_VOLUME_L(volume), pElemInfo->value.integer.max); 497 pElem->value.integer.value[0] = lVol; 498 499 if(pElemInfo->count > 1) { //stereo 500 rVol = ConvertVolume(GET_VOLUME_R(volume), pElemInfo->value.integer.max); 501 pElem->value.integer.value[1] = rVol; 502 } 513 503 514 504 dprintf(("OSS32_MixSetVolume of %s streamid %X to (%d,%d)(%d,%d) caps %d", … … 519 509 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem); 520 510 #else 521 522 523 524 525 511 // looking for more, then one opened streams to prevent of muting active stream 512 cnt = 0; 513 for (idx=0; idx < 8*256; idx++) 514 if (opened_handles[idx].handle != 0) 515 cnt++; 526 516 527 517 dprintf(("OSS32_MixSetVolume old cnt=%X line=%x lVol=%x rVol=%x", cnt, line, lVol, rVol)); 528 //if (((cnt == 1 && (lVol==0 && rVol==0)) || (lVol>0 && rVol>0)) ||529 530 518 // if (((cnt == 1 && (lVol==0 && rVol==0)) || (lVol>0 && rVol>0)) || 519 if (cnt == 1 || line != OSS32_MIX_VOLUME_PCM) 520 { 531 521 dprintf(("OSS32_MixSetVolume Ioctl")); 532 533 534 535 536 537 538 539 pElem->value.integer.value[0] = FALSE;//switch, not mute control (inversed)540 522 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem); 523 524 if(idxMute != -1 && volume == 0) { 525 //enable mute 526 pElem->id.numid = pHandle->pids[idxMute].numid; 527 pElem->indirect = 0; 528 529 pElem->value.integer.value[0] = FALSE; //switch, not mute control (inversed) 530 pElem->value.integer.value[1] = FALSE; 541 531 dprintf(("OSS32_MixSetVolume Ioctl mute")); 542 543 544 532 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem); 533 } 534 } 545 535 #endif 546 536 547 548 549 550 551 552 553 554 537 kfree(pElem); 538 pElem = NULL; 539 if(ret) { 540 rprintf(("OSS32_MixSetVolume ret=%x", ret)); 541 DebugInt3(); 542 return UNIXToOSSError(ret); 543 } 544 return OSSERR_SUCCESS; 555 545 556 546 fail: 557 558 547 if(pElem) kfree(pElem); 548 return ret; 559 549 } 560 550 //****************************************************************************** … … 562 552 OSSRET OSS32_MixSetProperty(OSSSTREAMID streamid, ULONG ulLine, ULONG ulValue) 563 553 { 564 mixerhandle*pHandle = (mixerhandle *)streamid;565 566 567 intret, idx = -1, lVol, rVol = 0, j, i;568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 idx= pHandle->idxRecCaps[j];604 605 606 pElemInfo->id.numid= pHandle->pids[idx].numid;607 608 609 610 611 612 613 614 615 616 617 618 619 pElem->id.numid= pHandle->pids[idx].numid;620 pElem->indirect= 0;621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 554 mixerhandle *pHandle = (mixerhandle *)streamid; 555 struct snd_ctl_elem_value *pElem = NULL; 556 struct snd_ctl_elem_info *pElemInfo; 557 int ret, idx = -1, lVol, rVol = 0, j, i; 558 559 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) { 560 DebugInt3(); 561 return OSSERR_INVALID_STREAMID; 562 } 563 //set operation to non-blocking 564 pHandle->file.f_flags = O_NONBLOCK; 565 566 //too big to put on the stack 567 pElem = (struct snd_ctl_elem_value *)kmalloc(sizeof(struct snd_ctl_elem_value) + sizeof(struct snd_ctl_elem_info), GFP_KERNEL); 568 if(pElem == NULL) { 569 DebugInt3(); 570 return OSSERR_OUT_OF_MEMORY; 571 } 572 pElemInfo = (struct snd_ctl_elem_info *)(pElem+1); 573 574 switch(ulLine) { 575 case OSS32_MIX_INPUTSRC: 576 idx = pHandle->controls[OSS_MIXER_IGAIN].idxCustom; 577 //is this capture source supported by the hardware?? 578 if(!(pHandle->reccaps & OSS32_MIX_FLAG(ulValue))) { 579 DebugInt3(); 580 ret = OSSERR_INVALID_PARAMETER; 581 goto fail; 582 } 583 if(pHandle->rectype == RECTYPE_SELECTOR) {//input source selector 584 //set left and right capture source 585 pElem->value.enumerated.item[0] = pHandle->idxRecCaps[ulValue]; 586 pElem->value.enumerated.item[1] = pHandle->idxRecCaps[ulValue]; 587 } 588 else {//capture switch for each input source 589 //first turn off all capture switches... 590 for(j=0;j<OSS32_MIX_RECSRC_MAX;j++) 591 { 592 if(pHandle->idxRecCaps[j] != -1) { 593 idx = pHandle->idxRecCaps[j]; 594 595 //request information about mixer control 596 pElemInfo->id.numid = pHandle->pids[idx].numid; 597 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo); 598 if(ret) { 599 ret = UNIXToOSSError(ret); 600 DebugInt3(); 601 goto fail; 602 } 603 if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN) { 604 ret = OSSERR_INVALID_PARAMETER; 605 DebugInt3(); 606 goto fail; 607 } 608 609 pElem->id.numid = pHandle->pids[idx].numid; 610 pElem->indirect = 0; 611 for(i=0;i<pElemInfo->count;i++) { 612 pElem->value.integer.value[i] = 0; 613 } 614 615 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem); 616 if(ret) { 617 ret = UNIXToOSSError(ret); 618 DebugInt3(); 619 goto fail; 620 } 621 } 622 } 623 //request information about mixer control 624 pElemInfo->id.numid = pHandle->pids[idx].numid; 625 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo); 626 if(ret) { 627 ret = UNIXToOSSError(ret); 628 DebugInt3(); 629 goto fail; 630 } 631 632 //and enable the capture switch for the selected input source 633 idx = pHandle->idxRecCaps[ulValue]; 634 for(i=0;i<pElemInfo->count;i++) { 635 pElem->value.integer.value[i] = 1; 636 } 637 } 638 639 break; 640 641 case OSS32_MIX_SWITCH_MICBOOST: 642 idx = pHandle->controls[OSS_MIXER_MIC].idxCustom; 643 if(idx == -1) { 644 DebugInt3(); 645 ret = OSSERR_INVALID_PARAMETER; 646 goto fail; 647 } 648 //set mic switch value (on/off) 649 pElem->value.integer.value[0] = ulValue; 650 break; 651 652 case OSS32_MIX_LEVEL_BASS: 653 idx = pHandle->controls[OSS_MIXER_BASS].idxVolume; 654 goto levelcontinue; 655 case OSS32_MIX_LEVEL_TREBLE: 656 idx = pHandle->controls[OSS_MIXER_TREBLE].idxVolume; 657 goto levelcontinue; 658 case OSS32_MIX_LEVEL_3DCENTER: 659 idx = pHandle->controls[OSS_MIXER_3DCENTER].idxVolume; 660 goto levelcontinue; 661 case OSS32_MIX_LEVEL_3DDEPTH: 662 idx = pHandle->controls[OSS_MIXER_3DDEPTH].idxVolume; 673 663 levelcontinue: 674 664 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 665 if(idx == -1) {//supported? 666 DebugInt3(); 667 ret = OSSERR_INVALID_PARAMETER; 668 goto fail; 669 } 670 //request information about mixer control 671 pElemInfo->id.numid = pHandle->pids[idx].numid; 672 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo); 673 if(ret) { 674 ret = UNIXToOSSError(ret); 675 DebugInt3(); 676 goto fail; 677 } 678 if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_INTEGER) { 679 ret = OSSERR_INVALID_PARAMETER; 680 DebugInt3(); 681 goto fail; 682 } 683 lVol = ConvertVolume(GET_VOLUME_L(ulValue), pElemInfo->value.integer.max); 684 pElem->value.integer.value[0] = lVol; 685 686 if(pElemInfo->count > 1) { //stereo 687 rVol = ConvertVolume(GET_VOLUME_R(ulValue), pElemInfo->value.integer.max); 688 pElem->value.integer.value[1] = rVol; 689 } 690 break; 691 692 default: 693 DebugInt3(); 694 ret = OSSERR_INVALID_PARAMETER; 695 goto fail; 696 } 697 pElem->id.numid = pHandle->pids[idx].numid; 698 pElem->indirect = 0; 699 700 dprintf(("OSS32_MixSetProperty of %s to %x", pHandle->pids[idx].name, ulValue)); 701 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem); 702 703 kfree(pElem); 704 pElem = NULL; 705 if(ret) { 706 DebugInt3(); 707 return UNIXToOSSError(ret); 708 } 709 return OSSERR_SUCCESS; 720 710 721 711 fail: 722 723 712 if(pElem) kfree(pElem); 713 return ret; 724 714 } 725 715 //****************************************************************************** … … 727 717 OSSRET OSS32_MixGetProperty(OSSSTREAMID streamid, ULONG line, ULONG *pValue) 728 718 { 729 730 intret;731 732 733 734 735 736 737 738 739 719 mixerhandle *pHandle = (mixerhandle *)streamid; 720 int ret; 721 722 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) { 723 DebugInt3(); 724 return OSSERR_INVALID_STREAMID; 725 } 726 //set operation to non-blocking 727 pHandle->file.f_flags = O_NONBLOCK; 728 729 return OSSERR_NOT_SUPPORTED; 740 730 } 741 731 //****************************************************************************** … … 743 733 ULONG OSSToALSAVolume(ULONG OSSVolIdx) 744 734 { 745 746 747 735 switch(OSSVolIdx) { 736 case OSS_MIXER_VOLUME: 737 return OSS32_MIX_VOLUME_MASTER_FRONT; 748 738 #if 0 749 750 739 case OSS_MIXER_VOLUME: //TODO: 740 return OSS32_MIX_VOLUME_MASTER_REAR; 751 741 #endif 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 742 case OSS_MIXER_PCM: 743 return OSS32_MIX_VOLUME_PCM; 744 case OSS_MIXER_SYNTH: 745 return OSS32_MIX_VOLUME_MIDI; 746 case OSS_MIXER_LINE: 747 return OSS32_MIX_VOLUME_LINEIN; 748 case OSS_MIXER_MIC: 749 return OSS32_MIX_VOLUME_MIC; 750 case OSS_MIXER_CD: 751 return OSS32_MIX_VOLUME_CD; 752 case OSS_MIXER_DIGITAL1: 753 return OSS32_MIX_VOLUME_SPDIF; 754 case OSS_MIXER_VIDEO: 755 return OSS32_MIX_VOLUME_VIDEO; 756 case OSS_MIXER_PCSPEAKER: 757 return OSS32_MIX_VOLUME_PCSPEAKER; 758 case OSS_MIXER_PHONEOUT: 759 return OSS32_MIX_VOLUME_PHONE; 760 case OSS_MIXER_IGAIN: 761 return OSS32_MIX_VOLUME_CAPTURE; 762 case OSS_MIXER_TREBLE: 763 return OSS32_MIX_LEVEL_TREBLE; 764 case OSS_MIXER_BASS: 765 return OSS32_MIX_LEVEL_BASS; 766 case OSS_MIXER_HEADPHONE: 767 return OSS32_MIX_VOLUME_HEADPHONE; 768 case OSS_MIXER_SPEAKER: 769 return OSS32_MIX_VOLUME_SPEAKER; 770 case OSS_MIXER_LINE1: 771 return OSS32_MIX_VOLUME_AUX; 772 } 773 return -1; 784 774 } 785 775 //****************************************************************************** … … 787 777 OSSRET OSS32_MixQueryCaps(OSSSTREAMID streamid, POSS32_MIXCAPS pCaps) 788 778 { 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 779 mixerhandle *pHandle = (mixerhandle *)streamid; 780 int i; 781 782 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) { 783 DebugInt3(); 784 return OSSERR_INVALID_STREAMID; 785 } 786 787 strncpy(pCaps->name, pHandle->info.mixername, sizeof(pCaps->name)); 788 pCaps->fuCtrlCaps = 0; 789 pCaps->fuRecCaps = 0; 790 791 for(i=0;i<OSS_MIXER_NRDEVICES;i++) 792 { 793 if(pHandle->controls[i].idxVolume != -1) { 794 ULONG volidx = OSSToALSAVolume(i); 795 if(volidx != -1) 796 pCaps->fuCtrlCaps |= OSS32_MIX_FLAG(volidx); 797 } 798 } 799 800 //if it has a capture source control or the card has capture route switches, 801 //then we support intput source selection 802 if(pHandle->controls[OSS_MIXER_IGAIN].idxCustom != -1 || 803 pHandle->rectype == RECTYPE_SWITCH) 804 { 805 pCaps->fuCtrlCaps |= OSS32_MIX_FLAG(OSS32_MIX_INPUTSRC); 806 pCaps->fuRecCaps = pHandle->reccaps; 807 } 808 return OSSERR_SUCCESS; 819 809 } 820 810 //****************************************************************************** … … 822 812 OSSRET OSS32_MixQueryName(ULONG deviceid, char *pszMixerName, ULONG cbMixerName) 823 813 { 824 825 intret, i, j;826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 pHandle->file.f_dentry= &pHandle->d_entry;842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 814 mixerhandle *pHandle = NULL; 815 int ret, i, j; 816 817 if(alsa_fops == NULL) 818 return OSSERR_NO_DEVICE_AVAILABLE; 819 820 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL); 821 if(pHandle == NULL) { 822 ret = OSSERR_OUT_OF_MEMORY; 823 goto failure; 824 } 825 memset(pHandle, 0, sizeof(mixerhandle)); 826 827 //set operation to non-blocking 828 pHandle->file.f_flags = O_NONBLOCK; 829 830 //setup pointers in file structure (used internally by ALSA) 831 pHandle->file.f_dentry = &pHandle->d_entry; 832 pHandle->file.f_dentry->d_inode = &pHandle->inode; 833 834 pHandle->file.f_mode = FMODE_WRITE; 835 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 836 837 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 838 if(ret) { 839 goto failure; 840 } 841 //retrieve mixer information 842 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 843 SNDRV_CTL_IOCTL_CARD_INFO, 844 (ULONG)&pHandle->info); 845 if(ret) { 846 goto failure; 847 } 848 849 strncpy(pszMixerName, pHandle->info.mixername, cbMixerName); 850 851 pHandle->file.f_flags = O_NONBLOCK; 852 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 853 if(ret) { 854 goto failure; 855 } 856 kfree(pHandle); 857 return OSSERR_SUCCESS; 868 858 869 859 failure: 870 871 872 873 874 860 if(pHandle) { 861 kfree(pHandle); 862 } 863 DebugInt3(); 864 return OSSERR_OUT_OF_MEMORY; 875 865 } 876 866 //****************************************************************************** 877 867 //****************************************************************************** 878 868 OSSRET OSS32_QueryNames(ULONG deviceid, char *pszDeviceName, ULONG cbDeviceName, 879 880 { 881 882 intret, i, j;883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 pHandle->file.f_dentry= &pHandle->d_entry;902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 // 932 933 934 935 936 937 938 939 940 869 char *pszMixerName, ULONG cbMixerName, BOOL fLongName) 870 { 871 mixerhandle *pHandle = NULL; 872 int ret, i, j; 873 874 if(alsa_fops == NULL) { 875 ret = OSSERR_NO_DEVICE_AVAILABLE; 876 printk("ret = OSSERR_NO_DEVICE_AVAILABLE\n"); 877 goto failure; 878 } 879 880 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL); 881 if(pHandle == NULL) { 882 ret = OSSERR_OUT_OF_MEMORY; 883 goto failure; 884 } 885 memset(pHandle, 0, sizeof(mixerhandle)); 886 887 //set operation to non-blocking 888 pHandle->file.f_flags = O_NONBLOCK; 889 890 //setup pointers in file structure (used internally by ALSA) 891 pHandle->file.f_dentry = &pHandle->d_entry; 892 pHandle->file.f_dentry->d_inode = &pHandle->inode; 893 894 pHandle->file.f_mode = FMODE_WRITE; 895 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 896 897 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 898 if(ret) { 899 printk("open ret = %i\n", ret); 900 goto failure; 901 } 902 //retrieve mixer information 903 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 904 SNDRV_CTL_IOCTL_CARD_INFO, 905 (ULONG)&pHandle->info); 906 if(ret) { 907 printk("ioctl ret = %i\n", ret); 908 goto failure; 909 } 910 911 if(pszDeviceName) { 912 if(fLongName == TRUE) { 913 strncpy(pszDeviceName, pHandle->info.longname, cbDeviceName); 914 } 915 else strncpy(pszDeviceName, pHandle->info.name, cbDeviceName); 916 } 917 if(pszMixerName) { 918 strncpy(pszMixerName, pHandle->info.mixername, cbMixerName); 919 } 920 921 // printk("Card: %s with mixer %s\n",pszDeviceName, pszMixerName); 922 923 pHandle->file.f_flags = O_NONBLOCK; 924 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 925 if(ret) { 926 printk("release ret = %i\n", ret); 927 goto failure; 928 } 929 kfree(pHandle); 930 return OSSERR_SUCCESS; 941 931 942 932 failure: 943 944 945 946 947 948 949 } 950 //****************************************************************************** 951 //****************************************************************************** 952 933 if(pHandle) { 934 kfree(pHandle); 935 } 936 DebugInt3(); 937 printk("OSS32_QueryNames() ret = %i\n", ret); 938 return OSSERR_OUT_OF_MEMORY; 939 } 940 //****************************************************************************** 941 //****************************************************************************** 942
Note:
See TracChangeset
for help on using the changeset viewer.