+ unsigned char val;\r
+\r
+ if(VER_MAJOR(dsp_ver) >= 4) {\r
+ /* DSP 4.x - SB16 */\r
+ val = vol & 0xf8;\r
+ if(ctl == AUDIO_PCM) {\r
+ write_mix(MIX_SB16_VOICE_L, vol);\r
+ write_mix(MIX_SB16_VOICE_R, vol);\r
+ } else {\r
+ write_mix(MIX_SB16_MASTER_L, vol);\r
+ write_mix(MIX_SB16_MASTER_R, vol);\r
+ }\r
+\r
+ } else if(VER_MAJOR(dsp_ver) >= 3) {\r
+ /* DSP 3.x - SBPro */\r
+ val = vol & 0xe0;\r
+ val |= val >> 4;\r
+\r
+ if(ctl == AUDIO_PCM) {\r
+ write_mix(MIX_SBPRO_VOICE, val);\r
+ } else {\r
+ write_mix(MIX_SBPRO_MASTER, val);\r
+ }\r
+\r
+ } else {\r
+ /* DSP 2.x - SB 2.0 */\r
+ if(ctl == AUDIO_PCM) {\r
+ val = (vol >> 5) & 6;\r
+ write_mix(MIX_VOICE, val);\r
+ } else {\r
+ val = (vol >> 4) & 0xe;\r
+ write_mix(MIX_MASTER, val);\r
+ }\r
+ }\r
+}\r
+\r
+static int getvolume(int ctl)\r
+{\r
+ int left, right;\r
+ unsigned char val;\r
+\r
+ if(VER_MAJOR(dsp_ver) >= 4) {\r
+ /* DSP 4.x - SB16 */\r
+ int lreg, rreg;\r
+ if(ctl == AUDIO_PCM) {\r
+ lreg = MIX_SB16_VOICE_L;\r
+ rreg = MIX_SB16_VOICE_R;\r
+ } else { /* MASTER or DEFAULT */\r
+ lreg = MIX_SB16_MASTER_L;\r
+ rreg = MIX_SB16_MASTER_R;\r
+ }\r
+\r
+ val = read_mix(lreg);\r
+ left = (val & 0xf8) | ((val >> 3) & 7); /* duplicate last 3 bits */\r
+ val = read_mix(rreg);\r
+ right = (val & 0xf8) | ((val >> 3) & 7);\r
+\r
+ } else if(VER_MAJOR(dsp_ver) >= 3) {\r
+ /* DSP 3.x - SBPro */\r
+ val = read_mix(ctl == AUDIO_PCM ? MIX_SBPRO_VOICE : MIX_SBPRO_MASTER);\r
+\r
+ /* left is top 3 bits, duplicate twice(-ish) */\r
+ left = (val & 0xe0) | ((val >> 3) & 0x1c) | (val >> 6);\r
+ /* right is top 3 bits of the lower nibble */\r
+ right = (val << 4) | ((val << 1) & 0x1c) | ((val >> 2) & 3);\r
+\r
+ } else {\r
+ int volume;\r
+\r
+ /* DSP 2.x - SB 2.0 */\r
+ if(ctl == AUDIO_PCM) {\r
+ /* voice is in bits 1 and 2 */\r
+ val = read_mix(MIX_VOICE);\r
+ volume = (val << 5) | ((val << 3) & 0x30) | ((val << 1) & 0xc) | ((val >> 1) & 3);\r
+ } else {\r
+ /* master is in the 3 top bits of the lower nibble */\r
+ val = read_mix(MIX_MASTER);\r
+ volume = (val << 4) | ((val << 1) & 0x1c) | ((val >> 2) & 3);\r
+ }\r
+ return volume;\r
+ }\r
+\r
+ return (left + right) >> 1;\r