diff options
Diffstat (limited to 'cras/src/alsa_plugin/ctl_cras.c')
-rw-r--r-- | cras/src/alsa_plugin/ctl_cras.c | 280 |
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); |