blob: 4b81ae298ef70e2c0452bf82b888f81be077aee2 [file] [log] [blame]
David Linee3fe402017-03-13 10:00:42 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_usb"
18
19#include <errno.h>
20#include <pthread.h>
21#include <stdlib.h>
22#include <cutils/log.h>
23#include <cutils/str_parms.h>
24#include <sys/ioctl.h>
25#include <fcntl.h>
26#include <sys/stat.h>
27#include <system/audio.h>
28#include <tinyalsa/asoundlib.h>
29#include <audio_hw.h>
30#include <cutils/properties.h>
31#include <ctype.h>
32#include <math.h>
33
34#ifdef USB_TUNNEL_ENABLED
35#define USB_BUFF_SIZE 2048
36#define CHANNEL_NUMBER_STR "Channels: "
37#define PLAYBACK_PROFILE_STR "Playback:"
38#define CAPTURE_PROFILE_STR "Capture:"
39#define USB_SIDETONE_GAIN_STR "usb_sidetone_gain"
40#define ABS_SUB(A, B) (((A) > (B)) ? ((A) - (B)):((B) - (A)))
41#define SAMPLE_RATE_8000 8000
42#define SAMPLE_RATE_11025 11025
43/* TODO: dynamically populate supported sample rates */
44static uint32_t supported_sample_rates[] =
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -080045 {192000, 176400, 96000, 88200, 64000, 48000, 44100};
46static uint32_t supported_sample_rates_mask[2];
47static const uint32_t MAX_SAMPLE_RATE_SIZE =
48 (sizeof(supported_sample_rates)/sizeof(supported_sample_rates[0]));
David Linee3fe402017-03-13 10:00:42 -070049
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -080050// assert on sizeof bm v/s size of rates if needed
David Linee3fe402017-03-13 10:00:42 -070051
52enum usb_usecase_type{
53 USB_PLAYBACK = 0,
54 USB_CAPTURE,
55};
56
57enum {
58 USB_SIDETONE_ENABLE_INDEX = 0,
59 USB_SIDETONE_VOLUME_INDEX,
60 USB_SIDETONE_MAX_INDEX,
61};
62
63struct usb_device_config {
64 struct listnode list;
65 unsigned int bit_width;
66 unsigned int channel_count;
67 unsigned int rate_size;
68 unsigned int rates[MAX_SAMPLE_RATE_SIZE];
69};
70
71struct usb_card_config {
72 struct listnode list;
73 audio_devices_t usb_device_type;
74 int usb_card;
75 struct listnode usb_device_conf_list;
76 struct mixer *usb_snd_mixer;
77 int usb_sidetone_index[USB_SIDETONE_MAX_INDEX];
78 int usb_sidetone_vol_min;
79 int usb_sidetone_vol_max;
80};
81
82struct usb_module {
83 struct listnode usb_card_conf_list;
84 struct audio_device *adev;
85 int sidetone_gain;
86 bool is_capture_supported;
87};
88
89static struct usb_module *usbmod = NULL;
90static bool usb_audio_debug_enable = false;
91static int usb_sidetone_gain = 0;
92
93static const char * const usb_sidetone_enable_str[] = {
94 "Sidetone Playback Switch",
95 "Mic Playback Switch",
96};
97
98static const char * const usb_sidetone_volume_str[] = {
99 "Sidetone Playback Volume",
100 "Mic Playback Volume",
101};
102
103static void usb_mixer_print_enum(struct mixer_ctl *ctl)
104{
105 unsigned int num_enums;
106 unsigned int i;
107 const char *string;
108
109 num_enums = mixer_ctl_get_num_enums(ctl);
110
111 for (i = 0; i < num_enums; i++) {
112 string = mixer_ctl_get_enum_string(ctl, i);
113 ALOGI("\t%s%s", mixer_ctl_get_value(ctl, 0) == (int)i ? ">" : "", string);
114 }
115}
116
117static void usb_soundcard_detail_control(struct mixer *mixer, const char *control)
118{
119 struct mixer_ctl *ctl;
120 enum mixer_ctl_type type;
121 unsigned int num_values;
122 unsigned int i;
123 int min, max;
124
125 if (isdigit(control[0]))
126 ctl = mixer_get_ctl(mixer, atoi(control));
127 else
128 ctl = mixer_get_ctl_by_name(mixer, control);
129
130 if (!ctl) {
131 fprintf(stderr, "Invalid mixer control\n");
132 return;
133 }
134
135 type = mixer_ctl_get_type(ctl);
136 num_values = mixer_ctl_get_num_values(ctl);
137
138 ALOGV("%s:", mixer_ctl_get_name(ctl));
139
140 for (i = 0; i < num_values; i++) {
141 switch (type) {
142 case MIXER_CTL_TYPE_INT:
143 ALOGV(" %d", mixer_ctl_get_value(ctl, i));
144 break;
145 case MIXER_CTL_TYPE_BOOL:
146 ALOGV(" %s", mixer_ctl_get_value(ctl, i) ? "On" : "Off");
147 break;
148 case MIXER_CTL_TYPE_ENUM:
149 usb_mixer_print_enum(ctl);
150 break;
151 case MIXER_CTL_TYPE_BYTE:
152 ALOGV(" 0x%02x", mixer_ctl_get_value(ctl, i));
153 break;
154 default:
155 ALOGV(" unknown");
156 break;
157 }
158 }
159
160 if (type == MIXER_CTL_TYPE_INT) {
161 min = mixer_ctl_get_range_min(ctl);
162 max = mixer_ctl_get_range_max(ctl);
163 ALOGV(" (range %d->%d)", min, max);
164 }
165}
166
167static void usb_soundcard_list_controls(struct mixer *mixer)
168{
169 struct mixer_ctl *ctl;
170 const char *name, *type;
171 unsigned int num_ctls, num_values;
172 unsigned int i;
173
174 num_ctls = mixer_get_num_ctls(mixer);
175
176 ALOGV("Number of controls: %d\n", num_ctls);
177
178 ALOGV("ctl\ttype\tnum\t%-40s value\n", "name");
179 for (i = 0; i < num_ctls; i++) {
180 ctl = mixer_get_ctl(mixer, i);
181 if (ctl != NULL) {
182 name = mixer_ctl_get_name(ctl);
183 type = mixer_ctl_get_type_string(ctl);
184 num_values = mixer_ctl_get_num_values(ctl);
185 ALOGV("%d\t%s\t%d\t%-40s", i, type, num_values, name);
186 if (name != NULL)
187 usb_soundcard_detail_control(mixer, name);
188 }
189 }
190}
191
192static int usb_set_dev_id_mixer_ctl(unsigned int usb_usecase_type, int card,
193 char *dev_mixer_ctl_name)
194{
195 struct mixer_ctl *ctl;
196 unsigned int dev_token;
197 const unsigned int pcm_device_number = 0;
198
199 /*
200 * usb_dev_token_id is 32 bit number and is defined as below:
201 * usb_sound_card_idx(31:16) | usb PCM device ID(15:8) | usb_usecase_type(7:0)
202 */
203 dev_token = (card << 16 ) |
204 (pcm_device_number << 8) | (usb_usecase_type & 0xFF);
205
206 ctl = mixer_get_ctl_by_name(usbmod->adev->mixer, dev_mixer_ctl_name);
207 if (!ctl) {
208 ALOGE("%s: Could not get ctl for mixer cmd - %s",
209 __func__, dev_mixer_ctl_name);
210 return -EINVAL;
211 }
212 mixer_ctl_set_value(ctl, 0, dev_token);
213
214 return 0;
215}
216
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800217static int usb_get_sample_rates(int type, char *rates_str,
David Linee3fe402017-03-13 10:00:42 -0700218 struct usb_device_config *config)
219{
220 uint32_t i;
221 char *next_sr_string, *temp_ptr;
222 uint32_t sr, min_sr, max_sr, sr_size = 0;
223
224 /* Sample rate string can be in any of the folloing two bit_widthes:
225 * Rates: 8000 - 48000 (continuous)
226 * Rates: 8000, 44100, 48000
227 * Support both the bit_widths
228 */
229 ALOGV("%s: rates_str %s", __func__, rates_str);
230 next_sr_string = strtok_r(rates_str, "Rates: ", &temp_ptr);
231 if (next_sr_string == NULL) {
232 ALOGE("%s: could not find min rates string", __func__);
233 return -EINVAL;
234 }
235 if (strstr(rates_str, "continuous") != NULL) {
236 min_sr = (uint32_t)atoi(next_sr_string);
237 next_sr_string = strtok_r(NULL, " ,.-", &temp_ptr);
238 if (next_sr_string == NULL) {
239 ALOGE("%s: could not find max rates string", __func__);
240 return -EINVAL;
241 }
242 max_sr = (uint32_t)atoi(next_sr_string);
243
244 for (i = 0; i < MAX_SAMPLE_RATE_SIZE; i++) {
245 if (supported_sample_rates[i] >= min_sr &&
246 supported_sample_rates[i] <= max_sr) {
247 config->rates[sr_size++] = supported_sample_rates[i];
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800248 supported_sample_rates_mask[type] |= (1<<i);
David Linee3fe402017-03-13 10:00:42 -0700249 ALOGI_IF(usb_audio_debug_enable,
250 "%s: continuous sample rate supported_sample_rates[%d] %d",
251 __func__, i, supported_sample_rates[i]);
252 }
253 }
254 } else {
255 do {
256 sr = (uint32_t)atoi(next_sr_string);
257 for (i = 0; i < MAX_SAMPLE_RATE_SIZE; i++) {
258 if (supported_sample_rates[i] == sr) {
259 ALOGI_IF(usb_audio_debug_enable,
260 "%s: sr %d, supported_sample_rates[%d] %d -> matches!!",
261 __func__, sr, i, supported_sample_rates[i]);
262 config->rates[sr_size++] = supported_sample_rates[i];
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800263 supported_sample_rates_mask[type] |= (1<<i);
David Linee3fe402017-03-13 10:00:42 -0700264 }
265 }
266 next_sr_string = strtok_r(NULL, " ,.-", &temp_ptr);
267 } while (next_sr_string != NULL);
268 }
269 config->rate_size = sr_size;
270 return 0;
271}
272
273static int usb_get_capability(int type,
274 struct usb_card_config *usb_card_info,
275 int card)
276{
277 int32_t size = 0;
278 int32_t fd=-1;
279 int32_t channels_no;
280 char *str_start = NULL;
281 char *str_end = NULL;
282 char *channel_start = NULL;
283 char *bit_width_start = NULL;
284 char *rates_str_start = NULL;
285 char *target = NULL;
286 char *read_buf = NULL;
287 char *rates_str = NULL;
288 char path[128];
289 int ret = 0;
290 char *bit_width_str = NULL;
291 struct usb_device_config * usb_device_info;
292 bool check = false;
Haynes Mathew George569b7482017-05-08 14:44:27 -0700293 int tries=5;
David Linee3fe402017-03-13 10:00:42 -0700294
295 memset(path, 0, sizeof(path));
296 ALOGV("%s: for %s", __func__, (type == USB_PLAYBACK) ?
297 PLAYBACK_PROFILE_STR : CAPTURE_PROFILE_STR);
298
299 /* TODO: convert the below to using alsa_utils */
300 ret = snprintf(path, sizeof(path), "/proc/asound/card%u/stream0",
301 card);
Haynes Mathew George569b7482017-05-08 14:44:27 -0700302 if (ret < 0) {
David Linee3fe402017-03-13 10:00:42 -0700303 ALOGE("%s: failed on snprintf (%d) to path %s\n",
304 __func__, ret, path);
305 goto done;
306 }
307
Haynes Mathew George569b7482017-05-08 14:44:27 -0700308 while (tries--) {
309 if (access(path, F_OK) < 0) {
310 ALOGW("stream %s doesn't exist retrying\n", path);
311 sleep(1);
312 continue;
313 }
314 }
315
David Linee3fe402017-03-13 10:00:42 -0700316 fd = open(path, O_RDONLY);
317 if (fd <0) {
318 ALOGE("%s: error failed to open config file %s error: %d\n",
319 __func__, path, errno);
320 ret = -EINVAL;
321 goto done;
322 }
323
324 read_buf = (char *)calloc(1, USB_BUFF_SIZE + 1);
325
326 if (!read_buf) {
327 ALOGE("Failed to create read_buf");
328 ret = -ENOMEM;
329 goto done;
330 }
331
332 if(read(fd, read_buf, USB_BUFF_SIZE) < 0) {
333 ALOGE("file read error\n");
334 goto done;
335 }
336 str_start = strstr(read_buf, ((type == USB_PLAYBACK) ?
337 PLAYBACK_PROFILE_STR : CAPTURE_PROFILE_STR));
338 if (str_start == NULL) {
339 ALOGE("%s: error %s section not found in usb config file",
340 __func__, ((type == USB_PLAYBACK) ?
341 PLAYBACK_PROFILE_STR : CAPTURE_PROFILE_STR));
342 ret = -EINVAL;
343 goto done;
344 }
345 str_end = strstr(read_buf, ((type == USB_PLAYBACK) ?
346 CAPTURE_PROFILE_STR : PLAYBACK_PROFILE_STR));
347 if (str_end > str_start)
348 check = true;
349
350 ALOGV("%s: usb_config = %s, check %d\n", __func__, str_start, check);
351
352 while (str_start != NULL) {
353 str_start = strstr(str_start, "Altset");
354 if ((str_start == NULL) || (check && (str_start >= str_end))) {
355 ALOGV("%s: done parsing %s\n", __func__, str_start);
356 break;
357 }
358 ALOGV("%s: remaining string %s\n", __func__, str_start);
359 str_start += sizeof("Altset");
360 usb_device_info = calloc(1, sizeof(struct usb_device_config));
361 if (usb_device_info == NULL) {
362 ALOGE("%s: error unable to allocate memory",
363 __func__);
364 ret = -ENOMEM;
365 break;
366 }
367 /* Bit bit_width parsing */
368 bit_width_start = strstr(str_start, "Format: ");
369 if (bit_width_start == NULL) {
370 ALOGI("%s: Could not find bit_width string", __func__);
371 free(usb_device_info);
372 continue;
373 }
374 target = strchr(bit_width_start, '\n');
375 if (target == NULL) {
376 ALOGI("%s:end of line not found", __func__);
377 free(usb_device_info);
378 continue;
379 }
380 size = target - bit_width_start;
381 if ((bit_width_str = (char *)malloc(size + 1)) == NULL) {
382 ALOGE("%s: unable to allocate memory to hold bit width strings",
383 __func__);
384 ret = -EINVAL;
385 free(usb_device_info);
386 break;
387 }
388 memcpy(bit_width_str, bit_width_start, size);
389 bit_width_str[size] = '\0';
390 if (strstr(bit_width_str, "S16_LE"))
391 usb_device_info->bit_width = 16;
392 else if (strstr(bit_width_str, "S24_LE"))
393 usb_device_info->bit_width = 24;
394 else if (strstr(bit_width_str, "S24_3LE"))
395 usb_device_info->bit_width = 24;
396 else if (strstr(bit_width_str, "S32_LE"))
397 usb_device_info->bit_width = 32;
398
399 if (bit_width_str)
400 free(bit_width_str);
401
402 /* channels parsing */
403 channel_start = strstr(str_start, CHANNEL_NUMBER_STR);
404 if (channel_start == NULL) {
405 ALOGI("%s: could not find Channels string", __func__);
406 free(usb_device_info);
407 continue;
408 }
409 channels_no = atoi(channel_start + strlen(CHANNEL_NUMBER_STR));
410 usb_device_info->channel_count = channels_no;
411
412 /* Sample rates parsing */
413 rates_str_start = strstr(str_start, "Rates: ");
414 if (rates_str_start == NULL) {
415 ALOGI("%s: cant find rates string", __func__);
416 free(usb_device_info);
417 continue;
418 }
419 target = strchr(rates_str_start, '\n');
420 if (target == NULL) {
421 ALOGI("%s: end of line not found", __func__);
422 free(usb_device_info);
423 continue;
424 }
425 size = target - rates_str_start;
426 if ((rates_str = (char *)malloc(size + 1)) == NULL) {
427 ALOGE("%s: unable to allocate memory to hold sample rate strings",
428 __func__);
429 ret = -EINVAL;
430 free(usb_device_info);
431 break;
432 }
433 memcpy(rates_str, rates_str_start, size);
434 rates_str[size] = '\0';
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800435 ret = usb_get_sample_rates(type, rates_str, usb_device_info);
David Linee3fe402017-03-13 10:00:42 -0700436 if (rates_str)
437 free(rates_str);
438 if (ret < 0) {
439 ALOGE("%s: error unable to get sample rate values",
440 __func__);
441 free(usb_device_info);
442 continue;
443 }
444 /* Add to list if every field is valid */
445 list_add_tail(&usb_card_info->usb_device_conf_list,
446 &usb_device_info->list);
447 }
448
449done:
450 if (fd >= 0) close(fd);
451 if (read_buf) free(read_buf);
452 return ret;
453}
454
455static int usb_get_device_playback_config(struct usb_card_config *usb_card_info,
456 int card)
457{
458 int ret;
459
460 /* get capabilities */
461 if ((ret = usb_get_capability(USB_PLAYBACK, usb_card_info, card))) {
462 ALOGE("%s: could not get Playback capabilities from usb device",
463 __func__);
464 goto exit;
465 }
466 usb_set_dev_id_mixer_ctl(USB_PLAYBACK, card, "USB_AUDIO_RX dev_token");
467
468exit:
469
470 return ret;
471}
472
473static int usb_get_device_capture_config(struct usb_card_config *usb_card_info,
474 int card)
475{
476 int ret;
477
478 /* get capabilities */
479 if ((ret = usb_get_capability(USB_CAPTURE, usb_card_info, card))) {
480 ALOGE("%s: could not get Playback capabilities from usb device",
481 __func__);
482 goto exit;
483 }
484 usb_set_dev_id_mixer_ctl(USB_CAPTURE, card, "USB_AUDIO_TX dev_token");
485
486exit:
487 return ret;
488}
489
490static void usb_get_sidetone_mixer(struct usb_card_config *usb_card_info)
491{
492 struct mixer_ctl *ctl;
493 unsigned int index;
494
495 for (index = 0; index < USB_SIDETONE_MAX_INDEX; index++)
496 usb_card_info->usb_sidetone_index[index] = -1;
497
498 usb_card_info->usb_snd_mixer = mixer_open(usb_card_info->usb_card);
499 for (index = 0;
500 index < sizeof(usb_sidetone_enable_str)/sizeof(usb_sidetone_enable_str[0]);
501 index++) {
502 ctl = mixer_get_ctl_by_name(usb_card_info->usb_snd_mixer,
503 usb_sidetone_enable_str[index]);
504 if (ctl) {
505 usb_card_info->usb_sidetone_index[USB_SIDETONE_ENABLE_INDEX] = index;
506 /* Disable device sidetone by default */
507 mixer_ctl_set_value(ctl, 0, false);
vivek mehta90933872017-06-15 18:04:39 -0700508 ALOGV("%s:: sidetone mixer Control found(%s) ... disabling by default",
509 __func__, usb_sidetone_enable_str[index]);
David Linee3fe402017-03-13 10:00:42 -0700510 break;
511 }
512 }
vivek mehta90933872017-06-15 18:04:39 -0700513#ifdef USB_SIDETONE_VOLUME
David Linee3fe402017-03-13 10:00:42 -0700514 for (index = 0;
515 index < sizeof(usb_sidetone_volume_str)/sizeof(usb_sidetone_volume_str[0]);
516 index++) {
517 ctl = mixer_get_ctl_by_name(usb_card_info->usb_snd_mixer,
518 usb_sidetone_volume_str[index]);
519 if (ctl) {
520 usb_card_info->usb_sidetone_index[USB_SIDETONE_VOLUME_INDEX] = index;
521 usb_card_info->usb_sidetone_vol_min = mixer_ctl_get_range_min(ctl);
522 usb_card_info->usb_sidetone_vol_max = mixer_ctl_get_range_max(ctl);
523 break;
524 }
525 }
vivek mehta90933872017-06-15 18:04:39 -0700526#endif // USB_SIDETONE_VOLUME
David Linee3fe402017-03-13 10:00:42 -0700527 if ((usb_card_info->usb_snd_mixer != NULL) && (usb_audio_debug_enable))
528 usb_soundcard_list_controls(usb_card_info->usb_snd_mixer);
529
530 return;
531}
532
Haynes Mathew George569b7482017-05-08 14:44:27 -0700533static inline bool usb_output_device(audio_devices_t device) {
534 // ignore accessory for now
535 if (device == AUDIO_DEVICE_OUT_USB_ACCESSORY) {
536 return false;
537 }
538 return audio_is_usb_out_device(device);
539}
540
541static inline bool usb_input_device(audio_devices_t device) {
542 // ignore accessory for now
543 if (device == AUDIO_DEVICE_IN_USB_ACCESSORY) {
544 return false;
545 }
546 return audio_is_usb_in_device(device);
547}
548
David Linee3fe402017-03-13 10:00:42 -0700549static bool usb_valid_device(audio_devices_t device)
550{
Haynes Mathew George569b7482017-05-08 14:44:27 -0700551 return usb_output_device(device) ||
552 usb_input_device(device);
David Linee3fe402017-03-13 10:00:42 -0700553}
554
555static void usb_print_active_device(void){
556 struct listnode *node_i, *node_j;
557 struct usb_device_config *dev_info;
558 struct usb_card_config *card_info;
559 unsigned int i;
560
561 ALOGI("%s", __func__);
562 list_for_each(node_i, &usbmod->usb_card_conf_list) {
563 card_info = node_to_item(node_i, struct usb_card_config, list);
564 ALOGI("%s: card_dev_type (0x%x), card_no(%d)",
565 __func__, card_info->usb_device_type, card_info->usb_card);
566 list_for_each(node_j, &card_info->usb_device_conf_list) {
567 dev_info = node_to_item(node_j, struct usb_device_config, list);
568 ALOGI("%s: bit-width(%d) channel(%d)",
569 __func__, dev_info->bit_width, dev_info->channel_count);
570 for (i = 0; i < dev_info->rate_size; i++)
571 ALOGI("%s: rate %d", __func__, dev_info->rates[i]);
572 }
573 }
574}
575
Haynes Mathew Georgedf0f8862017-06-28 13:36:40 -0700576static bool usb_get_best_bit_width(
David Linee3fe402017-03-13 10:00:42 -0700577 struct listnode *dev_list,
578 unsigned int stream_bit_width,
579 unsigned int *bit_width)
580{
581 struct listnode *node_i;
582 struct usb_device_config *dev_info;
583 unsigned int candidate = 0;
584
585 list_for_each(node_i, dev_list) {
586 dev_info = node_to_item(node_i, struct usb_device_config, list);
587 ALOGI_IF(usb_audio_debug_enable,
588 "%s: USB bw(%d), stream bw(%d), candidate(%d)",
589 __func__, dev_info->bit_width,
590 stream_bit_width, candidate);
Haynes Mathew Georgedf0f8862017-06-28 13:36:40 -0700591 if (candidate == 0) {
592 ALOGV("%s: candidate bit-width (%d)",
David Linee3fe402017-03-13 10:00:42 -0700593 __func__, dev_info->bit_width);
David Linee3fe402017-03-13 10:00:42 -0700594 candidate = dev_info->bit_width;
Haynes Mathew Georgedf0f8862017-06-28 13:36:40 -0700595 } else if (dev_info->bit_width > candidate) {
David Linee3fe402017-03-13 10:00:42 -0700596 candidate = dev_info->bit_width;
Haynes Mathew Georgedf0f8862017-06-28 13:36:40 -0700597 ALOGV("%s: Found better candidate bit-width (%d)",
598 __func__, dev_info->bit_width);
David Linee3fe402017-03-13 10:00:42 -0700599 }
600 }
Haynes Mathew Georgedf0f8862017-06-28 13:36:40 -0700601 ALOGV("%s: Use the best candidate bw(%d)",
David Linee3fe402017-03-13 10:00:42 -0700602 __func__, candidate);
603 *bit_width = candidate;
604exit:
605 return true;
606}
607
608static bool usb_get_best_match_for_channels(
609 struct listnode *dev_list,
610 unsigned int bit_width,
611 unsigned int stream_ch,
612 unsigned int *channel_count)
613{
614 struct listnode *node_i;
615 struct usb_device_config *dev_info;
616 unsigned int candidate = 0;
617
618 list_for_each(node_i, dev_list) {
619 dev_info = node_to_item(node_i, struct usb_device_config, list);
620 ALOGI_IF(usb_audio_debug_enable,
621 "%s: USB ch(%d)bw(%d), stream ch(%d)bw(%d), candidate(%d)",
622 __func__, dev_info->channel_count, dev_info->bit_width,
623 stream_ch, bit_width, candidate);
624 if (dev_info->bit_width != bit_width)
625 continue;
626 if (dev_info->channel_count== stream_ch) {
627 *channel_count = dev_info->channel_count;
628 ALOGV("%s: Found match channels (%d)",
629 __func__, dev_info->channel_count);
630 goto exit;
631 } else if (candidate == 0)
632 candidate = dev_info->channel_count;
633 /*
634 * If stream channel is 4, USB supports both 3 and 5, then
635 * higher channel 5 is picked up instead of 3
636 */
637 else if (ABS_SUB(stream_ch, dev_info->channel_count) <
638 ABS_SUB(stream_ch, candidate)) {
639 candidate = dev_info->channel_count;
640 } else if ((ABS_SUB(stream_ch, dev_info->channel_count) ==
641 ABS_SUB(stream_ch, candidate)) &&
642 (dev_info->channel_count > candidate)) {
643 candidate = dev_info->channel_count;
644 }
645 }
646 ALOGV("%s: No match found, use the best candidate ch(%d)",
647 __func__, candidate);
648 *channel_count = candidate;
649exit:
650 return true;
651
652}
653
654static bool usb_sample_rate_multiple(
655 unsigned int stream_sample_rate,
656 unsigned int base)
657{
658 return (((stream_sample_rate / base) * base) == stream_sample_rate);
659}
660
661static bool usb_find_sample_rate_candidate(unsigned int base,
662 unsigned stream_rate,
663 unsigned int usb_rate,
664 unsigned int cur_candidate,
665 unsigned int *update_candidate)
666{
667 /* For sample rate, we should consider fracational sample rate as high priority.
668 * For example, if the stream is 88.2kHz and USB device support both 44.1kH and
669 * 48kHz sample rate, we should pick 44.1kHz instead of 48kHz
670 */
671 if (!usb_sample_rate_multiple(cur_candidate, base) &&
672 usb_sample_rate_multiple(usb_rate, base)) {
673 *update_candidate = usb_rate;
674 } else if (usb_sample_rate_multiple(cur_candidate, base) &&
675 usb_sample_rate_multiple(usb_rate, base)) {
676 if (ABS_SUB(stream_rate, usb_rate) <
677 ABS_SUB(stream_rate, cur_candidate)) {
678 *update_candidate = usb_rate;
679 } else if ((ABS_SUB(stream_rate, usb_rate) ==
680 ABS_SUB(stream_rate, cur_candidate)) &&
681 (usb_rate > cur_candidate)) {
682 *update_candidate = usb_rate;
683 }
684 } else if (!usb_sample_rate_multiple(cur_candidate, base) &&
685 !usb_sample_rate_multiple(usb_rate, base)) {
686 if (ABS_SUB(stream_rate, usb_rate) <
687 ABS_SUB(stream_rate, cur_candidate)) {
688 *update_candidate = usb_rate;
689 } else if ((ABS_SUB(stream_rate, usb_rate) ==
690 ABS_SUB(stream_rate, cur_candidate)) &&
691 (usb_rate > cur_candidate)) {
692 *update_candidate = usb_rate;
693 }
694 }
695 return true;
696}
697
698static bool usb_get_best_match_for_sample_rate(
699 struct listnode *dev_list,
700 unsigned int bit_width,
701 unsigned int channel_count,
702 unsigned int stream_sample_rate,
703 unsigned int *sr)
704{
705 struct listnode *node_i;
706 struct usb_device_config *dev_info;
707 unsigned int candidate = 48000;
708 unsigned int base = SAMPLE_RATE_8000;
709 bool multiple_8k = usb_sample_rate_multiple(stream_sample_rate, base);
710 unsigned int i;
711
712 ALOGV("%s: stm ch(%d)bw(%d)sr(%d), stream sample multiple of 8kHz(%d)",
713 __func__, channel_count, bit_width, stream_sample_rate, multiple_8k);
714
715 list_for_each(node_i, dev_list) {
716 dev_info = node_to_item(node_i, struct usb_device_config, list);
717 ALOGI_IF(usb_audio_debug_enable,
718 "%s: USB ch(%d)bw(%d), stm ch(%d)bw(%d)sr(%d), candidate(%d)",
719 __func__, dev_info->channel_count, dev_info->bit_width,
720 channel_count, bit_width, stream_sample_rate, candidate);
721 if ((dev_info->bit_width != bit_width) || dev_info->channel_count != channel_count)
722 continue;
723
724 candidate = 0;
725 for (i = 0; i < dev_info->rate_size; i++) {
726 ALOGI_IF(usb_audio_debug_enable,
727 "%s: USB ch(%d)bw(%d)sr(%d), stm ch(%d)bw(%d)sr(%d), candidate(%d)",
728 __func__, dev_info->channel_count,
729 dev_info->bit_width, dev_info->rates[i],
730 channel_count, bit_width, stream_sample_rate, candidate);
731 if (stream_sample_rate == dev_info->rates[i]) {
732 *sr = dev_info->rates[i];
733 ALOGV("%s: Found match sample rate (%d)",
734 __func__, dev_info->rates[i]);
735 goto exit;
736 } else if (candidate == 0) {
737 candidate = dev_info->rates[i];
738 /*
739 * For sample rate, we should consider fracational sample rate as high priority.
740 * For example, if the stream is 88.2kHz and USB device support both 44.1kH and
741 * 48kHz sample rate, we should pick 44.1kHz instead of 48kHz
742 */
743 } else if (multiple_8k) {
744 usb_find_sample_rate_candidate(SAMPLE_RATE_8000,
745 stream_sample_rate,
746 dev_info->rates[i],
747 candidate,
748 &candidate);
749 } else {
750 usb_find_sample_rate_candidate(SAMPLE_RATE_11025,
751 stream_sample_rate,
752 dev_info->rates[i],
753 candidate,
754 &candidate);
755 }
756 }
757 }
758 ALOGV("%s: No match found, use the best candidate sr(%d)",
759 __func__, candidate);
760 *sr = candidate;
761exit:
762 return true;
763}
764
765static bool usb_audio_backend_apply_policy(struct listnode *dev_list,
766 unsigned int *bit_width,
767 unsigned int *sample_rate,
768 unsigned int *channel_count)
769{
770 ALOGV("%s: from stream: bit-width(%d) sample_rate(%d) channels (%d)",
771 __func__, *bit_width, *sample_rate, *channel_count);
772 if (list_empty(dev_list)) {
773 *sample_rate = 48000;
774 *bit_width = 16;
775 *channel_count = 2;
776 ALOGE("%s: list is empty,fall back to default setting", __func__);
777 goto exit;
778 }
Haynes Mathew Georgedf0f8862017-06-28 13:36:40 -0700779 usb_get_best_bit_width(dev_list, *bit_width, bit_width);
David Linee3fe402017-03-13 10:00:42 -0700780 usb_get_best_match_for_channels(dev_list,
781 *bit_width,
782 *channel_count,
783 channel_count);
784 usb_get_best_match_for_sample_rate(dev_list,
785 *bit_width,
786 *channel_count,
787 *sample_rate,
788 sample_rate);
789exit:
790 ALOGV("%s: Updated sample rate per profile: bit-width(%d) rate(%d) chs(%d)",
791 __func__, *bit_width, *sample_rate, *channel_count);
792 return true;
793}
794
795static int usb_get_sidetone_gain(struct usb_card_config *card_info)
796{
797 int gain = card_info->usb_sidetone_vol_min + usbmod->sidetone_gain;
798 if (gain > card_info->usb_sidetone_vol_max)
799 gain = card_info->usb_sidetone_vol_max;
800 return gain;
801}
802
803void audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
804 char *value, int len)
805{
806 int err;
807
808 err = str_parms_get_str(parms, USB_SIDETONE_GAIN_STR,
809 value, len);
810 if (err >= 0) {
811 usb_sidetone_gain = pow(10.0, (float)(atoi(value))/10.0);
812 ALOGV("%s: sidetone gain(%s) decimal %d",
813 __func__, value, usb_sidetone_gain);
814 str_parms_del(parms, USB_SIDETONE_GAIN_STR);
815 }
816 return;
817}
818
819int audio_extn_usb_enable_sidetone(int device, bool enable)
820{
821 int ret = -ENODEV;
822 struct listnode *node_i;
823 struct usb_card_config *card_info;
824 int i;
825 ALOGV("%s: card_dev_type (0x%x), sidetone enable(%d)",
826 __func__, device, enable);
827
828 list_for_each(node_i, &usbmod->usb_card_conf_list) {
829 card_info = node_to_item(node_i, struct usb_card_config, list);
830 ALOGV("%s: card_dev_type (0x%x), card_no(%d)",
831 __func__, card_info->usb_device_type, card_info->usb_card);
Haynes Mathew George569b7482017-05-08 14:44:27 -0700832 if (usb_output_device(card_info->usb_device_type)) {
David Linee3fe402017-03-13 10:00:42 -0700833 if ((i = card_info->usb_sidetone_index[USB_SIDETONE_ENABLE_INDEX]) != -1) {
834 struct mixer_ctl *ctl = mixer_get_ctl_by_name(
835 card_info->usb_snd_mixer,
836 usb_sidetone_enable_str[i]);
837 if (ctl)
838 mixer_ctl_set_value(ctl, 0, enable);
839 else
840 break;
841
vivek mehta90933872017-06-15 18:04:39 -0700842#ifdef USB_SIDETONE_VOLUME
David Linee3fe402017-03-13 10:00:42 -0700843 if ((i = card_info->usb_sidetone_index[USB_SIDETONE_VOLUME_INDEX]) != -1) {
844 ctl = mixer_get_ctl_by_name(
845 card_info->usb_snd_mixer,
846 usb_sidetone_volume_str[i]);
847 if (ctl == NULL)
848 ALOGV("%s: sidetone gain mixer command is not found",
849 __func__);
850 else if (enable)
851 mixer_ctl_set_value(ctl, 0,
852 usb_get_sidetone_gain(card_info));
853 }
vivek mehta90933872017-06-15 18:04:39 -0700854#endif // USB_SIDETONE_VOLUME
David Linee3fe402017-03-13 10:00:42 -0700855 ret = 0;
856 break;
857 }
858 }
859 }
860 return ret;
861}
862
863bool audio_extn_usb_is_config_supported(unsigned int *bit_width,
864 unsigned int *sample_rate,
865 unsigned int *channel_count,
866 bool is_playback)
867{
868 struct listnode *node_i;
869 struct usb_card_config *card_info;
870
871 ALOGV("%s: from stream: bit-width(%d) sample_rate(%d) ch(%d) is_playback(%d)",
872 __func__, *bit_width, *sample_rate, *channel_count, is_playback);
873 list_for_each(node_i, &usbmod->usb_card_conf_list) {
874 card_info = node_to_item(node_i, struct usb_card_config, list);
875 ALOGI_IF(usb_audio_debug_enable,
876 "%s: card_dev_type (0x%x), card_no(%d)",
877 __func__, card_info->usb_device_type, card_info->usb_card);
878 /* Currently only apply the first playback sound card configuration */
Haynes Mathew George569b7482017-05-08 14:44:27 -0700879 if ((is_playback && usb_output_device(card_info->usb_device_type)) ||
880 (!is_playback && usb_input_device(card_info->usb_device_type))) {
David Linee3fe402017-03-13 10:00:42 -0700881 usb_audio_backend_apply_policy(&card_info->usb_device_conf_list,
882 bit_width,
883 sample_rate,
884 channel_count);
885 break;
886 }
887 }
888 ALOGV("%s: updated: bit-width(%d) sample_rate(%d) channels (%d)",
889 __func__, *bit_width, *sample_rate, *channel_count);
890
891 return true;
892}
893
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800894#define _MAX(x, y) (((x) >= (y)) ? (x) : (y))
895#define _MIN(x, y) (((x) <= (y)) ? (x) : (y))
896
Haynes Mathew George569b7482017-05-08 14:44:27 -0700897int audio_extn_usb_get_max_channels(bool is_playback)
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800898{
899 struct listnode *node_i, *node_j;
900 struct usb_device_config *dev_info;
901 struct usb_card_config *card_info;
902 unsigned int max_ch = 1;
903 list_for_each(node_i, &usbmod->usb_card_conf_list) {
904 card_info = node_to_item(node_i, struct usb_card_config, list);
Haynes Mathew George569b7482017-05-08 14:44:27 -0700905 if (usb_output_device(card_info->usb_device_type) && !is_playback)
906 continue;
907 else if (usb_input_device(card_info->usb_device_type) && is_playback)
908 continue;
909
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800910 list_for_each(node_j, &card_info->usb_device_conf_list) {
911 dev_info = node_to_item(node_j, struct usb_device_config, list);
912 max_ch = _MAX(max_ch, dev_info->channel_count);
913 }
914 }
915
916 return max_ch;
917}
918
Haynes Mathew George569b7482017-05-08 14:44:27 -0700919int audio_extn_usb_get_max_bit_width(bool is_playback)
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800920{
921 struct listnode *node_i, *node_j;
922 struct usb_device_config *dev_info;
923 struct usb_card_config *card_info;
924 unsigned int max_bw = 16;
925 list_for_each(node_i, &usbmod->usb_card_conf_list) {
926 card_info = node_to_item(node_i, struct usb_card_config, list);
Haynes Mathew George569b7482017-05-08 14:44:27 -0700927 if (usb_output_device(card_info->usb_device_type) && !is_playback)
928 continue;
929 else if (usb_input_device(card_info->usb_device_type) && is_playback)
930 continue;
931
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800932 list_for_each(node_j, &card_info->usb_device_conf_list) {
933 dev_info = node_to_item(node_j, struct usb_device_config, list);
934 max_bw = _MAX(max_bw, dev_info->bit_width);
935 }
936 }
937
938 return max_bw;
939}
940
Haynes Mathew George569b7482017-05-08 14:44:27 -0700941int audio_extn_usb_sup_sample_rates(bool is_playback,
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800942 uint32_t *sample_rates,
943 uint32_t sample_rate_size)
944{
945 struct listnode *node_i, *node_j;
946 struct usb_device_config *dev_info;
947 struct usb_card_config *card_info;
948
Haynes Mathew George569b7482017-05-08 14:44:27 -0700949 int type = is_playback ? USB_PLAYBACK : USB_CAPTURE;
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -0800950
951 ALOGV("%s supported_sample_rates_mask 0x%x", __func__, supported_sample_rates_mask[type]);
952 uint32_t bm = supported_sample_rates_mask[type];
953 uint32_t tries = _MIN(sample_rate_size, (uint32_t)__builtin_popcount(bm));
954
955 int i = 0;
956 while (tries--) {
957 int idx = __builtin_ffs(bm) - 1;
958 sample_rates[i++] = supported_sample_rates[idx];
959 bm &= ~(1<<idx);
960 }
961
962 return i;
963}
964
David Linee3fe402017-03-13 10:00:42 -0700965bool audio_extn_usb_is_capture_supported()
966{
967 if (usbmod == NULL) {
968 ALOGE("%s: USB device object is NULL", __func__);
969 return false;
970 }
971 ALOGV("%s: capture_supported %d",__func__,usbmod->is_capture_supported);
972 return usbmod->is_capture_supported;
973}
974
975void audio_extn_usb_add_device(audio_devices_t device, int card)
976{
977 struct usb_card_config *usb_card_info;
978 char check_debug_enable[PROPERTY_VALUE_MAX];
979 struct listnode *node_i;
980
981 property_get("audio.usb.enable.debug", check_debug_enable, NULL);
982 if (atoi(check_debug_enable)) {
983 usb_audio_debug_enable = true;
984 }
985
986 ALOGI_IF(usb_audio_debug_enable,
987 "%s: parameters device(0x%x), card(%d)",
988 __func__, device, card);
989 if (usbmod == NULL) {
990 ALOGE("%s: USB device object is NULL", __func__);
991 goto exit;
992 }
993
994 if (!(usb_valid_device(device)) || (card < 0)) {
995 ALOGE("%s:device(0x%x), card(%d)",
996 __func__, device, card);
997 goto exit;
998 }
999
1000 list_for_each(node_i, &usbmod->usb_card_conf_list) {
1001 usb_card_info = node_to_item(node_i, struct usb_card_config, list);
1002 ALOGI_IF(usb_audio_debug_enable,
1003 "%s: list has capability for card_dev_type (0x%x), card_no(%d)",
1004 __func__, usb_card_info->usb_device_type, usb_card_info->usb_card);
1005 /* If we have cached the capability */
1006 if ((usb_card_info->usb_device_type == device) && (usb_card_info->usb_card == card)) {
1007 ALOGV("%s: capability for device(0x%x), card(%d) is cached, no need to update",
1008 __func__, device, card);
1009 goto exit;
1010 }
1011 }
1012 usb_card_info = calloc(1, sizeof(struct usb_card_config));
1013 if (usb_card_info == NULL) {
1014 ALOGE("%s: error unable to allocate memory",
1015 __func__);
1016 goto exit;
1017 }
1018 list_init(&usb_card_info->usb_device_conf_list);
Haynes Mathew George569b7482017-05-08 14:44:27 -07001019 if (usb_output_device(device)) {
David Linee3fe402017-03-13 10:00:42 -07001020 if (!usb_get_device_playback_config(usb_card_info, card)){
1021 usb_card_info->usb_card = card;
Haynes Mathew George569b7482017-05-08 14:44:27 -07001022 usb_card_info->usb_device_type = device;
David Linee3fe402017-03-13 10:00:42 -07001023 usb_get_sidetone_mixer(usb_card_info);
1024 list_add_tail(&usbmod->usb_card_conf_list, &usb_card_info->list);
1025 goto exit;
1026 }
Haynes Mathew George569b7482017-05-08 14:44:27 -07001027 } else if (usb_input_device(device)) {
David Linee3fe402017-03-13 10:00:42 -07001028 if (!usb_get_device_capture_config(usb_card_info, card)) {
1029 usb_card_info->usb_card = card;
Haynes Mathew George569b7482017-05-08 14:44:27 -07001030 usb_card_info->usb_device_type = device;
David Linee3fe402017-03-13 10:00:42 -07001031 usbmod->is_capture_supported = true;
1032 list_add_tail(&usbmod->usb_card_conf_list, &usb_card_info->list);
1033 goto exit;
1034 }
Haynes Mathew George569b7482017-05-08 14:44:27 -07001035 } else {
1036 ALOGW("%s: unknown device 0x%x", __func__, device);
David Linee3fe402017-03-13 10:00:42 -07001037 }
1038 /* free memory in error case */
1039 if (usb_card_info != NULL)
1040 free(usb_card_info);
1041exit:
1042 if (usb_audio_debug_enable)
1043 usb_print_active_device();
1044 return;
1045}
1046
1047void audio_extn_usb_remove_device(audio_devices_t device, int card)
1048{
1049 struct listnode *node_i, *temp_i;
1050 struct listnode *node_j, *temp_j;
1051 struct usb_device_config *dev_info;
1052 struct usb_card_config *card_info;
1053 unsigned int i;
1054
1055 ALOGV("%s: device(0x%x), card(%d)",
1056 __func__, device, card);
1057
1058 if (usbmod == NULL) {
1059 ALOGE("%s: USB device object is NULL", __func__);
1060 goto exit;
1061 }
1062
1063 if (!(usb_valid_device(device)) || (card < 0)) {
1064 ALOGE("%s: Invalid parameters device(0x%x), card(%d)",
1065 __func__, device, card);
1066 goto exit;
1067 }
1068 list_for_each_safe(node_i, temp_i, &usbmod->usb_card_conf_list) {
1069 card_info = node_to_item(node_i, struct usb_card_config, list);
1070 ALOGV("%s: card_dev_type (0x%x), card_no(%d)",
1071 __func__, card_info->usb_device_type, card_info->usb_card);
1072 if ((device == card_info->usb_device_type) && (card == card_info->usb_card)){
1073 list_for_each_safe(node_j, temp_j, &card_info->usb_device_conf_list) {
1074 dev_info = node_to_item(node_j, struct usb_device_config, list);
1075 ALOGV("%s: bit-width(%d) channel(%d)",
1076 __func__, dev_info->bit_width, dev_info->channel_count);
1077 for (i = 0; i < dev_info->rate_size; i++)
1078 ALOGV("%s: rate %d", __func__, dev_info->rates[i]);
1079
1080 list_remove(node_j);
1081 free(node_to_item(node_j, struct usb_device_config, list));
1082 }
1083 list_remove(node_i);
Haynes Mathew George569b7482017-05-08 14:44:27 -07001084 if (card_info->usb_snd_mixer) {
1085 mixer_close(card_info->usb_snd_mixer);
1086 }
David Linee3fe402017-03-13 10:00:42 -07001087 free(node_to_item(node_i, struct usb_card_config, list));
1088 }
1089 }
Haynes Mathew George98d8c152017-07-13 19:14:14 -07001090 if (audio_is_usb_in_device(device)) { // XXX not sure if we need to check for card
1091 usbmod->is_capture_supported = false;
1092 supported_sample_rates_mask[USB_CAPTURE] = 0;
1093 } else {
1094 supported_sample_rates_mask[USB_PLAYBACK] = 0;
1095 }
1096
David Linee3fe402017-03-13 10:00:42 -07001097exit:
1098 if (usb_audio_debug_enable)
1099 usb_print_active_device();
1100
1101 return;
1102}
1103
1104void audio_extn_usb_init(void *adev)
1105{
1106 if (usbmod == NULL) {
1107 usbmod = calloc(1, sizeof(struct usb_module));
1108 if (usbmod == NULL) {
1109 ALOGE("%s: error unable to allocate memory", __func__);
1110 goto exit;
1111 }
1112 } else {
1113 memset(usbmod, 0, sizeof(*usbmod));
1114 }
1115
1116 list_init(&usbmod->usb_card_conf_list);
1117 usbmod->adev = (struct audio_device*)adev;
1118 usbmod->sidetone_gain = usb_sidetone_gain;
1119 usbmod->is_capture_supported = false;
1120exit:
1121 return;
1122}
1123
1124void audio_extn_usb_deinit(void)
1125{
1126 if (NULL != usbmod){
1127 free(usbmod);
1128 usbmod = NULL;
1129 }
1130}
1131#endif /*USB_HEADSET_ENABLED end*/