ifx: Add necessary incantations for audio
authorDenis Kenzior <denkenz@gmail.com>
Wed, 8 Feb 2012 02:00:52 +0000 (20:00 -0600)
committerDenis Kenzior <denkenz@gmail.com>
Thu, 9 Feb 2012 14:36:18 +0000 (08:36 -0600)
drivers/ifxmodem/audio-settings.c

index f156cf7..c275398 100644 (file)
 
 static const char *none_prefix[] = { NULL };
 static const char *xprogress_prefix[] = { "+XPROGRESS:", NULL };
+static const char *xdrv_prefix[] = { "+XDRV:", NULL };
+
+enum xdrv_destination {
+       XDRV_DESTINATION_SPEECH_TX =    0,
+       XDRV_DESTINATION_ANALOG_OUT =   1,
+       XDRV_DESTINATION_I2SX_TX =      2,
+       XDRV_DESTINATION_I2SY_TX =      3,
+       XDRV_DESTINATION_PCM_GENERAL =  4,
+};
+
+enum xdrv_source {
+       XDRV_SOURCE_SPEECH_RX =         0,
+       XDRV_SOURCE_SPEECH_ANALOG_IN =  1,
+       XDRV_SOURCE_DIGITAL_MIC_IN =    2,
+       XDRV_SOURCE_I2SX_RX =           3,
+       XDRV_SOURCE_I2SY_RX =           4,
+       XDRV_SOURCE_SIMPLE_TONES =      5,
+};
+
+enum xdrv_sampling_rate {
+       XDRV_SAMPLING_RATE_8KHZ =       0,
+       XDRV_SAMPLING_RATE_11KHZ =      1,
+       XDRV_SAMPLING_RATE_12KHZ =      2,
+       XDRV_SAMPLING_RATE_16KHZ =      3,
+       XDRV_SAMPLING_RATE_22KHZ =      4,
+       XDRV_SAMPLING_RATE_24KHZ =      5,
+       XDRV_SAMPLING_RATE_32KHZ =      6,
+       XDRV_SAMPLING_RATE_44KHZ =      7,
+       XDRV_SAMPLING_RATE_48KHZ =      8,
+       XDRV_SAMPLING_RATE_96KHZ =      9,
+       XDRV_SAMPLING_RATE_192KHZ =     10,
+};
+
+enum xdrv_sampling_width {
+       XDRV_SAMPLING_WIDTH_16 =        0,
+       XDRV_SAMPLING_WIDTH_18 =        1,
+       XDRV_SAMPLING_WIDTH_20 =        2,
+       XDRV_SAMPLING_WIDTH_24 =        3,
+       XDRV_SAMPLING_WIDTH_32 =        4,
+       XDRV_SAMPLING_WIDTH_48 =        5,
+       XDRV_SAMPLING_WIDTH_64 =        6,
+};
+
+enum xdrv_i2s_mode {
+       XDRV_I2S_MODE_MASTER =          0,
+       XDRV_I2S_MODE_SLAVE =           1,
+};
+
+enum xdrv_i2s_clock {
+       XDRV_I2S_CLOCK_0 =              0,
+       XDRV_I2S_CLOCK_1 =              1,
+};
+
+enum xdrv_i2s_configuration_mode {
+       XDRV_I2S_CONFIGURATION_MODE_UPDATE_ALL =        0,
+       XDRV_I2S_CONFIGURATION_MODE_UPDATE_HW =         1,
+       XDRV_I2S_CONFIGURATION_MODE_UPDATE_TRANSDUCER = 2,
+};
+
+enum xdrv_i2s_settings {
+       XDRV_I2S_SETTINGS_NORMAL =      0,
+       XDRV_I2S_SETTINGS_SPECIAL1 =    1,
+       XDRV_I2S_SETTINGS_SPECIAL2 =    2,
+};
+
+enum xdrv_i2s_transmission_mode {
+       XDRV_I2S_TRANSMISSION_MODE_PCM =        0,
+       XDRV_I2S_TRANSMISSION_MODE_NORMAL =     1,
+       XDRV_IS2_TRANSMISSION_MODE_PCM_BURST =  2,
+};
+
+enum xdrv_source_transducer {
+       XDRV_SOURCE_TRANSDUCER_DEFAULT =                0,
+       XDRV_SOURCE_TRANSDUCER_HANDSET =                1,
+       XDRV_SOURCE_TRANSDUCER_HEADSET =                2,
+       XDRV_SOURCE_TRANSDUCER_HF =                     3,
+       XDRV_SOURCE_TRANSDUCER_AUX =                    4,
+       XDRV_SOURCE_TRANSDUCER_TTY =                    5,
+       XDRV_SOURCE_TRANSDUCER_BLUETOOTH =              6,
+       XDRV_SOURCE_TRANSDUCER_USER_DEFINED_15 =        21,
+};
+
+enum xdrv_dest_transducer {
+       XDRV_DEST_TRANSDUCER_DEFAULT =          0,
+       XDRV_DEST_TRANSDUCER_HANDSET =          1,
+       XDRV_DEST_TRANSDUCER_HEADSET =          2,
+       XDRV_DEST_TRANSDUCER_BACKSPEAKER =      3,
+       XDRV_DEST_TRANSDUCER_TTY =              6,
+       XDRV_DEST_TRANSDUCER_BLUETOOTH =        7,
+       XDRV_DEST_TRANSDUCER_USER_DEFINED_15 =  22,
+};
+
+enum xdrv_audio_mode {
+       XDRV_AUDIO_MODE_MONO =          0,
+       XDRV_AUDIO_MODE_DUAL_MONO =     1,
+       XDRV_AUDIO_MODE_STEREO =        2,
+       XDRV_AUDIO_MODE_DUAL_MONO_R =   3,
+       XDRV_AUDIO_MODE_DUAL_MONO_L =   4,
+};
 
 struct audio_settings_data {
        GAtChat *chat;
 };
 
