summaryrefslogtreecommitdiff
path: root/cras/src/alsa_plugin/ctl_cras.c
diff options
context:
space:
mode:
Diffstat (limited to 'cras/src/alsa_plugin/ctl_cras.c')
-rw-r--r--cras/src/alsa_plugin/ctl_cras.c280
1 files changed, 0 insertions, 280 deletions
diff --git a/cras/src/alsa_plugin/ctl_cras.c b/cras/src/alsa_plugin/ctl_cras.c
deleted file mode 100644
index 76b0c039..00000000
--- a/cras/src/alsa_plugin/ctl_cras.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <alsa/asoundlib.h>
-#include <alsa/control_external.h>
-#include <cras_client.h>
-
-static const size_t MAX_IODEVS = 10; /* Max devices to print out. */
-static const size_t MAX_IONODES = 20; /* Max ionodes to print out. */
-
-/* Support basic input/output volume/mute only. */
-enum CTL_CRAS_MIXER_CONTROLS {
- CTL_CRAS_MIXER_PLAYBACK_SWITCH,
- CTL_CRAS_MIXER_PLAYBACK_VOLUME,
- NUM_CTL_CRAS_MIXER_ELEMS
-};
-
-/* Hold info specific to each control. */
-struct cras_mixer_control {
- const char *name;
- int type;
- unsigned int access;
- unsigned int count;
-};
-
-/* CRAS mixer elements. */
-static const struct cras_mixer_control cras_elems[NUM_CTL_CRAS_MIXER_ELEMS] = {
- { "Master Playback Switch", SND_CTL_ELEM_TYPE_BOOLEAN,
- SND_CTL_EXT_ACCESS_READWRITE, 1 },
- { "Master Playback Volume", SND_CTL_ELEM_TYPE_INTEGER,
- SND_CTL_EXT_ACCESS_READWRITE, 1 },
-};
-
-/* Holds the client and ctl plugin pointers. */
-struct ctl_cras {
- snd_ctl_ext_t ext_ctl;
- struct cras_client *client;
-};
-
-/* Frees resources when the plugin is closed. */
-static void ctl_cras_close(snd_ctl_ext_t *ext_ctl)
-{
- struct ctl_cras *cras = (struct ctl_cras *)ext_ctl->private_data;
-
- if (cras) {
- cras_client_stop(cras->client);
- cras_client_destroy(cras->client);
- }
- free(cras);
-}
-
-/* Lists available controls. */
-static int ctl_cras_elem_list(snd_ctl_ext_t *ext_ctl, unsigned int offset,
- snd_ctl_elem_id_t *id)
-{
- snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
- if (offset >= NUM_CTL_CRAS_MIXER_ELEMS)
- return -EINVAL;
- snd_ctl_elem_id_set_name(id, cras_elems[offset].name);
- return 0;
-}
-
-/* Returns the number of available controls. */
-static int ctl_cras_elem_count(snd_ctl_ext_t *ext_ctl)
-{
- return NUM_CTL_CRAS_MIXER_ELEMS;
-}
-
-/* Gets a control key from a search id. */
-static snd_ctl_ext_key_t ctl_cras_find_elem(snd_ctl_ext_t *ext_ctl,
- const snd_ctl_elem_id_t *id)
-{
- const char *name;
- unsigned int numid;
-
- numid = snd_ctl_elem_id_get_numid(id);
- if (numid - 1 < NUM_CTL_CRAS_MIXER_ELEMS)
- return numid - 1;
-
- name = snd_ctl_elem_id_get_name(id);
-
- for (numid = 0; numid < NUM_CTL_CRAS_MIXER_ELEMS; numid++)
- if (strcmp(cras_elems[numid].name, name) == 0)
- return numid;
-
- return SND_CTL_EXT_KEY_NOT_FOUND;
-}
-
-/* Fills accessibility, type and count based on the specified control. */
-static int ctl_cras_get_attribute(snd_ctl_ext_t *ext_ctl, snd_ctl_ext_key_t key,
- int *type, unsigned int *acc,
- unsigned int *count)
-{
- if (key >= NUM_CTL_CRAS_MIXER_ELEMS)
- return -EINVAL;
- *type = cras_elems[key].type;
- *acc = cras_elems[key].access;
- *count = cras_elems[key].count;
- return 0;
-}
-
-/* Returns the range of the specified control. The volume sliders always run
- * from 0 to 100 for CRAS. */
-static int ctl_cras_get_integer_info(snd_ctl_ext_t *ext_ctl,
- snd_ctl_ext_key_t key, long *imin,
- long *imax, long *istep)
-{
- *istep = 0;
- *imin = 0;
- *imax = 100;
- return 0;
-}
-
-static int get_nodes(struct cras_client *client, enum CRAS_STREAM_DIRECTION dir,
- struct cras_ionode_info *nodes, size_t num_nodes)
-{
- struct cras_iodev_info devs[MAX_IODEVS];
- size_t num_devs;
- int rc;
-
- if (dir == CRAS_STREAM_OUTPUT)
- rc = cras_client_get_output_devices(client, devs, nodes,
- &num_devs, &num_nodes);
- else
- rc = cras_client_get_input_devices(client, devs, nodes,
- &num_devs, &num_nodes);
- if (rc < 0)
- return 0;
- return num_nodes;
-}
-
-/* Gets the value of the given control from CRAS and puts it in value. */
-static int ctl_cras_read_integer(snd_ctl_ext_t *ext_ctl, snd_ctl_ext_key_t key,
- long *value)
-{
- struct ctl_cras *cras = (struct ctl_cras *)ext_ctl->private_data;
- struct cras_ionode_info nodes[MAX_IONODES];
- int num_nodes, i;
-
- switch (key) {
- case CTL_CRAS_MIXER_PLAYBACK_SWITCH:
- *value = !cras_client_get_user_muted(cras->client);
- break;
- case CTL_CRAS_MIXER_PLAYBACK_VOLUME:
- num_nodes = get_nodes(cras->client, CRAS_STREAM_OUTPUT, nodes,
- MAX_IONODES);
- for (i = 0; i < num_nodes; i++) {
- if (!nodes[i].active)
- continue;
- *value = nodes[i].volume;
- break;
- }
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* Writes the given values to CRAS. */
-static int ctl_cras_write_integer(snd_ctl_ext_t *ext_ctl, snd_ctl_ext_key_t key,
- long *value)
-{
- struct ctl_cras *cras = (struct ctl_cras *)ext_ctl->private_data;
- struct cras_ionode_info nodes[MAX_IONODES];
- int num_nodes, i;
-
- switch (key) {
- case CTL_CRAS_MIXER_PLAYBACK_SWITCH:
- cras_client_set_user_mute(cras->client, !(*value));
- break;
- case CTL_CRAS_MIXER_PLAYBACK_VOLUME:
- num_nodes = get_nodes(cras->client, CRAS_STREAM_OUTPUT, nodes,
- MAX_IONODES);
- for (i = 0; i < num_nodes; i++) {
- if (!nodes[i].active)
- continue;
- cras_client_set_node_volume(
- cras->client,
- cras_make_node_id(nodes[i].iodev_idx,
- nodes[i].ionode_idx),
- *value);
- }
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const snd_ctl_ext_callback_t ctl_cras_ext_callback = {
- .close = ctl_cras_close,
- .elem_count = ctl_cras_elem_count,
- .elem_list = ctl_cras_elem_list,
- .find_elem = ctl_cras_find_elem,
- .get_attribute = ctl_cras_get_attribute,
- .get_integer_info = ctl_cras_get_integer_info,
- .read_integer = ctl_cras_read_integer,
- .write_integer = ctl_cras_write_integer,
-};
-
-SND_CTL_PLUGIN_DEFINE_FUNC(cras)
-{
- struct ctl_cras *cras;
- int rc;
-
- cras = malloc(sizeof(*cras));
- if (cras == NULL)
- return -ENOMEM;
-
- rc = cras_client_create(&cras->client);
- if (rc != 0 || cras->client == NULL) {
- fprintf(stderr, "Couldn't create CRAS client\n");
- free(cras);
- return rc;
- }
-
- rc = cras_client_connect(cras->client);
- if (rc < 0) {
- fprintf(stderr, "Couldn't connect to cras.\n");
- cras_client_destroy(cras->client);
- free(cras);
- return rc;
- }
-
- rc = cras_client_run_thread(cras->client);
- if (rc < 0) {
- fprintf(stderr, "Couldn't start client thread.\n");
- cras_client_stop(cras->client);
- cras_client_destroy(cras->client);
- free(cras);
- return rc;
- }
-
- rc = cras_client_connected_wait(cras->client);
- if (rc < 0) {
- fprintf(stderr, "CRAS client wouldn't connect.\n");
- cras_client_stop(cras->client);
- cras_client_destroy(cras->client);
- free(cras);
- return rc;
- }
-
- cras->ext_ctl.version = SND_CTL_EXT_VERSION;
- cras->ext_ctl.card_idx = 0;
- strncpy(cras->ext_ctl.id, "cras", sizeof(cras->ext_ctl.id) - 1);
- cras->ext_ctl.id[sizeof(cras->ext_ctl.id) - 1] = '\0';
- strncpy(cras->ext_ctl.driver, "CRAS plugin",
- sizeof(cras->ext_ctl.driver) - 1);
- cras->ext_ctl.driver[sizeof(cras->ext_ctl.driver) - 1] = '\0';
- strncpy(cras->ext_ctl.name, "CRAS", sizeof(cras->ext_ctl.name) - 1);
- cras->ext_ctl.name[sizeof(cras->ext_ctl.name) - 1] = '\0';
- strncpy(cras->ext_ctl.longname, "CRAS",
- sizeof(cras->ext_ctl.longname) - 1);
- cras->ext_ctl.longname[sizeof(cras->ext_ctl.longname) - 1] = '\0';
- strncpy(cras->ext_ctl.mixername, "CRAS",
- sizeof(cras->ext_ctl.mixername) - 1);
- cras->ext_ctl.mixername[sizeof(cras->ext_ctl.mixername) - 1] = '\0';
- cras->ext_ctl.poll_fd = -1;
-
- cras->ext_ctl.callback = &ctl_cras_ext_callback;
- cras->ext_ctl.private_data = cras;
-
- rc = snd_ctl_ext_create(&cras->ext_ctl, name, mode);
- if (rc < 0) {
- cras_client_stop(cras->client);
- cras_client_destroy(cras->client);
- free(cras);
- return rc;
- }
-
- *handlep = cras->ext_ctl.handle;
- return 0;
-}
-
-SND_CTL_PLUGIN_SYMBOL(cras);