Merge remote-tracking branches 'asoc/topic/atmel', 'asoc/topic/chmap', 'asoc/topic...
authorMark Brown <broonie@kernel.org>
Sun, 19 Feb 2017 16:36:13 +0000 (16:36 +0000)
committerMark Brown <broonie@kernel.org>
Sun, 19 Feb 2017 16:36:13 +0000 (16:36 +0000)
1  2  3  4  5 
include/drm/drm_edid.h
sound/soc/soc-core.c

diff --combined include/drm/drm_edid.h
@@@@@@ -248,6 -248,6 -248,7 -248,6 -248,6 +248,7 @@@@@@ struct detailed_timing 
     # define DRM_ELD_AUD_SYNCH_DELAY_MAX       0xfa    /* 500 ms */
     
     #define DRM_ELD_SPEAKER                    7
++ ++# define DRM_ELD_SPEAKER_MASK              0x7f
     # define DRM_ELD_SPEAKER_RLRC              (1 << 6)
     # define DRM_ELD_SPEAKER_FLRC              (1 << 5)
     # define DRM_ELD_SPEAKER_RC                (1 << 4)
@@@@@@ -330,6 -330,7 -331,7 -330,6 -330,7 +331,6 @@@@@@ int drm_edid_to_sad(struct edid *edid, 
     int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
     int drm_av_sync_delay(struct drm_connector *connector,
                      const struct drm_display_mode *mode);
 -- -struct drm_connector *drm_select_eld(struct drm_encoder *encoder);
     
     #ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
     int drm_load_edid_firmware(struct drm_connector *connector);
@@@@@@ -414,6 -415,6 -416,18 -414,6 -415,6 +415,18 @@@@@@ static inline int drm_eld_size(const ui
     }
     
     /**
++ ++ * drm_eld_get_spk_alloc - Get speaker allocation
++ ++ * @eld: pointer to an ELD memory structure
++ ++ *
++ ++ * The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER
++ ++ * field definitions to identify speakers.
++ ++ */
++ ++static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
++ ++{
++ ++   return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK;
++ ++}
++ ++
++ ++/**
      * drm_eld_get_conn_type - Get device type hdmi/dp connected
      * @eld: pointer to an ELD memory structure
      *
diff --combined sound/soc/soc-core.c
     #include <linux/ctype.h>
     #include <linux/slab.h>
     #include <linux/of.h>
 ++++#include <linux/dmi.h>
     #include <sound/core.h>
     #include <sound/jack.h>
     #include <sound/pcm.h>
@@@@@@ -1594,6 -1593,6 -1593,27 -1593,6 -1593,6 +1594,27 @@@@@@ static int soc_probe_dai(struct snd_soc
        return 0;
     }
     
++ ++static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais,
++ ++                           struct snd_soc_pcm_runtime *rtd)
++ ++{
++ ++   int i, ret = 0;
++ ++
++ ++   for (i = 0; i < num_dais; ++i) {
++ ++           struct snd_soc_dai_driver *drv = dais[i]->driver;
++ ++
++ ++           if (!rtd->dai_link->no_pcm && drv->pcm_new)
++ ++                   ret = drv->pcm_new(rtd, dais[i]);
++ ++           if (ret < 0) {
++ ++                   dev_err(dais[i]->dev,
++ ++                           "ASoC: Failed to bind %s with pcm device\n",
++ ++                           dais[i]->name);
++ ++                   return ret;
++ ++           }
++ ++   }
++ ++
++ ++   return 0;
++ ++}
++ ++
     static int soc_link_dai_widgets(struct snd_soc_card *card,
                                struct snd_soc_dai_link *dai_link,
                                struct snd_soc_pcm_runtime *rtd)
@@@@@@ -1705,6 -1704,6 -1725,13 -1704,6 -1704,6 +1726,13 @@@@@@ static int soc_probe_link_dais(struct s
                                       dai_link->stream_name, ret);
                                return ret;
                        }
++ ++                   ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
++ ++                   if (ret < 0)
++ ++                           return ret;
++ ++                   ret = soc_link_dai_pcm_new(rtd->codec_dais,
++ ++                                              rtd->num_codecs, rtd);
++ ++                   if (ret < 0)
++ ++                           return ret;
                } else {
                        INIT_DELAYED_WORK(&rtd->delayed_work,
                                                codec2codec_close_delayed_work);
@@@@@@ -1749,7 -1748,6 -1776,6 -1748,6 -1748,6 +1777,7 @@@@@@ static int soc_bind_aux_dev(struct snd_
     
        component->init = aux_dev->init;
        component->auxiliary = 1;
 ++++   list_add(&component->card_aux_list, &card->aux_comp_list);
     
        return 0;
     
     
     static int soc_probe_aux_devices(struct snd_soc_card *card)
     {
 ----   struct snd_soc_component *comp;
 ++++   struct snd_soc_component *comp, *tmp;
        int order;
        int ret;
     
        for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
                order++) {
 ----           list_for_each_entry(comp, &card->component_dev_list, card_list) {
 ----                   if (!comp->auxiliary)
 ----                           continue;
 ----
 ++++           list_for_each_entry_safe(comp, tmp, &card->aux_comp_list,
 ++++                                    card_aux_list) {
                        if (comp->driver->probe_order == order) {
                                ret = soc_probe_component(card, comp);
                                if (ret < 0) {
                                                comp->name, ret);
                                        return ret;
                                }
 ++++                           list_del(&comp->card_aux_list);
                        }
                }
        }
@@@@@@ -1889,139 -1888,6 -1916,6 -1888,6 -1888,6 +1917,139 @@@@@@ int snd_soc_runtime_set_dai_fmt(struct 
     }
     EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt);
     
 ++++
 ++++/* Trim special characters, and replace '-' with '_' since '-' is used to
 ++++ * separate different DMI fields in the card long name. Only number and
 ++++ * alphabet characters and a few separator characters are kept.
 ++++ */
 ++++static void cleanup_dmi_name(char *name)
 ++++{
 ++++   int i, j = 0;
 ++++
 ++++   for (i = 0; name[i]; i++) {
 ++++           if (isalnum(name[i]) || (name[i] == '.')
 ++++               || (name[i] == '_'))
 ++++                   name[j++] = name[i];
 ++++           else if (name[i] == '-')
 ++++                   name[j++] = '_';
 ++++   }
 ++++
 ++++   name[j] = '\0';
 ++++}
 ++++
 ++++/**
 ++++ * snd_soc_set_dmi_name() - Register DMI names to card
 ++++ * @card: The card to register DMI names
 ++++ * @flavour: The flavour "differentiator" for the card amongst its peers.
 ++++ *
 ++++ * An Intel machine driver may be used by many different devices but are
 ++++ * difficult for userspace to differentiate, since machine drivers ususally
 ++++ * use their own name as the card short name and leave the card long name
 ++++ * blank. To differentiate such devices and fix bugs due to lack of
 ++++ * device-specific configurations, this function allows DMI info to be used
 ++++ * as the sound card long name, in the format of
 ++++ * "vendor-product-version-board"
 ++++ * (Character '-' is used to separate different DMI fields here).
 ++++ * This will help the user space to load the device-specific Use Case Manager
 ++++ * (UCM) configurations for the card.
 ++++ *
 ++++ * Possible card long names may be:
 ++++ * DellInc.-XPS139343-01-0310JH
 ++++ * ASUSTeKCOMPUTERINC.-T100TA-1.0-T100TA
 ++++ * Circuitco-MinnowboardMaxD0PLATFORM-D0-MinnowBoardMAX
 ++++ *
 ++++ * This function also supports flavoring the card longname to provide
 ++++ * the extra differentiation, like "vendor-product-version-board-flavor".
 ++++ *
 ++++ * We only keep number and alphabet characters and a few separator characters
 ++++ * in the card long name since UCM in the user space uses the card long names
 ++++ * as card configuration directory names and AudoConf cannot support special
 ++++ * charactors like SPACE.
 ++++ *
 ++++ * Returns 0 on success, otherwise a negative error code.
 ++++ */
 ++++int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
 ++++{
 ++++   const char *vendor, *product, *product_version, *board;
 ++++   size_t longname_buf_size = sizeof(card->snd_card->longname);
 ++++   size_t len;
 ++++
 ++++   if (card->long_name)
 ++++           return 0; /* long name already set by driver or from DMI */
 ++++
 ++++   /* make up dmi long name as: vendor.product.version.board */
 ++++   vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
 ++++   if (!vendor) {
 ++++           dev_warn(card->dev, "ASoC: no DMI vendor name!\n");
 ++++           return 0;
 ++++   }
 ++++
 ++++   snprintf(card->dmi_longname, sizeof(card->snd_card->longname),
 ++++                    "%s", vendor);
 ++++   cleanup_dmi_name(card->dmi_longname);
 ++++
 ++++   product = dmi_get_system_info(DMI_PRODUCT_NAME);
 ++++   if (product) {
 ++++           len = strlen(card->dmi_longname);
 ++++           snprintf(card->dmi_longname + len,
 ++++                    longname_buf_size - len,
 ++++                    "-%s", product);
 ++++
 ++++           len++;  /* skip the separator "-" */
 ++++           if (len < longname_buf_size)
 ++++                   cleanup_dmi_name(card->dmi_longname + len);
 ++++
 ++++           /* some vendors like Lenovo may only put a self-explanatory
 ++++            * name in the product version field
 ++++            */
 ++++           product_version = dmi_get_system_info(DMI_PRODUCT_VERSION);
 ++++           if (product_version) {
 ++++                   len = strlen(card->dmi_longname);
 ++++                   snprintf(card->dmi_longname + len,
 ++++                            longname_buf_size - len,
 ++++                            "-%s", product_version);
 ++++
 ++++                   len++;
 ++++                   if (len < longname_buf_size)
 ++++                           cleanup_dmi_name(card->dmi_longname + len);
 ++++           }
 ++++   }
 ++++
 ++++   board = dmi_get_system_info(DMI_BOARD_NAME);
 ++++   if (board) {
 ++++           len = strlen(card->dmi_longname);
 ++++           snprintf(card->dmi_longname + len,
 ++++                    longname_buf_size - len,
 ++++                    "-%s", board);
 ++++
 ++++           len++;
 ++++           if (len < longname_buf_size)
 ++++                   cleanup_dmi_name(card->dmi_longname + len);
 ++++   } else if (!product) {
 ++++           /* fall back to using legacy name */
 ++++           dev_warn(card->dev, "ASoC: no DMI board/product name!\n");
 ++++           return 0;
 ++++   }
 ++++
 ++++   /* Add flavour to dmi long name */
 ++++   if (flavour) {
 ++++           len = strlen(card->dmi_longname);
 ++++           snprintf(card->dmi_longname + len,
 ++++                    longname_buf_size - len,
 ++++                    "-%s", flavour);
 ++++
 ++++           len++;
 ++++           if (len < longname_buf_size)
 ++++                   cleanup_dmi_name(card->dmi_longname + len);
 ++++   }
 ++++
 ++++   /* set the card long name */
 ++++   card->long_name = card->dmi_longname;
 ++++
 ++++   return 0;
 ++++}
 ++++EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name);
 ++++
     static int snd_soc_instantiate_card(struct snd_soc_card *card)
     {
        struct snd_soc_codec *codec;
@@@@@@ -3110,8 -2976,6 -3004,6 -2976,6 -2976,6 +3138,8 @@@@@@ static int snd_soc_component_initialize
        component->remove = component->driver->remove;
        component->suspend = component->driver->suspend;
        component->resume = component->driver->resume;
 ++++   component->pcm_new = component->driver->pcm_new;
 ++++   component->pcm_free= component->driver->pcm_free;
     
        dapm = &component->dapm;
        dapm->dev = dev;
@@@@@@ -3294,21 -3158,6 -3186,6 -3158,6 -3158,6 +3322,21 @@@@@@ static void snd_soc_platform_drv_remove
        platform->driver->remove(platform);
     }
     
 ++++static int snd_soc_platform_drv_pcm_new(struct snd_soc_pcm_runtime *rtd)
 ++++{
 ++++   struct snd_soc_platform *platform = rtd->platform;
 ++++
 ++++   return platform->driver->pcm_new(rtd);
 ++++}
 ++++
 ++++static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm)
 ++++{
 ++++   struct snd_soc_pcm_runtime *rtd = pcm->private_data;
 ++++   struct snd_soc_platform *platform = rtd->platform;
 ++++
 ++++   platform->driver->pcm_free(pcm);
 ++++}
 ++++
     /**
      * snd_soc_add_platform - Add a platform to the ASoC core
      * @dev: The parent device for the platform
@@@@@@ -3332,10 -3181,6 -3209,6 -3181,6 -3181,6 +3360,10 @@@@@@ int snd_soc_add_platform(struct device 
                platform->component.probe = snd_soc_platform_drv_probe;
        if (platform_drv->remove)
                platform->component.remove = snd_soc_platform_drv_remove;
 ++++   if (platform_drv->pcm_new)
 ++++           platform->component.pcm_new = snd_soc_platform_drv_pcm_new;
 ++++   if (platform_drv->pcm_free)
 ++++           platform->component.pcm_free = snd_soc_platform_drv_pcm_free;
     
     #ifdef CONFIG_DEBUG_FS
        platform->component.debugfs_prefix = "platform";