Changeset 528
- Timestamp:
- Jul 25, 2010, 7:16:22 PM (15 years ago)
- Location:
- GPL/trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/alsa-kernel/core/control.c
r479 r528 1218 1218 } 1219 1219 up_read(&snd_ioctl_rwsem); 1220 snd_printdd(" unknown ioctl = 0x%x\n", cmd);1220 snd_printdd("snd_ctl_ioctl: unknown ioctl = 0x%x", cmd); 1221 1221 return -ENOTTY; 1222 1222 } -
GPL/trunk/alsa-kernel/core/pcm_native.c
r479 r528 2590 2590 return snd_pcm_drop(substream); 2591 2591 case SNDRV_PCM_IOCTL_PAUSE: 2592 {2592 { 2593 2593 int res; 2594 2594 snd_pcm_stream_lock_irq(substream); … … 2596 2596 snd_pcm_stream_unlock_irq(substream); 2597 2597 return res; 2598 }2599 } 2600 snd_printd(" unknown ioctl = 0x%x\n", cmd);2598 } 2599 } 2600 snd_printd("snd_pcm_common_ioctl1: unknown ioctl = 0x%x", cmd); 2601 2601 return -ENOTTY; 2602 2602 } -
GPL/trunk/alsa-kernel/core/pcm_os2.c
r32 r528 1 Apparently this file is not used in the driver 2 1 3 #ifdef TARGET_OS2 2 4 static int snd_pcm_setvolume(snd_pcm_substream_t * substream, snd_pcm_volume_t * _volume) -
GPL/trunk/alsa-kernel/pci/hda/patch_sigmatel.c
r464 r528 547 547 548 548 static hda_nid_t stac9200_pin_nids[8] = { 549 0x08, 0x09, 0x0d, 0x0e, 549 0x08, 0x09, 0x0d, 0x0e, 550 550 0x0f, 0x10, 0x11, 0x12, 551 551 }; 552 552 553 553 static hda_nid_t stac925x_pin_nids[8] = { 554 0x07, 0x08, 0x0a, 0x0b, 554 0x07, 0x08, 0x0a, 0x0b, 555 555 0x0c, 0x0d, 0x10, 0x11, 556 556 }; … … 1410 1410 */ 1411 1411 static unsigned int dell9200_d21_pin_configs[8] = { 1412 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, 1412 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, 1413 1413 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, 1414 1414 }; 1415 1415 1416 /* 1416 /* 1417 1417 STAC 9200 pin configs for 1418 1418 102801C0 … … 1420 1420 */ 1421 1421 static unsigned int dell9200_d22_pin_configs[8] = { 1422 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 1422 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 1423 1423 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, 1424 1424 }; 1425 1425 1426 /* 1426 /* 1427 1427 STAC 9200 pin configs for 1428 1428 102801C4 (Dell Dimension E310) … … 1434 1434 */ 1435 1435 static unsigned int dell9200_d23_pin_configs[8] = { 1436 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 1437 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, 1438 }; 1439 1440 1441 /* 1436 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 1437 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, 1438 }; 1439 1440 1441 /* 1442 1442 STAC 9200-32 pin configs for 1443 1443 102801B5 (Dell Inspiron 630m) … … 1449 1449 }; 1450 1450 1451 /* 1451 /* 1452 1452 STAC 9200-32 pin configs for 1453 1453 102801C2 (Dell Latitude D620) 1454 102801C8 1454 102801C8 1455 1455 102801CC (Dell Latitude D820) 1456 102801D4 1457 102801D6 1456 102801D4 1457 102801D6 1458 1458 */ 1459 1459 static unsigned int dell9200_m22_pin_configs[8] = { 1460 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, 1460 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, 1461 1461 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, 1462 1462 }; 1463 1463 1464 /* 1464 /* 1465 1465 STAC 9200-32 pin configs for 1466 1466 102801CE (Dell XPS M1710) … … 1473 1473 1474 1474 /* 1475 STAC 9200-32 pin configs for 1475 STAC 9200-32 pin configs for 1476 1476 102801C9 1477 1477 102801CA … … 1480 1480 */ 1481 1481 static unsigned int dell9200_m24_pin_configs[8] = { 1482 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, 1483 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, 1482 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, 1483 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, 1484 1484 }; 1485 1485 … … 1491 1491 */ 1492 1492 static unsigned int dell9200_m25_pin_configs[8] = { 1493 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 1493 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 1494 1494 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, 1495 1495 }; … … 1501 1501 */ 1502 1502 static unsigned int dell9200_m26_pin_configs[8] = { 1503 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, 1503 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, 1504 1504 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, 1505 1505 }; … … 1963 1963 static unsigned int dell_922x_m81_pin_configs[10] = { 1964 1964 0x0321101f, 0x01112024, 0x01111222, 0x91174220, 1965 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, 1965 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, 1966 1966 0x40C003f1, 0x405003f0, 1967 1967 }; … … 1972 1972 */ 1973 1973 static unsigned int dell_922x_m82_pin_configs[10] = { 1974 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, 1975 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 1976 0x508003f3, 0x405003f4, 1974 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, 1975 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 1976 0x508003f3, 0x405003f4, 1977 1977 }; 1978 1978 … … 2162 2162 SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000, 2163 2163 "ECS/PC chips", STAC_ECS_202), 2164 SND_PCI_QUIRK(0x107b, 0x6051, "eMachines T5226", STAC_D945_REF), 2164 2165 {0} /* terminator */ 2165 2166 }; … … 2167 2168 static unsigned int ref927x_pin_configs[14] = { 2168 2169 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, 2169 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, 2170 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, 2170 2171 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, 2171 2172 0x01c42190, 0x40000100, … … 2622 2623 struct sigmatel_spec *spec = codec->spec; 2623 2624 int nid = kcontrol->private_value; 2624 2625 2625 2626 spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0; 2626 2627 … … 4631 4632 spec->eapd_mask); 4632 4633 } 4633 } 4634 } 4634 4635 4635 4636 /* return non-zero if the hp-pin of the given array index isn't … … 4710 4711 * So, it's basically a problem of default pin configs, likely a BIOS issue. 4711 4712 * But, disabling the code below just works around it, and I'm too tired of 4712 * bug reports with such devices... 4713 * bug reports with such devices... 4713 4714 */ 4714 4715 else … … 4716 4717 #endif /* FIXME */ 4717 4718 } 4718 } 4719 } 4719 4720 4720 4721 static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, … … 4870 4871 { 4871 4872 if (nid == codec->afg) 4872 snd_iprintf(buffer, "Power-Map: 0x%02x\n", 4873 snd_iprintf(buffer, "Power-Map: 0x%02x\n", 4873 4874 snd_hda_codec_read(codec, nid, 0, 0x0fec, 0x0)); 4874 4875 } -
GPL/trunk/lib32/ioctl.c
r518 r528 40 40 void uniaud_set_interrupted_substream(struct snd_pcm_substream *substream) 41 41 { 42 43 44 45 46 47 48 49 //printk("added %x to %i\n", substream, i);50 51 52 53 54 //printk("already exist %x at %i\n", substream, i);55 56 57 42 int i; 43 44 for (i=0; i < 8*256; i++) 45 { 46 if (substream_int[i] == 0) 47 { 48 substream_int[i] = substream; // interrupted substream 49 // printk("added %x to %i\n", substream, i); 50 break; 51 } 52 if (substream_int[i] == substream) 53 { 54 // printk("already exist %x at %i\n", substream, i); 55 break; 56 } 57 } 58 58 } 59 59 60 60 int WaitForControlChange(int card_id, int timeout) 61 61 { 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 62 int ctl_id; 63 ULONG blkid = 0; 64 int i = 0; 65 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++; 75 76 if (i > timeout) 77 return -ETIME; 78 79 MyDevBlock(blkid, 1, 0); 80 if (unlock_all) 81 { 82 unlock_all = 0; 83 break; 84 } 85 } 86 return ctl_id; 87 87 } 88 88 89 89 int WaitForPCMInterrupt(void *handle, int timeout) 90 90 { 91 92 93 94 95 96 97 soundhandle*pHandle = (soundhandle *)handle;98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 91 ULONG blkid = 0; 92 int i = 0; 93 int j = 0; 94 struct snd_pcm_file *pcm_file = NULL; 95 struct snd_pcm_substream *substream; 96 struct snd_pcm_runtime *runtime; 97 soundhandle *pHandle = (soundhandle *)handle; 98 struct file *pfile; 99 100 if (handle == NULL) 101 return -ENXIO; 102 103 pfile = &pHandle->file; 104 105 if (pfile == NULL) 106 return -ENXIO; 107 108 pcm_file = (struct snd_pcm_file *)pfile->private_data; 109 110 if (pcm_file == NULL) 111 return -ENXIO; 112 113 substream = pcm_file->substream; 114 115 if (substream == NULL) 116 return -ENXIO; 117 118 runtime = substream->runtime; 119 120 if ((pfile->f_mode == FMODE_WRITE) && 121 (runtime->status->state != SNDRV_PCM_STATE_RUNNING)) 122 return -EBADFD; 123 124 //printk("wait for %x. tout %i\n",substream, timeout); 125 126 while (1) 127 { 128 for (i=0; i < 8*256; i++) 129 { 130 if (substream_int[i] == substream) 131 { 132 // printk("found %x at %i\n",substream_int[i], i); 133 substream_int[i] = 0; 134 //printk("j =%i\n",j); 135 return j; /* milliseconds */ 136 } 137 } 138 139 if (j++ > timeout) 140 { 141 printk("j with tout =%i. handle: %x\n",j, pHandle); 142 return -ETIME; 143 } 144 145 MyDevBlock(blkid, 1, 0); 146 if (unlock_all) 147 { 148 unlock_all = 0; 149 break; 150 } 151 } 152 //printk("j at exit =%i\n",j); 153 return j; 154 154 } 155 155 … … 159 159 int GetNumberOfCards(void) 160 160 { 161 161 return nrCardsDetected; 162 162 } 163 163 … … 167 167 int GetNumberOfPcm(int card_id) 168 168 { 169 169 return pcm_instances(card_id); 170 170 } 171 171 172 172 int SetPCMInstance(int card_id, int pcm) 173 173 { 174 175 176 177 178 179 174 if (pcm>=0 && pcm <= pcm_instances(card_id)) 175 { 176 pcm_device = pcm; 177 return pcm; 178 } else 179 return pcm_device; 180 180 } 181 181 182 182 int GetPcmForChannels(ULONG deviceid, int type, int channels) 183 183 { 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 184 POSS32_DEVCAPS pcaps = NULL; 185 WAVE_CAPS *wc; 186 int i; 187 int sel_pcm = -1; 188 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 } 198 199 pcaps = pcmcaps[deviceid]; 200 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 } 219 220 return sel_pcm; 221 221 } 222 222 223 223 int GetMaxChannels(ULONG deviceid, int type) 224 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 225 POSS32_DEVCAPS pcaps = NULL; 226 WAVE_CAPS *wc; 227 int i; 228 int sel_pcm = -1; 229 int max_ch = 0; 230 231 if (!pcmcaps[deviceid]) 232 { 233 FillCaps(deviceid); 234 if (!pcmcaps[deviceid]) 235 { 236 printk("Error querying caps for device: %i\n", deviceid); 237 return -1; 238 } 239 } 240 241 pcaps = pcmcaps[deviceid]; 242 243 for (i=0; i<pcm_instances(deviceid);i++) 244 { 245 switch(type) 246 { 247 case OSS32_CAPS_WAVE_PLAYBACK: // play 248 wc = &pcaps->waveOutCaps; 249 break; 250 case OSS32_CAPS_WAVE_CAPTURE: // record 251 wc = &pcaps->waveInCaps; 252 break; 253 } 254 if (wc->ulMaxChannels > max_ch) 255 max_ch = wc->ulMaxChannels; 256 pcaps++; 257 } 258 return max_ch; 259 259 } 260 260 … … 264 264 int GetUniaudPcmCaps1(ULONG deviceid, void *caps) 265 265 { 266 POSS32_DEVCAPS pcaps = (POSS32_DEVCAPS)caps; 267 int i; 268 OSSSTREAMID streamid = 0; 269 soundhandle *pHandle; 270 struct snd_pcm_info *pcminfo = NULL; 271 struct snd_pcm_hw_params *params; 272 int ret, fmt, j; 273 ULONG format_mask; 274 struct snd_mask *mask; 275 int pcms = 0; 276 277 pcms = pcm_instances(deviceid); 278 279 if (!pcaps || !pcms) return -1; 280 281 282 //these structures are too big to put on the stack 283 pcminfo = (struct snd_pcm_info *)kmalloc(sizeof(struct snd_pcm_info)+sizeof(struct snd_pcm_hw_params), GFP_KERNEL); 284 if(pcminfo == NULL) { 285 DebugInt3(); 286 rprintf(("GetUniaudPcmCaps: out of memory")); 287 return OSSERR_OUT_OF_MEMORY; 288 } 289 params = (struct snd_pcm_hw_params *)(pcminfo+1); 290 291 for (i=0; i<pcms;i++) 292 { 293 pcaps->nrDevices = nrCardsDetected; 294 pcaps->ulCaps = OSS32_CAPS_WAVE_PLAYBACK | OSS32_CAPS_WAVE_CAPTURE; 295 296 //query wave in & out caps 297 for(j=0;j<2;j++) 298 { 299 PWAVE_CAPS pWaveCaps = (j == 0) ? &pcaps->waveOutCaps : &pcaps->waveInCaps; 300 301 ret = OSS32_WaveOpen(deviceid, (j == 0) ? OSS32_STREAM_WAVEOUT : OSS32_STREAM_WAVEIN, &streamid, i, 0); 302 if(ret != OSSERR_SUCCESS) 303 { 304 rprintf(("GetUniaudPcmCaps: wave open error %i %s at pcm %i", ret, 305 (j == 0) ?"PLAY":"REC", i)); 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 } 315 316 //set operation to non-blocking 317 pHandle->file.f_flags = O_NONBLOCK; 318 319 dprintf(("GetUniaudPcmCaps: cp1. phandle %x", pHandle)); 320 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo); 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)); 330 331 if(pcminfo->subname[0]) { 332 strncpy(pcaps->szMixerName, pcminfo->subname, sizeof(pcaps->szMixerName)); 333 } 334 335 pWaveCaps->nrStreams = pcminfo->subdevices_count; 336 337 dprintf(("GetUniaudPcmCaps: cp2. nr of streams: %i", pWaveCaps->nrStreams)); 338 //get all hardware parameters 339 _snd_pcm_hw_params_any(params); 340 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params); 341 if(ret != 0) { 342 rprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i", ret)); 343 ret = UNIXToOSSError(ret); 344 //goto fail; 345 continue; 346 } 347 //dprintf("GetUniaudPcmCaps: cp3")); 348 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 366 pWaveCaps->ulMinRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min; 367 pWaveCaps->ulMaxRate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max; 368 369 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_RATE_MASK); 266 POSS32_DEVCAPS pcaps = (POSS32_DEVCAPS)caps; 267 int i; 268 OSSSTREAMID streamid = 0; 269 soundhandle *pHandle; 270 struct snd_pcm_info *pcminfo = NULL; 271 struct snd_pcm_hw_params *params; 272 int ret, fmt, j; 273 ULONG format_mask; 274 struct snd_mask *mask; 275 int pcms = 0; 276 277 pcms = pcm_instances(deviceid); 278 279 if (!pcaps || !pcms) return -1; 280 281 282 //these structures are too big to put on the stack 283 pcminfo = (struct snd_pcm_info *)kmalloc(sizeof(struct snd_pcm_info)+sizeof(struct snd_pcm_hw_params), GFP_KERNEL); 284 if(pcminfo == NULL) { 285 DebugInt3(); 286 rprintf(("GetUniaudPcmCaps: out of memory")); 287 return OSSERR_OUT_OF_MEMORY; 288 } 289 params = (struct snd_pcm_hw_params *)(pcminfo+1); 290 291 for (i=0; i<pcms;i++) 292 { 293 pcaps->nrDevices = nrCardsDetected; 294 pcaps->ulCaps = OSS32_CAPS_WAVE_PLAYBACK | OSS32_CAPS_WAVE_CAPTURE; 295 296 //query wave in & out caps 297 for(j=0;j<2;j++) 298 { 299 PWAVE_CAPS pWaveCaps = (j == 0) ? &pcaps->waveOutCaps : &pcaps->waveInCaps; 300 301 ret = OSS32_WaveOpen(deviceid, (j == 0) ? OSS32_STREAM_WAVEOUT : OSS32_STREAM_WAVEIN, &streamid, i, 0); 302 if(ret != OSSERR_SUCCESS) 303 { 304 dprintf(("GetUniaudPcmCaps: wave open error %i %s at pcm %i", ret, (j == 0) ?"PLAY":"REC", i)); 305 continue; 306 //goto fail; 307 } 308 pHandle = (soundhandle *)streamid; 309 if(pHandle == NULL || pHandle->magic != MAGIC_WAVE_ALSA32) { 310 rprintf(("GetUniaudPcmCaps: invalid stream id")); 311 ret = OSSERR_INVALID_STREAMID; 312 //goto fail; 313 } 314 315 //set operation to non-blocking 316 pHandle->file.f_flags = O_NONBLOCK; 317 318 dprintf(("GetUniaudPcmCaps: cp1. phandle %x", pHandle)); 319 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_INFO, (ULONG)pcminfo); 320 if(ret != 0) { 321 rprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_INFO error %i", ret)); 322 ret = UNIXToOSSError(ret); 323 continue; 324 } 325 if(pcminfo->name[0]) { 326 strncpy(pcaps->szDeviceName, pcminfo->name, sizeof(pcaps->szDeviceName)); 327 } 328 else strncpy(pcaps->szDeviceName, pcminfo->id, sizeof(pcaps->szDeviceName)); 329 330 if(pcminfo->subname[0]) { 331 strncpy(pcaps->szMixerName, pcminfo->subname, sizeof(pcaps->szMixerName)); 332 } 333 334 pWaveCaps->nrStreams = pcminfo->subdevices_count; 335 336 dprintf(("GetUniaudPcmCaps: cp2. nr of streams: %i", pWaveCaps->nrStreams)); 337 //get all hardware parameters 338 _snd_pcm_hw_params_any(params); 339 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params); 340 if(ret != 0) { 341 dprintf(("GetUniaudPcmCaps: SNDRV_PCM_IOCTL_HW_REFINE error %i", ret)); 342 ret = UNIXToOSSError(ret); 343 //goto fail; 344 continue; 345 } 346 //dprintf("GetUniaudPcmCaps: cp3")); 347 348 pWaveCaps->ulMinChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min; 349 pWaveCaps->ulMaxChannels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max; 350 dprintf(("chan: from %i to %i\n", pWaveCaps->ulMinChannels,pWaveCaps->ulMaxChannels)); 351 pWaveCaps->ulChanFlags = 0; 352 if(pWaveCaps->ulMinChannels == 1) { 353 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_MONO; 354 } 355 if(pWaveCaps->ulMaxChannels >= 2) { 356 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_STEREO; 357 } 358 if(pWaveCaps->ulMaxChannels >= 4) { 359 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_QUAD; 360 } 361 if(pWaveCaps->ulMaxChannels >= 6) { 362 pWaveCaps->ulChanFlags |= OSS32_CAPS_PCM_CHAN_5_1; 363 } 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; 367 368 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_RATE_MASK); 370 369 //mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 371 pWaveCaps->ulRateFlags= mask->bits[0];372 373 pWaveCaps->ulRateFlags= ALSAToOSSRateFlags(pWaveCaps->ulRateFlags);374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 370 pWaveCaps->ulRateFlags = mask->bits[0]; 371 372 pWaveCaps->ulRateFlags = ALSAToOSSRateFlags(pWaveCaps->ulRateFlags); 373 374 pWaveCaps->ulDataFormats = 0; 375 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 } 387 388 OSS32_WaveClose(streamid); 389 streamid = 0; 390 } // for j 391 pcaps++; // next pcm 392 } // for i 393 394 if (pcminfo) kfree(pcminfo); 395 return OSSERR_SUCCESS; 397 396 } 398 397 399 398 void FillCaps(ULONG deviceid) 400 399 { 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 400 int pcms = 0; 401 402 pcms = pcm_instances(deviceid); 403 404 dprintf(("FillCaps: pcms=%i\n", pcms)); 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; 416 415 } 417 416 418 417 int GetUniaudPcmCaps(ULONG deviceid, void *caps) 419 418 { 420 421 422 423 424 // 425 426 427 428 429 430 431 432 433 419 int pcms = 0; 420 421 pcms = pcm_instances(deviceid); 422 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 } 434 433 } 435 434 … … 439 438 int UniaudCtlGetPowerState(ULONG deviceid, void *state) 440 439 { 441 442 intret, i, j;443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 pHandle->file.f_dentry= &pHandle->d_entry;461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 440 mixerhandle *pHandle = NULL; 441 int ret, i, j; 442 443 if(alsa_fops == NULL) { 444 ret = OSSERR_NO_DEVICE_AVAILABLE; 445 goto failure; 446 } 447 448 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL); 449 if(pHandle == NULL) { 450 ret = OSSERR_OUT_OF_MEMORY; 451 goto failure; 452 } 453 memset(pHandle, 0, sizeof(mixerhandle)); 454 455 //set operation to non-blocking 456 pHandle->file.f_flags = O_NONBLOCK; 457 458 //setup pointers in file structure (used internally by ALSA) 459 pHandle->file.f_dentry = &pHandle->d_entry; 460 pHandle->file.f_dentry->d_inode = &pHandle->inode; 461 462 pHandle->file.f_mode = FMODE_WRITE; 463 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 464 465 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 466 if(ret) { 467 goto failure; 468 } 469 //retrieve mixer information 470 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 471 SNDRV_CTL_IOCTL_POWER_STATE, 472 (ULONG)state); 473 474 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 475 476 kfree(pHandle); 477 478 if(ret) { 479 goto failure; 480 } 481 482 return OSSERR_SUCCESS; 484 483 failure: 485 486 484 DebugInt3(); 485 return ret; 487 486 } 488 487 … … 492 491 int UniaudCtlSetPowerState(ULONG deviceid, void *state) 493 492 { 494 495 intret, i, j;496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 pHandle->file.f_dentry= &pHandle->d_entry;514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 493 mixerhandle *pHandle = NULL; 494 int ret, i, j; 495 496 if(alsa_fops == NULL) { 497 ret = OSSERR_NO_DEVICE_AVAILABLE; 498 goto failure; 499 } 500 501 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL); 502 if(pHandle == NULL) { 503 ret = OSSERR_OUT_OF_MEMORY; 504 goto failure; 505 } 506 memset(pHandle, 0, sizeof(mixerhandle)); 507 508 //set operation to non-blocking 509 pHandle->file.f_flags = O_NONBLOCK; 510 511 //setup pointers in file structure (used internally by ALSA) 512 pHandle->file.f_dentry = &pHandle->d_entry; 513 pHandle->file.f_dentry->d_inode = &pHandle->inode; 514 515 pHandle->file.f_mode = FMODE_WRITE; 516 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 517 518 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 519 if(ret) { 520 goto failure; 521 } 522 //retrieve mixer information 523 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 524 SNDRV_CTL_IOCTL_POWER, 525 (ULONG)state); 526 527 pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 528 529 kfree(pHandle); 530 531 if(ret) { 532 goto failure; 533 } 534 535 return OSSERR_SUCCESS; 537 536 failure: 538 539 537 DebugInt3(); 538 return ret; 540 539 } 541 540 … … 545 544 int GetUniaudCardInfo(ULONG deviceid, void *info) 546 545 { 547 548 intret, i, j;549 // 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 pHandle->file.f_dentry= &pHandle->d_entry;568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 546 mixerhandle *pHandle = NULL; 547 int ret, i, j; 548 // struct snd_ctl_card_info *pinfo; 549 550 if(alsa_fops == NULL) { 551 ret = OSSERR_NO_DEVICE_AVAILABLE; 552 goto failure; 553 } 554 555 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL); 556 if(pHandle == NULL) { 557 ret = OSSERR_OUT_OF_MEMORY; 558 goto failure; 559 } 560 memset(pHandle, 0, sizeof(mixerhandle)); 561 562 //set operation to non-blocking 563 pHandle->file.f_flags = O_NONBLOCK; 564 565 //setup pointers in file structure (used internally by ALSA) 566 pHandle->file.f_dentry = &pHandle->d_entry; 567 pHandle->file.f_dentry->d_inode = &pHandle->inode; 568 569 pHandle->file.f_mode = FMODE_WRITE; 570 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 571 572 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 573 if(ret) { 574 goto failure; 575 } 576 //retrieve mixer information 577 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 578 SNDRV_CTL_IOCTL_CARD_INFO, 579 (ULONG)(struct snd_ctl_card_info *)info); 580 if(ret) { 581 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 582 goto failure; 583 } 584 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 585 586 if(pHandle) { 587 kfree(pHandle); 588 } 589 return OSSERR_SUCCESS; 591 590 failure: 592 593 594 595 596 591 if(pHandle) { 592 kfree(pHandle); 593 } 594 DebugInt3(); 595 return OSSERR_OUT_OF_MEMORY; 597 596 } 598 597 599 598 int GetUniaudControlNum(ULONG deviceid) 600 599 { 601 602 intret, i, j, sz;603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 pHandle->file.f_dentry= &pHandle->d_entry;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 600 mixerhandle *pHandle = NULL; 601 int ret, i, j, sz; 602 603 if(alsa_fops == NULL) { 604 ret = OSSERR_NO_DEVICE_AVAILABLE; 605 goto failure; 606 } 607 608 sz = sizeof(mixerhandle); 609 pHandle = kmalloc(sz, GFP_KERNEL); 610 if(pHandle == NULL) { 611 ret = OSSERR_OUT_OF_MEMORY; 612 goto failure; 613 } 614 memset(pHandle, 0, sizeof(mixerhandle)); 615 616 //set operation to non-blocking 617 pHandle->file.f_flags = O_NONBLOCK; 618 619 //setup pointers in file structure (used internally by ALSA) 620 pHandle->file.f_dentry = &pHandle->d_entry; 621 pHandle->file.f_dentry->d_inode = &pHandle->inode; 622 623 pHandle->file.f_mode = FMODE_WRITE; 624 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 625 626 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 627 if(ret) { 628 goto failure; 629 } 630 //retrieve mixer information 631 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 632 SNDRV_CTL_IOCTL_CARD_INFO, 633 (ULONG)&pHandle->info); 634 if(ret) { 635 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 636 goto failure; 637 } 638 //get the number of mixer elements 639 pHandle->list.offset = 0; 640 pHandle->list.space = 0; 641 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 642 SNDRV_CTL_IOCTL_ELEM_LIST, 643 (ULONG)&pHandle->list); 644 if(ret) { 645 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 646 goto failure; 647 } 648 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 649 if(pHandle) { 650 if(pHandle->pids) kfree(pHandle->pids); 651 kfree(pHandle); 652 } 653 return pHandle->list.count; 655 654 failure: 656 657 658 659 660 661 655 if(pHandle) { 656 if(pHandle->pids) kfree(pHandle->pids); 657 kfree(pHandle); 658 } 659 DebugInt3(); 660 return OSSERR_OUT_OF_MEMORY; 662 661 } 663 662 664 663 int GetUniaudControls(ULONG deviceid, void *pids) 665 664 { 666 667 intret, i, j, sz;668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 pHandle->file.f_dentry= &pHandle->d_entry;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 720 721 722 723 724 725 pHandle->list.pids= pHandle->pids;726 727 728 729 730 731 732 733 // 734 // 735 // 736 737 738 739 // 740 741 742 665 mixerhandle *pHandle = NULL; 666 int ret, i, j, sz; 667 668 if(alsa_fops == NULL) { 669 ret = OSSERR_NO_DEVICE_AVAILABLE; 670 goto failure; 671 } 672 673 sz = sizeof(mixerhandle); 674 pHandle = kmalloc(sz, GFP_KERNEL); 675 if(pHandle == NULL) { 676 ret = OSSERR_OUT_OF_MEMORY; 677 goto failure; 678 } 679 memset(pHandle, 0, sizeof(mixerhandle)); 680 681 //set operation to non-blocking 682 pHandle->file.f_flags = O_NONBLOCK; 683 684 //setup pointers in file structure (used internally by ALSA) 685 pHandle->file.f_dentry = &pHandle->d_entry; 686 pHandle->file.f_dentry->d_inode = &pHandle->inode; 687 688 pHandle->file.f_mode = FMODE_WRITE; 689 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 690 691 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 692 if(ret) { 693 goto failure; 694 } 695 //retrieve mixer information 696 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 697 SNDRV_CTL_IOCTL_CARD_INFO, 698 (ULONG)&pHandle->info); 699 if(ret) { 700 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 701 goto failure; 702 } 703 //get the number of mixer elements 704 pHandle->list.offset = 0; 705 pHandle->list.space = 0; 706 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 707 SNDRV_CTL_IOCTL_ELEM_LIST, 708 (ULONG)&pHandle->list); 709 if(ret) { 710 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 711 goto failure; 712 } 713 714 //allocate memory for all mixer elements 715 pHandle->pids = (struct snd_ctl_elem_id *)pids; 716 //kmalloc(sizeof(struct snd_ctl_elem_id)*pHandle->list.count, GFP_KERNEL); 717 if(pHandle->pids == NULL) { 718 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 719 goto failure; 720 } 721 //and retrieve all mixer elements 722 pHandle->list.offset = 0; 723 pHandle->list.space = pHandle->list.count; 724 pHandle->list.pids = pHandle->pids; 725 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, 726 SNDRV_CTL_IOCTL_ELEM_LIST, 727 (ULONG)&pHandle->list); 728 if(ret) { 729 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 730 goto failure; 731 } 732 // if (pids) 733 // memcpy(pids, pHandle->pids, 734 // sizeof(struct snd_ctl_elem_id)*pHandle->list.count); 735 736 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 737 if(pHandle) { 738 // if(pHandle->pids) kfree(pHandle->pids); 739 kfree(pHandle); 740 } 741 return pHandle->list.count; 743 742 failure: 744 745 // 746 747 748 749 743 if(pHandle) { 744 // if(pHandle->pids) kfree(pHandle->pids); 745 kfree(pHandle); 746 } 747 DebugInt3(); 748 return OSSERR_OUT_OF_MEMORY; 750 749 } 751 750 752 751 int GetUniaudControlInfo(ULONG deviceid, ULONG id, void *info) 753 752 { 754 755 756 757 intret, i, j, sz;758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 pHandle->file.f_dentry= &pHandle->d_entry;777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 // 795 796 797 798 799 800 // 801 753 struct snd_ctl_elem_value *pElem = NULL; 754 struct snd_ctl_elem_info *pElemInfo = NULL; 755 mixerhandle *pHandle = NULL; 756 int ret, i, j, sz; 757 758 if(alsa_fops == NULL) { 759 ret = OSSERR_NO_DEVICE_AVAILABLE; 760 goto failure; 761 } 762 763 sz = sizeof(mixerhandle); 764 pHandle = kmalloc(sz, GFP_KERNEL); 765 if(pHandle == NULL) { 766 ret = OSSERR_OUT_OF_MEMORY; 767 goto failure; 768 } 769 memset(pHandle, 0, sizeof(mixerhandle)); 770 771 //set operation to non-blocking 772 pHandle->file.f_flags = O_NONBLOCK; 773 774 //setup pointers in file structure (used internally by ALSA) 775 pHandle->file.f_dentry = &pHandle->d_entry; 776 pHandle->file.f_dentry->d_inode = &pHandle->inode; 777 778 pHandle->file.f_mode = FMODE_WRITE; 779 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 780 781 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 782 if(ret) { 783 goto failure; 784 } 785 786 //allocate memory for info element 787 pElemInfo = (struct snd_ctl_elem_info *)info; 788 if(pElemInfo == NULL) { 789 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 790 goto failure; 791 } 792 793 // printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info)); 794 795 pElemInfo->id.numid = id; 796 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo); 797 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 798 if(pHandle) kfree(pHandle); 799 // printk("elem type: %i, id: %i, card: %i\n", pElemInfo->type, pElemInfo->id.numid, deviceid); 800 return OSSERR_SUCCESS; 802 801 803 802 failure: 804 805 806 807 808 803 if(pHandle) { 804 kfree(pHandle); 805 } 806 DebugInt3(); 807 return OSSERR_OUT_OF_MEMORY; 809 808 } 810 809 811 810 int GetUniaudControlValueGet(ULONG deviceid, ULONG id, void *value) 812 811 { 813 814 815 816 intret, i, j, sz;817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 pHandle->file.f_dentry= &pHandle->d_entry;836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 // 853 854 855 856 857 858 859 860 812 struct snd_ctl_elem_value *pElem = NULL; 813 struct snd_ctl_elem_info *pElemInfo = NULL; 814 mixerhandle *pHandle = NULL; 815 int ret, i, j, sz; 816 817 if(alsa_fops == NULL) { 818 ret = OSSERR_NO_DEVICE_AVAILABLE; 819 goto failure; 820 } 821 822 sz = sizeof(mixerhandle); 823 pHandle = kmalloc(sz, GFP_KERNEL); 824 if(pHandle == NULL) { 825 ret = OSSERR_OUT_OF_MEMORY; 826 goto failure; 827 } 828 memset(pHandle, 0, sizeof(mixerhandle)); 829 830 //set operation to non-blocking 831 pHandle->file.f_flags = O_NONBLOCK; 832 833 //setup pointers in file structure (used internally by ALSA) 834 pHandle->file.f_dentry = &pHandle->d_entry; 835 pHandle->file.f_dentry->d_inode = &pHandle->inode; 836 837 pHandle->file.f_mode = FMODE_WRITE; 838 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 839 840 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 841 if(ret) { 842 goto failure; 843 } 844 845 pElem = (struct snd_ctl_elem_value *)value; 846 if(pElem == NULL) { 847 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 848 goto failure; 849 } 850 851 // printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info)); 852 853 pElem->id.numid = id; 854 pElem->indirect = 0; 855 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_READ, (ULONG)pElem); 856 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 857 if(pHandle) kfree(pHandle); 858 859 return OSSERR_SUCCESS; 861 860 failure: 862 863 864 865 866 861 if(pHandle) { 862 kfree(pHandle); 863 } 864 DebugInt3(); 865 return OSSERR_OUT_OF_MEMORY; 867 866 } 868 867 869 868 int GetUniaudControlValuePut(ULONG deviceid, ULONG id, void *value) 870 869 { 871 872 873 874 intret, i, j, sz;875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 pHandle->file.f_dentry= &pHandle->d_entry;894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 // 911 912 913 914 915 916 917 918 870 struct snd_ctl_elem_value *pElem = NULL; 871 struct snd_ctl_elem_info *pElemInfo = NULL; 872 mixerhandle *pHandle = NULL; 873 int ret, i, j, sz; 874 875 if(alsa_fops == NULL) { 876 ret = OSSERR_NO_DEVICE_AVAILABLE; 877 goto failure; 878 } 879 880 sz = sizeof(mixerhandle); 881 pHandle = kmalloc(sz, GFP_KERNEL); 882 if(pHandle == NULL) { 883 ret = OSSERR_OUT_OF_MEMORY; 884 goto failure; 885 } 886 memset(pHandle, 0, sizeof(mixerhandle)); 887 888 //set operation to non-blocking 889 pHandle->file.f_flags = O_NONBLOCK; 890 891 //setup pointers in file structure (used internally by ALSA) 892 pHandle->file.f_dentry = &pHandle->d_entry; 893 pHandle->file.f_dentry->d_inode = &pHandle->inode; 894 895 pHandle->file.f_mode = FMODE_WRITE; 896 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL); 897 898 ret = alsa_fops->open(&pHandle->inode, &pHandle->file); 899 if(ret) { 900 goto failure; 901 } 902 903 pElem = (struct snd_ctl_elem_value *)value; 904 if(pElem == NULL) { 905 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 906 goto failure; 907 } 908 909 // printk("sizeof elem_info %i\n",sizeof(struct snd_ctl_elem_info)); 910 911 pElem->id.numid = id; 912 pElem->indirect = 0; 913 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem); 914 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file); 915 if(pHandle) kfree(pHandle); 916 917 return OSSERR_SUCCESS; 919 918 920 919 failure: 921 922 923 924 925 920 if(pHandle) { 921 kfree(pHandle); 922 } 923 DebugInt3(); 924 return OSSERR_OUT_OF_MEMORY; 926 925 } 927 926 928 927 int UniaudIoctlHWRefine(OSSSTREAMID streamid, void *pHwParams) 929 928 { 930 931 soundhandle*pHandle = (soundhandle *)streamid;932 933 934 935 936 937 938 939 940 941 942 929 int ret; 930 soundhandle *pHandle = (soundhandle *)streamid; 931 struct snd_pcm_hw_params *params = NULL; 932 printk("PS UniaudIoctlHWRefine\n"); 933 params = (struct snd_pcm_hw_params *)pHwParams; 934 935 if (!params) return -1001; 936 937 if (!pHandle) return -1002; 938 939 pHandle->file.f_flags = O_NONBLOCK; 940 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_REFINE, (ULONG)params); 941 return ret; 943 942 } 944 943 945 944 int UniaudIoctlHWParamSet(OSSSTREAMID streamid, void *pHwParams) 946 945 { 947 948 soundhandle*pHandle = (soundhandle *)streamid;949 950 951 952 953 954 955 956 957 958 946 int ret; 947 soundhandle *pHandle = (soundhandle *)streamid; 948 struct snd_pcm_hw_params *params = NULL; 949 printk("PS UniaudIoctlHWParamSet\n"); 950 params = (struct snd_pcm_hw_params *)pHwParams; 951 952 if (!params) return -1001; 953 if (!pHandle) return -1002; 954 955 pHandle->file.f_flags = O_NONBLOCK; 956 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_HW_PARAMS, (ULONG)params); 957 return ret; 959 958 } 960 959 961 960 int UniaudIoctlSWParamSet(OSSSTREAMID streamid, void *pSwParams) 962 961 { 963 964 soundhandle*pHandle = (soundhandle *)streamid;965 966 967 968 969 970 971 972 973 974 975 962 int ret; 963 soundhandle *pHandle = (soundhandle *)streamid; 964 struct snd_pcm_sw_params *params = NULL; 965 printk("PS UniaudIoctlSWParamSet\n"); 966 params = (struct snd_pcm_sw_params *)pSwParams; 967 968 if (!params) return -1001; 969 if (!pHandle) return -1002; 970 971 pHandle->file.f_flags = O_NONBLOCK; 972 973 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_SW_PARAMS, (ULONG)params); 974 return ret; 976 975 } 977 976 978 977 int UniaudIoctlPCMStatus(OSSSTREAMID streamid, void *pstatus) 979 978 { 980 981 soundhandle*pHandle = (soundhandle *)streamid;982 struct snd_pcm_status*status = (struct snd_pcm_status *)pstatus;983 984 985 986 987 988 989 990 979 int ret; 980 soundhandle *pHandle = (soundhandle *)streamid; 981 struct snd_pcm_status *status = (struct snd_pcm_status *)pstatus; 982 983 if (!status) return -1001; 984 if (!pHandle) return -1002; 985 986 pHandle->file.f_flags = O_NONBLOCK; 987 988 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)status); 989 return ret; 991 990 } 992 991 993 992 int UniaudIoctlPCMWrite(OSSSTREAMID streamid, char *buf, int size) 994 993 { 995 996 soundhandle*pHandle = (soundhandle *)streamid;997 998 999 1000 1001 1002 1003 1004 1005 994 int ret; 995 soundhandle *pHandle = (soundhandle *)streamid; 996 997 if (!buf) return -1001; 998 if (!pHandle) return -1002; 999 1000 pHandle->file.f_flags = O_NONBLOCK; 1001 1002 ret = pHandle->file.f_op->write(&pHandle->file, buf, size, &pHandle->file.f_pos); 1003 1004 return ret; 1006 1005 } 1007 1006 1008 1007 int UniaudIoctlPCMRead(OSSSTREAMID streamid, char *buf, int size) 1009 1008 { 1010 1011 soundhandle*pHandle = (soundhandle *)streamid;1012 1013 1014 1015 1016 1017 1018 1019 1020 1009 int ret; 1010 soundhandle *pHandle = (soundhandle *)streamid; 1011 1012 if (!buf) return -1001; 1013 if (!pHandle) return -1002; 1014 1015 pHandle->file.f_flags = O_NONBLOCK; 1016 1017 ret = pHandle->file.f_op->read(&pHandle->file, buf, size, &pHandle->file.f_pos); 1018 1019 return ret; 1021 1020 } 1022 1021 1023 1022 int UniaudIoctlPCMPrepare(OSSSTREAMID streamid) 1024 1023 { 1025 1026 soundhandle*pHandle = (soundhandle *)streamid;1027 1028 1029 1030 1031 1032 1033 1024 int ret; 1025 soundhandle *pHandle = (soundhandle *)streamid; 1026 1027 if (!pHandle) return -1002; 1028 1029 pHandle->file.f_flags = O_NONBLOCK; 1030 1031 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1032 return ret; 1034 1033 } 1035 1034 1036 1035 int UniaudIoctlPCMResume(OSSSTREAMID streamid, int pause) 1037 1036 { 1038 1039 soundhandle*pHandle = (soundhandle *)streamid;1040 1041 1042 1043 1044 1045 1046 1047 1037 int ret; 1038 soundhandle *pHandle = (soundhandle *)streamid; 1039 1040 if (!pHandle) return -1002; 1041 1042 pHandle->file.f_flags = O_NONBLOCK; 1043 1044 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PAUSE, pause); 1045 1046 return ret; 1048 1047 } 1049 1048 1050 1049 int UniaudIoctlPCMStart(OSSSTREAMID streamid) 1051 1050 { 1052 1053 soundhandle*pHandle = (soundhandle *)streamid;1054 1055 1056 1057 1058 1059 1060 1061 1051 int ret; 1052 soundhandle *pHandle = (soundhandle *)streamid; 1053 1054 if (!pHandle) return -1002; 1055 1056 pHandle->file.f_flags = O_NONBLOCK; 1057 1058 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_START, 0); 1059 1060 return ret; 1062 1061 } 1063 1062 1064 1063 int UniaudIoctlPCMDrop(OSSSTREAMID streamid) 1065 1064 { 1066 1067 soundhandle*pHandle = (soundhandle *)streamid;1068 1069 1070 1071 1072 1073 1074 1075 1065 int ret; 1066 soundhandle *pHandle = (soundhandle *)streamid; 1067 1068 if (!pHandle) return -1002; 1069 1070 pHandle->file.f_flags = O_NONBLOCK; 1071 1072 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_DROP, 0); 1073 1074 return ret; 1076 1075 } 1077 1076 1078 1077 void UniaudCloseAll(USHORT fileid) 1079 1078 { 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 } 1079 int i; 1080 1081 for (i=0; i < 8*256; i++) 1082 { 1083 if (opened_handles[i].handle != 0) 1084 { 1085 if (fileid) 1086 { 1087 if (fileid == opened_handles[i].FileId) 1088 { 1089 opened_handles[i].reuse = 0; 1090 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0) 1091 opened_handles[i].handle = 0; 1092 } 1093 } 1094 else 1095 { 1096 opened_handles[i].reuse = 0; 1097 if (OSS32_WaveClose((OSSSTREAMID)opened_handles[i].handle) == 0) 1098 opened_handles[i].handle = 0; 1099 } 1100 } 1101 } 1102 return; 1103 } -
GPL/trunk/lib32/sound.c
r518 r528 1116 1116 iRet = pHandle->file.f_op->write(&pHandle->file, (char *)ulBuffer, ulSize, &pHandle->file.f_pos); 1117 1117 1118 if (iRet != ulSize) rprintf(("WaveAddBuffer: ReqSize=%x Size=%x iRet=%x\n", ulReqSize, ulSize, iRet)); 1119 1118 1120 if (iRet < 0 ) break; 1119 1121 ulTransferred = iRet; … … 1134 1136 } 1135 1137 1138 rprintf(("WaveAddBuffer: ReqSize=%x Size=%x\n", ulReqSize, ulSize)); 1139 1136 1140 // size should be aligned to channels number * samplesize //PS+++ what is it and why?!?!?! 1137 1141 ulJ = 10; // 10 try if error 1138 1142 iRet = -11; 1139 while (ulSize && ulJ && iRet) 1140 { 1141 for (ulI=0; ulI < 1000; ulI++) 1142 { 1143 while (ulSize && ulJ && iRet) { 1144 for (ulI=0; ulI < 1000; ulI++) { 1143 1145 iRet1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_STATUS, (ULONG)__Stack32ToFlat(&status)); 1144 1146 // If here any state and have free buffer to any byte … … 1148 1150 } 1149 1151 if (ulI > 998) { 1150 // printk("timeout stat %x avail:%d hw:%d app:%d\n",status.state,samples_to_bytes(status.avail),samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr));1152 rprintf(("timeout state=%x avail=%d hw=%d app=%d",status.state,samples_to_bytes(status.avail),samples_to_bytes(status.hw_ptr), samples_to_bytes(status.appl_ptr))); 1151 1153 iRet1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1152 1154 } … … 1154 1156 1155 1157 if (iRet1 < 0) { 1156 // printk("Status Error iRet1:%i trans: %i need %d tot:%d\n",iRet1,ulTransferred, ulReqSize,ulSize);1158 rprintf(("iRet1=%i trans=%x ReqSize=%x Size=%x\n", iRet1, ulTransferred, ulReqSize, ulSize)); 1157 1159 break; // We have any global error, don't try more 1158 1160 } 1159 1161 1160 1162 iRet = pHandle->file.f_op->write(&pHandle->file, (char *)ulBuffer, ulSize, &pHandle->file.f_pos); 1163 rprintf(("J=%x iRet=%x", ulJ, iRet)); 1161 1164 1162 1165 if (iRet < 0 ) { // We have any error, don't try more 1163 1166 ulJ--; 1164 if ( iRet != -11 ) 1165 iRet1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1166 // printk("Error ret:%i ret1:%i trans: %d need %d tot:%d\n",iRet,iRet1,ulTransferred, ulReqSize,ulSize); 1167 rprintf(("Error ret=%i ret1=%i trans=%x ReqSize=%x Size=%x", iRet, iRet1, ulTransferred, ulReqSize, ulSize)); 1168 if ( iRet != -11 ) { 1169 rprintf(("Doing prepare")); 1170 iRet1 = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_PCM_IOCTL_PREPARE, 0); 1171 } 1167 1172 continue; 1168 1173 } 1169 if (iRet == 0) continue; 1174 if (iRet == 0) { 1175 continue; 1176 } 1170 1177 ulTransferred += iRet; 1171 1178 // printk("written: now: %d, trans: %d need %d tot:%d\n", iRet, ulTransferred, ulReqSize,ulSize); -
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.