From 5cb52e556fed8eb0cf74d1052fe413fbb7406b0e Mon Sep 17 00:00:00 2001 From: Fulup Ar Foll Date: Thu, 9 Mar 2017 15:58:04 +0100 Subject: Syncup Status with Microchip --- AlsaSound/HALayer/CMakeLists.txt | 26 +++ AlsaSound/HALayer/IntelHda/CMakeLists.txt | 36 +++++ AlsaSound/HALayer/IntelHda/IntelHdaHAL.c | 74 +++++++++ AlsaSound/HALayer/Shared/CMakeLists.txt | 30 ++++ AlsaSound/HALayer/Shared/SharedHalLib.c | 252 ++++++++++++++++++++++++++++++ AlsaSound/HALayer/include/AlsaHalCtls.h | 57 +++++++ AlsaSound/HALayer/include/AlsaHalIface.h | 52 ++++++ AlsaSound/HALayer/include/MiscHelpers.h | 33 ++++ 8 files changed, 560 insertions(+) create mode 100644 AlsaSound/HALayer/CMakeLists.txt create mode 100644 AlsaSound/HALayer/IntelHda/CMakeLists.txt create mode 100644 AlsaSound/HALayer/IntelHda/IntelHdaHAL.c create mode 100644 AlsaSound/HALayer/Shared/CMakeLists.txt create mode 100644 AlsaSound/HALayer/Shared/SharedHalLib.c create mode 100644 AlsaSound/HALayer/include/AlsaHalCtls.h create mode 100644 AlsaSound/HALayer/include/AlsaHalIface.h create mode 100644 AlsaSound/HALayer/include/MiscHelpers.h (limited to 'AlsaSound/HALayer') diff --git a/AlsaSound/HALayer/CMakeLists.txt b/AlsaSound/HALayer/CMakeLists.txt new file mode 100644 index 0000000..0b12f62 --- /dev/null +++ b/AlsaSound/HALayer/CMakeLists.txt @@ -0,0 +1,26 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Fulup Ar Foll +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +PROJECT(hadware-abstraction-layer C) + +# Fulup NOTE: this might have to be change for a formal static/dynamic lib +set(halsharedlib ${CMAKE_CURRENT_SOURCE_DIR}/Shared/SharedHalLib.c) + +ADD_SUBDIRECTORY(IntelHda) +ADD_SUBDIRECTORY(Shared) + diff --git a/AlsaSound/HALayer/IntelHda/CMakeLists.txt b/AlsaSound/HALayer/IntelHda/CMakeLists.txt new file mode 100644 index 0000000..77218e2 --- /dev/null +++ b/AlsaSound/HALayer/IntelHda/CMakeLists.txt @@ -0,0 +1,36 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Fulup Ar Foll +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + + +INCLUDE_DIRECTORIES(${include_dirs}) + +################################################## +# Inte-HDA sound card Hardware Abstraction Layer +################################################## +ADD_LIBRARY(intel-hda-hal MODULE IntelHdaHAL.c ${halsharedlib}) + +SET_TARGET_PROPERTIES(intel-hda-hal PROPERTIES + PREFIX "" + LINK_FLAGS "-Wl,--version-script=${CMAKE_SOURCE_DIR}/export.map" +) + +TARGET_LINK_LIBRARIES(intel-hda-hal ${link_libraries}) +INSTALL(TARGETS intel-hda-hal + LIBRARY DESTINATION ${binding_install_dir}) + + diff --git a/AlsaSound/HALayer/IntelHda/IntelHdaHAL.c b/AlsaSound/HALayer/IntelHda/IntelHdaHAL.c new file mode 100644 index 0000000..b04b545 --- /dev/null +++ b/AlsaSound/HALayer/IntelHda/IntelHdaHAL.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 "IoT.bzh" + * Author Fulup Ar Foll + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define _GNU_SOURCE +#include "AlsaHalIface.h" // Include Share Interface to Alsa Sound Card HAL + +/***************************************************************************** + * alsaCtlsMap link hight level sound control with low level Alsa numid ctls. + * + * To find out which control your sound card uses + * aplay -l + * amixer -D hw:xx controls + * amixer -D hw:xx contents + * amixer -D "hw:3" cget numid=xx + *****************************************************************************/ +STATIC alsaHalCtlMapT alsaHalCtlsMap[]= { + { .control=Master_Playback_Volume, .numid=16, .group=OUTVOL, .values=1, .minval=0, .maxval= 87 , .step=0, .acl=RW, .info= "Master Playback Volume" }, + { .control=PCM_Playback_Volume , .numid=27, .group=PCMVOL, .values=2, .minval=0, .maxval= 255, .step=0, .acl=RW, .info= "PCM Playback Volume" }, + { .control=PCM_Playback_Switch , .numid=17, .group=SWITCH, .values=1, .minval=0, .maxval= 1 , .step=0, .acl=RW, .info= "Master Playback Switch" }, + { .control=Capture_Volume , .numid=12, .group=INVOL , .values=2, .minval=0, .maxval= 31 , .step=0, .acl=RW, .info= "Capture Volume" }, + { .numid=0 } /* marker for end of the array */ +} ; + +/*********************************************************************************** + * AlsaHalSndT provides + * - cardname used to map a given card to its HAL + * - ctls previously defined AlsaHalMapT control maps + * - info free text + * + * WARNING: name should fit with 'aplay -l' as it used to map from devid to HAL + * you may also retreive shortname when AudioBinder is running from a browser + * http://localhost:1234/api/alsacore/getcardid?devid=hw:xxx + * + ***********************************************************************************/ +PUBLIC alsaHalSndCardT alsaHalSndCard = { + .name = "HDA Intel PCH", + .info = "Hardware Abstraction Layer for IntelHDA sound card", + .ctls = alsaHalCtlsMap, +}; + +/*********************************************************************************** + * AlsaHalSndT provides + * - cardname used to map a given card to its HAL + * - ctls previously defined AlsaHalMapT control maps + * - info free text + * + * WARNING: name should fit with 'aplay -l' as it used to map from devid to HAL + * you may also retreive shortname when AudioBinder is running from a browser + * http://localhost:1234/api/alsacore/getcardid?devid=hw:xxx + * + ***********************************************************************************/ +PUBLIC struct afb_binding alsaHalBinding = { + /* description conforms to VERSION 1 */ + .type= AFB_BINDING_VERSION_1, + .v1= { + .prefix= "intel-hda", + .info = "Hardware Abstraction Layer for IntelHDA sound card", + } +}; + + diff --git a/AlsaSound/HALayer/Shared/CMakeLists.txt b/AlsaSound/HALayer/Shared/CMakeLists.txt new file mode 100644 index 0000000..27d93e0 --- /dev/null +++ b/AlsaSound/HALayer/Shared/CMakeLists.txt @@ -0,0 +1,30 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Fulup Ar Foll +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + + +INCLUDE_DIRECTORIES(${include_dirs}) + +################################################## +# Shared HAL(Hardware Abstraction Layer) +################################################## +ADD_LIBRARY(shared-hal MODULE SharedHalLib.c) + +TARGET_LINK_LIBRARIES(shared-hal ${link_libraries}) +INSTALL(TARGETS shared-hal LIBRARY DESTINATION ${binding_install_dir}) + + diff --git a/AlsaSound/HALayer/Shared/SharedHalLib.c b/AlsaSound/HALayer/Shared/SharedHalLib.c new file mode 100644 index 0000000..ffa25e0 --- /dev/null +++ b/AlsaSound/HALayer/Shared/SharedHalLib.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2016 "IoT.bzh" + * Author Fulup Ar Foll + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * reference: + * amixer contents; amixer controls; + * http://www.tldp.org/HOWTO/Alsa-sound-6.html + */ +#define _GNU_SOURCE // needed for vasprintf +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "MiscHelpers.h" +#include "AlsaHalIface.h" + +typdef struct { + int numid; +} shareHallMap_T; + +static struct afb_service srvitf; +static const struct afb_binding_interface *afbIface; +static shareHallMap_T *shareHallMap; + + +STATIC void localping(struct afb_req request) { + json_object *query = afb_req_json(request); + afb_req_success(request, query, NULL); +} + +// This callback when api/alsacore/subscribe returns +STATIC void alsaSubcribeCB (void *handle, int iserror, struct json_object *result) { + struct afb_req request = afb_req_unstore(handle); + struct json_object *x, *resp = NULL; + const char *info = NULL; + + if (result) { + INFO (afbIface, "result=[%s]\n", json_object_to_json_string (result)); + if (json_object_object_get_ex(result, "request", &x) && json_object_object_get_ex(x, "info", &x)) + info = json_object_get_string(x); + if (!json_object_object_get_ex(result, "response", &resp)) resp = NULL; + } + + // push message respond + if (iserror) afb_req_fail_f(request, "Fail", info); + else afb_req_success(request, resp, info); + + // free calling request + afb_req_unref(request); +} + +// Create and subscribe to alsacore ctl events +STATIC void halMonitor(struct afb_req request) { + + // save request in session as it might be used after return by callback + struct afb_req *handle = afb_req_store(request); + + // push request to low level binding + if (!handle) afb_req_fail(request, "error", "out of memory"); + else afb_service_call(srvitf, "alsacore", "subctl", json_object_get(afb_req_json(request)), alsaSubcribeCB, handle); + + // success/failure messages return from callback +} + +// Subscribe to AudioBinding events +STATIC void halSubscribe (struct afb_req request) { + const char *devid = afb_req_value(request, "devid"); + if (devid == NULL) { + afb_req_fail_f (request, "devid-missing", "devid=hw:xxx missing"); + } +} + +// Call when all bindings are loaded and ready to accept request +STATIC void halGetVol(struct afb_req request) { + + // Should call here Hardware Alsa Abstraction Layer for corresponding Sound Card + afb_req_success (request, NULL, NULL); + return; + +} + +STATIC void halSetVol(struct afb_req request) { + const char *arg; + const char *pcm; + + arg = afb_req_value(request, "vol"); + if (arg == NULL) { + afb_req_fail_f (request, "argument-missing", "vol=[0,100] missing"); + goto OnErrorExit; + } + + pcm = afb_req_value(request, "pcm"); + if (pcm == NULL) pcm="Master"; + + // Should call here Hardware Alsa Abstraction Layer for corresponding Sound Card + afb_req_success (request, NULL, NULL); + return; + + OnErrorExit: + return; + +} + +// this is call when after all bindings are loaded +STATIC int halGetControl(struct afb_service service) { + srvitf = service; + struct json_object *queryin, *queryout, *ctls, *devid; + + // get query from request + queryin = afb_req_json(request); + + // check devid was given + devid= json_object_object_get(queryin,"devid"); + if (!ctls) { + afb_req_fail_f(request, "devid-notfound", "No DevID given query=[%s]", json_object_get_string(queryin)); + goto OnErrorExit; + } + + // loop on requested controls + ctls= json_object_object_get(queryin,"ctls"); + if (!ctls || json_object_array_length(ctls) <= 0) { + afb_req_fail_f(request, "ctls-notfound", "No Controls given query=[%s]", json_object_get_string(queryin)); + goto OnErrorExit; + } + + for (int idx=0; idx< json_object_array_length(ctls), idx++) { + struct json_object *ctl; + halControlEnumT control; + int value; + + // each controls should be halControlEnumT+value + ctl = json_object_array_get_idx(ctls, idx); + if (json_object_array_length(ctl != 2)) { + afb_req_fail_f(request, "ctl-invalid", "Invalid Control devid=%s ctl=[%s]"json_object_get_string(devid), json_object_get_string(cls)); + goto OnErrorExit; + } + + // As HAL and Business logic use the same AlsaMixerHal.h direct conversion is not an issue + control = (halControlEnumT)json_object_get_int(json_object_array_get_idx(ctl,0)); + value = json_object_get_int(json_object_array_get_idx(ctl,0)); + + if (control >= EndHalCrlTag || control <= StartHalCrlTag) { + afb_req_fail_f(request, "ctl-invalid", "Invalid Control devid=%s ctl=[%s] should be [%d=%d]" + , json_object_get_string(devid), json_object_get_string(cls)), StartHalCrlTag, EndHalCrlTag; + goto OnErrorExit; + } + + + default: + NOTICE (afbIface, "audioLogicOpenCB2 unknown HAL control=[%s]", json_object_get_string(ctl)): + } + } + + + // register HAL with Alsa Low Level Binder devid=hw:0&numid=1&quiet=0 + queryurl=json_object_new_object(); + json_object_object_add(queryurl, "prefix",json_object_new_string(alsaHalBinding.v1.prefix)); + json_object_object_add(queryurl, "name" ,json_object_new_string(alsaHalSndCard.name)); + afb_service_call(srvitf, "alsacore", "registerHal", queryurl, halGetControlCB, queryurl); + + + afb_req_success (request, sndctrls, NULL); + return; + +OnErrorExit: + +}; + +STATIC void halInitCB (void *handle, int iserror, struct json_object *result) { + struct json_object *queryurl = (json_object*)handle; + + if (iserror) NOTICE (afbIface, "halInitCB: registration alsaHAL query=[%s] Fail", json_object_to_json_string(queryurl)); + else DEBUG(afbIface, "halInitCB: registration alsaHAL card=[%s] Success", json_object_to_json_string(queryurl)); +} + +// This receive all event this binding subscribe to +PUBLIC void afbBindingV1ServiceEvent(const char *evtname, struct json_object *object) { + + NOTICE (afbIface, "afbBindingV1ServiceEvent evtname=%s [msg=%s]", evtname, json_object_to_json_string(object)); +} + +// this is call when after all bindings are loaded +PUBLIC int afbBindingV1ServiceInit(struct afb_service service) { + srvitf = service; + struct json_object *queryurl; + + // API prefix is used as sndcard halname + alsaHalBinding.v1.prefix= prefix; + + // register HAL with Alsa Low Level Binder + queryurl=json_object_new_object(); + json_object_object_add(ctx->queryurl, "prefix",json_object_new_string(alsaHalBinding.v1.prefix)); + json_object_object_add(ctx->queryurl, "name" ,json_object_new_string(alsaHalSndCard.name)); + afb_service_call(srvitf, "alsacore", "registerHal", queryurl, halInitCB, NULL); + + return 0; +}; + + +// Every HAL export the same API & Interface Mapping from SndCard to AudioLogic is done through alsaHalSndCardT +STATIC const struct afb_verb_desc_v1 halSharedApi[] = { + /* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */ + { .name= "ping" , .session= AFB_SESSION_NONE, .callback= localping, .info= "Ping Binding" }, + { .name= "getcontrol", .session= AFB_SESSION_NONE, .callback= halGetControl,.info= "Get Control" }, + { .name= "setvolume", .session= AFB_SESSION_NONE, .callback= halSetVol, .info= "Set Volume" }, + { .name= "getvolume", .session= AFB_SESSION_NONE, .callback= halGetVol, .info= "Get Volume" }, + { .name= "subscribe", .session= AFB_SESSION_NONE, .callback= halSubscribe, .info= "Subscribe AudioBinding Events" }, + { .name= NULL } /* marker for end of the array */ +}; + +// Process HAL mapping from alsaHalSndCardT before registering HAL binder +PUBLIC const struct afb_binding *afbBindingV1Register(const struct afb_binding_interface *itf) { + int count; + afbIface= itf; // need to keep a static trace of binder interface for avances functions + alsaHalBinding.verbs=halSharedApi; // complete sndcard specific alsaHalBinding with standard HAL APIs + alsaHalCtlMapT *alsaHalCtls = MapalsaHalSndCard.alsaHalCtlsMap; // Get sndcard specific HAL control mapping + + if (alsaHalCtls == NULL) { + ERROR (afbIface, "afbBindingV1Register Fail alsaHalCtlsMap==NULL"); + return NULL; + } + + // Create a zone to store HAL high/low level mapping + shareHallMap = calloc (EndHalCrlTag * sizeof(shareHallMap_T)); + for (int idx= 0; alsaHalCtlsMap[idx].numid != 0; idx++) { + shareHallMap[alsaHalCtlsMap[idx].]->numid = alsaHalCtlsMap[idx].numid; + } + + return alsaHalBinding; /* returns the description of the binding */ +} diff --git a/AlsaSound/HALayer/include/AlsaHalCtls.h b/AlsaSound/HALayer/include/AlsaHalCtls.h new file mode 100644 index 0000000..a17315a --- /dev/null +++ b/AlsaSound/HALayer/include/AlsaHalCtls.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 "IoT.bzh" + * Author Fulup Ar Foll + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * reference: + * amixer contents; amixer controls; + * http://www.tldp.org/HOWTO/Alsa-sound-6.html + */ + + + +#ifndef ALSAMIXERMAP_H +#define ALSAMIXERMAP_H + +// Most controls are MIXER but some vendor specific are possible +typedef enum { + OUTVOL, + PCMVOL, + INVOL, + SWITCH, + ROUTE, + CARD, +} halGroupEnumT; + +typedef enum { + READ, + WRITE, + RW, +} halAclEnumT; + +typedef enum { + StartHalCrlTag=0, + + // HighLevel Audio Control List + Master_Playback_Volume, + PCM_Playback_Volume, + PCM_Playback_Switch, + Capture_Volume, + + EndHalCrlTag // used to compute number of ctls +} halControlEnumT; + + +#endif /* ALSAMIXERMAP_H */ + diff --git a/AlsaSound/HALayer/include/AlsaHalIface.h b/AlsaSound/HALayer/include/AlsaHalIface.h new file mode 100644 index 0000000..83ab57c --- /dev/null +++ b/AlsaSound/HALayer/include/AlsaHalIface.h @@ -0,0 +1,52 @@ +/* + * AlsaLibMapping -- provide low level interface with AUDIO lib (extracted from alsa-json-gateway code) + * Copyright (C) 2015,2016,2017, Fulup Ar Foll fulup@iot.bzh + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SHAREDHALLIB_H +#define SHAREDHALLIB_H + +#include +#include + +#include "MiscHelpers.h" +#include "AlsaHalCtls.h" + +typedef const struct { + halControlEnumT control; + int numid; + halGroupEnumT group; + int values; + int minval; + int maxval; + int step; + char* info; + halAclEnumT acl; + +} alsaHalCtlMapT; + +typedef struct { + const char *prefix; + const char *name; + const char *info; + alsaHalCtlMapT *ctls; + +} alsaHalSndCardT; + +PUBLIC alsaHalSndCardT alsaHalSndCard; +PUBLIC struct afb_binding alsaHalBinding; + +#endif /* SHAREDHALLIB_H */ + diff --git a/AlsaSound/HALayer/include/MiscHelpers.h b/AlsaSound/HALayer/include/MiscHelpers.h new file mode 100644 index 0000000..0181847 --- /dev/null +++ b/AlsaSound/HALayer/include/MiscHelpers.h @@ -0,0 +1,33 @@ +/* + * AlsaLibMapping -- provide low level interface with AUDIO lib (extracted from alsa-json-gateway code) + * Copyright (C) 2015,2016,2017, Fulup Ar Foll fulup@iot.bzh + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MISCHELPER_H +#define MISCHELPER_H + +#ifndef PUBLIC + #define PUBLIC +#endif +#ifndef FALSE + #define FALSE 0 +#endif +#ifndef TRUE + #define TRUE 1 +#endif +#define STATIC static + +#endif /* MISCHELPER_H */ + -- cgit 1.2.3-korg