Changeset ce1e5ea in mainline
- Timestamp:
- 2011-10-02T13:19:09Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0f2e7c1
- Parents:
- bf38143
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/audio/sb16/mixer.c
rbf38143 rce1e5ea 36 36 #define CT_MIXER_RESET_ADDRESS 0x00 37 37 38 typedef struct channel { 39 uint8_t address; 40 unsigned shift; 41 unsigned volume_levels; 42 bool preserve_bits; 43 } channel_t; 44 38 45 typedef struct volume_item { 39 uint8_t address;46 const char *description; 40 47 uint8_t channels; 41 const char *description; 42 unsigned volume_levels; 43 unsigned shift; 44 bool same_reg; 48 const channel_t *channel_table; 45 49 } volume_item_t; 46 50 51 /* CT1335 channels */ 52 static const channel_t channels_table_ct1335[] = { 53 { 0x02, 1, 8, false }, /* Master, Mono, 3bit volume level */ 54 { 0x06, 1, 8, false }, /* Midi, Mono, 3bit volume level */ 55 { 0x08, 1, 8, false }, /* CD, Mono, 3bit volume level */ 56 { 0x0a, 1, 4, false }, /* Voice, Mono, 2bit volume level */ 57 }; 58 59 /* CT1345 channels */ 60 static const channel_t channels_table_ct1345[] = { 61 { 0x22, 5, 8, true }, /* Master, Left, 3bit volume level */ 62 { 0x22, 1, 8, true }, /* Master, Right, 3bit volume level */ 63 { 0x26, 5, 8, true }, /* Midi, Left, 3bit volume level */ 64 { 0x26, 1, 8, true }, /* Midi, Right, 3bit volume level */ 65 { 0x28, 5, 8, true }, /* CD, Left, 3bit volume level */ 66 { 0x28, 1, 8, true }, /* CD, Right, 3bit volume level */ 67 { 0x2e, 5, 8, true }, /* Line, Left, 3bit volume level */ 68 { 0x2e, 1, 8, true }, /* Line, Right, 3bit volume level */ 69 { 0x04, 5, 8, true }, /* Voice, Left, 3bit volume level */ 70 { 0x04, 1, 8, true }, /* Voice, Right, 3bit volume level */ 71 { 0x0a, 1, 4, false }, /* Mic, Mono, 2bit volume level */ 72 }; 73 74 /* CT1745 channels */ 75 static const channel_t channels_table_ct1745[] = { 76 { 0x30, 3, 32, false }, /* Master, Left, 5bit volume level */ 77 { 0x31, 3, 32, false }, /* Master, Right, 5bit volume level */ 78 { 0x32, 3, 32, false }, /* Voice, Left, 5bit volume level */ 79 { 0x33, 3, 32, false }, /* Voice, Right, 5bit volume level */ 80 { 0x34, 3, 32, false }, /* MIDI, Left, 5bit volume level */ 81 { 0x35, 3, 32, false }, /* MIDI, Right, 5bit volume level */ 82 { 0x36, 3, 32, false }, /* CD, Left, 5bit volume level */ 83 { 0x37, 3, 32, false }, /* CD, Right, 5bit volume level */ 84 { 0x38, 3, 32, false }, /* Line, Left, 5bit volume level */ 85 { 0x39, 3, 32, false }, /* Line, Right, 5bit volume level */ 86 { 0x3a, 3, 32, false }, /* Mic, Mono, 5bit volume level */ 87 { 0x3b, 6, 4, false }, /* PC speaker, Mono, 2bit volume level */ 88 { 0x3f, 6, 4, false }, /* Input Gain, Left, 2bit volume level */ 89 { 0x40, 6, 4, false }, /* Input Gain, Right, 2bit volume level */ 90 { 0x41, 6, 4, false }, /* Output Gain, Left, 2bit volume level */ 91 { 0x42, 6, 4, false }, /* Output Gain, Right, 2bit volume level */ 92 { 0x44, 4, 16, false }, /* Treble, Left, 4bit volume level */ 93 { 0x45, 4, 16, false }, /* Treble, Right, 4bit volume level */ 94 { 0x46, 4, 16, false }, /* Bass, Left, 4bit volume level */ 95 { 0x47, 4, 16, false }, /* Bass, Right, 4bit volume level */ 96 }; 97 47 98 static const volume_item_t volume_ct1335[] = { 48 { 0x02, 1, "Master", 8, 1, true},49 { 0x06, 1, "MIDI", 8, 1, true},50 { 0x08, 1, "CD", 8, 1, true},51 { 0x0a, 1, "Voice", 4, 1, true},99 { "Master", 1, &channels_table_ct1335[0] }, 100 { "MIDI", 1, &channels_table_ct1335[1] }, 101 { "CD", 1, &channels_table_ct1335[2] }, 102 { "Voice", 1, &channels_table_ct1335[3] }, 52 103 }; 53 104 54 105 static const volume_item_t volume_ct1345[] = { 55 { 0x22, 2, "Master", 8, 1, true},56 { 0x04, 2, "Voice", 8, 1, true},57 { 0x0a, 1, "Mic", 4, 1, true},58 { 0x26, 2, "MIDI", 8, 1, true},59 { 0x28, 2, "CD", 8, 1, true},60 { 0x2e, 2, "Line", 8, 1, true},106 { "Master", 2, &channels_table_ct1345[0] }, 107 { "Voice", 2, &channels_table_ct1345[8] }, 108 { "Mic", 1, &channels_table_ct1345[10] }, 109 { "MIDI", 2, &channels_table_ct1345[2] }, 110 { "CD", 2, &channels_table_ct1345[4] }, 111 { "Line", 2, &channels_table_ct1345[6] }, 61 112 }; 62 113 63 114 static const volume_item_t volume_ct1745[] = { 64 { 0x30, 2, "Master", 32, 3, false},65 { 0x32, 2, "Voice", 32, 3, false},66 { 0x34, 2, "MIDI", 32, 3, false},67 { 0x36, 2, "CD", 32, 3, false},68 { 0x38, 2, "Line", 32, 3, false},69 { 0x3a, 1, "Mic", 32, 3, false},70 { 0x3b, 1, "PC Speaker", 4, 6, false},71 { 0x3f, 2, "Input Gain", 4, 6, false},72 { 0x41, 2, "Output Gain", 4, 6, false},73 { 0x44, 2, "Treble", 16, 4, false},74 { 0x46, 2, "Bass", 16, 4, false},115 { "Master", 2, &channels_table_ct1745[0] }, 116 { "Voice", 2, &channels_table_ct1745[2] }, 117 { "MIDI", 2, &channels_table_ct1745[4] }, 118 { "CD", 2, &channels_table_ct1745[6] }, 119 { "Line", 2, &channels_table_ct1745[8] }, 120 { "Mic", 1, &channels_table_ct1745[10] }, 121 { "PC Speaker", 1, &channels_table_ct1745[11] }, 122 { "Input Gain", 2, &channels_table_ct1745[12] }, 123 { "Output Gain", 2, &channels_table_ct1745[14] }, 124 { "Treble", 2, &channels_table_ct1745[16] }, 125 { "Bass", 2, &channels_table_ct1745[0] }, 75 126 }; 76 127 … … 155 206 return ENOENT; 156 207 208 const volume_item_t item = volume_table[mixer->type].table[index]; 157 209 if (name) 158 *name = volume_table[mixer->type].table[index].description;210 *name = item.description; 159 211 if (channels) 160 *channels = volume_table[mixer->type].table[index].channels;212 *channels = item.channels; 161 213 if (levels) 162 *levels = volume_table[mixer->type].table[index].volume_levels;214 *levels = item.channel_table[0].volume_levels; 163 215 return EOK; 164 216 } … … 171 223 if (index >= volume_table[mixer->type].count) 172 224 return ENOENT; 173 if (level >= volume_table[mixer->type].table[index].volume_levels)174 return ENOTSUP;175 225 if (channel >= volume_table[mixer->type].table[index].channels) 176 226 return ENOENT; 177 178 const volume_item_t item = volume_table[mixer->type].table[index]; 179 const uint8_t address = item.address + (item.same_reg ? 0 : channel); 180 pio_write_8(&mixer->regs->mixer_address, address); 181 if (!item.same_reg) { 182 const uint8_t value = level << item.shift; 183 pio_write_8(&mixer->regs->mixer_data, value); 184 } else { 185 /* Nasty stuff */ 186 uint8_t value = pio_read_8(&mixer->regs->mixer_data); 187 /* Remove value that is to be replaced register format is L:R*/ 188 value &= (channel ? 0xf0 : 0x0f); 189 /* Add the new value */ 190 value |= (level << item.shift) << (channel ? 0 : 4); 191 pio_write_8(&mixer->regs->mixer_data, value); 227 const channel_t chan = 228 volume_table[mixer->type].table[index].channel_table[channel]; 229 230 if (level > chan.volume_levels) 231 level = chan.volume_levels; 232 233 pio_write_8(&mixer->regs->mixer_address, chan.address); 234 uint8_t value = 0; 235 236 if (chan.preserve_bits) { 237 value = pio_read_8(&mixer->regs->mixer_data); 238 value &= ~(uint8_t)((chan.volume_levels - 1) << chan.shift); 192 239 } 240 241 value |= level << chan.shift; 242 pio_write_8(&mixer->regs->mixer_data, value); 193 243 return EOK; 194 244 } … … 204 254 return 0; 205 255 206 const volume_item_t item = volume_table[mixer->type].table[index]; 207 const uint8_t address = item.address + (item.same_reg ? 0 : channel); 208 pio_write_8(&mixer->regs->mixer_address, address); 209 if (!item.same_reg) { 210 return pio_read_8(&mixer->regs->mixer_data) >> item.shift; 211 } else { 212 const uint8_t value = 213 pio_read_8(&mixer->regs->mixer_data) >> (channel ? 0 : 4); 214 return value >> item.shift; 215 } 216 return 0; 217 } 256 const channel_t chan = 257 volume_table[mixer->type].table[index].channel_table[channel]; 258 pio_write_8(&mixer->regs->mixer_address, chan.address); 259 return (pio_read_8(&mixer->regs->mixer_data) >> chan.shift) 260 & (chan.volume_levels - 1); 261 }
Note:
See TracChangeset
for help on using the changeset viewer.