Routines to set routes on various paths (Speaker and Headphones on Galaxy S2)
[yamaha-mc1n2-audio.git] / yamaha-mc1n2-audio.c
index 0a00c14..29a25b3 100644 (file)
@@ -28,6 +28,8 @@
 #define LOG_TAG "Yamaha-MC1N2-Audio"
 #include <cutils/log.h>
 
+#include <system/audio.h>
+
 #include <yamaha-mc1n2-audio.h>
 
 struct yamaha_mc1n2_audio_pdata *yamaha_mc1n2_audio_platforms[] = {
@@ -116,7 +118,7 @@ int yamaha_mc1n2_audio_routine_init(struct yamaha_mc1n2_audio_pdata *pdata)
        if(pdata == NULL || pdata->ops == NULL)
                return -1;
 
-       routine = pdata->ops->routine.init;
+       routine = pdata->ops->routines.init;
        if(routine == NULL)
                return -1;
 
@@ -165,15 +167,44 @@ int yamaha_mc1n2_audio_routine_init(struct yamaha_mc1n2_audio_pdata *pdata)
        return 0;
 }
 
+int yamaha_mc1n2_audio_routine_postopen(struct yamaha_mc1n2_audio_pdata *pdata)
+{
+       struct yamaha_mc1n2_audio_routine_postopen *routine = NULL;
+       int rc = -1;
+
+       if(pdata == NULL || pdata->ops == NULL)
+               return -1;
+
+       routine = pdata->ops->routines.postopen;
+       if(routine == NULL)
+               return -1;
+
+       rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_AUDIOENGINE,
+               &routine->ae_info, 0x0f);
+       if(rc < 0) {
+               LOGE("SET_AUDIOENGINE IOCTL failed, aborting!");
+               return -1;
+       }
+
+       rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_AUDIOENGINE,
+               &routine->ae_info, 0x0f);
+       if(rc < 0) {
+               LOGE("SET_AUDIOENGINE IOCTL failed, aborting!");
+               return -1;
+       }
+
+       return 0;
+}
+
 int yamaha_mc1n2_audio_routine_route_init(struct yamaha_mc1n2_audio_pdata *pdata)
 {
-       struct yamaha_mc1n2_audio_routine_route_init *routine = NULL;
+       struct yamaha_mc1n2_audio_routine_route *routine = NULL;
        int rc = -1;
 
        if(pdata == NULL || pdata->ops == NULL)
                return -1;
 
-       routine = pdata->ops->routine.route_init;
+       routine = pdata->ops->routines.route_init;
        if(routine == NULL)
                return -1;
 
@@ -194,10 +225,127 @@ int yamaha_mc1n2_audio_routine_route_init(struct yamaha_mc1n2_audio_pdata *pdata
        return 0;
 }
 
+int yamaha_mc1n2_audio_routine_route_start(struct yamaha_mc1n2_audio_pdata *pdata)
+{
+       struct yamaha_mc1n2_audio_routine_route *routine = NULL;
+       int rc = -1;
+       int i;
+
+       if(pdata == NULL || pdata->ops == NULL || pdata->ops->routines.route_start == NULL)
+               return -1;
+
+       for(i=0 ; i < pdata->ops->routines.route_start_count ; i++) {
+               if(pdata->ops->routines.route_start[i].device == pdata->device_current &&
+                       pdata->ops->routines.route_start[i].mode == pdata->mode_current) {
+                       routine = &(pdata->ops->routines.route_start[i]);
+                       break;
+               }
+       }
+
+       if(routine == NULL) {
+               LOGE("Unable to find route routine for device: 0x%x",
+                       pdata->device_current);
+               return -1;
+       }
+
+       rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_AUDIOENGINE,
+               &routine->ae_info, 0x0f);
+       if(rc < 0) {
+               LOGE("SET_AUDIOENGINE IOCTL failed, aborting!");
+               return -1;
+       }
+
+       rc = yamaha_mc1n2_audio_ioctl_notify(pdata, MCDRV_NOTIFY_MEDIA_PLAY_START);
+       if(rc < 0) {
+               LOGE("NOTIFY_MEDIA_PLAY_START IOCTL failed, aborting!");
+               return -1;
+       }
+
+       rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_PATH,
+               &routine->path_info, 0x00);
+       if(rc < 0) {
+               LOGE("SET_PATH IOCTL failed, aborting!");
+               return -1;
+       }
+
+       rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DAC,
+               &routine->dac_info, 0x07);
+       if(rc < 0) {
+               LOGE("SET_DAC IOCTL failed, aborting!");
+               return -1;
+       }
+
+       pdata->route_started = 1;
+
+       return 0;
+}
+
+int yamaha_mc1n2_audio_routine_route_stop(struct yamaha_mc1n2_audio_pdata *pdata)
+{
+       struct yamaha_mc1n2_audio_routine_route *routine = NULL;
+       int rc = -1;
+
+       if(pdata == NULL || pdata->ops == NULL)
+               return -1;
+
+       routine = pdata->ops->routines.route_stop;
+       if(routine == NULL)
+               return -1;
+
+       rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_AUDIOENGINE,
+               &routine->ae_info, 0x0f);
+       if(rc < 0) {
+               LOGE("SET_AUDIOENGINE IOCTL failed, aborting!");
+               return -1;
+       }
+
+       rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_PATH,
+               &routine->path_info, 0x00);
+       if(rc < 0) {
+               LOGE("SET_PATH IOCTL failed, aborting!");
+               return -1;
+       }
+
+       rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DAC,
+               &routine->dac_info, 0x07);
+       if(rc < 0) {
+               LOGE("SET_DAC IOCTL failed, aborting!");
+               return -1;
+       }
+
+       pdata->route_started = 0;
+
+       return 0;
+}
+
 /*
  * Values configuration
  */
 
+int yamaha_mc1n2_audio_set_route(struct yamaha_mc1n2_audio_pdata *pdata,
+       audio_devices_t device, audio_mode_t mode)
+{
+       int rc;
+
+       if(pdata == NULL)
+               return -1;
+
+       // In this case, we are making sound, so we need to switch now
+       if((pdata->device_current != device || pdata->mode_current != mode) &&
+               pdata->route_started) {
+               pdata->device_current = device;
+               pdata->mode_current = mode;
+
+               rc = yamaha_mc1n2_audio_routine_route_start(pdata);
+               return rc;
+       }
+
+       pdata->device_current = device;
+       pdata->mode_current = mode;
+
+       return 0;
+}
+
 char *yamaha_mc1n2_audio_get_hw_node(struct yamaha_mc1n2_audio_pdata *pdata)
 {
        if(pdata == NULL)