From patchwork Tue Jan 3 06:09:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mengdong.lin@linux.intel.com X-Patchwork-Id: 9494669 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 28AF660414 for ; Tue, 3 Jan 2017 09:19:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E8C426B39 for ; Tue, 3 Jan 2017 09:19:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 12B9226CF9; Tue, 3 Jan 2017 09:19:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 56A2E26B39 for ; Tue, 3 Jan 2017 09:19:29 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id B3A2426733B; Tue, 3 Jan 2017 10:19:28 +0100 (CET) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id CB482267323; Tue, 3 Jan 2017 10:17:09 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id B39D1266DA0; Tue, 3 Jan 2017 07:06:22 +0100 (CET) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by alsa0.perex.cz (Postfix) with ESMTP id 6AB60266D86 for ; Tue, 3 Jan 2017 07:06:18 +0100 (CET) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga105.fm.intel.com with ESMTP; 02 Jan 2017 22:06:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,451,1477983600"; d="scan'208";a="48665571" Received: from amanda-haswell-pc.sh.intel.com ([10.239.159.21]) by orsmga005.jf.intel.com with ESMTP; 02 Jan 2017 22:06:15 -0800 From: mengdong.lin@linux.intel.com To: alsa-devel@alsa-project.org, broonie@kernel.org Date: Tue, 3 Jan 2017 14:09:18 +0800 Message-Id: <1483423758-8986-1-git-send-email-mengdong.lin@linux.intel.com> X-Mailer: git-send-email 2.5.0 Cc: Mengdong Lin , tiwai@suse.de, mengdong.lin@intel.com, liam.r.girdwood@linux.intel.com, vinod.koul@intel.com, pierre-louis.bossart@intel.com Subject: [alsa-devel] [RFC PATCH] ucm: Add support for device positions X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Mengdong Lin Users can provide prosition info of audio devices as a device value. This will help the sound server to choose an audio devices from some candidates based on the their locations and the status of the machine. The value name is the "Postion", and its value should be a composition of "Top", "Bottom", "Left", "Right", "Front" and "Back". For example, a speaker may have a position like "Front Top". The postion value can be got by either of the two APIs: - snd_use_case_get(), via identifier 'Postion/device', to get the original position string defined by the user. - snd_use_case_geti(), via identifier '_devpos/device', to get the integer value of the position. If the user has not define a position, 0 will be returned that means an unknown position. Signed-off-by: Mengdong Lin diff --git a/include/use-case.h b/include/use-case.h index 8911645..b3b451b 100644 --- a/include/use-case.h +++ b/include/use-case.h @@ -165,6 +165,28 @@ extern "C" { #define SND_USE_CASE_TQ_VOICE "Voice" /**< Voice Tone Quality */ #define SND_USE_CASE_TQ_TONES "Tones" /**< Tones Tone Quality */ + +/** + * Device Position bits + * + * 0 is reserved for unknown position in each dimesion. Users can get the + * integer value of the device postion by API snd_use_case_geti() via + * identifier '_devpos/device', and the returned value is a compostion of + * three dimesions. + * + * NOTE: Users can also get the position string like "Top Left" by API + * snd_use_case_get() via identifier 'Position/device". + */ +#define SND_USE_CASE_POS_LEFT (1<<0) +#define SND_USE_CASE_POS_RIGHT (2<<0) +#define SND_USE_CASE_POS_HORIZON_MASK (0xffff<<0) +#define SND_USE_CASE_POS_TOP (1<<4) +#define SND_USE_CASE_POS_BOTTOM (2<<4) +#define SND_USE_CASE_POS_VERTICAL_MASK (0xffff<<4) +#define SND_USE_CASE_POS_FRONT (1<<8) +#define SND_USE_CASE_POS_BACK (2<<8) +#define SND_USE_CASE_DEPTH_MASK (0xffff<<8) + /** use case container */ typedef struct snd_use_case_mgr snd_use_case_mgr_t; @@ -319,6 +341,10 @@ int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr, * trick upper software layers to e.g. automatically mute speakers when * headphones are plugged in, but that's application policy * configuration that doesn't belong to UCM configuration files. + * - Position + * Position of the device, a composition of "Left", "Right", "Top", + * "Bottom", "Front" and "Back". For example, a device speaker may + * have a position like "Front Top". */ int snd_use_case_get(snd_use_case_mgr_t *uc_mgr, const char *identifier, diff --git a/src/ucm/main.c b/src/ucm/main.c index 2d33886..d196a57 100644 --- a/src/ucm/main.c +++ b/src/ucm/main.c @@ -801,6 +801,26 @@ long device_status(snd_use_case_mgr_t *uc_mgr, return 0; } +/* get the device postion */ +long device_position(snd_use_case_mgr_t *uc_mgr, const char *device_name) +{ + struct use_case_device *dev; + struct list_head *pos, *base; + + if (uc_mgr->active_verb == NULL) + return -EINVAL; + + base = &uc_mgr->active_verb->device_list; + list_for_each(pos, base) { + dev = list_entry(pos, struct use_case_device, list); + if (strcmp(dev->name, device_name) == 0) + return dev->position; + } + + /* cannot find the device */ + return -1; +} + long modifier_status(snd_use_case_mgr_t *uc_mgr, const char *modifier_name) { @@ -1645,6 +1665,19 @@ int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr, } else if (identifier[0] == '_') err = -ENOENT; #endif + } else if (check_identifier(identifier, "_devpos")) { + if (!str) { + err = -EINVAL; + goto __end; + } + + err = device_position(uc_mgr, str); + if (err >= 0) { + *value = err; + err = 0; + } else { + err = -EINVAL; + } } else err = -ENOENT; if (str) diff --git a/src/ucm/parser.c b/src/ucm/parser.c index 4dc35c3..fc035c3 100644 --- a/src/ucm/parser.c +++ b/src/ucm/parser.c @@ -55,6 +55,22 @@ static const char * const component_dir[] = { NULL, /* terminator */ }; +struct position { + int val; + const char *id; +}; + +/* device positions */ +static struct position positions[] = { + { SND_USE_CASE_POS_LEFT, "Left" }, + { SND_USE_CASE_POS_RIGHT, "Right" }, + { SND_USE_CASE_POS_TOP, "Top" }, + { SND_USE_CASE_POS_BOTTOM, "Bottom" }, + { SND_USE_CASE_POS_FRONT, "Front" }, + { SND_USE_CASE_POS_BACK, "Back" }, + { 0, NULL }, /* terminator */ +}; + static int filename_filter(const struct dirent *dirent); static int is_component_directory(const char *dir); @@ -62,6 +78,30 @@ static int parse_sequence(snd_use_case_mgr_t *uc_mgr, struct list_head *base, snd_config_t *cfg); +static unsigned int parse_position(struct list_head *value_list) +{ + struct list_head *pos; + struct ucm_value *val; + int i, position = 0; + + list_for_each(pos, value_list) { + val = list_entry(pos, struct ucm_value, list); + if (strncmp("Position", val->name, MAX_IDENTIFIER) == 0) { + i = 0; + while (positions[i].id) { + if (strstr(val->data, positions[i].id)) + position |= positions[i].val; + i++; + } + + return position; + } + } + + /* unknown position */ + return 0; +} + /* * Parse string */ @@ -870,6 +910,7 @@ static int parse_device(snd_use_case_mgr_t *uc_mgr, uc_error("error: failed to parse Value"); return err; } + device->position = parse_position(&device->value_list); continue; } } diff --git a/src/ucm/ucm_local.h b/src/ucm/ucm_local.h index 299a5b9..2537a1d 100644 --- a/src/ucm/ucm_local.h +++ b/src/ucm/ucm_local.h @@ -42,6 +42,7 @@ #define MAX_FILE 256 #define MAX_CARD_LONG_NAME 80 +#define MAX_IDENTIFIER 32 /* Max length of identifier string */ #define ALSA_USE_CASE_DIR ALSA_CONFIG_DIR "/ucm" #define SEQUENCE_ELEMENT_TYPE_CDEV 1 @@ -139,6 +140,7 @@ struct use_case_device { char *name; char *comment; + int position; /* bits of SND_USE_CASE_POS_, 0 for unknown position */ /* device enable and disable sequences */ struct list_head enable_list;