Ignore:
Timestamp:
Jul 25, 2010, 7:16:22 PM (15 years ago)
Author:
David Azarewicz
Message:

debug statement changes, add quirk for eMachines STAC mixer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • GPL/trunk/lib32/soundmixer.c

    r518 r528  
    4141
    4242static struct {
    43     char *name;
    44     unsigned int index;
    45     unsigned int recsrc;
     43        char *name;
     44        unsigned int index;
     45        unsigned int recsrc;
    4646} ossid[OSS_MIXER_NRDEVICES] = {
    4747        /* OSS_MIXER_VOLUME   */ { "Master", 0 , -1},
    48         /* OSS_MIXER_BASS     */ { "Tone Control - Bass", 0, -1},
     48        /* OSS_MIXER_BASS         */ { "Tone Control - Bass", 0, -1},
    4949        /* 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},
     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},
    5757        /* OSS_MIXER_ALTPCM   */ { "PCM",       1 , -1},
    5858        /* 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},
     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},
    6464        /* OSS_MIXER_DIGITAL1 */ { "Digital", 0 , -1},
    6565        /* OSS_MIXER_DIGITAL2 */ { "Digital", 1 , -1},
     
    6767        /* OSS_MIXER_PHONEIN  */ { "Phone", 0 , OSS32_MIX_RECSRC_PHONE},
    6868        /* OSS_MIXER_PHONEOUT */ { "Phone", 1 , -1},
    69         /* OSS_MIXER_VIDEO    */ { "Video", 0 , OSS32_MIX_RECSRC_VIDEO},
    70         /* OSS_MIXER_RADIO    */ { "Radio", 0 , -1},
     69        /* OSS_MIXER_VIDEO        */ { "Video", 0 , OSS32_MIX_RECSRC_VIDEO},
     70        /* OSS_MIXER_RADIO        */ { "Radio", 0 , -1},
    7171        /* OSS_MIXER_MONITOR  */ { "Monitor", 0 , -1},
    7272        /* OSS_MIXER_3DDEPTH  */ { "3D Control - Depth", 0 , -1},
    73     /* OSS_MIXER_3DCENTER */ { "3D Control - Center", 0 , -1},
    74         /* OSS_MIXER_FRONT    */ { "Front", 0 , -1},
     73        /* OSS_MIXER_3DCENTER */ { "3D Control - Center", 0 , -1},
     74        /* OSS_MIXER_FRONT        */ { "Front", 0 , -1},
    7575        /* OSS_MIXER_SPEAKER  */ { "Speaker", 0 , -1},
    7676        /* OSS_MIXER_HEADPHONE */ { "Headphone", 0 , -1},
    7777};
    7878char *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"
    8080};
    8181
    8282static 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,
    9393 100
    9494};
     
    9999ULONG ConvertVolume(ULONG ulLinVolume, ULONG ulLogVolMax)
    100100{
    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;
    107107}
    108108
     
    111111OSSRET OSS32_MixOpen(ULONG deviceid, OSSSTREAMID *pStreamId)
    112112{
    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     }
     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        }
    180180
    181181#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        }
    187187#endif
    188188
    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;
    321311
    322312failure:
    323     if(pHandle) {
    324         if(pHandle->pids) kfree(pHandle->pids);
    325         kfree(pHandle);
    326     }
    327     DebugInt3();
    328     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;
    329319}
    330320//******************************************************************************
     
    332322OSSRET OSS32_MixClose(OSSSTREAMID streamid)
    333323{
    334     mixerhandle *pHandle = (mixerhandle *)streamid;
    335     int          ret;
    336 
    337     if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {
    338         DebugInt3();
    339         return OSSERR_INVALID_STREAMID;
    340     }
    341     //set operation to non-blocking
    342     pHandle->file.f_flags = O_NONBLOCK;
    343     ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
    344     kfree(pHandle->pids);  //free mixer element array
    345     kfree(pHandle);        //free handle data
    346 
    347     if(ret) {
    348         DebugInt3();
    349         return UNIXToOSSError(ret);
    350     }
    351     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;
    352342}
    353343//******************************************************************************
     
    355345OSSRET OSS32_MixGetVolume(OSSSTREAMID streamid, ULONG line, ULONG *pVolume)
    356346{
    357     mixerhandle *pHandle = (mixerhandle *)streamid;
    358     int          ret;
    359 
    360     if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {
    361         DebugInt3();
    362         return OSSERR_INVALID_STREAMID;
    363     }
    364     //set operation to non-blocking
    365     pHandle->file.f_flags = O_NONBLOCK;
    366 
    367     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;
    368358}
    369359//******************************************************************************
     
    371361OSSRET OSS32_MixSetVolume(OSSSTREAMID streamid, ULONG line, ULONG volume)
    372362{
    373     mixerhandle          *pHandle = (mixerhandle *)streamid;
    374     struct snd_ctl_elem_value *pElem = NULL;
    375     struct snd_ctl_elem_info  *pElemInfo;
    376     int                   ret, idx, lVol, rVol = 0, idxMute, cnt;
    377 
    378     //dprintf(("OSS32_MixSetVolume line=%d\n", line));
    379     if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {
    380         printk("Invalid handle in OSS32_MixSetVolume\n");
    381         DebugInt3();
    382         return OSSERR_INVALID_STREAMID;
    383     }
    384     //set operation to non-blocking
    385     pHandle->file.f_flags = O_NONBLOCK;
    386 
    387     //too big to put on the stack
    388     pElem = (struct snd_ctl_elem_value *)kmalloc(sizeof(struct snd_ctl_elem_value) + sizeof(struct snd_ctl_elem_info), GFP_KERNEL);
    389     if(pElem == NULL) {
    390         printk("Out of memory in OSS32_MixSetVolume\n");
    391         DebugInt3();
    392         return OSSERR_OUT_OF_MEMORY;
    393     }
    394     pElemInfo = (struct snd_ctl_elem_info *)(pElem+1);
    395 
    396     switch(line) {
    397     case OSS32_MIX_VOLUME_MASTER_FRONT:
    398         idx = pHandle->controls[OSS_MIXER_VOLUME].idxVolume;
    399         idxMute = pHandle->controls[OSS_MIXER_VOLUME].idxMute;
    400         if (idx == -1)
    401         {
    402             /* HDA codecs workaround */
    403             idx = pHandle->controls[OSS_MIXER_FRONT].idxVolume;
    404             idxMute = pHandle->controls[OSS_MIXER_FRONT].idxMute;
    405         }
    406         break;
    407     case OSS32_MIX_VOLUME_MASTER_REAR: //TODO:
    408         idx = pHandle->controls[OSS_MIXER_VOLUME].idxVolume;
    409         idxMute = pHandle->controls[OSS_MIXER_VOLUME].idxMute;
    410         break;
    411     case OSS32_MIX_VOLUME_PCM:
    412         idx = pHandle->controls[OSS_MIXER_PCM].idxVolume;
    413         idxMute = pHandle->controls[OSS_MIXER_PCM].idxMute;
    414         if (idx == -1)
    415         {
    416             /* HDA codecs workaround */
    417             idx = pHandle->controls[OSS_MIXER_FRONT].idxVolume;
    418             idxMute = pHandle->controls[OSS_MIXER_FRONT].idxMute;
    419         }
    420         break;
    421     case OSS32_MIX_VOLUME_MIDI:
    422         idx = pHandle->controls[OSS_MIXER_SYNTH].idxVolume;
    423         idxMute = pHandle->controls[OSS_MIXER_SYNTH].idxMute;
    424         break;
    425     case OSS32_MIX_VOLUME_LINEIN:
    426         idx = pHandle->controls[OSS_MIXER_LINE].idxVolume;
    427         idxMute = pHandle->controls[OSS_MIXER_LINE].idxMute;
    428         break;
    429     case OSS32_MIX_VOLUME_MIC:
    430         idx = pHandle->controls[OSS_MIXER_MIC].idxVolume;
    431         idxMute = pHandle->controls[OSS_MIXER_MIC].idxMute;
    432         break;
    433     case OSS32_MIX_VOLUME_CD:
    434         idx = pHandle->controls[OSS_MIXER_CD].idxVolume;
    435         idxMute = pHandle->controls[OSS_MIXER_CD].idxMute;
    436         break;
    437     case OSS32_MIX_VOLUME_SPDIF:
    438         idx = pHandle->controls[OSS_MIXER_DIGITAL1].idxVolume;
    439         idxMute = pHandle->controls[OSS_MIXER_DIGITAL1].idxMute;
    440         break;
    441     case OSS32_MIX_VOLUME_VIDEO:
    442         idx = pHandle->controls[OSS_MIXER_VIDEO].idxVolume;
    443         idxMute = pHandle->controls[OSS_MIXER_VIDEO].idxMute;
    444         break;
    445     case OSS32_MIX_VOLUME_PCSPEAKER:
    446         idx = pHandle->controls[OSS_MIXER_PCSPEAKER].idxVolume;
    447         idxMute = pHandle->controls[OSS_MIXER_PCSPEAKER].idxMute;
    448         break;
    449     case OSS32_MIX_VOLUME_PHONE:
    450         idx = pHandle->controls[OSS_MIXER_PHONEOUT].idxVolume;
    451         idxMute = pHandle->controls[OSS_MIXER_PHONEOUT].idxMute;
    452         break;
    453     case OSS32_MIX_VOLUME_HEADPHONE:
    454         idx = pHandle->controls[OSS_MIXER_HEADPHONE].idxVolume;
    455         idxMute = pHandle->controls[OSS_MIXER_HEADPHONE].idxMute;
    456         break;
    457     case OSS32_MIX_VOLUME_SPEAKER:
    458         idx = pHandle->controls[OSS_MIXER_SPEAKER].idxVolume;
    459         idxMute = pHandle->controls[OSS_MIXER_SPEAKER].idxMute;
    460         break;
    461     case OSS32_MIX_VOLUME_AUX:
    462         idx = pHandle->controls[OSS_MIXER_LINE1].idxVolume;
    463         idxMute = pHandle->controls[OSS_MIXER_LINE1].idxMute;
    464         break;
    465     case OSS32_MIX_VOLUME_CAPTURE:
    466         idx = pHandle->controls[OSS_MIXER_IGAIN].idxVolume;
    467         idxMute = pHandle->controls[OSS_MIXER_IGAIN].idxMute;
    468         break;
    469 
    470     default:
    471         DebugInt3();
    472         ret = OSSERR_INVALID_PARAMETER;
    473         goto fail;
    474     }
    475     if(idx == -1) {
    476         rprintf(("Unknown control %d", line));
    477         ret = OSSERR_INVALID_PARAMETER;
    478         goto fail;
    479     }
    480 
    481     if(idxMute != -1 && volume != 0) {
    482         //disable mute
    483         pElem->id.numid = pHandle->pids[idxMute].numid;
    484         pElem->indirect = 0;
    485 
    486         pElem->value.integer.value[0] = TRUE;  //switch, not mute control (inversed)
    487         pElem->value.integer.value[1] = TRUE;
    488         ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
    489     }
    490     //request information about mixer control
    491     pElemInfo->id.numid = pHandle->pids[idx].numid;
    492     ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
    493     if(ret) {
    494         ret = UNIXToOSSError(ret);
    495         DebugInt3();
    496         goto fail;
    497     }
    498     if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_INTEGER) {
    499         ret = OSSERR_INVALID_PARAMETER;
    500         DebugInt3();
    501         goto fail;
    502     }
    503     pElem->id.numid = pHandle->pids[idx].numid;
    504     pElem->indirect = 0;
    505 
    506     lVol = ConvertVolume(GET_VOLUME_L(volume), pElemInfo->value.integer.max);
    507     pElem->value.integer.value[0] = lVol;
    508 
    509     if(pElemInfo->count > 1) { //stereo
    510         rVol = ConvertVolume(GET_VOLUME_R(volume), pElemInfo->value.integer.max);
    511         pElem->value.integer.value[1] = rVol;
    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        }
    513503
    514504        dprintf(("OSS32_MixSetVolume of %s streamid %X to (%d,%d)(%d,%d) caps %d",
     
    519509        ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
    520510#else
    521     // looking for more, then one opened streams to prevent of muting active stream
    522     cnt = 0;
    523     for (idx=0; idx < 8*256; idx++)
    524         if (opened_handles[idx].handle != 0)
    525             cnt++;
     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++;
    526516
    527517        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     if (cnt == 1 || line != OSS32_MIX_VOLUME_PCM)
    530     {
     518        //        if (((cnt == 1 && (lVol==0 && rVol==0)) || (lVol>0 && rVol>0)) ||
     519        if (cnt == 1 || line != OSS32_MIX_VOLUME_PCM)
     520        {
    531521                dprintf(("OSS32_MixSetVolume Ioctl"));
    532         ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
    533 
    534         if(idxMute != -1 && volume == 0) {
    535             //enable mute
    536             pElem->id.numid = pHandle->pids[idxMute].numid;
    537             pElem->indirect = 0;
    538 
    539             pElem->value.integer.value[0] = FALSE;  //switch, not mute control (inversed)
    540             pElem->value.integer.value[1] = FALSE;
     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;
    541531                        dprintf(("OSS32_MixSetVolume Ioctl mute"));
    542             ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
    543         }
    544     }
     532                        ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
     533                }
     534        }
    545535#endif
    546536
    547     kfree(pElem);
    548     pElem = NULL;
    549     if(ret) {
    550         rprintf(("OSS32_MixSetVolume ret=%x", ret));
    551         DebugInt3();
    552         return UNIXToOSSError(ret);
    553     }
    554     return OSSERR_SUCCESS;
     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;
    555545
    556546fail:
    557     if(pElem) kfree(pElem);
    558     return ret;
     547        if(pElem) kfree(pElem);
     548        return ret;
    559549}
    560550//******************************************************************************
     
    562552OSSRET OSS32_MixSetProperty(OSSSTREAMID streamid, ULONG ulLine, ULONG ulValue)
    563553{
    564     mixerhandle          *pHandle = (mixerhandle *)streamid;
    565     struct snd_ctl_elem_value *pElem = NULL;
    566     struct snd_ctl_elem_info  *pElemInfo;
    567     int                   ret, idx = -1, lVol, rVol = 0, j, i;
    568 
    569     if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {
    570         DebugInt3();
    571         return OSSERR_INVALID_STREAMID;
    572     }
    573     //set operation to non-blocking
    574     pHandle->file.f_flags = O_NONBLOCK;
    575 
    576     //too big to put on the stack
    577     pElem = (struct snd_ctl_elem_value *)kmalloc(sizeof(struct snd_ctl_elem_value) + sizeof(struct snd_ctl_elem_info), GFP_KERNEL);
    578     if(pElem == NULL) {
    579         DebugInt3();
    580         return OSSERR_OUT_OF_MEMORY;
    581     }
    582     pElemInfo = (struct snd_ctl_elem_info *)(pElem+1);
    583 
    584     switch(ulLine) {
    585     case OSS32_MIX_INPUTSRC:
    586         idx = pHandle->controls[OSS_MIXER_IGAIN].idxCustom;
    587         //is this capture source supported by the hardware??
    588         if(!(pHandle->reccaps & OSS32_MIX_FLAG(ulValue))) {
    589             DebugInt3();
    590             ret = OSSERR_INVALID_PARAMETER;
    591             goto fail;
    592         }
    593         if(pHandle->rectype == RECTYPE_SELECTOR) {//input source selector
    594             //set left and right capture source
    595             pElem->value.enumerated.item[0] = pHandle->idxRecCaps[ulValue];
    596             pElem->value.enumerated.item[1] = pHandle->idxRecCaps[ulValue];
    597         }
    598         else {//capture switch for each input source
    599             //first turn off all capture switches...
    600             for(j=0;j<OSS32_MIX_RECSRC_MAX;j++)
    601             {
    602                 if(pHandle->idxRecCaps[j] != -1) {
    603                     idx                           = pHandle->idxRecCaps[j];
    604 
    605                     //request information about mixer control
    606                     pElemInfo->id.numid           = pHandle->pids[idx].numid;
    607                     ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
    608                     if(ret) {
    609                         ret = UNIXToOSSError(ret);
    610                         DebugInt3();
    611                         goto fail;
    612                     }
    613                     if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN) {
    614                         ret = OSSERR_INVALID_PARAMETER;
    615                         DebugInt3();
    616                         goto fail;
    617                     }
    618 
    619                     pElem->id.numid               = pHandle->pids[idx].numid;
    620                     pElem->indirect               = 0;
    621                     for(i=0;i<pElemInfo->count;i++) {
    622                         pElem->value.integer.value[i] = 0;
    623                     }
    624 
    625                     ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
    626                     if(ret) {
    627                         ret = UNIXToOSSError(ret);
    628                         DebugInt3();
    629                         goto fail;
    630                     }
    631                 }
    632             }
    633             //request information about mixer control
    634             pElemInfo->id.numid = pHandle->pids[idx].numid;
    635             ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
    636             if(ret) {
    637                 ret = UNIXToOSSError(ret);
    638                 DebugInt3();
    639                 goto fail;
    640             }
    641 
    642             //and enable the capture switch for the selected input source
    643             idx = pHandle->idxRecCaps[ulValue];
    644             for(i=0;i<pElemInfo->count;i++) {
    645                 pElem->value.integer.value[i] = 1;
    646             }
    647         }
    648 
    649         break;
    650 
    651     case OSS32_MIX_SWITCH_MICBOOST:
    652         idx = pHandle->controls[OSS_MIXER_MIC].idxCustom;
    653         if(idx == -1) {
    654             DebugInt3();
    655             ret = OSSERR_INVALID_PARAMETER;
    656             goto fail;
    657         }
    658         //set mic switch value (on/off)
    659         pElem->value.integer.value[0] = ulValue;
    660         break;
    661 
    662     case OSS32_MIX_LEVEL_BASS:
    663         idx = pHandle->controls[OSS_MIXER_BASS].idxVolume;
    664         goto levelcontinue;
    665     case OSS32_MIX_LEVEL_TREBLE:
    666         idx = pHandle->controls[OSS_MIXER_TREBLE].idxVolume;
    667         goto levelcontinue;
    668     case OSS32_MIX_LEVEL_3DCENTER:
    669         idx = pHandle->controls[OSS_MIXER_3DCENTER].idxVolume;
    670         goto levelcontinue;
    671     case OSS32_MIX_LEVEL_3DDEPTH:
    672         idx = pHandle->controls[OSS_MIXER_3DDEPTH].idxVolume;
     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;
    673663levelcontinue:
    674664
    675         if(idx == -1) {//supported?
    676             DebugInt3();
    677             ret = OSSERR_INVALID_PARAMETER;
    678             goto fail;
    679         }
    680         //request information about mixer control
    681         pElemInfo->id.numid = pHandle->pids[idx].numid;
    682         ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_INFO, (ULONG)pElemInfo);
    683         if(ret) {
    684             ret = UNIXToOSSError(ret);
    685             DebugInt3();
    686             goto fail;
    687         }
    688         if(pElemInfo->type != SNDRV_CTL_ELEM_TYPE_INTEGER) {
    689             ret = OSSERR_INVALID_PARAMETER;
    690             DebugInt3();
    691             goto fail;
    692         }
    693         lVol = ConvertVolume(GET_VOLUME_L(ulValue), pElemInfo->value.integer.max);
    694         pElem->value.integer.value[0] = lVol;
    695 
    696         if(pElemInfo->count > 1) { //stereo
    697             rVol = ConvertVolume(GET_VOLUME_R(ulValue), pElemInfo->value.integer.max);
    698             pElem->value.integer.value[1] = rVol;
    699         }
    700         break;
    701 
    702     default:
    703         DebugInt3();
    704         ret = OSSERR_INVALID_PARAMETER;
    705         goto fail;
    706     }
    707     pElem->id.numid = pHandle->pids[idx].numid;
    708     pElem->indirect = 0;
    709 
    710     dprintf(("OSS32_MixSetProperty of %s to %x", pHandle->pids[idx].name, ulValue));
    711     ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file, SNDRV_CTL_IOCTL_ELEM_WRITE, (ULONG)pElem);
    712 
    713     kfree(pElem);
    714     pElem = NULL;
    715     if(ret) {
    716         DebugInt3();
    717         return UNIXToOSSError(ret);
    718     }
    719     return OSSERR_SUCCESS;
     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;
    720710
    721711fail:
    722     if(pElem) kfree(pElem);
    723     return ret;
     712        if(pElem) kfree(pElem);
     713        return ret;
    724714}
    725715//******************************************************************************
     
    727717OSSRET OSS32_MixGetProperty(OSSSTREAMID streamid, ULONG line, ULONG *pValue)
    728718{
    729     mixerhandle *pHandle = (mixerhandle *)streamid;
    730     int          ret;
    731 
    732     if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {
    733         DebugInt3();
    734         return OSSERR_INVALID_STREAMID;
    735     }
    736     //set operation to non-blocking
    737     pHandle->file.f_flags = O_NONBLOCK;
    738 
    739     return OSSERR_NOT_SUPPORTED;
     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;
    740730}
    741731//******************************************************************************
     
    743733ULONG OSSToALSAVolume(ULONG OSSVolIdx)
    744734{
    745     switch(OSSVolIdx) {
    746     case OSS_MIXER_VOLUME:
    747         return OSS32_MIX_VOLUME_MASTER_FRONT;
     735        switch(OSSVolIdx) {
     736        case OSS_MIXER_VOLUME:
     737                return OSS32_MIX_VOLUME_MASTER_FRONT;
    748738#if 0
    749     case OSS_MIXER_VOLUME: //TODO:
    750         return OSS32_MIX_VOLUME_MASTER_REAR;
     739        case OSS_MIXER_VOLUME: //TODO:
     740                return OSS32_MIX_VOLUME_MASTER_REAR;
    751741#endif
    752     case OSS_MIXER_PCM:
    753         return OSS32_MIX_VOLUME_PCM;
    754     case OSS_MIXER_SYNTH:
    755         return OSS32_MIX_VOLUME_MIDI;
    756     case OSS_MIXER_LINE:
    757         return OSS32_MIX_VOLUME_LINEIN;
    758     case OSS_MIXER_MIC:
    759         return OSS32_MIX_VOLUME_MIC;
    760     case OSS_MIXER_CD:
    761         return OSS32_MIX_VOLUME_CD;
    762     case OSS_MIXER_DIGITAL1:
    763         return OSS32_MIX_VOLUME_SPDIF;
    764     case OSS_MIXER_VIDEO:
    765         return OSS32_MIX_VOLUME_VIDEO;
    766     case OSS_MIXER_PCSPEAKER:
    767         return OSS32_MIX_VOLUME_PCSPEAKER;
    768     case OSS_MIXER_PHONEOUT:
    769         return OSS32_MIX_VOLUME_PHONE;
    770     case OSS_MIXER_IGAIN:
    771         return OSS32_MIX_VOLUME_CAPTURE;
    772     case OSS_MIXER_TREBLE:
    773         return OSS32_MIX_LEVEL_TREBLE;
    774     case OSS_MIXER_BASS:
    775         return OSS32_MIX_LEVEL_BASS;
    776     case OSS_MIXER_HEADPHONE:
    777         return OSS32_MIX_VOLUME_HEADPHONE;
    778     case OSS_MIXER_SPEAKER:
    779         return OSS32_MIX_VOLUME_SPEAKER;
    780     case OSS_MIXER_LINE1:
    781         return OSS32_MIX_VOLUME_AUX;
    782     }
    783     return -1;
     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;
    784774}
    785775//******************************************************************************
     
    787777OSSRET OSS32_MixQueryCaps(OSSSTREAMID streamid, POSS32_MIXCAPS pCaps)
    788778{
    789     mixerhandle *pHandle = (mixerhandle *)streamid;
    790     int i;
    791 
    792     if(pHandle == NULL || pHandle->magic != MAGIC_MIXER_ALSA32) {
    793         DebugInt3();
    794         return OSSERR_INVALID_STREAMID;
    795     }
    796 
    797     strncpy(pCaps->name, pHandle->info.mixername, sizeof(pCaps->name));
    798     pCaps->fuCtrlCaps = 0;
    799     pCaps->fuRecCaps  = 0;
    800 
    801     for(i=0;i<OSS_MIXER_NRDEVICES;i++)
    802     {
    803         if(pHandle->controls[i].idxVolume != -1) {
    804             ULONG volidx = OSSToALSAVolume(i);
    805             if(volidx != -1)
    806                 pCaps->fuCtrlCaps |= OSS32_MIX_FLAG(volidx);
    807         }
    808     }
    809 
    810     //if it has a capture source control or the card has capture route switches,
    811     //then we support intput source selection
    812     if(pHandle->controls[OSS_MIXER_IGAIN].idxCustom != -1 ||
    813        pHandle->rectype == RECTYPE_SWITCH)
    814     {
    815         pCaps->fuCtrlCaps |= OSS32_MIX_FLAG(OSS32_MIX_INPUTSRC);
    816         pCaps->fuRecCaps   = pHandle->reccaps;
    817     }
    818     return OSSERR_SUCCESS;
     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;
    819809}
    820810//******************************************************************************
     
    822812OSSRET OSS32_MixQueryName(ULONG deviceid, char *pszMixerName, ULONG cbMixerName)
    823813{
    824     mixerhandle *pHandle = NULL;
    825     int          ret, i, j;
    826 
    827     if(alsa_fops == NULL)
    828         return OSSERR_NO_DEVICE_AVAILABLE;
    829 
    830     pHandle = kmalloc(sizeof(mixerhandle), GFP_KERNEL);
    831     if(pHandle == NULL) {
    832         ret = OSSERR_OUT_OF_MEMORY;
    833         goto failure;
    834     }
    835     memset(pHandle, 0, sizeof(mixerhandle));
    836 
    837     //set operation to non-blocking
    838     pHandle->file.f_flags = O_NONBLOCK;
    839 
    840     //setup pointers in file structure (used internally by ALSA)
    841     pHandle->file.f_dentry          = &pHandle->d_entry;
    842     pHandle->file.f_dentry->d_inode = &pHandle->inode;
    843 
    844     pHandle->file.f_mode  = FMODE_WRITE;
    845     pHandle->inode.i_rdev = SNDRV_MINOR(deviceid, SNDRV_MINOR_CONTROL);
    846 
    847     ret = alsa_fops->open(&pHandle->inode, &pHandle->file);
    848     if(ret) {
    849         goto failure;
    850     }
    851     //retrieve mixer information
    852     ret = pHandle->file.f_op->ioctl(&pHandle->inode, &pHandle->file,
    853                                     SNDRV_CTL_IOCTL_CARD_INFO,
    854                                     (ULONG)&pHandle->info);
    855     if(ret) {
    856         goto failure;
    857     }
    858 
    859     strncpy(pszMixerName, pHandle->info.mixername, cbMixerName);
    860 
    861     pHandle->file.f_flags = O_NONBLOCK;
    862     ret = pHandle->file.f_op->release(&pHandle->inode, &pHandle->file);
    863     if(ret) {
    864         goto failure;
    865     }
    866     kfree(pHandle);
    867     return OSSERR_SUCCESS;
     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;
    868858
    869859failure:
    870     if(pHandle) {
    871         kfree(pHandle);
    872     }
    873     DebugInt3();
    874     return OSSERR_OUT_OF_MEMORY;
     860        if(pHandle) {
     861                kfree(pHandle);
     862        }
     863        DebugInt3();
     864        return OSSERR_OUT_OF_MEMORY;
    875865}
    876866//******************************************************************************
    877867//******************************************************************************
    878868OSSRET OSS32_QueryNames(ULONG deviceid, char *pszDeviceName, ULONG cbDeviceName,
    879                         char *pszMixerName, ULONG cbMixerName, BOOL fLongName)
    880 {
    881     mixerhandle *pHandle = NULL;
    882     int          ret, 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;
     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;
    941931
    942932failure:
    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 
     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.