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