[alsa-devel] [PATCH 1/2] ucm: Automatically load the best config file based on the card long name
Lin, Mengdong
mengdong.lin at intel.com
Wed Dec 21 17:12:37 CET 2016
> -----Original Message-----
> From: Liam Girdwood [mailto:liam.r.girdwood at linux.intel.com]
> Sent: Wednesday, December 21, 2016 10:39 PM
>
> On Wed, 2016-12-21 at 21:09 +0800, mengdong.lin at linux.intel.com wrote:
> > From: Mengdong Lin <mengdong.lin at linux.intel.com>
> >
> > Intel DSP platform drivers are used by many different devices. For
> > user space to differentiate them, ASoC machine driver may include the
> > DMI info (vendor, product and board) in card long name. Possible card
> > long names
> > are:
> > broadwell-rt286-Dell Inc.-XPS 13 9343-0310JH
>
> See my previous comments on the kernel patch, but the longname should be
> like :-
>
> "Dell Inc.-XPS 13"
May we keep it? It can make the matching code simpler.
>
> > broadwell-rt286-Intel Corp.-Broadwell Client platform-Wilson Beach SDS
> > bytcr-rt5640-ASUSTeK COMPUTER INC.-T100TA-T100TA
> > bytcr-rt5651-Circuitco-Minnowboard Max D0 PLATFORM-MinnowBoard
> MAX ...
> >
> > And user space can define configuration files including fields
> > separated by '.' as below:
> > broadwell-rt286
> > broadwell-rt286.Dell.XPS
>
> Dont need to use a . as the names should be unique.
>
> > bytcr-rt5640
> > bytcr-rt5640.ASUS.T100
> > bytcr-rt5651.MinnowboardMax
> > ...
> >
> > When being asked to load configuration file of a card, UCM will try to
> > find the card long name from the local machine, and then scan all
> > available configuration file names, search every field of config file
> > name in the card long name. The more characters match, the higher
> > score the file has. Finally, the file with the highest score will be
> > loaded to configure the sound card.
> >
> > Signed-off-by: Mengdong Lin <mengdong.lin at linux.intel.com>
> >
> > diff --git a/src/ucm/parser.c b/src/ucm/parser.c index
> > c98373a..ff75da7 100644
> > --- a/src/ucm/parser.c
> > +++ b/src/ucm/parser.c
> > @@ -55,6 +55,9 @@ static const char * const component_dir[] = {
> > NULL, /* terminator */
> > };
> >
> > +static int filename_filter(const struct dirent *dirent); static int
> > +is_component_directory(const char *dir);
> > +
> > static int parse_sequence(snd_use_case_mgr_t *uc_mgr,
> > struct list_head *base,
> > snd_config_t *cfg);
> > @@ -1328,6 +1331,210 @@ static int
> parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
> > return 0;
> > }
> >
> > +/* trim SPACE (0x20) from the string */ static void trim_space(char
> > +*str) {
> > + int i, j = 0;
> > +
> > + for (i = 0; str[i] && i < MAX_FILE; i++) {
> > + if (str[i] != 0x20)
> > + str[j++] = str[i];
> > + }
> > +
> > + str[j] = '\0';
> > +}
> > +
> > +/* find and store the card long name if the card is in this machine
> > +*/ static int get_card_long_name(snd_use_case_mgr_t *mgr) {
> > + const char *card_name = mgr->card_name;
> > + snd_ctl_t *handle;
> > + int card, err, dev, idx;
> > + snd_ctl_card_info_t *info;
> > + const char *_name, *_long_name;
> > +
> > + snd_ctl_card_info_alloca(&info);
> > +
> > + card = -1;
> > + if (snd_card_next(&card) < 0 || card < 0) {
> > + uc_error("no soundcards found...");
> > + return -1;
> > + }
> > +
> > + while (card >= 0) {
> > + char name[32];
> > +
> > + sprintf(name, "hw:%d", card);
> > + err = snd_ctl_open(&handle, name, 0);
> > + if (err < 0) {
> > + uc_error("control open (%i): %s", card,
> > + snd_strerror(err));
> > + goto next_card;
> > + }
> > +
> > + err = snd_ctl_card_info(handle, info);
> > + if (err < 0) {
> > + uc_error("control hardware info (%i): %s", card,
> > + snd_strerror(err));
> > + snd_ctl_close(handle);
> > + goto next_card;
> > + }
> > +
> > + _name = snd_ctl_card_info_get_name(info);
> > + if (!strncmp(card_name, _name, 32)) {
> > + _long_name = snd_ctl_card_info_get_longname(info);
> > + strncpy(mgr->card_long_name, _long_name,
> > + MAX_CARD_LONG_NAME);
> > + snd_ctl_close(handle);
> > + return 0;
> > + }
> > +
> > + snd_ctl_close(handle);
> > +next_card:
> > + if (snd_card_next(&card) < 0) {
> > + uc_error("snd_card_next");
> > + break;
> > + }
> > + }
> > +
> > + return -1;
> > +}
> > +
> > +/* This function will find the best device-specific configuration
> > +file based
> > + * on the sound card long name.
> > + * Different devices may share the same sound driver and thus the
> > +same sound
> > + * card name (short name), but they may still need different
> > +device-specific
> > + * configurations. For user space to differentiate them, kernel
> > +drivers may
> > + * include the DMI info (vendor, product and board) in the card long
> name.
> > + * And user space can define configuration file names appending DMI
> > +keywords
> > + * to the card name, like:
> > + * bytcr-rt5640.ASUS.T100
> > + * bytcr-rt5651.MinnowBoard
> > + *
> > + * When being asked to load the configuration file for a card, this
> > +function
> > + * will try to find the card long name from the local machine, and
> > +then scan
> > + * all available configuration file names, search every field of the
> > +config
> > + * file name in the card long name. The more characters match, the
> > +higher
> > + * score the file has. Finally, the file with the highest score will be loaded.
> > + */
>
> Id' expect this function to try and open card longname and then card name if
> longname is not found. So providing we use the exact same names as the
> DMI name we wont need any string formatting or scoring (i.e. file
> open("longname/longname.conf") will either succeed or fail)
>
> Liam
I feel we cannot use the exact same names for the configuration file and card long name. The DMI info in the card long name can be lengthy, including '.' , SPACE, meaningless info like "Corp." and sometime duplicated info for some OEMs.I hope developers can just extract key words from the messy DMI info to make a simple configuration file name, and UCM automatically do the matching and give each configuration file a score. Then the file with highest score will be used for the card.
Thanks
Mengdong
More information about the Alsa-devel
mailing list