2 This file is part of PulseAudio.
4 Copyright 2015 Sangchul Lee <sc11.lee@samsung.com>
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2.1 of the License,
9 or (at your option) any later version.
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 #include "hal-manager.h"
27 #include <pulsecore/shared.h>
29 /* Audio HAL library */
30 #define LIB_TIZEN_AUDIO "libtizen-audio.so"
32 pa_hal_manager* pa_hal_manager_get(pa_core *core, void *user_data) {
37 if ((h = pa_shared_get(core, "hal-manager")))
38 return pa_hal_manager_ref(h);
40 h = pa_xnew0(pa_hal_manager, 1);
44 /* Load library & init HAL manager */
45 h->dl_handle = dlopen(LIB_TIZEN_AUDIO, RTLD_NOW);
47 h->intf.init = dlsym(h->dl_handle, "audio_init");
48 h->intf.deinit = dlsym(h->dl_handle, "audio_deinit");
49 h->intf.reset_volume = dlsym(h->dl_handle, "audio_reset_volume");
50 h->intf.get_volume_level_max = dlsym(h->dl_handle, "audio_get_volume_level_max");
51 h->intf.get_volume_level = dlsym(h->dl_handle, "audio_get_volume_level");
52 h->intf.set_volume_level = dlsym(h->dl_handle, "audio_set_volume_level");
53 h->intf.get_volume_value = dlsym(h->dl_handle, "audio_get_volume_value");
54 h->intf.get_volume_mute = dlsym(h->dl_handle, "audio_get_volume_mute");
55 h->intf.set_volume_mute = dlsym(h->dl_handle, "audio_set_volume_mute");
56 h->intf.alsa_pcm_open = dlsym(h->dl_handle, "audio_alsa_pcm_open");
57 h->intf.alsa_pcm_close = dlsym(h->dl_handle, "audio_alsa_pcm_close");
58 h->intf.pcm_open = dlsym(h->dl_handle, "audio_pcm_open");
59 h->intf.pcm_close = dlsym(h->dl_handle, "audio_pcm_close");
60 h->intf.pcm_avail = dlsym(h->dl_handle, "audio_pcm_avail");
61 h->intf.pcm_write = dlsym(h->dl_handle, "audio_pcm_write");
62 h->intf.do_route = dlsym(h->dl_handle, "audio_do_route");
63 h->intf.update_route_option = dlsym(h->dl_handle, "audio_update_route_option");
64 h->intf.update_stream_connection_info = dlsym(h->dl_handle, "audio_update_stream_connection_info");
65 h->intf.get_buffer_attr = dlsym(h->dl_handle, "audio_get_buffer_attr");
67 /* TODO : no need to pass platform_data as second param. need to fix hal. */
68 if (h->intf.init(&h->data, user_data) != AUDIO_RET_OK) {
69 pa_log_error("hal_manager init failed");
72 #if 1 /* remove comment after enable NEW_HAL */
73 pa_shared_set(core, "tizen-audio-data", h->data);
74 pa_shared_set(core, "tizen-audio-interface", &h->intf);
78 pa_log_error("open hal_manager failed :%s", dlerror());
82 pa_shared_set(core, "hal-manager", h);
87 pa_hal_manager* pa_hal_manager_ref(pa_hal_manager *h) {
89 pa_assert(PA_REFCNT_VALUE(h) > 0);
96 void pa_hal_manager_unref(pa_hal_manager *h) {
98 pa_assert(PA_REFCNT_VALUE(h) > 0);
100 if (PA_REFCNT_DEC(h) > 0)
103 /* Deinit HAL manager & unload library */
104 if (h->intf.deinit) {
105 if (h->intf.deinit(&h->data) != AUDIO_RET_OK) {
106 pa_log_error("hal_manager deinit failed");
110 dlclose(h->dl_handle);
114 pa_shared_remove(h->core, "hal-manager");
119 int32_t pa_hal_manager_get_buffer_attribute(pa_hal_manager *h, io_direction_t direction, const char *latency, void *new_data, uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize) {
121 audio_return_t hal_ret = AUDIO_RET_OK;
122 pa_sample_spec *sample_spec = NULL;
127 sample_spec = (direction==DIRECTION_OUT)?(&((pa_sink_input_new_data*)new_data)->sample_spec):(&((pa_source_output_new_data*)new_data)->sample_spec);
128 pa_log_info("latency:%s, rate:%u, format:%d, channels:%u", latency, sample_spec->rate, sample_spec->format, sample_spec->channels);
130 if (AUDIO_IS_ERROR(hal_ret = h->intf.get_buffer_attr(h->data, direction, latency, sample_spec->rate, sample_spec->format, sample_spec->channels, maxlength, tlength, prebuf, minreq, fragsize))) {
131 pa_log_error("get_buffer_attr returns error:0x%x", hal_ret);
134 pa_log_info("maxlength:%d, tlength:%d, prebuf:%d, minreq:%d, fragsize:%d", *maxlength, *tlength, *prebuf, *minreq, *fragsize);
139 int32_t pa_hal_manager_reset_volume (pa_hal_manager *h) {
141 audio_return_t hal_ret = AUDIO_RET_OK;
145 if (AUDIO_IS_ERROR(hal_ret = h->intf.reset_volume(h->data))) {
146 pa_log_error("reset volume returns error:0x%x", hal_ret);
152 int32_t pa_hal_manager_get_volume_level_max (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t *level) {
154 audio_return_t hal_ret = AUDIO_RET_OK;
155 audio_volume_info_t info = {NULL, NULL, 0};
158 pa_assert(volume_type);
161 info.type = volume_type;
162 info.direction = direction;
164 if (AUDIO_IS_ERROR((hal_ret = h->intf.get_volume_level_max(h->data, &info, level)))) {
165 pa_log_error("get_volume_level_max returns error:0x%x", hal_ret);
171 int32_t pa_hal_manager_get_volume_level (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t *level) {
173 audio_return_t hal_ret = AUDIO_RET_OK;
174 audio_volume_info_t info = {NULL, NULL, 0};
177 pa_assert(volume_type);
180 info.type = volume_type;
181 info.direction = direction;
183 if (AUDIO_IS_ERROR((hal_ret = h->intf.get_volume_level(h->data, &info, level)))) {
184 pa_log_error("get_volume_level returns error:0x%x", hal_ret);
190 int32_t pa_hal_manager_set_volume_level (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t level) {
192 audio_return_t hal_ret = AUDIO_RET_OK;
193 audio_volume_info_t info = {NULL, NULL, 0};
196 pa_assert(volume_type);
198 info.type = volume_type;
199 info.direction = direction;
201 if (AUDIO_IS_ERROR((hal_ret = h->intf.set_volume_level(h->data, &info, level)))) {
202 pa_log_error("set_volume_level returns error:0x%x", hal_ret);
209 int32_t pa_hal_manager_get_volume_value (pa_hal_manager *h, const char *volume_type, const char *gain_type, io_direction_t direction, uint32_t level, double *value) {
211 audio_return_t hal_ret = AUDIO_RET_OK;
212 audio_volume_info_t info = {NULL, NULL, 0};
215 pa_assert(volume_type);
218 info.type = volume_type;
219 info.gain = gain_type;
220 info.direction = direction;
222 if (AUDIO_IS_ERROR((hal_ret = h->intf.get_volume_value(h->data, &info, level, value)))) {
223 pa_log_error("get_volume_value returns error:0x%x", hal_ret);
230 int32_t pa_hal_manager_get_mute (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t *mute) {
232 audio_return_t hal_ret = AUDIO_RET_OK;
233 audio_volume_info_t info = {NULL, NULL, 0};
236 pa_assert(volume_type);
239 info.type = volume_type;
240 info.direction = direction;
242 if (AUDIO_IS_ERROR(hal_ret = h->intf.get_volume_mute(h->data, &info, mute))) {
243 pa_log_error("get_mute returns error:0x%x", hal_ret);
249 int32_t pa_hal_manager_set_mute (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t mute) {
251 audio_return_t hal_ret = AUDIO_RET_OK;
252 audio_volume_info_t info = {NULL, NULL, 0};
255 pa_assert(volume_type);
257 info.type = volume_type;
258 info.direction = direction;
260 if (AUDIO_IS_ERROR(hal_ret = h->intf.set_volume_mute(h->data, &info, mute))) {
261 pa_log_error("set_mute returns error:0x%x", hal_ret);
267 int32_t pa_hal_manager_do_route (pa_hal_manager *h, hal_route_info *info) {
269 audio_return_t hal_ret = AUDIO_RET_OK;
274 if (AUDIO_IS_ERROR(hal_ret = h->intf.do_route(h->data, (audio_route_info_t*)info))) {
275 pa_log_error("do_route returns error:0x%x", hal_ret);
281 int32_t pa_hal_manager_update_route_option (pa_hal_manager *h, hal_route_option *option) {
283 audio_return_t hal_ret = AUDIO_RET_OK;
288 if (AUDIO_IS_ERROR(hal_ret = h->intf.update_route_option(h->data, (audio_route_option_t*)option))) {
289 pa_log_error("update_route_option returns error:0x%x", hal_ret);
295 int32_t pa_hal_manager_update_stream_connection_info (pa_hal_manager *h, hal_stream_connection_info *info) {
297 audio_return_t hal_ret = AUDIO_RET_OK;
298 audio_stream_info_t hal_info;
303 hal_info.role = info->role;
304 hal_info.direction = info->direction;
305 hal_info.idx = info->idx;
307 if (AUDIO_IS_ERROR(hal_ret = h->intf.update_stream_connection_info(h->data, &hal_info, (uint32_t)info->is_connected))) {
308 pa_log_error("update_stream_connection_info returns error:0x%x", hal_ret);