Changeset 604 for GPL/trunk/lib32
- Timestamp:
- Jan 8, 2018, 2:07:36 AM (8 years ago)
- Location:
- GPL/trunk/lib32
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/lib32/Makefile
r598 r604 10 10 !if "$(IBM_BUILD)" == "1" 11 11 CDEFINES += -DIBM_BUILD 12 !endif 13 14 !ifdef %DRV32KIT 15 CDEFINES+= -DUSE_MSI 12 16 !endif 13 17 -
GPL/trunk/lib32/irq.c
r577 r604 42 42 //****************************************************************************** 43 43 44 static IRQ_SLOT arSlots[MAX_IRQ_SLOTS] = { 0 };45 static ULONG eoiIrq[255] = {0};44 static IRQ_SLOT arSlots[MAX_IRQ_SLOTS] = { 0 }; 45 static ULONG eoiIrq[255] = {0}; 46 46 47 47 … … 50 50 static IRQ_SLOT *FindSlot(unsigned irq) 51 51 { 52 IRQ_SLOT*pSlot;53 54 for( pSlot = arSlots; pSlot != &arSlots[MAX_IRQ_SLOTS]; pSlot++ )55 {56 if( pSlot->irqNo == irq )return pSlot;57 }58 59 return NULL;52 IRQ_SLOT *pSlot; 53 54 for( pSlot = arSlots; pSlot != &arSlots[MAX_IRQ_SLOTS]; pSlot++ ) 55 { 56 if( pSlot->irqNo == irq ) return pSlot; 57 } 58 59 return NULL; 60 60 } 61 61 … … 65 65 66 66 int request_irq(unsigned irq, irq_handler_t handler, 67 unsigned long ulSharedFlag, const char *pchName, void *pUserData) 68 { 69 IRQ_SLOT *pSlot = FindSlot(irq & 0xff); 70 unsigned u, uSlotNo = (unsigned)-1; 71 ULONG hRes; 72 73 rprintf(("request_irq: irq %d", irq & 0xff )); 74 if ( !pSlot ) { 75 // find empty slot 76 for( uSlotNo = 0; uSlotNo < MAX_IRQ_SLOTS; uSlotNo++ ) { 77 if( arSlots[uSlotNo].flHandlers == 0 ) { 78 pSlot = &arSlots[uSlotNo]; 79 break; 80 } 81 } 82 } 83 84 if ( pSlot ) { 85 hRes = 0; 86 if (RMRequestIRQ(irq, (ulSharedFlag & SA_SHIRQ) != 0, &hRes) == FALSE) { 87 rprintf(("RMRequestIRQ failed for irq %d", irq)); 88 return 1; 89 } 90 pSlot->irqNo = irq & 0xff; 91 pSlot->hRes = hRes; 92 93 for ( u = 0; u < MAX_SHAREDIRQS; u++ ) { 94 if ( pSlot->irqHandlers[u].handler == NULL ) { 95 pSlot->irqHandlers[u].handler = handler; 96 pSlot->irqHandlers[u].x0 = ulSharedFlag; 97 pSlot->irqHandlers[u].x1 = (char *)pchName; 98 pSlot->irqHandlers[u].x2 = pUserData; 99 100 if( pSlot->flHandlers != 0 || ALSA_SetIrq( irq & 0xff, uSlotNo, (ulSharedFlag & SA_SHIRQ) != 0) ) { 101 pSlot->flHandlers |= 1 << u; 102 return 0; 103 } 104 105 break; 106 } 107 } 108 } 109 110 rprintf(("request_irq: Unable to register irq handler for irq %d", irq & 0xff )); 111 return 1; 67 unsigned long ulSharedFlag, const char *pchName, void *pUserData) 68 { 69 IRQ_SLOT *pSlot = FindSlot(irq & 0xff); 70 unsigned u, uSlotNo = (unsigned)-1; 71 ULONG hRes; 72 73 rprintf(("request_irq: irq %d", irq & 0xff )); 74 if ( !pSlot ) 75 { 76 // find empty slot 77 for( uSlotNo = 0; uSlotNo < MAX_IRQ_SLOTS; uSlotNo++ ) 78 { 79 if( arSlots[uSlotNo].flHandlers == 0 ) 80 { 81 pSlot = &arSlots[uSlotNo]; 82 break; 83 } 84 } 85 } 86 87 if ( pSlot ) 88 { 89 hRes = 0; 90 if (RMRequestIRQ(irq, (ulSharedFlag & SA_SHIRQ) != 0, &hRes) == FALSE) 91 { 92 rprintf(("RMRequestIRQ failed for irq %d", irq)); 93 return 1; 94 } 95 pSlot->irqNo = irq & 0xff; 96 pSlot->hRes = hRes; 97 98 for ( u = 0; u < MAX_SHAREDIRQS; u++ ) 99 { 100 if ( pSlot->irqHandlers[u].handler == NULL ) 101 { 102 pSlot->irqHandlers[u].handler = handler; 103 pSlot->irqHandlers[u].x0 = ulSharedFlag; 104 pSlot->irqHandlers[u].x1 = (char *)pchName; 105 pSlot->irqHandlers[u].x2 = pUserData; 106 107 if( pSlot->flHandlers != 0 || ALSA_SetIrq( irq & 0xff, uSlotNo, (ulSharedFlag & SA_SHIRQ) != 0) ) 108 { 109 pSlot->flHandlers |= 1 << u; 110 return 0; 111 } 112 113 break; 114 } 115 } 116 } 117 118 rprintf(("request_irq: Unable to register irq handler for irq %d", irq & 0xff )); 119 return 1; 112 120 } 113 121 … … 117 125 void free_irq(unsigned int irq, void *userdata) 118 126 { 119 unsignedu;120 IRQ_SLOT*pSlot;121 122 if( (pSlot = FindSlot(irq&0xff)) != NULL ) {123 for( u = 0; u < MAX_SHAREDIRQS; u++ ) {124 if( pSlot->irqHandlers[u].x2 == userdata ) {125 pSlot->flHandlers &= ~(1 << u);126 if( pSlot->flHandlers == 0 ) {127 rprintf(("free_irq: irq %d", irq & 0xff ));128 ALSA_FreeIrq(pSlot->irqNo);129 pSlot->irqNo = 0;130 RMDeallocateIRQ(pSlot->hRes);131 pSlot->hRes = 0;132 // pSlot->fEOI = 0;133 }134 135 pSlot->irqHandlers[u].handler = NULL;136 pSlot->irqHandlers[u].x0 = 0;137 pSlot->irqHandlers[u].x1 = NULL;138 pSlot->irqHandlers[u].x2 = NULL;139 140 return;141 142 }143 }144 }127 unsigned u; 128 IRQ_SLOT *pSlot; 129 130 if( (pSlot = FindSlot(irq&0xff)) != NULL ) { 131 for( u = 0; u < MAX_SHAREDIRQS; u++ ) { 132 if( pSlot->irqHandlers[u].x2 == userdata ) { 133 pSlot->flHandlers &= ~(1 << u); 134 if( pSlot->flHandlers == 0 ) { 135 rprintf(("free_irq: irq %d", irq & 0xff )); 136 ALSA_FreeIrq(pSlot->irqNo); 137 pSlot->irqNo = 0; 138 RMDeallocateIRQ(pSlot->hRes); 139 pSlot->hRes = 0; 140 // pSlot->fEOI = 0; 141 } 142 143 pSlot->irqHandlers[u].handler = NULL; 144 pSlot->irqHandlers[u].x0 = 0; 145 pSlot->irqHandlers[u].x1 = NULL; 146 pSlot->irqHandlers[u].x2 = NULL; 147 148 return; 149 150 } 151 } 152 } 145 153 } 146 154 … … 150 158 void eoi_irq(unsigned int irq) 151 159 { 152 /*(void)irq; */153 /*154 IRQ_SLOT*pSlot = FindSlot(irq);155 156 if( pSlot )pSlot->fEOI = 1;157 */158 eoiIrq[irq & 0xff]++;160 /*(void)irq; */ 161 /* 162 IRQ_SLOT *pSlot = FindSlot(irq); 163 164 if( pSlot ) pSlot->fEOI = 1; 165 */ 166 eoiIrq[irq & 0xff]++; 159 167 } 160 168 … … 164 172 BOOL process_interrupt(ULONG ulSlotNo, ULONG *pulIrq) 165 173 { 166 unsignedu;167 int rc;168 IRQ_SLOT*pSlot;169 170 //dprintf(("enter int proc %d %d",ulSlotNo, *pulIrq));171 172 if( ulSlotNo < MAX_IRQ_SLOTS )173 {174 pSlot = &arSlots[ulSlotNo];175 176 for( u = 0; u < MAX_SHAREDIRQS; u++ )177 {178 if(pSlot && pSlot->irqHandlers[u].handler )179 {180 fInInterrupt = TRUE;174 unsigned u; 175 int rc; 176 IRQ_SLOT *pSlot; 177 178 //dprintf(("enter int proc %d %d",ulSlotNo, *pulIrq)); 179 180 if( ulSlotNo < MAX_IRQ_SLOTS ) 181 { 182 pSlot = &arSlots[ulSlotNo]; 183 184 for( u = 0; u < MAX_SHAREDIRQS; u++ ) 185 { 186 if(pSlot && pSlot->irqHandlers[u].handler ) 187 { 188 fInInterrupt = TRUE; 181 189 #if 0 182 rc = pSlot->irqHandlers[u].handler(pSlot->irqNo,183 pSlot->irqHandlers[u].x2, 0);190 rc = pSlot->irqHandlers[u].handler(pSlot->irqNo, 191 pSlot->irqHandlers[u].x2, 0); 184 192 #else 185 rc = pSlot->irqHandlers[u].handler(pSlot->irqNo,186 pSlot->irqHandlers[u].x2);193 rc = pSlot->irqHandlers[u].handler(pSlot->irqNo, 194 pSlot->irqHandlers[u].x2); 187 195 #endif 188 196 189 // HDA Hardware generates controller interrupts and stream interrupts190 // the uniaud16 driver only cares about stream interrupts.191 // azx_interrupt in alsa-kernel/pci/hda/hda_intel.c will return rc 2 if192 // the interrupt is from the controller. There is no need to call uniaud16193 // for these interrupts194 if ( rc == 2 ) {195 fInInterrupt = FALSE;196 *pulIrq = pSlot->irqNo;197 eoiIrq[pSlot->irqNo] = 0;198 return TRUE;199 }200 201 if (rc == 1) eoi_irq(pSlot->irqNo);202 rc = (eoiIrq[pSlot->irqNo] > 0);203 fInInterrupt = FALSE;204 205 if( rc /*== 1 || pSlot->fEOI*/ ) {206 207 *pulIrq = pSlot->irqNo;208 //pSlot->fEOI = 0;209 210 //ok, this interrupt was intended for us; notify the 16 bits MMPM/2 driver211 OSS32_ProcessIRQ();212 //dprintf(("exit(1) int proc %d %d",ulSlotNo, *pulIrq));213 eoiIrq[pSlot->irqNo] = 0;214 return TRUE;215 }216 }217 }218 }219 //dprintf(("exit(0) int proc %d %d",ulSlotNo, *pulIrq));220 221 return FALSE;197 // HDA Hardware generates controller interrupts and stream interrupts 198 // the uniaud16 driver only cares about stream interrupts. 199 // azx_interrupt in alsa-kernel/pci/hda/hda_intel.c will return rc 2 if 200 // the interrupt is from the controller. There is no need to call uniaud16 201 // for these interrupts 202 if ( rc == 2 ) { 203 fInInterrupt = FALSE; 204 *pulIrq = pSlot->irqNo; 205 eoiIrq[pSlot->irqNo] = 0; 206 return TRUE; 207 } 208 209 if (rc == 1) eoi_irq(pSlot->irqNo); 210 rc = (eoiIrq[pSlot->irqNo] > 0); 211 fInInterrupt = FALSE; 212 213 if( rc /*== 1 || pSlot->fEOI*/ ) { 214 215 *pulIrq = pSlot->irqNo; 216 // pSlot->fEOI = 0; 217 218 //ok, this interrupt was intended for us; notify the 16 bits MMPM/2 driver 219 OSS32_ProcessIRQ(); 220 //dprintf(("exit(1) int proc %d %d",ulSlotNo, *pulIrq)); 221 eoiIrq[pSlot->irqNo] = 0; 222 return TRUE; 223 } 224 } 225 } 226 } 227 //dprintf(("exit(0) int proc %d %d",ulSlotNo, *pulIrq)); 228 229 return FALSE; 222 230 } 223 231 … … 227 235 int in_interrupt() 228 236 { 229 return fInInterrupt;237 return fInInterrupt; 230 238 } 231 239 … … 235 243 void disable_irq(int irq) 236 244 { 237 dprintf(("disable_irq %d NOT implemented", irq));238 } 239 240 //****************************************************************************** 241 //****************************************************************************** 242 245 dprintf(("disable_irq %d NOT implemented", irq)); 246 } 247 248 //****************************************************************************** 249 //****************************************************************************** 250 -
GPL/trunk/lib32/pci.c
r602 r604 245 245 pcidev->irq_resource[0].start = pcidev->irq_resource[0].end = ulTmp1 & 0xffff; 246 246 pcidev->irq = (u8)ulTmp1; // This is the interrupt used for init time processing 247 pcidev->irq_pin = ulTmp1>>8; 247 248 } 248 249 … … 1015 1016 } 1016 1017 1018 #ifdef USE_MSI 1019 extern int __syscall UniMsiAlloc(USHORT usBusDevFunc, ULONG *pulCount, UCHAR *pucIrq); 1020 int snd_pci_enable_msi(struct pci_dev *dev) 1021 { 1022 ULONG p; 1023 UCHAR irq; 1024 1025 if (dev->irq_pin) 1026 { 1027 p = 1; /* int count */ 1028 if (UniMsiAlloc((dev->bus->number<<8) | dev->devfn, &p, &irq)) return -1; 1029 /* we have an msi interrupt */ 1030 dev->irq = irq; 1031 dev->irq_pin = 0; 1032 } 1033 return 0; 1034 } 1035 #else 1036 int snd_pci_enable_msi(struct pci_dev *dev) 1037 { 1038 return -1; 1039 } 1040 #endif 1041 -
GPL/trunk/lib32/sound.c
r598 r604 976 976 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_RATE, 977 977 pHwParams->ulSampleRate, 0); 978 979 /* Change from Andy. If statement added around 5 statements. 980 * Andy says: TODO: determine why small buffers are a problem for this code 981 * DAZ: This change is questionable. 982 */ 983 if (periodsize > 6 * minperiodsize) 984 { 978 985 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 979 986 periodsize, 0); … … 986 993 _snd_pcm_hw_param_set(¶ms, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 987 994 periodbytes*nrperiods, 0); 988 995 } 989 996 990 997 dprintf(("HWP: SR rate %ld, BPS %ld, CH %ld, PRSZ %lx, periods %lx", -
GPL/trunk/lib32/soundmixer.c
r598 r604 41 41 42 42 static struct { 43 char *name;44 unsigned int index;45 unsigned int recsrc;43 char *name; 44 unsigned int index; 45 unsigned int recsrc; 46 46 } ossid[OSS_MIXER_NRDEVICES] = { 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},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 "Mic", "CD", "Line", "Video", "Aux", "Mix", "Mix Mono", "Phone", "Synth"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, 99, 99, 100, 100, 100, 100, 100,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 if(ulLinVolume > OSS32_MAX_VOLUME) {102 ulLinVolume = OSS32_MAX_VOLUME;103 }104 ulLinVolume = LinToLog[ulLinVolume];105 106 return (ulLinVolume * ulLogVolMax) / OSS32_MAX_VOLUME;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 mixerhandle *pHandle = NULL;114 intret, 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-blocking136 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 information150 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 elements157 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 elements166 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 elements171 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 }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 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 }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 names190 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 match204 pHandle->controls[j].idxVolume = i;205 break;206 } else { //first part of the control name is correct; now find out what is it exactly207 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 control213 pHandle->controls[j].idxVolume = i;214 }215 else216 if(strncmp(nextword, MIXER_PLAYBACKSWITCH, sizeof(MIXER_PLAYBACKSWITCH)-1) == 0 ||217 strncmp(nextword, MIXER_SWITCH, sizeof(MIXER_SWITCH)-1) == 0)218 { //mute control219 pHandle->controls[j].idxMute = i;220 if (pHandle->controls[j].idxVolume == -1) pHandle->controls[j].idxVolume = i;221 }222 else223 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 else228 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 else234 if(i == OSS_MIXER_MIC) {235 if(strncmp(nextword, MIXER_BOOST, sizeof(MIXER_BOOST)-1) == 0) { //mic boost switch236 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 sources250 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-blocking257 pHandle->file.f_flags = O_NONBLOCK;258 259 pHandle->rectype = RECTYPE_SELECTOR;260 261 //too big to put on the stack262 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 index286 break;287 }288 }289 }290 kfree(pElemInfo);291 }292 else293 {//This card has no record source selection, but probably route switches for294 //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 index304 }305 }306 }307 308 pHandle->magic = MAGIC_MIXER_ALSA32;309 *pStreamId = (ULONG)pHandle;310 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; 311 311 312 312 failure: 313 if(pHandle) {314 if(pHandle->pids) kfree(pHandle->pids);315 kfree(pHandle);316 }317 DebugInt3();318 return OSSERR_OUT_OF_MEMORY;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 mixerhandle *pHandle = (mixerhandle *)streamid;325 intret;326 327 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {328 DebugInt3();329 return OSSERR_INVALID_STREAMID;330 }331 //set operation to non-blocking332 pHandle->file.f_flags = O_NONBLOCK;333 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);334 kfree(pHandle->pids); //free mixer element array335 kfree(pHandle);//free handle data336 337 if(ret) {338 DebugInt3();339 return UNIXToOSSError(ret);340 }341 return OSSERR_SUCCESS;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 mixerhandle *pHandle = (mixerhandle *)streamid;348 //intret;349 350 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {351 DebugInt3();352 return OSSERR_INVALID_STREAMID;353 }354 //set operation to non-blocking355 pHandle->file.f_flags = O_NONBLOCK;356 357 return OSSERR_NOT_SUPPORTED;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 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);517 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem); 511 518 #else 512 // looking for more, then one opened streams to prevent of muting active stream513 cnt = 0;514 for (idx=0; idx < 8*256; idx++)515 if (opened_handles[idx].handle != 0)516 cnt++;517 518 dprintf(("OSS32_MixSetVolume old cnt=%X line=%x lVol=%x rVol=%x", cnt, line, lVol, rVol));519 //if (((cnt == 1 && (lVol==0 && rVol==0)) || (lVol>0 && rVol>0)) ||520 if (cnt == 1 || line != OSS32_MIX_VOLUME_PCM)521 {522 dprintf(("OSS32_MixSetVolume Ioctl"));523 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);524 525 if(idxMute != -1 && volume == 0) {526 //enable mute527 pElem->id.numid = pHandle->pids[idxMute].numid;528 pElem->indirect = 0;529 530 pElem->value.integer.value[0] = FALSE;//switch, not mute control (inversed)531 pElem->value.integer.value[1] = FALSE;532 dprintf(("OSS32_MixSetVolume Ioctl mute"));533 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);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 kfree(pElem);539 pElem = NULL;540 if(ret) {541 rprintf(("OSS32_MixSetVolume ret=%x", ret));542 DebugInt3();543 return UNIXToOSSError(ret);544 }545 return OSSERR_SUCCESS;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 if(pElem) kfree(pElem);549 return ret;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 struct snd_ctl_elem_value *pElem = NULL;557 struct snd_ctl_elem_info *pElemInfo;558 intret, idx = -1, lVol, rVol = 0, j, i;559 560 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {561 DebugInt3();562 return OSSERR_INVALID_STREAMID;563 }564 //set operation to non-blocking565 pHandle->file.f_flags = O_NONBLOCK;566 567 //too big to put on the stack568 pElem = (struct snd_ctl_elem_value *)kmalloc(sizeof(struct snd_ctl_elem_value) + sizeof(struct snd_ctl_elem_info), GFP_KERNEL);569 if(pElem == NULL) {570 DebugInt3();571 return OSSERR_OUT_OF_MEMORY;572 }573 pElemInfo = (struct snd_ctl_elem_info *)(pElem+1);574 575 switch(ulLine) {576 case OSS32_MIX_INPUTSRC:577 idx = pHandle->controls[OSS_MIXER_IGAIN].idxCustom;578 //is this capture source supported by the hardware??579 if(!(pHandle->reccaps & OSS32_MIX_FLAG(ulValue))) {580 DebugInt3();581 ret = OSSERR_INVALID_PARAMETER;582 goto fail;583 }584 if(pHandle->rectype == RECTYPE_SELECTOR) {//input source selector585 //set left and right capture source586 pElem->value.enumerated.item[0] = pHandle->idxRecCaps[ulValue];587 pElem->value.enumerated.item[1] = pHandle->idxRecCaps[ulValue];588 }589 else {//capture switch for each input source590 //first turn off all capture switches...591 for(j=0;j<OSS32_MIX_RECSRC_MAX;j++)592 {593 if(pHandle->idxRecCaps[j] != -1) {594 idx= pHandle->idxRecCaps[j];595 596 //request information about mixer control597 pElemInfo->id.numid= pHandle->pids[idx].numid;598 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);599 if(ret) {600 ret = UNIXToOSSError(ret);601 DebugInt3();602 goto fail;603 }604 if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN) {605 ret = OSSERR_INVALID_PARAMETER;606 DebugInt3();607 goto fail;608 }609 610 pElem->id.numid= pHandle->pids[idx].numid;611 pElem->indirect= 0;612 for(i=0;i<pElemInfo->count;i++) {613 pElem->value.integer.value[i] = 0;614 }615 616 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);617 if(ret) {618 ret = UNIXToOSSError(ret);619 DebugInt3();620 goto fail;621 }622 }623 }624 //request information about mixer control625 pElemInfo->id.numid = pHandle->pids[idx].numid;626 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);627 if(ret) {628 ret = UNIXToOSSError(ret);629 DebugInt3();630 goto fail;631 }632 633 //and enable the capture switch for the selected input source634 idx = pHandle->idxRecCaps[ulValue];635 for(i=0;i<pElemInfo->count;i++) {636 pElem->value.integer.value[i] = 1;637 }638 }639 640 break;641 642 case OSS32_MIX_SWITCH_MICBOOST:643 idx = pHandle->controls[OSS_MIXER_MIC].idxCustom;644 if(idx == -1) {645 DebugInt3();646 ret = OSSERR_INVALID_PARAMETER;647 goto fail;648 }649 //set mic switch value (on/off)650 pElem->value.integer.value[0] = ulValue;651 break;652 653 case OSS32_MIX_LEVEL_BASS:654 idx = pHandle->controls[OSS_MIXER_BASS].idxVolume;655 goto levelcontinue;656 case OSS32_MIX_LEVEL_TREBLE:657 idx = pHandle->controls[OSS_MIXER_TREBLE].idxVolume;658 goto levelcontinue;659 case OSS32_MIX_LEVEL_3DCENTER:660 idx = pHandle->controls[OSS_MIXER_3DCENTER].idxVolume;661 goto levelcontinue;662 case OSS32_MIX_LEVEL_3DDEPTH:663 idx = pHandle->controls[OSS_MIXER_3DDEPTH].idxVolume;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 if(idx == -1) {//supported?667 DebugInt3();668 ret = OSSERR_INVALID_PARAMETER;669 goto fail;670 }671 //request information about mixer control672 pElemInfo->id.numid = pHandle->pids[idx].numid;673 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);674 if(ret) {675 ret = UNIXToOSSError(ret);676 DebugInt3();677 goto fail;678 }679 if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_INTEGER) {680 ret = OSSERR_INVALID_PARAMETER;681 DebugInt3();682 goto fail;683 }684 lVol = ConvertVolume(GET_VOLUME_L(ulValue), pElemInfo->value.integer.max);685 pElem->value.integer.value[0] = lVol;686 687 if(pElemInfo->count > 1) { //stereo688 rVol = ConvertVolume(GET_VOLUME_R(ulValue), pElemInfo->value.integer.max);689 pElem->value.integer.value[1] = rVol;690 }691 break;692 693 default:694 DebugInt3();695 ret = OSSERR_INVALID_PARAMETER;696 goto fail;697 }698 pElem->id.numid = pHandle->pids[idx].numid;699 pElem->indirect = 0;700 701 dprintf(("OSS32_MixSetProperty of %s to %x", pHandle->pids[idx].name, ulValue));702 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);703 704 kfree(pElem);705 pElem = NULL;706 if(ret) {707 DebugInt3();708 return UNIXToOSSError(ret);709 }710 return OSSERR_SUCCESS;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 if(pElem) kfree(pElem);714 return ret;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 mixerhandle *pHandle = (mixerhandle *)streamid;721 //intret;722 723 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {724 DebugInt3();725 return OSSERR_INVALID_STREAMID;726 }727 //set operation to non-blocking728 pHandle->file.f_flags = O_NONBLOCK;729 730 return OSSERR_NOT_SUPPORTED;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 switch(OSSVolIdx) {737 case OSS_MIXER_VOLUME:738 return OSS32_MIX_VOLUME_MASTER_FRONT;743 switch(OSSVolIdx) { 744 case OSS_MIXER_VOLUME: 745 return OSS32_MIX_VOLUME_MASTER_FRONT; 739 746 #if 0 740 case OSS_MIXER_VOLUME: //TODO:741 return OSS32_MIX_VOLUME_MASTER_REAR;747 case OSS_MIXER_VOLUME: //TODO: 748 return OSS32_MIX_VOLUME_MASTER_REAR; 742 749 #endif 743 case OSS_MIXER_PCM:744 return OSS32_MIX_VOLUME_PCM;745 case OSS_MIXER_SYNTH:746 return OSS32_MIX_VOLUME_MIDI;747 case OSS_MIXER_LINE:748 return OSS32_MIX_VOLUME_LINEIN;749 case OSS_MIXER_MIC:750 return OSS32_MIX_VOLUME_MIC;751 case OSS_MIXER_CD:752 return OSS32_MIX_VOLUME_CD;753 case OSS_MIXER_DIGITAL1:754 return OSS32_MIX_VOLUME_SPDIF;755 case OSS_MIXER_VIDEO:756 return OSS32_MIX_VOLUME_VIDEO;757 case OSS_MIXER_PCSPEAKER:758 return OSS32_MIX_VOLUME_PCSPEAKER;759 case OSS_MIXER_PHONEOUT:760 return OSS32_MIX_VOLUME_PHONE;761 case OSS_MIXER_IGAIN:762 return OSS32_MIX_VOLUME_CAPTURE;763 case OSS_MIXER_TREBLE:764 return OSS32_MIX_LEVEL_TREBLE;765 case OSS_MIXER_BASS:766 return OSS32_MIX_LEVEL_BASS;767 case OSS_MIXER_HEADPHONE:768 return OSS32_MIX_VOLUME_HEADPHONE;769 case OSS_MIXER_SPEAKER:770 return OSS32_MIX_VOLUME_SPEAKER;771 case OSS_MIXER_LINE1:772 return OSS32_MIX_VOLUME_AUX;773 }774 return -1;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 mixerhandle *pHandle = (mixerhandle *)streamid;781 int i;782 783 if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {784 DebugInt3();785 return OSSERR_INVALID_STREAMID;786 }787 788 strncpy(pCaps->name, pHandle->info.mixername, sizeof(pCaps->name));789 pCaps->fuCtrlCaps = 0;790 pCaps->fuRecCaps = 0;791 792 for(i=0;i<OSS_MIXER_NRDEVICES;i++)793 {794 if(pHandle->controls[i].idxVolume != -1) {795 ULONG volidx = OSSToALSAVolume(i);796 if(volidx != -1)797 pCaps->fuCtrlCaps |= OSS32_MIX_FLAG(volidx);798 }799 }800 801 //if it has a capture source control or the card has capture route switches,802 //then we support intput source selection803 if(pHandle->controls[OSS_MIXER_IGAIN].idxCustom != -1 ||804 pHandle->rectype == RECTYPE_SWITCH)805 {806 pCaps->fuCtrlCaps |= OSS32_MIX_FLAG(OSS32_MIX_INPUTSRC);807 pCaps->fuRecCaps = pHandle->reccaps;808 }809 return OSSERR_SUCCESS;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 mixerhandle *pHandle = NULL;816 intret;817 //int i, j;818 819 if(alsa_fops == NULL)820 return OSSERR_NO_DEVICE_AVAILABLE;821 822 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);823 if(pHandle == NULL) {824 ret = OSSERR_OUT_OF_MEMORY;825 goto failure;826 }827 memset(pHandle, 0, sizeof(mixerhandle));828 829 //set operation to non-blocking830 pHandle->file.f_flags = O_NONBLOCK;831 832 //setup pointers in file structure (used internally by ALSA)833 pHandle->file.f_dentry= &pHandle->d_entry;834 pHandle->file.f_dentry->d_inode = &pHandle->inode;835 836 pHandle->file.f_mode = FMODE_WRITE;837 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);838 839 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);840 if(ret) {841 goto failure;842 }843 //retrieve mixer information844 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,845 SNDRV_CTL_IOCTL_CARD_INFO,846 (ULONG)&pHandle->info);847 if(ret) {848 goto failure;849 }850 851 strncpy(pszMixerName, pHandle->info.mixername, cbMixerName);852 853 pHandle->file.f_flags = O_NONBLOCK;854 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);855 if(ret) {856 goto failure;857 }858 kfree(pHandle);859 return OSSERR_SUCCESS;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 if(pHandle) {863 kfree(pHandle);864 }865 DebugInt3();866 return OSSERR_OUT_OF_MEMORY;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 char *pszMixerName, ULONG cbMixerName, BOOL fLongName)872 { 873 mixerhandle *pHandle = NULL;874 intret;875 //int i, j;876 877 if(alsa_fops == NULL) {878 ret = OSSERR_NO_DEVICE_AVAILABLE;879 printk("ret = OSSERR_NO_DEVICE_AVAILABLE\n");880 goto failure;881 }882 883 pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);884 if(pHandle == NULL) {885 ret = OSSERR_OUT_OF_MEMORY;886 goto failure;887 }888 memset(pHandle, 0, sizeof(mixerhandle));889 890 //set operation to non-blocking891 pHandle->file.f_flags = O_NONBLOCK;892 893 //setup pointers in file structure (used internally by ALSA)894 pHandle->file.f_dentry= &pHandle->d_entry;895 pHandle->file.f_dentry->d_inode = &pHandle->inode;896 897 pHandle->file.f_mode = FMODE_WRITE;898 pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);899 900 ret = alsa_fops->open(&pHandle->inode, &pHandle->file);901 if(ret) {902 printk("open ret = %i\n", ret);903 goto failure;904 }905 //retrieve mixer information906 ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,907 SNDRV_CTL_IOCTL_CARD_INFO,908 (ULONG)&pHandle->info);909 if(ret) {910 printk("ioctl ret = %i\n", ret);911 goto failure;912 }913 914 if(pszDeviceName) {915 if(fLongName == TRUE) {916 strncpy(pszDeviceName, pHandle->info.longname, cbDeviceName);917 }918 else strncpy(pszDeviceName, pHandle->info.name, cbDeviceName);919 }920 if(pszMixerName) {921 strncpy(pszMixerName, pHandle->info.mixername, cbMixerName);922 }923 924 // printk("Card: %s with mixer %s\n",pszDeviceName, pszMixerName);925 926 pHandle->file.f_flags = O_NONBLOCK;927 ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);928 if(ret) {929 printk("release ret = %i\n", ret);930 goto failure;931 }932 kfree(pHandle);933 return OSSERR_SUCCESS;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 if(pHandle) {937 kfree(pHandle);938 }939 DebugInt3();940 printk("OSS32_QueryNames() ret = %i\n", ret);941 return OSSERR_OUT_OF_MEMORY;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.
