Changeset 1912b45 in mainline
- Timestamp:
- 2013-04-10T20:52:26Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5b77efc
- Parents:
- 8a7d78cc
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/mixerctl/mixerctl.c
r8a7d78cc r1912b45 43 43 #define DEFAULT_DEVICE "/hw/pci0/00:01.0/sb16/control" 44 44 45 /** 46 * Print volume levels on all channels on all control items. 47 * @param exch IPC exchange 48 */ 45 49 static void print_levels(async_exch_t *exch) 46 50 { … … 52 56 return; 53 57 } 54 printf("MIXER %s:\n ", name);58 printf("MIXER %s:\n\n", name); 55 59 56 60 for (unsigned i = 0; i < count; ++i) { 57 61 const char *name = NULL; 58 unsigned channels= 0;59 constint ret =60 audio_mixer_get_item_info(exch, i, &name, & channels);62 unsigned levels = 0, current = 0; 63 int ret = 64 audio_mixer_get_item_info(exch, i, &name, &levels); 61 65 if (ret != EOK) { 62 66 printf("Failed to get item %u info: %s.\n", … … 64 68 continue; 65 69 } 66 for (unsigned j = 0; j < channels; ++j) { 67 const char *chan = NULL; 68 int ret = audio_mixer_get_channel_info( 69 exch, i, j, &chan, NULL); 70 if (ret != EOK) { 71 printf( 72 "Failed to get channel %u-%u info: %s.\n", 73 i, j, str_error(ret)); 74 } 75 unsigned level = 0, max = 0; 76 ret = audio_mixer_channel_volume_get( 77 exch, i, j, &level, &max); 78 if (ret != EOK) { 79 printf("Failed to get channel %u-%u volume:" 80 " %s.\n", i, j, str_error(ret)); 81 } 82 bool mute = false; 83 ret = audio_mixer_channel_mute_get( 84 exch, i, j, &mute); 85 if (ret != EOK) { 86 printf("Failed to get channel %u-%u mute" 87 " status: %s.\n", i, j, str_error(ret)); 88 } 70 ret = audio_mixer_get_item_level(exch, i, ¤t); 71 if (ret != EOK) { 72 printf("Failed to get item %u info: %s.\n", 73 i, str_error(ret)); 74 continue; 75 } 89 76 90 printf("\tChannel(%u/%u) %s %s volume: %u/%u%s.\n", 91 i, j, name, chan, level, max, mute ? " (M)":""); 92 free(chan); 93 } 77 printf("Control item %u `%s' : %u/%u.\n", 78 i, name, current, levels - 1); 94 79 free(name); 95 80 96 81 } 97 82 } 98 /*----------------------------------------------------------------------------*/ 83 99 84 static unsigned get_number(const char* str) 100 85 { … … 103 88 return num; 104 89 } 105 /*----------------------------------------------------------------------------*/ 106 static void set_volume(async_exch_t *exch, int argc, char *argv[]) 107 { 108 assert(exch); 109 if (argc != 5 && argc != 6) { 110 printf("%s [device] setvolume item channel value\n", argv[0]); 111 } 112 unsigned params = argc == 6 ? 3 : 2; 113 const unsigned item = get_number(argv[params++]); 114 const unsigned channel = get_number(argv[params++]); 115 const unsigned value = get_number(argv[params]); 116 int ret = audio_mixer_channel_volume_set(exch, item, channel, value); 117 if (ret != EOK) { 118 printf("Failed to set mixer volume: %s.\n", str_error(ret)); 119 return; 120 } 121 printf("Channel %u-%u volume set to %u.\n", item, channel, value); 122 } 123 /*----------------------------------------------------------------------------*/ 124 static void get_volume(async_exch_t *exch, int argc, char *argv[]) 90 91 static void set_level(async_exch_t *exch, int argc, char *argv[]) 125 92 { 126 93 assert(exch); 127 94 if (argc != 4 && argc != 5) { 128 printf("%s [device] getvolume item channel\n", argv[0]); 95 printf("%s [device] setlevel item value\n", argv[0]); 96 return; 129 97 } 130 98 unsigned params = argc == 5 ? 3 : 2; 131 99 const unsigned item = get_number(argv[params++]); 132 const unsigned channel = get_number(argv[params++]); 133 unsigned value = 0, max = 0; 134 135 int ret = audio_mixer_channel_volume_get( 136 exch, item, channel, &value, &max); 100 const unsigned value = get_number(argv[params]); 101 int ret = audio_mixer_set_item_level(exch, item, value); 137 102 if (ret != EOK) { 138 printf("Failed to get mixer volume: %s.\n", str_error(ret));103 printf("Failed to set item level: %s.\n", str_error(ret)); 139 104 return; 140 105 } 141 printf("C hannel %u-%u volume: %u/%u.\n", item, channel, value, max);106 printf("Control item %u new level is %u.\n", item, value); 142 107 } 143 /*----------------------------------------------------------------------------*/ 108 109 static void get_level(async_exch_t *exch, int argc, char *argv[]) 110 { 111 assert(exch); 112 if (argc != 3 && argc != 4) { 113 printf("%s [device] getlevel item \n", argv[0]); 114 return; 115 } 116 unsigned params = argc == 4 ? 3 : 2; 117 const unsigned item = get_number(argv[params++]); 118 unsigned value = 0; 119 120 int ret = audio_mixer_get_item_level(exch, item, &value); 121 if (ret != EOK) { 122 printf("Failed to get item level: %s.\n", str_error(ret)); 123 return; 124 } 125 printf("Control item %u level: %u.\n", item, value); 126 } 127 144 128 int main(int argc, char *argv[]) 145 129 { … … 147 131 void (*command)(async_exch_t *, int, char*[]) = NULL; 148 132 149 if (argc >= 2 && str_cmp(argv[1], "set volume") == 0) {150 command = set_ volume;151 if (argc == 6)133 if (argc >= 2 && str_cmp(argv[1], "setlevel") == 0) { 134 command = set_level; 135 if (argc == 5) 152 136 device = argv[1]; 153 137 } 154 138 155 if (argc >= 2 && str_cmp(argv[1], "get volume") == 0) {156 command = get_ volume;157 if (argc == 5)139 if (argc >= 2 && str_cmp(argv[1], "getlevel") == 0) { 140 command = get_level; 141 if (argc == 4) 158 142 device = argv[1]; 159 143 } -
uspace/drv/audio/sb16/mixer.c
r8a7d78cc r1912b45 45 45 } channel_t; 46 46 47 typedef struct volume_item {48 const char *description;49 uint8_t channels;50 const channel_t *channel_table;51 } volume_item_t;52 53 47 /* CT1335 channels */ 54 48 static const channel_t channels_table_ct1335[] = { 55 { "M ono", 0x02, 1, 8, false }, /* Master, Mono, 3bit volume level */56 { "M ono", 0x06, 1, 8, false }, /* Midi, Mono, 3bit volume level */57 { " Mono", 0x08, 1, 8, false }, /* CD, Mono, 3bit volume level */58 { " Mono", 0x0a, 1, 4, false }, /* Voice, Mono, 2bit volume level */49 { "Master", 0x02, 1, 8, false }, /* Master, Mono, 3bit volume level */ 50 { "Midi", 0x06, 1, 8, false }, /* Midi, Mono, 3bit volume level */ 51 { "CD", 0x08, 1, 8, false }, /* CD, Mono, 3bit volume level */ 52 { "Voice", 0x0a, 1, 4, false }, /* Voice, Mono, 2bit volume level */ 59 53 }; 60 54 61 55 /* CT1345 channels */ 62 56 static const channel_t channels_table_ct1345[] = { 63 { " Left", 0x22, 5, 8, true }, /* Master, Left, 3bit volume level */64 { " Right", 0x22, 1, 8, true }, /* Master, Right, 3bit volume level */65 { " Left", 0x26, 5, 8, true }, /* Midi, Left, 3bit volume level */66 { " Right", 0x26, 1, 8, true }, /* Midi, Right, 3bit volume level */67 { " Left", 0x28, 5, 8, true }, /* CD, Left, 3bit volume level */68 { " Right", 0x28, 1, 8, true }, /* CD, Right, 3bit volume level */69 { "L eft", 0x2e, 5, 8, true }, /* Line, Left, 3bit volume level */70 { " Right", 0x2e, 1, 8, true }, /* Line, Right, 3bit volume level */71 { " Left", 0x04, 5, 8, true }, /* Voice, Left, 3bit volume level */72 { " Right", 0x04, 1, 8, true }, /* Voice, Right, 3bit volume level */73 { "M ono", 0x0a, 1, 4, false }, /* Mic, Mono, 2bit volume level */57 { "Master Left", 0x22, 5, 8, true }, /* Master, Left, 3bit volume level */ 58 { "Master Right", 0x22, 1, 8, true }, /* Master, Right, 3bit volume level */ 59 { "MIDI Left", 0x26, 5, 8, true }, /* Midi, Left, 3bit volume level */ 60 { "MIDI Right", 0x26, 1, 8, true }, /* Midi, Right, 3bit volume level */ 61 { "CD Left", 0x28, 5, 8, true }, /* CD, Left, 3bit volume level */ 62 { "CD Right", 0x28, 1, 8, true }, /* CD, Right, 3bit volume level */ 63 { "Line In Left", 0x2e, 5, 8, true }, /* Line, Left, 3bit volume level */ 64 { "Line In Right", 0x2e, 1, 8, true }, /* Line, Right, 3bit volume level */ 65 { "Voice Left", 0x04, 5, 8, true }, /* Voice, Left, 3bit volume level */ 66 { "Voice Right", 0x04, 1, 8, true }, /* Voice, Right, 3bit volume level */ 67 { "Mic", 0x0a, 1, 4, false }, /* Mic, Mono, 2bit volume level */ 74 68 }; 75 69 76 70 /* CT1745 channels */ 77 71 static const channel_t channels_table_ct1745[] = { 78 { "Left", 0x30, 3, 32, false }, /* Master, Left, 5bit volume level */ 79 { "Right", 0x31, 3, 32, false }, /* Master, Right, 5bit volume level */ 80 { "Left", 0x32, 3, 32, false }, /* Voice, Left, 5bit volume level */ 81 { "Right", 0x33, 3, 32, false }, /* Voice, Right, 5bit volume level */ 82 { "Left", 0x34, 3, 32, false }, /* MIDI, Left, 5bit volume level */ 83 { "Right", 0x35, 3, 32, false }, /* MIDI, Right, 5bit volume level */ 84 { "Left", 0x36, 3, 32, false }, /* CD, Left, 5bit volume level */ 85 { "Right", 0x37, 3, 32, false }, /* CD, Right, 5bit volume level */ 86 { "Left", 0x38, 3, 32, false }, /* Line, Left, 5bit volume level */ 87 { "Right", 0x39, 3, 32, false }, /* Line, Right, 5bit volume level */ 88 { "Mono", 0x3a, 3, 32, false }, /* Mic, Mono, 5bit volume level */ 89 { "Mono", 0x3b, 6, 4, false }, /* PC speaker, Mono, 2bit level */ 90 { "Left", 0x3f, 6, 4, false }, /* Input Gain, Left, 2bit level */ 91 { "Right", 0x40, 6, 4, false }, /* Input Gain, Right, 2bit level */ 92 { "Left", 0x41, 6, 4, false }, /* Output Gain, Left, 2bit level */ 93 { "Right", 0x42, 6, 4, false }, /* Output Gain, Right, 2bit level */ 94 { "Left", 0x44, 4, 16, false }, /* Treble, Left, 4bit volume level */ 95 { "Right", 0x45, 4, 16, false }, /* Treble, Right, 4bit volume level */ 96 { "Left", 0x46, 4, 16, false }, /* Bass, Left, 4bit volume level */ 97 { "Right", 0x47, 4, 16, false }, /* Bass, Right, 4bit volume level */ 98 }; 99 100 static const volume_item_t volume_ct1335[] = { 101 { "Master", 1, &channels_table_ct1335[0] }, 102 { "MIDI", 1, &channels_table_ct1335[1] }, 103 { "CD", 1, &channels_table_ct1335[2] }, 104 { "Voice", 1, &channels_table_ct1335[3] }, 105 }; 106 107 static const volume_item_t volume_ct1345[] = { 108 { "Master", 2, &channels_table_ct1345[0] }, 109 { "Voice", 2, &channels_table_ct1345[8] }, 110 { "Mic", 1, &channels_table_ct1345[10] }, 111 { "MIDI", 2, &channels_table_ct1345[2] }, 112 { "CD", 2, &channels_table_ct1345[4] }, 113 { "Line", 2, &channels_table_ct1345[6] }, 114 }; 115 116 static const volume_item_t volume_ct1745[] = { 117 { "Master", 2, &channels_table_ct1745[0] }, 118 { "Voice", 2, &channels_table_ct1745[2] }, 119 { "MIDI", 2, &channels_table_ct1745[4] }, 120 { "CD", 2, &channels_table_ct1745[6] }, 121 { "Line", 2, &channels_table_ct1745[8] }, 122 { "Mic", 1, &channels_table_ct1745[10] }, 123 { "PC Speaker", 1, &channels_table_ct1745[11] }, 124 { "Input Gain", 2, &channels_table_ct1745[12] }, 125 { "Output Gain", 2, &channels_table_ct1745[14] }, 126 { "Treble", 2, &channels_table_ct1745[16] }, 127 { "Bass", 2, &channels_table_ct1745[18] }, 72 { "Master Left", 0x30, 3, 32, false }, /* Master, Left, 5bit volume level */ 73 { "Master Right", 0x31, 3, 32, false }, /* Master, Right, 5bit volume level */ 74 { "Voice Left", 0x32, 3, 32, false }, /* Voice, Left, 5bit volume level */ 75 { "Voice Right", 0x33, 3, 32, false }, /* Voice, Right, 5bit volume level */ 76 { "MIDI Left", 0x34, 3, 32, false }, /* MIDI, Left, 5bit volume level */ 77 { "MIDI Right", 0x35, 3, 32, false }, /* MIDI, Right, 5bit volume level */ 78 { "CD Left", 0x36, 3, 32, false }, /* CD, Left, 5bit volume level */ 79 { "CD Right", 0x37, 3, 32, false }, /* CD, Right, 5bit volume level */ 80 { "Line In Left", 0x38, 3, 32, false }, /* Line, Left, 5bit volume level */ 81 { "Line In Right", 0x39, 3, 32, false }, /* Line, Right, 5bit volume level */ 82 { "Mic", 0x3a, 3, 32, false }, /* Mic, Mono, 5bit volume level */ 83 { "PC Speaker", 0x3b, 6, 4, false }, /* PC speaker, Mono, 2bit level */ 84 { "Input Gain Left", 0x3f, 6, 4, false }, /* Input Gain, Left, 2bit level */ 85 { "Input Gain Right", 0x40, 6, 4, false }, /* Input Gain, Right, 2bit level */ 86 { "Output Gain Left", 0x41, 6, 4, false }, /* Output Gain, Left, 2bit level */ 87 { "Output Gain Right", 0x42, 6, 4, false }, /* Output Gain, Right, 2bit level */ 88 { "Treble Left", 0x44, 4, 16, false }, /* Treble, Left, 4bit volume level */ 89 { "Treble Right", 0x45, 4, 16, false }, /* Treble, Right, 4bit volume level */ 90 { "Bass Left", 0x46, 4, 16, false }, /* Bass, Left, 4bit volume level */ 91 { "Bass Right", 0x47, 4, 16, false }, /* Bass, Right, 4bit volume level */ 128 92 }; 129 93 130 94 static const struct { 131 const volume_item_t *table;95 const channel_t *table; 132 96 size_t count; 133 97 } volume_table[] = { 134 98 [SB_MIXER_NONE] = { NULL, 0 }, 135 99 [SB_MIXER_UNKNOWN] = { NULL, 0 }, 136 [SB_MIXER_CT1335] = { volume_ct1335, ARRAY_SIZE(volume_ct1335) }, 137 [SB_MIXER_CT1345] = { volume_ct1345, ARRAY_SIZE(volume_ct1345) }, 138 [SB_MIXER_CT1745] = { volume_ct1745, ARRAY_SIZE(volume_ct1745) }, 100 [SB_MIXER_CT1335] = { 101 channels_table_ct1335, 102 ARRAY_SIZE(channels_table_ct1335), 103 }, 104 [SB_MIXER_CT1345] = { 105 channels_table_ct1345, 106 ARRAY_SIZE(channels_table_ct1345), 107 }, 108 [SB_MIXER_CT1745] = { 109 channels_table_ct1745, 110 ARRAY_SIZE(channels_table_ct1745), 111 }, 139 112 }; 140 113 … … 177 150 } 178 151 179 int sb_mixer_get_control_item_info(const sb_mixer_t *mixer, unsigned i ndex,180 const char** name, unsigned * channels)181 { 182 assert(mixer); 183 if (i ndex> volume_table[mixer->type].count)152 int sb_mixer_get_control_item_info(const sb_mixer_t *mixer, unsigned item, 153 const char** name, unsigned *levels) 154 { 155 assert(mixer); 156 if (item > volume_table[mixer->type].count) 184 157 return ENOENT; 185 158 186 const volume_item_t *item = &volume_table[mixer->type].table[index];159 const channel_t *ch = &volume_table[mixer->type].table[item]; 187 160 if (name) 188 *name = item->description; 189 if (channels) 190 *channels = item->channels; 191 return EOK; 192 } 193 194 int sb_mixer_get_channel_info(const sb_mixer_t *mixer, unsigned index, 195 unsigned channel, const char **name, unsigned *levels) 196 { 197 assert(mixer); 198 if (index > volume_table[mixer->type].count) 161 *name = ch->name; 162 if (levels) 163 *levels = ch->volume_levels; 164 return EOK; 165 } 166 167 /** 168 * Write new volume level from mixer registers. 169 * @param mixer SB Mixer to use. 170 * @param index Control item(channel) index. 171 * @param value New volume level. 172 * @return Error code. 173 */ 174 int sb_mixer_get_control_item_value(const sb_mixer_t *mixer, unsigned item, 175 unsigned *value) 176 { 177 assert(mixer); 178 if (!value) 179 return EBADMEM; 180 if (item > volume_table[mixer->type].count) 199 181 return ENOENT; 200 182 201 const volume_item_t *item = &volume_table[mixer->type].table[index]; 202 if (channel > item->channels) 183 const channel_t *chan = &volume_table[mixer->type].table[item]; 184 pio_write_8(&mixer->regs->mixer_address, chan->address); 185 *value = (pio_read_8(&mixer->regs->mixer_data) >> chan->shift) 186 & (chan->volume_levels - 1); 187 return EOK; 188 } 189 190 /** 191 * Write new volume level to mixer registers. 192 * @param mixer SB Mixer to use. 193 * @param index Control item(channel) index. 194 * @param value New volume level. 195 * @return Error code. 196 */ 197 int sb_mixer_set_control_item_value(const sb_mixer_t *mixer, unsigned item, 198 unsigned value) 199 { 200 assert(mixer); 201 if (item > volume_table[mixer->type].count) 203 202 return ENOENT; 204 203 205 const channel_t *chan = &item->channel_table[channel]; 206 if (name) 207 *name = chan->name; 208 if (levels) 209 *levels = chan->volume_levels; 210 return EOK; 211 } 212 213 int sb_mixer_set_volume_level(const sb_mixer_t *mixer, 214 unsigned index, unsigned channel, unsigned level) 215 { 216 if (mixer->type == SB_MIXER_UNKNOWN || mixer->type == SB_MIXER_NONE) 217 return ENOTSUP; 218 if (index >= volume_table[mixer->type].count) 219 return ENOENT; 220 if (channel >= volume_table[mixer->type].table[index].channels) 221 return ENOENT; 222 223 const channel_t *chan = 224 &volume_table[mixer->type].table[index].channel_table[channel]; 225 226 if (level >= chan->volume_levels) 227 level = chan->volume_levels - 1; 204 const channel_t *chan = &volume_table[mixer->type].table[item]; 205 if (value >= chan->volume_levels) 206 value = chan->volume_levels - 1; 228 207 229 208 pio_write_8(&mixer->regs->mixer_address, chan->address); 230 209 231 uint8_t value= 0;210 uint8_t regv = 0; 232 211 if (chan->preserve_bits) { 233 value= pio_read_8(&mixer->regs->mixer_data);234 value&= ~(uint8_t)((chan->volume_levels - 1) << chan->shift);212 regv = pio_read_8(&mixer->regs->mixer_data); 213 regv &= ~(uint8_t)((chan->volume_levels - 1) << chan->shift); 235 214 } 236 215 237 value |= level << chan->shift; 238 pio_write_8(&mixer->regs->mixer_data, value); 239 ddf_log_note("Channel %s %s volume set to: %u.", 240 volume_table[mixer->type].table[index].description, 241 chan->name, level); 242 return EOK; 243 } 244 245 unsigned sb_mixer_get_volume_level(const sb_mixer_t *mixer, unsigned index, 246 unsigned channel) 247 { 248 assert(mixer); 249 if (mixer->type == SB_MIXER_UNKNOWN 250 || mixer->type == SB_MIXER_NONE 251 || (index >= volume_table[mixer->type].count) 252 || (channel >= volume_table[mixer->type].table[index].channels)) 253 return 0; 254 255 const channel_t *chan = 256 &volume_table[mixer->type].table[index].channel_table[channel]; 257 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 } 216 regv |= value << chan->shift; 217 pio_write_8(&mixer->regs->mixer_data, regv); 218 ddf_log_note("Item %s new value is: %u.", 219 volume_table[mixer->type].table[item].name, value); 220 return EOK; 221 } -
uspace/drv/audio/sb16/mixer.h
r8a7d78cc r1912b45 54 54 int sb_mixer_get_control_item_count(const sb_mixer_t *mixer); 55 55 int sb_mixer_get_control_item_info(const sb_mixer_t *mixer, unsigned index, 56 const char **name, unsigned *channels); 57 int sb_mixer_get_channel_info(const sb_mixer_t *mixer, unsigned index, 58 unsigned channel, const char **name, unsigned *levels); 59 int sb_mixer_set_volume_level(const sb_mixer_t *mixer, 60 unsigned item, unsigned channel, unsigned level); 61 unsigned sb_mixer_get_volume_level(const sb_mixer_t *mixer, 62 unsigned item, unsigned channel); 56 const char **name, unsigned *levels); 57 int sb_mixer_get_control_item_value(const sb_mixer_t *mixer, unsigned index, 58 unsigned *value); 59 int sb_mixer_set_control_item_value(const sb_mixer_t *mixer, unsigned index, 60 unsigned value); 63 61 #endif 64 62 /** -
uspace/drv/audio/sb16/mixer_iface.c
r8a7d78cc r1912b45 50 50 return EOK; 51 51 } 52 /*----------------------------------------------------------------------------*/ 52 53 53 static int sb_get_item_info(ddf_fun_t *fun, unsigned item, const char** name, 54 unsigned * channels)54 unsigned *max_level) 55 55 { 56 56 assert(fun); … … 58 58 assert(mixer); 59 59 return 60 sb_mixer_get_control_item_info(mixer, item, name, channels);60 sb_mixer_get_control_item_info(mixer, item, name, max_level); 61 61 } 62 /*----------------------------------------------------------------------------*/ 63 static int sb_get_channel_info(ddf_fun_t *fun, unsigned item, unsigned channel, 64 const char** name, unsigned *levels) 62 63 static int sb_set_item_level(ddf_fun_t *fun, unsigned item, unsigned value) 65 64 { 66 65 assert(fun); 67 66 const sb_mixer_t *mixer = ddf_fun_data_get(fun); 68 67 assert(mixer); 69 return sb_mixer_ get_channel_info(mixer, item, channel, name, levels);68 return sb_mixer_set_control_item_value(mixer, item, value); 70 69 } 71 /*----------------------------------------------------------------------------*/ 72 static int sb_channel_mute_set(ddf_fun_t *fun, unsigned item, unsigned channel, 73 bool mute) 74 { 75 return ENOTSUP; 76 } 77 /*----------------------------------------------------------------------------*/ 78 static int sb_channel_mute_get(ddf_fun_t *fun, unsigned item, unsigned channel, 79 bool *mute) 80 { 81 *mute = false; 82 return EOK; 83 } 84 /*----------------------------------------------------------------------------*/ 85 static int sb_channel_volume_set(ddf_fun_t *fun, unsigned item, unsigned channel, 86 unsigned volume) 70 71 static int sb_get_item_level(ddf_fun_t *fun, unsigned item, unsigned *value) 87 72 { 88 73 assert(fun); 89 74 const sb_mixer_t *mixer = ddf_fun_data_get(fun); 90 75 assert(mixer); 91 return sb_mixer_set_volume_level(mixer, item, channel, volume); 92 } 93 /*----------------------------------------------------------------------------*/ 94 static int sb_channel_volume_get(ddf_fun_t *fun, unsigned item, unsigned channel, 95 unsigned *level, unsigned *max) 96 { 97 assert(fun); 98 const sb_mixer_t *mixer = ddf_fun_data_get(fun); 99 assert(mixer); 100 unsigned levels; 101 const int ret = 102 sb_mixer_get_channel_info(mixer, item, channel, NULL, &levels); 103 if (ret == EOK && max) 104 *max = --levels; 105 if (ret == EOK && level) 106 *level = sb_mixer_get_volume_level(mixer, item, channel); 107 108 return ret; 76 return sb_mixer_get_control_item_value(mixer, item, value); 109 77 } 110 78 … … 112 80 .get_info = sb_get_info, 113 81 .get_item_info = sb_get_item_info, 114 .get_channel_info = sb_get_channel_info,115 82 116 .channel_mute_set = sb_channel_mute_set, 117 .channel_mute_get = sb_channel_mute_get, 118 119 .channel_volume_set = sb_channel_volume_set, 120 .channel_volume_get = sb_channel_volume_get, 121 83 .get_item_level = sb_get_item_level, 84 .set_item_level = sb_set_item_level, 122 85 }; 123 86 /** -
uspace/lib/drv/generic/remote_audio_mixer.c
r8a7d78cc r1912b45 65 65 IPC_M_AUDIO_MIXER_GET_ITEM_INFO, 66 66 67 /** Asks for channel name and number of volume levels.67 /** Set new control item setting 68 68 * Answer: 69 69 * - ENOTSUP - call not supported 70 * - ENOENT - no such c hannel70 * - ENOENT - no such control item 71 71 * - EOK - call successful, info is valid 72 * Answer arguments:73 * - Channel name74 * - Volume levels75 72 */ 76 IPC_M_AUDIO_MIXER_ GET_CHANNEL_INFO,77 78 /** Set channel mute status73 IPC_M_AUDIO_MIXER_SET_ITEM_LEVEL, 74 75 /** Get control item setting 79 76 * Answer: 80 77 * - ENOTSUP - call not supported 81 * - ENOENT - no such c hannel78 * - ENOENT - no such control item 82 79 * - EOK - call successful, info is valid 83 80 */ 84 IPC_M_AUDIO_MIXER_CHANNEL_MUTE_SET, 85 86 /** Get channel mute status 87 * Answer: 88 * - ENOTSUP - call not supported 89 * - ENOENT - no such channel 90 * - EOK - call successful, info is valid 91 * Answer arguments: 92 * - Channel mute status 93 */ 94 IPC_M_AUDIO_MIXER_CHANNEL_MUTE_GET, 95 96 /** Set channel volume level 97 * Answer: 98 * - ENOTSUP - call not supported 99 * - ENOENT - no such channel 100 * - EOK - call successful, info is valid 101 */ 102 IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_SET, 103 104 /** Get channel volume level 105 * Answer: 106 * - ENOTSUP - call not supported 107 * - ENOENT - no such channel 108 * - EOK - call successful, info is valid 109 * Answer arguments: 110 * - Channel volume level 111 * - Channel maximum volume level 112 */ 113 IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_GET, 81 IPC_M_AUDIO_MIXER_GET_ITEM_LEVEL, 114 82 } audio_mixer_iface_funcs_t; 115 83 … … 162 130 */ 163 131 int audio_mixer_get_item_info(async_exch_t *exch, unsigned item, 164 const char **name, unsigned * channels)132 const char **name, unsigned *levels) 165 133 { 166 134 if (!exch) 167 135 return EINVAL; 168 sysarg_t name_size, chans;136 sysarg_t name_size, lvls; 169 137 const int ret = async_req_2_2(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), 170 IPC_M_AUDIO_MIXER_GET_ITEM_INFO, item, &name_size, & chans);138 IPC_M_AUDIO_MIXER_GET_ITEM_INFO, item, &name_size, &lvls); 171 139 if (ret == EOK && name) { 172 140 char *name_place = calloc(1, name_size); … … 185 153 *name = name_place; 186 154 } 187 if (ret == EOK && chans)188 * channels = chans;155 if (ret == EOK && levels) 156 *levels = lvls; 189 157 return ret; 190 158 } 191 159 192 160 /** 193 * Query audio mixer for channel specific info (name and volume levels).161 * Set control item to a new level. 194 162 * @param[in] exch IPC exchange connected to the device. 195 * @param[in] item TH control item controlling the channel. 196 * @param[in] channel The channel. 197 * @param[out] name Audio channel string identifier. 198 * @param[out] volume_levels Number of volume levels. 163 * @param[in] item The control item controlling the channel. 164 * @param[in] level The new value. 199 165 * @return Error code. 200 166 */ 201 int audio_mixer_ get_channel_info(async_exch_t *exch, unsigned item,202 unsigned channel, const char **name, unsigned *volume_levels)167 int audio_mixer_set_item_level(async_exch_t *exch, unsigned item, 168 unsigned level) 203 169 { 204 170 if (!exch) 205 171 return EINVAL; 206 sysarg_t name_size, levels; 207 const int ret = async_req_3_2(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), 208 IPC_M_AUDIO_MIXER_GET_CHANNEL_INFO, item, channel, 209 &name_size, &levels); 210 if (ret == EOK && name) { 211 char *name_place = calloc(1, name_size); 212 if (!name_place) { 213 /* Make the other side fail 214 * as it waits for read request */ 215 async_data_read_start(exch, (void*)-1, 0); 216 return ENOMEM; 217 } 218 const int ret = 219 async_data_read_start(exch, name_place, name_size); 220 if (ret != EOK) { 221 free(name_place); 222 return ret; 223 } 224 *name = name_place; 225 } 226 if (ret == EOK && volume_levels) 227 *volume_levels = levels; 228 return ret; 229 } 230 231 /** 232 * Set MUTE status on an audio channel. 172 return async_req_3_0(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), 173 IPC_M_AUDIO_MIXER_SET_ITEM_LEVEL, item, level); 174 } 175 176 /** 177 * Get current level of a control item. 233 178 * @param[in] exch IPC exchange connected to the device. 234 179 * @param[in] item The control item controlling the channel. 235 180 * @param[in] channel The channel index. 236 * @param[ in] mute_status A new MUTE status.181 * @param[out] level Currently set value. 237 182 * @return Error code. 238 183 */ 239 int audio_mixer_ channel_mute_set(async_exch_t *exch, unsigned item,240 unsigned channel, bool mute_status)184 int audio_mixer_get_item_level(async_exch_t *exch, unsigned item, 185 unsigned *level) 241 186 { 242 187 if (!exch) 243 188 return EINVAL; 244 return async_req_4_0(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), 245 IPC_M_AUDIO_MIXER_CHANNEL_MUTE_SET, item, channel, mute_status); 246 } 247 248 /** 249 * Get MUTE status on an audio channel. 250 * @param[in] exch IPC exchange connected to the device. 251 * @param[in] item The control item controlling the channel. 252 * @param[in] channel The channel index. 253 * @param[out] mute_status Currently set MUTE status. 254 * @return Error code. 255 */ 256 int audio_mixer_channel_mute_get(async_exch_t *exch, unsigned item, 257 unsigned channel, bool *mute_status) 258 { 259 if (!exch) 260 return EINVAL; 261 sysarg_t mute; 262 const int ret = async_req_3_1(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), 263 IPC_M_AUDIO_MIXER_CHANNEL_MUTE_GET, item, channel, &mute); 264 if (ret == EOK && mute_status) 265 *mute_status = (bool)mute; 266 return ret; 267 } 268 269 /** 270 * Set VOLUME LEVEL on an audio channel. 271 * @param[in] exch IPC exchange connected to the device. 272 * @param[in] item The control item controlling the channel. 273 * @param[in] channel The channel index. 274 * @param[in] volume A new VOLUME LEVEL. 275 * @return Error code. 276 */ 277 int audio_mixer_channel_volume_set(async_exch_t *exch, unsigned item, 278 unsigned channel, unsigned volume) 279 { 280 if (!exch) 281 return EINVAL; 282 return async_req_4_0(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), 283 IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_SET, item, channel, volume); 284 } 285 286 /** 287 * Get VOLUME LEVEL on an audio channel. 288 * @param[in] exch IPC exchange connected to the device. 289 * @param[in] item The control item controlling the channel. 290 * @param[in] channel The channel index. 291 * @param[out] volume_current Currently set VOLUME LEVEL. 292 * @param[out] volume_max Maximum VOLUME LEVEL. 293 * @return Error code. 294 */ 295 int audio_mixer_channel_volume_get(async_exch_t *exch, unsigned item, 296 unsigned channel, unsigned *volume_current, unsigned *volume_max) 297 { 298 if (!exch) 299 return EINVAL; 300 sysarg_t current, max; 301 const int ret = async_req_3_2(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), 302 IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_GET, item, channel, 303 ¤t, &max); 304 if (ret == EOK && volume_current) 305 *volume_current = current; 306 if (ret == EOK && volume_max) 307 *volume_max = max; 189 sysarg_t current; 190 const int ret = async_req_2_1(exch, DEV_IFACE_ID(AUDIO_MIXER_IFACE), 191 IPC_M_AUDIO_MIXER_GET_ITEM_LEVEL, item, ¤t); 192 if (ret == EOK && level) 193 *level = current; 308 194 return ret; 309 195 } … … 314 200 static void remote_audio_mixer_get_info(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 315 201 static void remote_audio_mixer_get_item_info(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 316 static void remote_audio_mixer_get_channel_info(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 317 static void remote_audio_mixer_channel_mute_set(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 318 static void remote_audio_mixer_channel_mute_get(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 319 static void remote_audio_mixer_channel_volume_set(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 320 static void remote_audio_mixer_channel_volume_get(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 202 static void remote_audio_mixer_get_item_level(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 203 static void remote_audio_mixer_set_item_level(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 321 204 322 205 /** Remote audio mixer interface operations. */ … … 324 207 [IPC_M_AUDIO_MIXER_GET_INFO] = remote_audio_mixer_get_info, 325 208 [IPC_M_AUDIO_MIXER_GET_ITEM_INFO] = remote_audio_mixer_get_item_info, 326 [IPC_M_AUDIO_MIXER_GET_CHANNEL_INFO] = remote_audio_mixer_get_channel_info, 327 [IPC_M_AUDIO_MIXER_CHANNEL_MUTE_SET] = remote_audio_mixer_channel_mute_set, 328 [IPC_M_AUDIO_MIXER_CHANNEL_MUTE_GET] = remote_audio_mixer_channel_mute_get, 329 [IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_SET] = remote_audio_mixer_channel_volume_set, 330 [IPC_M_AUDIO_MIXER_CHANNEL_VOLUME_GET] = remote_audio_mixer_channel_volume_get, 209 [IPC_M_AUDIO_MIXER_GET_ITEM_LEVEL] = remote_audio_mixer_get_item_level, 210 [IPC_M_AUDIO_MIXER_SET_ITEM_LEVEL] = remote_audio_mixer_set_item_level, 331 211 }; 332 212 … … 380 260 const unsigned item = DEV_IPC_GET_ARG1(*call); 381 261 const char *name = NULL; 382 unsigned channels = 0;383 const int ret = mixer_iface->get_item_info(fun, item, &name, & channels);262 unsigned values = 0; 263 const int ret = mixer_iface->get_item_info(fun, item, &name, &values); 384 264 const size_t name_size = name ? str_size(name) + 1 : 0; 385 async_answer_2(callid, ret, name_size, channels);265 async_answer_2(callid, ret, name_size, values); 386 266 /* Send the name. */ 387 267 if (ret == EOK && name_size > 0) { … … 400 280 } 401 281 402 void remote_audio_mixer_ get_channel_info(282 void remote_audio_mixer_set_item_level( 403 283 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 404 284 { 405 285 audio_mixer_iface_t *mixer_iface = iface; 406 286 407 if (!mixer_iface-> get_channel_info) {287 if (!mixer_iface->set_item_level) { 408 288 async_answer_0(callid, ENOTSUP); 409 289 return; 410 290 } 411 412 291 const unsigned item = DEV_IPC_GET_ARG1(*call); 413 const unsigned channel = DEV_IPC_GET_ARG2(*call); 414 const char *name = NULL; 415 unsigned levels = 0; 416 const int ret = 417 mixer_iface->get_channel_info(fun, item, channel, &name, &levels); 418 const size_t name_size = name ? str_size(name) + 1 : 0; 419 async_answer_2(callid, ret, name_size, levels); 420 /* Send the name. */ 421 if (ret == EOK && name_size > 0) { 422 size_t size; 423 ipc_callid_t name_id; 424 if (!async_data_read_receive(&name_id, &size)) { 425 async_answer_0(name_id, EPARTY); 426 return; 427 } 428 if (size != name_size) { 429 async_answer_0(name_id, ELIMIT); 430 return; 431 } 432 async_data_read_finalize(name_id, name, name_size); 433 } 434 } 435 436 void remote_audio_mixer_channel_mute_set( 292 const unsigned value = DEV_IPC_GET_ARG2(*call); 293 const int ret = mixer_iface->set_item_level(fun, item, value); 294 async_answer_0(callid, ret); 295 } 296 297 void remote_audio_mixer_get_item_level( 437 298 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 438 299 { 439 300 audio_mixer_iface_t *mixer_iface = iface; 440 301 441 if (!mixer_iface-> channel_mute_set) {302 if (!mixer_iface->get_item_level) { 442 303 async_answer_0(callid, ENOTSUP); 443 304 return; 444 305 } 445 306 const unsigned item = DEV_IPC_GET_ARG1(*call); 446 const unsigned channel = DEV_IPC_GET_ARG2(*call); 447 const bool mute = DEV_IPC_GET_ARG3(*call); 448 const int ret = mixer_iface->channel_mute_set(fun, item, channel, mute); 449 async_answer_0(callid, ret); 450 } 451 452 void remote_audio_mixer_channel_mute_get( 453 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 454 { 455 audio_mixer_iface_t *mixer_iface = iface; 456 457 if (!mixer_iface->channel_mute_get) { 458 async_answer_0(callid, ENOTSUP); 459 return; 460 } 461 const unsigned item = DEV_IPC_GET_ARG1(*call); 462 const unsigned channel = DEV_IPC_GET_ARG2(*call); 463 bool mute = false; 307 unsigned current = 0; 464 308 const int ret = 465 mixer_iface->channel_mute_get(fun, item, channel, &mute); 466 async_answer_1(callid, ret, mute); 467 } 468 469 void remote_audio_mixer_channel_volume_set( 470 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 471 { 472 audio_mixer_iface_t *mixer_iface = iface; 473 474 if (!mixer_iface->channel_volume_set) { 475 async_answer_0(callid, ENOTSUP); 476 return; 477 } 478 const unsigned item = DEV_IPC_GET_ARG1(*call); 479 const unsigned channel = DEV_IPC_GET_ARG2(*call); 480 const unsigned level = DEV_IPC_GET_ARG3(*call); 481 const int ret = 482 mixer_iface->channel_volume_set(fun, item, channel, level); 483 async_answer_0(callid, ret); 484 } 485 486 void remote_audio_mixer_channel_volume_get( 487 ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call) 488 { 489 audio_mixer_iface_t *mixer_iface = iface; 490 491 if (!mixer_iface->channel_volume_get) { 492 async_answer_0(callid, ENOTSUP); 493 return; 494 } 495 const unsigned item = DEV_IPC_GET_ARG1(*call); 496 const unsigned channel = DEV_IPC_GET_ARG2(*call); 497 unsigned current = 0, max = 0; 498 const int ret = 499 mixer_iface->channel_volume_get(fun, item, channel, ¤t, &max); 500 async_answer_2(callid, ret, current, max); 309 mixer_iface->get_item_level(fun, item, ¤t); 310 async_answer_1(callid, ret, current); 501 311 } 502 312 -
uspace/lib/drv/include/audio_mixer_iface.h
r8a7d78cc r1912b45 46 46 int audio_mixer_get_item_info(async_exch_t *, unsigned, 47 47 const char **, unsigned *); 48 int audio_mixer_get_channel_info(async_exch_t *, unsigned, unsigned, 49 const char **, unsigned *); 50 int audio_mixer_channel_mute_set(async_exch_t *, unsigned, unsigned, bool); 51 int audio_mixer_channel_mute_get(async_exch_t *, unsigned, unsigned, bool *); 52 int audio_mixer_channel_volume_set(async_exch_t *, unsigned, unsigned, 53 unsigned); 54 int audio_mixer_channel_volume_get(async_exch_t *, unsigned, unsigned, 55 unsigned *, unsigned *); 48 int audio_mixer_get_item_level(async_exch_t *, unsigned, unsigned *); 49 int audio_mixer_set_item_level(async_exch_t *, unsigned, unsigned); 56 50 57 51 … … 60 54 int (*get_info)(ddf_fun_t *, const char **, unsigned *); 61 55 int (*get_item_info)(ddf_fun_t *, unsigned, const char **, unsigned *); 62 int (*get_channel_info)(ddf_fun_t *, unsigned, unsigned, 63 const char **, unsigned *); 64 int (*channel_mute_set)(ddf_fun_t *, unsigned, unsigned, bool); 65 int (*channel_mute_get)(ddf_fun_t *, unsigned, unsigned, bool *); 66 int (*channel_volume_set)(ddf_fun_t *, unsigned, unsigned, unsigned); 67 int (*channel_volume_get)(ddf_fun_t *, unsigned, unsigned, 68 unsigned *, unsigned *); 56 int (*get_item_level)(ddf_fun_t *, unsigned, unsigned *); 57 int (*set_item_level)(ddf_fun_t *, unsigned, unsigned); 69 58 } audio_mixer_iface_t; 70 59
Note:
See TracChangeset
for help on using the changeset viewer.