summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArun Raghavan <arun.raghavan@collabora.co.uk>2013-08-20 12:13:56 +0530
committerArun Raghavan <arun.raghavan@collabora.co.uk>2013-08-20 12:13:56 +0530
commitda51b597423eba4805b307c511dc00242348962b (patch)
tree5294e2c548d8fa96be8b35e4960cc0ab9b9aeda0
parent6d6cecdc1765dadc56ea81a95b2c180f49f06f20 (diff)
Make mako csd-daemon more robust
This factors out device enable and voice start to share code, makes sure that the start/stop-voice on probe doesn't trigger an error (we only really call stop if start was really triggered by an enable-device). This also removes the deferred disable-device logic. As it turns out, we probably should be disabling the device immediately to follow how the Android HAL does it (since the modem bits are so fragile). In order to not trigger an error by doing a stop-voice while no device is enabled, we do a fake enable-device if required before calling stop-voice. This is seriously ugly, but I don't see a better way to do it other than Qualcomm fixing their library/firmware.
-rw-r--r--tools/mako/csd-daemon.c104
1 files changed, 61 insertions, 43 deletions
diff --git a/tools/mako/csd-daemon.c b/tools/mako/csd-daemon.c
index 61277ab..61d4f33 100644
--- a/tools/mako/csd-daemon.c
+++ b/tools/mako/csd-daemon.c
@@ -48,8 +48,9 @@
struct state {
int sockfd;
int rx_dev, tx_dev;
- int start_voice;
- int disable_device;
+
+ int start_voice, started_voice;
+ int enabled_device;
snd_pcm_t *play, *rec;
};
@@ -227,6 +228,42 @@ static void close_pcms(void)
}
}
+static int start_voice(void)
+{
+ int ret;
+
+ state.start_voice = 0;
+ ret = csd_client_start_voice();
+
+ if (ret == 0) {
+ state.started_voice = 1;
+
+ DBG("Opening PCMs\n");
+ ret = open_pcms();
+ }
+
+ return ret;
+}
+
+static int enable_device(void)
+{
+ int ret = 0;
+
+ if (ret == 0) {
+ ret = csd_client_enable_device(state.rx_dev, state.tx_dev,
+ ACDB_SETTINGS);
+
+ if (ret == 0) {
+ state.enabled_device = 1;
+
+ if (state.start_voice)
+ ret = start_voice();
+ }
+ }
+
+ return ret;
+}
+
/* Return negative value to signal death (currently only returns 0 */
static int process(const char *command)
{
@@ -241,18 +278,8 @@ static int process(const char *command)
DBG("enable rx device: %d\n", state.rx_dev);
/* Only enable device after we get both rx and tx device */
- if (state.rx_dev != -1 && state.tx_dev != -1) {
- ret = csd_client_enable_device(state.rx_dev, state.tx_dev, ACDB_SETTINGS);
- if (ret == 0 && state.start_voice) {
- state.start_voice = 0;
- ret = csd_client_start_voice();
-
- if (ret == 0) {
- DBG("Opening PCMs\n");
- ret = open_pcms();
- }
- }
- }
+ if (state.rx_dev != -1 && state.tx_dev != -1)
+ ret = enable_device();
} else if (strncmp(command, "enable-tx-device", 16) == 0) {
if (sscanf(command, "%*s %d", &state.tx_dev) != 1) {
@@ -263,33 +290,15 @@ static int process(const char *command)
DBG("enable tx device: %d\n", state.tx_dev);
/* Only enable device after we get both rx and tx device */
- if (state.rx_dev != -1 && state.tx_dev != -1) {
- if (state.disable_device) {
- state.disable_device = 0;
- ret = csd_client_disable_device();
- }
-
- if (ret == 0) {
- ret = csd_client_enable_device(state.rx_dev, state.tx_dev,
- ACDB_SETTINGS);
- }
-
- if (ret == 0 && state.start_voice) {
- state.start_voice = 0;
- ret = csd_client_start_voice();
-
- if (ret == 0) {
- DBG("Opening PCMs\n");
- ret = open_pcms();
- }
- }
- }
+ if (state.rx_dev != -1 && state.tx_dev != -1)
+ ret = enable_device();
} else if (strcmp(command, "disable-device") == 0) {
- /* We need to disable the device before an enable-device but _after_
+ /* We need to disable the device before an enable-device and ignore for
* stop-voice. Since we don't know what's coming next, we wait for
* these to happen before actually executing the command. */
- state.disable_device = 1;
+ ret = csd_client_disable_device();
+ state.enabled_device = 0;
} else if (strncmp(command, "volume", 6) == 0) {
int volume;
@@ -313,7 +322,7 @@ static int process(const char *command)
} else if (strcmp(command, "start-voice") == 0) {
if (state.rx_dev != -1 && state.tx_dev != -1)
- ret = csd_client_start_voice();
+ ret = start_voice();
else {
DBG("Deferring start voice till devices are enabled\n");
state.start_voice = 1;
@@ -321,16 +330,25 @@ static int process(const char *command)
}
} else if (strcmp(command, "stop-voice") == 0) {
- ret = csd_client_stop_voice();
+ if (state.started_voice) {
+ if (!state.enabled_device) {
+ /* Run a fake enable device because the firmware can't deal
+ * with a stop-voice after disable-device */
+ if (csd_client_enable_device(7, 6, ACDB_SETTINGS) < 0)
+ ERR("Error enabling device before shutdown\n");
+ }
+
+ ret = csd_client_stop_voice();
- if (ret == 0) {
DBG("Closing PCMs\n");
close_pcms();
- }
+
+ } else
+ DBG("Ignoring stop-voice before start-voice was executed\n");
/* Reset all the things */
- state.start_voice = 0;
- state.disable_device = 0;
+ state.start_voice = state.started_voice = 0;
+ state.enabled_device = 0;
state.rx_dev = state.tx_dev = -1;
} else {