+static inline void xdrv_enable_source(GAtChat *chat, enum xdrv_source src)
+{
+       char buf[256];
+
+       sprintf(buf, "AT+XDRV=40,2,%i", src);
+       g_at_chat_send(chat, buf, xdrv_prefix, NULL, NULL, NULL);
+}
+
+static inline void xdrv_disable_source(GAtChat *chat, enum xdrv_source src)
+{
+       char buf[256];
+
+       sprintf(buf, "AT+XDRV=40,3,%i", src);
+       g_at_chat_send(chat, buf, xdrv_prefix, NULL, NULL, NULL);
+}
+
+static inline void xdrv_configure_source(GAtChat *chat, enum xdrv_source src,
+                               enum xdrv_i2s_clock clock,
+                               enum xdrv_i2s_mode master_slave,
+                               enum xdrv_sampling_rate sample_rate,
+                               enum xdrv_sampling_width bits,
+                               enum xdrv_i2s_transmission_mode tx_mode,
+                               enum xdrv_i2s_settings settings,
+                               enum xdrv_audio_mode mode,
+                               enum xdrv_i2s_configuration_mode config_mode,
+                               enum xdrv_source_transducer transducer_mode)
+{
+       char buf[256];
+       int ctx = 0; /* This is always 0 for now */
+
+       sprintf(buf, "AT+XDRV=40,4,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i",
+               src, ctx, clock, master_slave, sample_rate, bits,
+               tx_mode, settings, mode, config_mode, transducer_mode);
+       g_at_chat_send(chat, buf, xdrv_prefix, NULL, NULL, NULL);
+}
+
+static inline void xdrv_configure_destination(GAtChat *chat,
+                               enum xdrv_destination dest,
+                               enum xdrv_i2s_clock clock,
+                               enum xdrv_i2s_mode master_slave,
+                               enum xdrv_sampling_rate sample_rate,
+                               enum xdrv_sampling_width bits,
+                               enum xdrv_i2s_transmission_mode tx_mode,
+                               enum xdrv_i2s_settings settings,
+                               enum xdrv_audio_mode mode,
+                               enum xdrv_i2s_configuration_mode config_mode,
+                               enum xdrv_dest_transducer transducer_mode)
+{
+       char buf[256];
+       int ctx = 0; /* This is always 0 for now */
+
+       sprintf(buf, "AT+XDRV=40,5,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i",
+               dest, ctx, clock, master_slave, sample_rate, bits,
+               tx_mode, settings, mode, config_mode, transducer_mode);
+       g_at_chat_send(chat, buf, xdrv_prefix, NULL, NULL, NULL);
+}
+
+static inline void xdrv_set_destination_for_source(GAtChat *chat,
+                                               enum xdrv_source src,
+                                               enum xdrv_destination dest)
+{
+       char buf[256];
+
+       sprintf(buf, "AT+XDRV=40,6,%i,%i", src, dest);
+       g_at_chat_send(chat, buf, xdrv_prefix, NULL, NULL, NULL);
+}
+
+static inline void xdrv_set_destination_volume(GAtChat *chat,
+                                               enum xdrv_destination dest,
+                                               int volume)
+{
+       char buf[256];
+
+       sprintf(buf, "AT+XDRV=40,8,%i,%i", dest, volume);
+       g_at_chat_send(chat, buf, xdrv_prefix, NULL, NULL, NULL);
+}
+
+static void send_xdrv_setup_sequence(struct ofono_audio_settings *as)
+{
+       struct audio_settings_data *asd = ofono_audio_settings_get_data(as);
+
+       /* Mute */
+       xdrv_set_destination_volume(asd->chat, XDRV_DESTINATION_I2SX_TX, 0);
+       xdrv_set_destination_volume(asd->chat, XDRV_DESTINATION_SPEECH_TX, 0);
+
+       xdrv_set_destination_for_source(asd->chat, XDRV_SOURCE_SPEECH_RX,
+                                       XDRV_DESTINATION_PCM_GENERAL);
+
+       xdrv_disable_source(asd->chat, XDRV_SOURCE_I2SX_RX);
+       xdrv_disable_source(asd->chat, XDRV_SOURCE_I2SY_RX);
+
+       xdrv_configure_source(asd->chat, XDRV_SOURCE_I2SX_RX, XDRV_I2S_CLOCK_1,
+                               XDRV_I2S_MODE_MASTER, XDRV_SAMPLING_RATE_48KHZ,
+                               XDRV_SAMPLING_WIDTH_16,
+                               XDRV_I2S_TRANSMISSION_MODE_NORMAL,
+                               XDRV_I2S_SETTINGS_NORMAL,
+                               XDRV_AUDIO_MODE_STEREO,
+                               XDRV_I2S_CONFIGURATION_MODE_UPDATE_ALL,
+                               XDRV_SOURCE_TRANSDUCER_USER_DEFINED_15);
+       xdrv_configure_destination(asd->chat, XDRV_DESTINATION_I2SX_TX,
+                                       XDRV_I2S_CLOCK_1, XDRV_I2S_MODE_MASTER,
+                                       XDRV_SAMPLING_RATE_48KHZ,
+                                       XDRV_SAMPLING_WIDTH_16,
+                                       XDRV_I2S_TRANSMISSION_MODE_NORMAL,
+                                       XDRV_I2S_SETTINGS_NORMAL,
+                                       XDRV_AUDIO_MODE_STEREO,
+                                       XDRV_I2S_CONFIGURATION_MODE_UPDATE_ALL,
+                                       XDRV_DEST_TRANSDUCER_USER_DEFINED_15);
+
+       xdrv_configure_source(asd->chat, XDRV_SOURCE_I2SY_RX, XDRV_I2S_CLOCK_0,
+                               XDRV_I2S_MODE_MASTER, XDRV_SAMPLING_RATE_48KHZ,
+                               XDRV_SAMPLING_WIDTH_16,
+                               XDRV_I2S_TRANSMISSION_MODE_NORMAL,
+                               XDRV_I2S_SETTINGS_NORMAL,
+                               XDRV_AUDIO_MODE_STEREO,
+                               XDRV_I2S_CONFIGURATION_MODE_UPDATE_ALL,
+                               XDRV_SOURCE_TRANSDUCER_USER_DEFINED_15);
+       xdrv_configure_destination(asd->chat, XDRV_DESTINATION_I2SY_TX,
+                                       XDRV_I2S_CLOCK_0, XDRV_I2S_MODE_MASTER,
+                                       XDRV_SAMPLING_RATE_48KHZ,
+                                       XDRV_SAMPLING_WIDTH_16,
+                                       XDRV_I2S_TRANSMISSION_MODE_NORMAL,
+                                       XDRV_I2S_SETTINGS_NORMAL,
+                                       XDRV_AUDIO_MODE_STEREO,
+                                       XDRV_I2S_CONFIGURATION_MODE_UPDATE_ALL,
+                                       XDRV_DEST_TRANSDUCER_USER_DEFINED_15);
+
+       /* Seems unnecessary
+       xdrv_set_destination_for_source(asd->chat, XDRV_SOURCE_SPEECH_RX,
+                                       XDRV_DESTINATION_PCM_GENERAL);
+       */
+       xdrv_set_destination_for_source(asd->chat, XDRV_SOURCE_I2SX_RX,
+                                       XDRV_DESTINATION_SPEECH_TX);
+       xdrv_set_destination_for_source(asd->chat, XDRV_SOURCE_I2SY_RX,
+                                       XDRV_DESTINATION_I2SX_TX);
+       xdrv_set_destination_for_source(asd->chat, XDRV_SOURCE_SIMPLE_TONES,
+                                       XDRV_DESTINATION_I2SX_TX);
+
+       xdrv_enable_source(asd->chat, XDRV_SOURCE_I2SX_RX);
+       xdrv_enable_source(asd->chat, XDRV_SOURCE_I2SY_RX);
+
+       xdrv_set_destination_for_source(asd->chat, XDRV_SOURCE_SPEECH_RX,
+                                       XDRV_DESTINATION_I2SX_TX);
+
+       /* Unmute */
+       xdrv_set_destination_volume(asd->chat, XDRV_DESTINATION_I2SX_TX, 66);
+       xdrv_set_destination_volume(asd->chat, XDRV_DESTINATION_SPEECH_TX, 100);
+}
+
 static void xprogress_notify(GAtResult *result, gpointer user_data)
 {
        struct ofono_audio_settings *as = user_data;
@@ -103,6 +351,8 @@ static void xprogress_support_cb(gboolean ok, GAtResult *result,
 
        ofono_audio_settings_register(as);
 
+       send_xdrv_setup_sequence(as);
+
        modem = ofono_audio_settings_get_modem(as);
        setting = ofono_modem_get_string(modem, "AudioSetting");