Changeset ce1e5ea in mainline


Ignore:
Timestamp:
2011-10-02T13:19:09Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0f2e7c1
Parents:
bf38143
Message:

sb16: Use channel tables to simplify channel volume manipulation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/audio/sb16/mixer.c

    rbf38143 rce1e5ea  
    3636#define CT_MIXER_RESET_ADDRESS 0x00
    3737
     38typedef struct channel {
     39        uint8_t address;
     40        unsigned shift;
     41        unsigned volume_levels;
     42        bool preserve_bits;
     43} channel_t;
     44
    3845typedef struct volume_item {
    39         uint8_t address;
     46        const char *description;
    4047        uint8_t channels;
    41         const char *description;
    42         unsigned volume_levels;
    43         unsigned shift;
    44         bool same_reg;
     48        const channel_t *channel_table;
    4549} volume_item_t;
    4650
     51/* CT1335 channels */
     52static 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 */
     60static 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 */
     75static 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
    4798static 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] },
    52103};
    53104
    54105static 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] },
    61112};
    62113
    63114static 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] },
    75126};
    76127
     
    155206                return ENOENT;
    156207
     208        const volume_item_t item = volume_table[mixer->type].table[index];
    157209        if (name)
    158                 *name = volume_table[mixer->type].table[index].description;
     210                *name = item.description;
    159211        if (channels)
    160                 *channels = volume_table[mixer->type].table[index].channels;
     212                *channels = item.channels;
    161213        if (levels)
    162                 *levels = volume_table[mixer->type].table[index].volume_levels;
     214                *levels = item.channel_table[0].volume_levels;
    163215        return EOK;
    164216}
     
    171223        if (index >= volume_table[mixer->type].count)
    172224                return ENOENT;
    173         if (level >= volume_table[mixer->type].table[index].volume_levels)
    174                 return ENOTSUP;
    175225        if (channel >= volume_table[mixer->type].table[index].channels)
    176226                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);
    192239        }
     240
     241        value |= level << chan.shift;
     242        pio_write_8(&mixer->regs->mixer_data, value);
    193243        return EOK;
    194244}
     
    204254                return 0;
    205255
    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.