4 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 /*===========================================================================================
24 ========================================================================================== */
32 #include <sys/ioctl.h>
37 #include <mm_message.h>
40 #include "mm_radio_priv_hal.h"
42 /*===========================================================================================
43 LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE
44 ========================================================================================== */
45 /*---------------------------------------------------------------------------
46 GLOBAL CONSTANT DEFINITIONS:
47 ---------------------------------------------------------------------------*/
49 /*---------------------------------------------------------------------------
50 IMPORTED VARIABLE DECLARATIONS:
51 ---------------------------------------------------------------------------*/
53 /*---------------------------------------------------------------------------
54 IMPORTED FUNCTION DECLARATIONS:
55 ---------------------------------------------------------------------------*/
57 /*---------------------------------------------------------------------------
59 ---------------------------------------------------------------------------*/
60 #define DEFAULT_DEVICE "/dev/radio0"
63 #define DEFAULT_FREQ 107700
66 #define RADIO_FREQ_FORMAT_SET(x_freq) ((x_freq) * FREQ_FRAC)
67 #define RADIO_FREQ_FORMAT_GET(x_freq) ((x_freq) / FREQ_FRAC)
68 /* If non-zero, wrap around when at the end of the frequency range, else stop seeking */
69 #define DEFAULT_WRAP_AROUND 1
71 #define RADIO_DEFAULT_REGION MM_RADIO_REGION_GROUP_USA
72 #define READ_MAX_BUFFER_SIZE 1024
73 #define DEFAULT_MAX_MEDIA_VOLUME 15
74 /*---------------------------------------------------------------------------
75 LOCAL CONSTANT DEFINITIONS:
76 ---------------------------------------------------------------------------*/
78 /*---------------------------------------------------------------------------
79 LOCAL DATA TYPE DEFINITIONS:
80 ---------------------------------------------------------------------------*/
82 /*---------------------------------------------------------------------------
83 GLOBAL VARIABLE DEFINITIONS:
84 ---------------------------------------------------------------------------*/
87 /*---------------------------------------------------------------------------
88 LOCAL VARIABLE DEFINITIONS:
89 ---------------------------------------------------------------------------*/
90 /* radio region configuration table */
91 static const MMRadioRegion_t region_table[] = {
92 { /* Notrh America, South America, South Korea, Taiwan, Australia */
93 MM_RADIO_REGION_GROUP_USA, /* region type */
94 MM_RADIO_DEEMPHASIS_75_US, /* de-emphasis */
95 MM_RADIO_FREQ_MIN_87500_KHZ, /* min freq. */
96 MM_RADIO_FREQ_MAX_108000_KHZ, /* max freq. */
99 { /* China, Europe, Africa, Middle East, Hong Kong, India, Indonesia, Russia, Singapore */
100 MM_RADIO_REGION_GROUP_EUROPE,
101 MM_RADIO_DEEMPHASIS_50_US,
102 MM_RADIO_FREQ_MIN_87500_KHZ,
103 MM_RADIO_FREQ_MAX_108000_KHZ,
107 MM_RADIO_REGION_GROUP_JAPAN,
108 MM_RADIO_DEEMPHASIS_50_US,
109 MM_RADIO_FREQ_MIN_76100_KHZ,
110 MM_RADIO_FREQ_MAX_89900_KHZ,
115 /*---------------------------------------------------------------------------
116 LOCAL FUNCTION PROTOTYPES:
117 ---------------------------------------------------------------------------*/
118 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param);
119 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command);
120 static int __mmradio_get_state(mm_radio_t *radio);
121 static bool __mmradio_set_state(mm_radio_t *radio, int new_state);
122 void _mmradio_seek_cancel(mm_radio_t *radio);
123 static void __mmradio_seek_thread(mm_radio_t *radio);
124 static void __mmradio_scan_thread(mm_radio_t *radio);
125 static bool __is_tunable_frequency(mm_radio_t *radio, int freq);
127 #ifdef TIZEN_FEATURE_SOUND_FOCUS
128 static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
129 mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
130 const char *additional_info, void *user_data);
131 static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
132 mm_sound_focus_state_e focus_state, const char *reason_for_change,
133 const char *additional_info, void *user_data);
136 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data);
137 static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level);
139 int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update)
141 int ret = MM_ERROR_NONE;
145 MMRADIO_LOG_FENTER();
147 MMRADIO_CHECK_INSTANCE(radio);
148 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_REGION);
150 /* if needed, radio region must be updated.
151 * Otherwise, just applying settings to device without it.
154 count = ARRAY_SIZE(region_table);
156 /* TODO: if auto is supported...get the region info. here */
158 /* update radio region settings */
159 for (index = 0; index < count; index++) {
160 /* find the region from pre-defined table */
161 if (region_table[index].country == region) {
162 radio->region_setting.country = region_table[index].country;
163 radio->region_setting.deemphasis = region_table[index].deemphasis;
164 radio->region_setting.band_min = region_table[index].band_min;
165 radio->region_setting.band_max = region_table[index].band_max;
166 radio->region_setting.channel_spacing = region_table[index].channel_spacing;
171 MMRADIO_LOG_INFO("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz",
172 radio->region_setting.country, radio->region_setting.deemphasis,
173 radio->region_setting.band_min, radio->region_setting.band_max);
175 MMRADIO_LOG_FLEAVE();
180 int _mmradio_create_radio(mm_radio_t *radio)
182 int ret = MM_ERROR_NONE;
184 MMRADIO_LOG_FENTER();
186 MMRADIO_CHECK_INSTANCE(radio);
187 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE);
189 /* set default value */
190 radio->freq = DEFAULT_FREQ;
191 #ifdef TIZEN_FEATURE_SOUND_FOCUS
192 memset(&radio->sound_focus, 0, sizeof(mm_radio_sound_focus));
194 memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t));
195 radio->local_volume = 1.0;
197 /* create command lock */
198 ret = pthread_mutex_init(&radio->cmd_lock, NULL);
200 MMRADIO_LOG_ERROR("mutex creation failed");
201 return MM_ERROR_RADIO_INTERNAL;
204 ret = pthread_mutex_init(&radio->volume_lock, NULL);
206 MMRADIO_LOG_ERROR("volume mutex creation failed");
207 return MM_ERROR_RADIO_INTERNAL;
210 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
212 #ifdef TIZEN_FEATURE_SOUND_FOCUS
213 ret = mmradio_sound_focus_register(&radio->sound_focus,
214 (mm_sound_focus_changed_cb)__mmradio_sound_focus_cb,
215 (mm_sound_focus_changed_watch_cb)__mmradio_sound_focus_watch_cb,
219 /* NOTE : we are dealing it as an error since we cannot expect it's behavior */
220 MMRADIO_LOG_ERROR("mmradio_audio_focus_register is failed");
221 return MM_ERROR_RADIO_INTERNAL;
225 ret = radio_hal_interface_init(&(radio->hal_inf));
227 MMRADIO_LOG_ERROR("mmradio hal interface init failed");
231 MMRADIO_LOG_FLEAVE();
233 return MM_ERROR_NONE;
236 int _mmradio_realize(mm_radio_t *radio)
238 int ret = MM_ERROR_NONE;
242 MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE;
244 MMRADIO_LOG_FENTER();
246 MMRADIO_CHECK_INSTANCE(radio);
247 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE);
249 ret = pthread_mutex_init(&radio->seek_cancel_mutex, NULL);
251 MMRADIO_LOG_ERROR("Mutex creation failed %d", ret);
252 return MM_ERROR_RADIO_INTERNAL;
255 if (radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE) {
256 /* not initialized yet. set it with default region */
257 region = RADIO_DEFAULT_REGION;
260 /* already initialized by application */
261 region = radio->region_setting.country;
264 ret = _mmradio_apply_region(radio, region, update);
266 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
267 ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_RADIO, NULL, radio, &radio->stream_info);
268 if (ret != MM_ERROR_NONE) {
269 MMRADIO_LOG_ERROR("sound_manager_create_stream_information_internal error");
270 MMRADIO_LOG_FLEAVE();
273 ret = sound_manager_create_virtual_stream(radio->stream_info, &radio->vstream);
274 if (ret != MM_ERROR_NONE) {
275 MMRADIO_LOG_ERROR("sound_manager_create_virtual_stream error");
276 MMRADIO_LOG_FLEAVE();
281 ret = sound_manager_get_max_volume(SOUND_TYPE_MEDIA, &max);
282 if (ret != MM_ERROR_NONE) {
283 MMRADIO_LOG_WARNING("sound_manager_get_max_volume error");
284 radio->max_media_volume = DEFAULT_MAX_MEDIA_VOLUME;
286 radio->max_media_volume = max;
289 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
291 if (ret != MM_ERROR_NONE)
292 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
294 MMRADIO_VOLUME_LOCK(radio);
295 radio->media_volume = volume;
296 MMRADIO_VOLUME_UNLOCK(radio);
298 ret = mm_sound_add_volume_changed_callback(__mmradio_volume_changed_cb, (void *)radio, &radio->volume_subs_id);
299 if (ret != MM_ERROR_NONE)
300 MMRADIO_LOG_WARNING("mm_sound_add_volume_changed_callback error");
302 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
304 MMRADIO_LOG_FLEAVE();
306 return MM_ERROR_NONE;
309 int _mmradio_unrealize(mm_radio_t *radio)
311 int ret = MM_ERROR_NONE;
313 MMRADIO_LOG_FENTER();
315 MMRADIO_CHECK_INSTANCE(radio);
316 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNREALIZE);
318 ret = mm_sound_remove_volume_changed_callback(radio->volume_subs_id);
319 if (ret != MM_ERROR_NONE)
320 MMRADIO_LOG_WARNING("mm_sound_remove_volume_changed_callback error");
322 /*Finish if there are scans*/
323 _mmradio_stop_scan(radio);
325 /*Stop radio if started*/
326 _mmradio_stop(radio);
328 /* close radio device here !!!! */
329 radio_hal_close(radio->hal_inf);
330 radio_hal_unprepare(radio->hal_inf);
331 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
332 sound_manager_destroy_virtual_stream(radio->vstream);
333 sound_manager_destroy_stream_information(radio->stream_info);
335 pthread_mutex_destroy(&radio->seek_cancel_mutex);
337 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
339 MMRADIO_LOG_FLEAVE();
344 int _mmradio_destroy(mm_radio_t *radio)
346 int ret = MM_ERROR_NONE;
347 MMRADIO_LOG_FENTER();
349 MMRADIO_CHECK_INSTANCE(radio);
350 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY);
352 _mmradio_unrealize(radio);
354 ret = radio_hal_interface_deinit(radio->hal_inf);
356 MMRADIO_LOG_ERROR("mmradio hal interface deinit failed");
360 /* destroy command lock */
361 ret = pthread_mutex_destroy(&radio->cmd_lock);
363 MMRADIO_LOG_ERROR("mutex destroy failed\n");
366 ret = pthread_mutex_destroy(&radio->volume_lock);
368 MMRADIO_LOG_ERROR("volume mutex destroy failed\n");
371 #ifdef TIZEN_FEATURE_SOUND_FOCUS
372 ret = mmradio_sound_focus_deregister(&radio->sound_focus);
374 MMRADIO_LOG_ERROR("failed to deregister sound focus");
375 return MM_ERROR_RADIO_INTERNAL;
378 MMRADIO_LOG_FLEAVE();
380 return MM_ERROR_NONE;
383 /* unit should be KHz */
384 int _mmradio_set_frequency(mm_radio_t *radio, int freq)
386 int ret = MM_ERROR_NONE;
388 MMRADIO_LOG_FENTER();
390 MMRADIO_CHECK_INSTANCE(radio);
391 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_FREQ);
393 MMRADIO_LOG_INFO("Setting %d frequency", freq);
397 ret = radio_hal_set_frequency(radio->hal_inf, freq);
398 if (ret != MM_ERROR_NONE) {
399 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
400 MMRADIO_LOG_FLEAVE();
404 MMRADIO_LOG_FLEAVE();
410 int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq)
412 int ret = MM_ERROR_NONE;
414 MMRADIO_LOG_FENTER();
416 MMRADIO_CHECK_INSTANCE(radio);
417 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_FREQ);
419 return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT);
421 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
422 if (ret != MM_ERROR_NONE) {
423 MMRADIO_LOG_ERROR("radio_hal_get_frequency error");
428 /* update freq in handle */
429 MMRADIO_LOG_INFO("Updating %d frequency", freq);
432 *pFreq = (int)radio->freq;
434 MMRADIO_LOG_FLEAVE();
439 int _mmradio_mute(mm_radio_t *radio)
441 int ret = MM_ERROR_NONE;
442 MMRADIO_LOG_FENTER();
444 MMRADIO_CHECK_INSTANCE(radio);
445 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE);
447 ret = radio_hal_mute(radio->hal_inf);
448 if (ret == MM_ERROR_NOT_SUPPORT_API) {
449 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
450 } else if (ret != MM_ERROR_NONE) {
451 MMRADIO_LOG_ERROR("radio_hal_mute error");
452 MMRADIO_LOG_FLEAVE();
456 radio->is_muted = TRUE;
457 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
458 MMRADIO_LOG_FLEAVE();
463 int _mmradio_unmute(mm_radio_t *radio)
465 int ret = MM_ERROR_NONE;
466 MMRADIO_LOG_FENTER();
468 MMRADIO_CHECK_INSTANCE(radio);
469 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNMUTE);
471 ret = radio_hal_unmute(radio->hal_inf);
472 if (ret == MM_ERROR_NOT_SUPPORT_API) {
473 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
474 } else if (ret != MM_ERROR_NONE) {
475 MMRADIO_LOG_ERROR("radio_hal_unmute error");
476 MMRADIO_LOG_FLEAVE();
480 radio->is_muted = FALSE;
481 MMRADIO_LOG_INFO("Radio mute state [%d]", radio->is_muted);
482 MMRADIO_LOG_FLEAVE();
487 int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param)
489 MMRADIO_LOG_FENTER();
491 MMRADIO_CHECK_INSTANCE(radio);
493 radio->msg_cb = callback;
494 radio->msg_cb_param = user_param;
496 MMRADIO_LOG_DEBUG("msg_cb : 0x%x msg_cb_param : 0x%x", callback, user_param);
498 MMRADIO_LOG_FLEAVE();
500 return MM_ERROR_NONE;
503 int _mmradio_get_state(mm_radio_t *radio, int *pState)
507 MMRADIO_LOG_FENTER();
509 MMRADIO_CHECK_INSTANCE(radio);
510 return_val_if_fail(pState, MM_ERROR_INVALID_ARGUMENT);
512 state = __mmradio_get_state(radio);
516 MMRADIO_LOG_FLEAVE();
518 return MM_ERROR_NONE;
521 int _mmradio_start(mm_radio_t *radio)
523 int ret = MM_ERROR_NONE;
524 unsigned int volume = 0;
526 MMRADIO_LOG_FENTER();
528 MMRADIO_CHECK_INSTANCE(radio);
529 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START);
531 MMRADIO_LOG_INFO("now tune to frequency : %d", radio->freq);
533 #ifdef TIZEN_FEATURE_SOUND_FOCUS
534 if (radio->sound_focus.handle > 0) {
535 ret = mmradio_acquire_sound_focus(&radio->sound_focus);
536 if (ret != MM_ERROR_NONE) {
537 MMRADIO_LOG_ERROR("failed to set sound focus");
543 if (!radio->is_ready) {
544 ret = radio_hal_prepare(radio->hal_inf);
545 if (ret == MM_ERROR_NOT_SUPPORT_API) {
546 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
547 } else if (ret != MM_ERROR_NONE) {
548 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
552 ret = radio_hal_open(radio->hal_inf);
553 if (ret == MM_ERROR_NOT_SUPPORT_API) {
554 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
555 } else if (ret != MM_ERROR_NONE) {
556 MMRADIO_LOG_ERROR("radio_hal_init error");
559 radio->is_ready = TRUE;
561 MMRADIO_LOG_DEBUG("radio prepared and opened");
564 ret = mm_sound_volume_get_value(VOLUME_TYPE_MEDIA, &volume);
565 if (ret != MM_ERROR_NONE)
566 MMRADIO_LOG_WARNING("failed to get MEDIA_VOLUME");
568 ret = __mmradio_set_media_volume(radio, volume);
569 if (ret != MM_ERROR_NONE) {
570 MMRADIO_LOG_ERROR("failed to media volume");
574 ret = radio_hal_start(radio->hal_inf);
575 if (ret == MM_ERROR_NOT_SUPPORT_API) {
576 MMRADIO_LOG_WARNING("radio_hal_start is not supported");
578 MMRADIO_LOG_ERROR("failed to radio_hal_start");
582 /* set stored frequency */
583 ret = radio_hal_set_frequency(radio->hal_inf, radio->freq);
585 MMRADIO_LOG_ERROR("failed to radio_hal_set_frequency");
589 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
590 ret = sound_manager_start_virtual_stream(radio->vstream);
592 MMRADIO_LOG_ERROR("failed to sound_manager_start_virtual_stream");
597 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
599 MMRADIO_LOG_FLEAVE();
601 return MM_ERROR_NONE;
603 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
605 sound_manager_stop_virtual_stream(radio->vstream);
608 radio_hal_close(radio->hal_inf);
610 radio_hal_unprepare(radio->hal_inf);
611 radio->is_ready = FALSE;
615 int _mmradio_stop(mm_radio_t *radio)
617 int ret = MM_ERROR_NONE;
619 MMRADIO_LOG_FENTER();
621 MMRADIO_CHECK_INSTANCE(radio);
622 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP);
624 radio->seek_unmute = FALSE;
625 /*cancel if any seek*/
626 _mmradio_seek_cancel(radio);
627 #ifdef TIZEN_FEATURE_SOUND_VSTREAM
628 ret = sound_manager_stop_virtual_stream(radio->vstream);
629 if (ret != MM_ERROR_NONE) {
630 MMRADIO_LOG_ERROR("failed to stop virtual_stream");
635 ret = radio_hal_stop(radio->hal_inf);
636 if (ret == MM_ERROR_NOT_SUPPORT_API) {
637 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
639 MMRADIO_LOG_ERROR("failed to radio_hal_stop");
643 /* close radio device here !!!! */
644 ret = radio_hal_close(radio->hal_inf);
645 if (ret == MM_ERROR_NOT_SUPPORT_API) {
646 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
647 } else if (ret != MM_ERROR_NONE) {
648 MMRADIO_LOG_ERROR("radio_hal_close_device error");
652 ret = radio_hal_unprepare(radio->hal_inf);
653 if (ret == MM_ERROR_NOT_SUPPORT_API) {
654 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
655 } else if (ret != MM_ERROR_NONE) {
656 MMRADIO_LOG_ERROR("radio_hal_close_device error");
660 radio->is_ready = FALSE;
662 #ifdef TIZEN_FEATURE_SOUND_FOCUS
663 if (radio->sound_focus.handle > 0) {
664 ret = mmradio_release_sound_focus(&radio->sound_focus);
666 MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed");
671 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
673 MMRADIO_LOG_FLEAVE();
675 return MM_ERROR_NONE;
678 int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
680 int ret = MM_ERROR_NONE;
682 MMRADIO_LOG_FENTER();
684 MMRADIO_CHECK_INSTANCE(radio);
685 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK);
687 if (radio->is_seeking) {
688 MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again");
689 return MM_ERROR_RADIO_INTERNAL;
692 radio->seek_unmute = FALSE;
693 radio->is_seeking = TRUE;
694 radio->seek_cancel = FALSE;
696 if (!radio->is_muted) {
697 ret = radio_hal_mute(radio->hal_inf);
698 if (ret == MM_ERROR_NOT_SUPPORT_API) {
699 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
701 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
704 radio->seek_unmute = TRUE;
707 MMRADIO_LOG_INFO("trying to seek. direction[0:UP/1:DOWN) %d", direction);
708 radio->seek_direction = direction;
710 ret = pthread_create(&radio->seek_thread, NULL, (void *)__mmradio_seek_thread, (void *)radio);
713 MMRADIO_LOG_DEBUG("failed create thread");
714 radio->is_seeking = FALSE;
715 radio->seek_cancel = TRUE;
716 if (radio->seek_unmute) {
717 ret = radio_hal_mute(radio->hal_inf);
718 if (ret == MM_ERROR_NOT_SUPPORT_API) {
719 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
721 MMRADIO_LOG_ERROR("failed to radio_hal_mute");
722 radio->seek_unmute = FALSE;
726 return MM_ERROR_RADIO_INTERNAL;
729 MMRADIO_LOG_FLEAVE();
731 return MM_ERROR_NONE;
734 void _mmradio_seek_cancel(mm_radio_t *radio)
736 int ret = MM_ERROR_NONE;
737 char str_error[READ_MAX_BUFFER_SIZE];
738 MMRADIO_LOG_FENTER();
740 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
742 /*cancel any outstanding seek request*/
743 radio->seek_cancel = TRUE;
744 if (radio->seek_thread) {
745 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
746 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
747 if (ret == EBUSY) { /* it was already locked by other */
748 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
749 } else if (ret == 0) {
750 MMRADIO_LOG_INFO("trylock is successful. unlock now");
751 pthread_mutex_unlock(&radio->seek_cancel_mutex);
753 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
755 MMRADIO_LOG_DEBUG("pthread_join seek_thread");
756 pthread_join(radio->seek_thread, NULL);
757 MMRADIO_LOG_DEBUG("done");
758 radio->is_seeking = FALSE;
759 radio->seek_thread = 0;
761 MMRADIO_LOG_FLEAVE();
765 int _mmradio_start_scan(mm_radio_t *radio)
767 int ret = MM_ERROR_NONE;
769 MMRADIO_LOG_FENTER();
771 MMRADIO_CHECK_INSTANCE(radio);
772 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_START_SCAN);
776 radio->stop_scan = false;
778 if (!radio->is_ready) {
779 ret = radio_hal_prepare(radio->hal_inf);
780 if (ret == MM_ERROR_NOT_SUPPORT_API) {
781 MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
782 } else if (ret != MM_ERROR_NONE) {
783 MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
787 ret = radio_hal_open(radio->hal_inf);
788 if (ret == MM_ERROR_NOT_SUPPORT_API) {
789 MMRADIO_LOG_WARNING("radio_hal_open is not supported");
790 } else if (ret != MM_ERROR_NONE) {
791 MMRADIO_LOG_ERROR("radio_hal_init error");
792 MMRADIO_LOG_FLEAVE();
795 radio->is_ready = TRUE;
797 MMRADIO_LOG_DEBUG("radio prepared and opened");
800 scan_tr_id = pthread_create(&radio->scan_thread, NULL, (void *)__mmradio_scan_thread, (void *)radio);
802 if (scan_tr_id != 0) {
803 MMRADIO_LOG_ERROR("failed to create thread : scan");
804 return MM_ERROR_RADIO_NOT_INITIALIZED;
807 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
809 MMRADIO_LOG_FLEAVE();
811 return MM_ERROR_NONE;
814 int _mmradio_stop_scan(mm_radio_t *radio)
817 char str_error[READ_MAX_BUFFER_SIZE];
818 MMRADIO_LOG_FENTER();
820 MMRADIO_CHECK_INSTANCE(radio);
821 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP_SCAN);
823 radio->stop_scan = true;
825 if (radio->scan_thread > 0) {
826 /* make sure all the search is stopped else we'll wait till search finish which is not ideal*/
827 ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
828 MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
829 if (ret == EBUSY) { /* it was already locked by other */
830 MMRADIO_LOG_WARNING("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
831 } else if (ret == 0) {
832 MMRADIO_LOG_INFO("trylock is successful. unlock now");
833 pthread_mutex_unlock(&radio->seek_cancel_mutex);
835 MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
837 MMRADIO_LOG_DEBUG("pthread_join scan_thread");
838 pthread_join(radio->scan_thread, NULL);
839 radio->scan_thread = 0;
842 MMRADIO_LOG_FLEAVE();
844 return MM_ERROR_NONE;
847 int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value)
849 int ret = MM_ERROR_NONE;
850 uint32_t strength = 0;
851 MMRADIO_LOG_FENTER();
852 MMRADIO_CHECK_INSTANCE(radio);
854 return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT);
856 /* just return stored frequency if radio device is not ready */
857 ret = radio_hal_get_signal_strength(radio->hal_inf, &strength);
858 if (ret == MM_ERROR_NOT_SUPPORT_API) {
859 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
860 } else if (ret != MM_ERROR_NONE) {
861 MMRADIO_LOG_ERROR("radio_hal_get_signal_strength error");
863 MMRADIO_LOG_FLEAVE();
866 *value = (int)strength;
867 MMRADIO_LOG_FLEAVE();
868 return MM_ERROR_NONE;
871 void __mmradio_scan_thread(mm_radio_t *radio)
873 int ret = MM_ERROR_NONE;
876 MMRADIO_LOG_FENTER();
877 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
879 ret = radio_hal_mute(radio->hal_inf);
881 if (ret == MM_ERROR_NOT_SUPPORT_API) {
882 MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
883 } else if (ret != MM_ERROR_NONE) {
884 MMRADIO_LOG_ERROR("radio_hal_mute error");
887 ret = radio_hal_set_frequency(radio->hal_inf, radio->region_setting.band_min);
889 if (ret != MM_ERROR_NONE)
892 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL);
893 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
895 while (!radio->stop_scan) {
897 MMMessageParamType param = { 0, };
899 MMRADIO_LOG_DEBUG("scanning....");
901 pthread_mutex_lock(&radio->seek_cancel_mutex);
903 if (radio->stop_scan) {
904 MMRADIO_LOG_INFO("scan was canceled");
905 pthread_mutex_unlock(&radio->seek_cancel_mutex);
909 ret = radio_hal_seek(radio->hal_inf, MM_RADIO_SEEK_UP);
911 pthread_mutex_unlock(&radio->seek_cancel_mutex);
913 if (ret != MM_ERROR_NONE) {
914 MMRADIO_LOG_ERROR("radio scanning error");
918 /* now we can get new frequency from radio device */
919 if (radio->stop_scan)
922 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
923 if (ret != MM_ERROR_NONE) {
924 MMRADIO_LOG_ERROR("failed to get current frequency");
926 if (freq <= prev_freq) {
927 MMRADIO_LOG_ERROR("frequency is less than previous [%d] -> [%d] we wrapped around, we are finished scanning", prev_freq, freq);
931 prev_freq = param.radio_scan.frequency = (int)freq;
932 MMRADIO_LOG_INFO("scanning : new frequency : [%d]", param.radio_scan.frequency);
934 /* drop if max freq is scanned */
935 if (param.radio_scan.frequency >= radio->region_setting.band_max) {
936 MMRADIO_LOG_WARNING("%d freq is dropping...and stopping scan", param.radio_scan.frequency);
940 if (radio->stop_scan) {
941 /* doesn't need to post */
945 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, ¶m);
949 if (radio->old_state == MM_RADIO_STATE_READY) {
950 MMRADIO_LOG_DEBUG("old state is ready");
951 } else if (radio->old_state == MM_RADIO_STATE_PLAYING) {
952 MMRADIO_LOG_DEBUG("old state is playing");
953 ret = radio_hal_unmute(radio->hal_inf);
954 if (ret == MM_ERROR_NOT_SUPPORT_API) {
955 MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
956 } else if (ret != MM_ERROR_NONE) {
957 MMRADIO_LOG_ERROR("radio_hal_unmute error");
960 ret = radio_hal_set_frequency(radio->hal_inf, prev_freq);
961 if (ret == MM_ERROR_NOT_SUPPORT_API) {
962 MMRADIO_LOG_WARNING("radio_hal_set_frequency is not supported");
963 } else if (ret != MM_ERROR_NONE) {
964 MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
971 radio->scan_thread = 0;
973 if (radio->old_state == MM_RADIO_STATE_PLAYING) {
974 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
976 /* close radio device here !!!! */
977 ret = radio_hal_close(radio->hal_inf);
978 if (ret == MM_ERROR_NOT_SUPPORT_API)
979 MMRADIO_LOG_WARNING("radio_hal_close is not supported");
980 else if (ret != MM_ERROR_NONE)
981 MMRADIO_LOG_ERROR("radio_hal_close_device error");
983 ret = radio_hal_unprepare(radio->hal_inf);
984 if (ret == MM_ERROR_NOT_SUPPORT_API)
985 MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
986 else if (ret != MM_ERROR_NONE)
987 MMRADIO_LOG_ERROR("radio_hal_close_device error");
989 radio->is_ready = FALSE;
991 MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
994 if (!radio->stop_scan)
995 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_FINISH, NULL);
997 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_STOP, NULL);
999 MMRADIO_LOG_FLEAVE();
1006 bool __is_tunable_frequency(mm_radio_t *radio, int freq)
1008 MMRADIO_LOG_FENTER();
1010 MMRADIO_CHECK_INSTANCE(radio);
1012 if (freq >= radio->region_setting.band_max
1013 || freq <= radio->region_setting.band_min)
1016 MMRADIO_LOG_FLEAVE();
1021 void __mmradio_seek_thread(mm_radio_t *radio)
1023 int ret = MM_ERROR_NONE;
1025 MMMessageParamType param = {0, };
1027 MMRADIO_LOG_FENTER();
1028 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1030 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL);
1032 MMRADIO_LOG_DEBUG("seeking....");
1034 if (!radio->seek_cancel) {
1036 MMRADIO_LOG_DEBUG("try to seek ");
1037 pthread_mutex_lock(&radio->seek_cancel_mutex);
1038 MMRADIO_LOG_DEBUG("seek start");
1040 if (radio->seek_cancel) {
1041 MMRADIO_LOG_INFO("seek was canceled so we return failure to application");
1042 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1046 ret = radio_hal_seek(radio->hal_inf, radio->seek_direction);
1047 pthread_mutex_unlock(&radio->seek_cancel_mutex);
1049 MMRADIO_LOG_ERROR("radio_hal_seek failed");
1053 /* now we can get new frequency from radio device */
1054 ret = radio_hal_get_frequency(radio->hal_inf, &freq);
1056 MMRADIO_LOG_ERROR("failed to get current frequency");
1060 MMRADIO_LOG_DEBUG("found frequency");
1062 /* if same freq is found, ignore it and search next one. */
1063 if (freq == radio->prev_seek_freq) {
1064 MMRADIO_LOG_WARNING("It's same with previous found one. So, trying next one.");
1068 /* check if it's limit freq or not */
1069 if (__is_tunable_frequency(radio, freq)) {
1070 /* now tune to new frequency */
1071 ret = radio_hal_set_frequency(radio->hal_inf, freq);
1073 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1078 if (radio->seek_unmute) {
1079 /* now turn on radio
1080 * In the case of limit freq, tuner should be unmuted.
1081 * Otherwise, sound can't output even though application set new frequency.
1083 ret = radio_hal_unmute(radio->hal_inf);
1085 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1088 radio->seek_unmute = FALSE;
1091 param.radio_scan.frequency = radio->prev_seek_freq = (int)freq;
1092 MMRADIO_LOG_INFO("seeking : new frequency : [%d]", param.radio_scan.frequency);
1093 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1096 radio->seek_thread = 0;
1097 radio->is_seeking = FALSE;
1099 MMRADIO_LOG_FLEAVE();
1106 if (radio->seek_unmute) {
1107 /* now turn on radio
1108 * In the case of limit freq, tuner should be unmuted.
1109 * Otherwise, sound can't output even though application set new frequency.
1111 ret = radio_hal_unmute(radio->hal_inf);
1113 MMRADIO_LOG_ERROR("failed to tune to new frequency");
1114 radio->seek_unmute = FALSE;
1116 /* freq -1 means it's failed to seek */
1117 param.radio_scan.frequency = -1;
1118 MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, ¶m);
1119 radio->is_seeking = FALSE;
1124 static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype, MMMessageParamType *param)
1126 MMRADIO_CHECK_INSTANCE(radio);
1128 MMRADIO_LOG_FENTER();
1130 if (!radio->msg_cb) {
1131 MMRADIO_LOG_WARNING("failed to post a message");
1135 MMRADIO_LOG_DEBUG("address of msg_cb : %p", radio->msg_cb);
1137 radio->msg_cb(msgtype, param, radio->msg_cb_param);
1139 MMRADIO_LOG_FLEAVE();
1144 static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command)
1146 MMRadioStateType radio_state = MM_RADIO_STATE_NUM;
1148 MMRADIO_LOG_FENTER();
1150 MMRADIO_CHECK_INSTANCE(radio);
1152 radio_state = __mmradio_get_state(radio);
1154 MMRADIO_LOG_INFO("incomming command : %d current state : %d", command, radio_state);
1157 case MMRADIO_COMMAND_CREATE:
1159 if (radio_state != 0)
1164 case MMRADIO_COMMAND_REALIZE:
1166 if (radio_state == MM_RADIO_STATE_READY ||
1167 radio_state == MM_RADIO_STATE_PLAYING ||
1168 radio_state == MM_RADIO_STATE_SCANNING)
1171 if (radio_state == 0)
1176 case MMRADIO_COMMAND_UNREALIZE:
1178 if (radio_state == MM_RADIO_STATE_NULL)
1181 /* we can call unrealize at any higher state */
1185 case MMRADIO_COMMAND_START:
1187 if (radio_state == MM_RADIO_STATE_PLAYING)
1190 if (radio_state != MM_RADIO_STATE_READY)
1195 case MMRADIO_COMMAND_STOP:
1197 if (radio_state == MM_RADIO_STATE_READY)
1200 if (radio_state != MM_RADIO_STATE_PLAYING)
1205 case MMRADIO_COMMAND_START_SCAN:
1207 if (radio_state == MM_RADIO_STATE_SCANNING)
1210 if (radio_state == MM_RADIO_STATE_NULL)
1215 case MMRADIO_COMMAND_STOP_SCAN:
1217 if (radio_state == MM_RADIO_STATE_READY)
1220 if (radio_state != MM_RADIO_STATE_SCANNING)
1225 case MMRADIO_COMMAND_DESTROY:
1226 case MMRADIO_COMMAND_MUTE:
1227 case MMRADIO_COMMAND_UNMUTE:
1228 case MMRADIO_COMMAND_SET_FREQ:
1229 case MMRADIO_COMMAND_GET_FREQ:
1230 case MMRADIO_COMMAND_SET_REGION:
1231 case MMRADIO_COMMAND_SET_VOLUME:
1232 case MMRADIO_COMMAND_GET_VOLUME:
1234 /* we can do it at any state */
1238 case MMRADIO_COMMAND_SEEK:
1240 if (radio_state != MM_RADIO_STATE_PLAYING)
1245 case MMRADIO_COMMAND_GET_REGION:
1247 if (radio_state == MM_RADIO_STATE_NULL)
1253 MMRADIO_LOG_DEBUG("not handled in FSM. don't care it");
1257 MMRADIO_LOG_DEBUG("status OK");
1259 radio->cmd = command;
1261 MMRADIO_LOG_FLEAVE();
1263 return MM_ERROR_NONE;
1266 MMRADIO_LOG_WARNING("invalid state. current : %d command : %d", radio_state, command);
1267 MMRADIO_LOG_FLEAVE();
1268 return MM_ERROR_RADIO_INVALID_STATE;
1271 MMRADIO_LOG_WARNING("mm-radio is in the desired state(%d). doing noting", radio_state);
1272 MMRADIO_LOG_FLEAVE();
1273 return MM_ERROR_RADIO_NO_OP;
1277 static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
1279 MMMessageParamType msg = { 0, };
1280 int msg_type = MM_MESSAGE_UNKNOWN;
1282 MMRADIO_LOG_FENTER();
1285 MMRADIO_LOG_WARNING("calling set_state with invalid radio handle");
1289 if (radio->current_state == new_state && radio->pending_state == 0) {
1290 MMRADIO_LOG_WARNING("we are in same state");
1295 radio->old_state = radio->current_state;
1296 radio->current_state = new_state;
1298 /* fill message param */
1299 msg.state.previous = radio->old_state;
1300 msg.state.current = radio->current_state;
1302 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1303 /* post message to application */
1304 if (radio->sound_focus.by_focus_cb) {
1305 msg_type = MM_MESSAGE_STATE_INTERRUPTED;
1306 msg.union_type = MM_MSG_UNION_CODE;
1307 msg.code = radio->sound_focus.event_src;
1308 MMRADIO_POST_MSG(radio, msg_type, &msg);
1310 msg_type = MM_MESSAGE_STATE_CHANGED;
1311 MMRADIO_POST_MSG(radio, msg_type, &msg);
1314 msg_type = MM_MESSAGE_STATE_CHANGED;
1315 MMRADIO_POST_MSG(radio, msg_type, &msg);
1318 MMRADIO_LOG_FLEAVE();
1323 static int __mmradio_get_state(mm_radio_t *radio)
1325 MMRADIO_CHECK_INSTANCE(radio);
1327 MMRADIO_LOG_INFO("radio state : current : [%d] old : [%d] pending : [%d]",
1328 radio->current_state, radio->old_state, radio->pending_state);
1330 return radio->current_state;
1333 #ifdef TIZEN_FEATURE_SOUND_FOCUS
1334 static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
1335 mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
1336 const char *additional_info, void *user_data)
1338 mm_radio_t *radio = (mm_radio_t *)user_data;
1339 enum MMMessageInterruptedCode event_source;
1340 int result = MM_ERROR_NONE;
1341 int postMsg = false;
1343 MMRADIO_LOG_FENTER();
1344 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1345 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1347 mmradio_get_sound_focus_reason(focus_state, reason_for_change, FALSE, &event_source, &postMsg);
1348 radio->sound_focus.event_src = event_source;
1350 switch (focus_state) {
1351 case FOCUS_IS_RELEASED:{
1352 radio->sound_focus.cur_focus_type &= ~focus_type;
1353 radio->sound_focus.by_focus_cb = true;
1355 result = _mmradio_stop(radio);
1357 MMRADIO_LOG_ERROR("failed to stop radio");
1359 radio->sound_focus.by_focus_cb = false;
1361 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1365 case FOCUS_IS_ACQUIRED:{
1366 MMMessageParamType msg = { 0, };
1367 msg.union_type = MM_MSG_UNION_CODE;
1368 msg.code = event_source;
1370 radio->sound_focus.cur_focus_type |= focus_type;
1372 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1373 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1375 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1380 MMRADIO_LOG_DEBUG("Unknown focus_state");
1384 MMRADIO_LOG_FLEAVE();
1387 static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
1388 mm_sound_focus_state_e focus_state, const char *reason_for_change,
1389 const char *additional_info, void *user_data)
1391 mm_radio_t *radio = (mm_radio_t *)user_data;
1392 enum MMMessageInterruptedCode event_source;
1393 int result = MM_ERROR_NONE;
1394 int postMsg = false;
1396 MMRADIO_LOG_FENTER();
1397 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1398 MMRADIO_LOG_INFO("focus_state [%d]", focus_state);
1400 mmradio_get_sound_focus_reason(focus_state, reason_for_change, TRUE, &event_source, &postMsg);
1401 radio->sound_focus.event_src = event_source;
1403 switch (focus_state) {
1404 case FOCUS_IS_ACQUIRED: {
1405 radio->sound_focus.cur_focus_type &= ~focus_type;
1406 radio->sound_focus.by_focus_cb = true;
1408 result = _mmradio_stop(radio);
1410 MMRADIO_LOG_ERROR("failed to stop radio");
1412 radio->sound_focus.by_focus_cb = false;
1414 MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
1418 case FOCUS_IS_RELEASED: {
1419 MMMessageParamType msg = { 0, };
1420 msg.union_type = MM_MSG_UNION_CODE;
1421 msg.code = event_source;
1423 radio->sound_focus.cur_focus_type |= focus_type;
1425 if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
1426 MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
1428 MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d", radio->sound_focus.cur_focus_type);
1433 MMRADIO_LOG_DEBUG("Unknown focus_state");
1437 MMRADIO_LOG_FLEAVE();
1441 static void __mmradio_volume_changed_cb(volume_type_t type, unsigned int volume, void *user_data)
1443 mm_radio_t *radio = (mm_radio_t *)user_data;
1444 int ret = MM_ERROR_NONE;
1445 MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
1446 if (type == VOLUME_TYPE_MEDIA) {
1447 MMRADIO_LOG_INFO("Change FM Radio volume to %d", volume);
1448 ret = __mmradio_set_media_volume(radio, volume);
1449 if (ret != MM_ERROR_NONE)
1450 MMRADIO_LOG_ERROR("__mmradio_set_media_volume error");
1455 int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
1457 MMRADIO_LOG_FENTER();
1458 MMRADIO_CHECK_INSTANCE(radio);
1459 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1461 return_val_if_fail(type, MM_ERROR_INVALID_ARGUMENT);
1463 *type = radio->region_setting.country;
1465 MMRADIO_LOG_FLEAVE();
1466 return MM_ERROR_NONE;
1469 int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq)
1471 MMRADIO_LOG_FENTER();
1472 MMRADIO_CHECK_INSTANCE(radio);
1473 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1475 return_val_if_fail(min_freq && max_freq, MM_ERROR_INVALID_ARGUMENT);
1477 *min_freq = radio->region_setting.band_min;
1478 *max_freq = radio->region_setting.band_max;
1480 MMRADIO_LOG_FLEAVE();
1481 return MM_ERROR_NONE;
1484 int _mmradio_get_channel_spacing(mm_radio_t *radio, unsigned int *ch_spacing)
1486 MMRADIO_LOG_FENTER();
1487 MMRADIO_CHECK_INSTANCE(radio);
1488 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_REGION);
1490 return_val_if_fail(ch_spacing, MM_ERROR_INVALID_ARGUMENT);
1492 *ch_spacing = radio->region_setting.channel_spacing;
1494 MMRADIO_LOG_FLEAVE();
1495 return MM_ERROR_NONE;
1498 int _mmradio_set_volume(mm_radio_t *radio, float volume)
1500 int ret = MM_ERROR_NONE;
1502 MMRADIO_LOG_FENTER();
1504 MMRADIO_CHECK_INSTANCE(radio);
1505 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1507 MMRADIO_LOG_INFO("Setting %f volume", volume);
1509 MMRADIO_VOLUME_LOCK(radio);
1510 radio->local_volume = volume;
1511 MMRADIO_VOLUME_UNLOCK(radio);
1513 ret = radio_hal_set_volume(radio->hal_inf, volume);
1514 if (ret != MM_ERROR_NONE)
1515 MMRADIO_LOG_ERROR("radio_hal_set_volume error");
1517 MMRADIO_LOG_FLEAVE();
1522 int _mmradio_get_volume(mm_radio_t *radio, float *pVolume)
1524 int ret = MM_ERROR_NONE;
1526 MMRADIO_LOG_FENTER();
1528 MMRADIO_CHECK_INSTANCE(radio);
1529 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_GET_VOLUME);
1531 return_val_if_fail(pVolume, MM_ERROR_INVALID_ARGUMENT);
1533 ret = radio_hal_get_volume(radio->hal_inf, &volume);
1534 if (ret != MM_ERROR_NONE) {
1535 MMRADIO_LOG_ERROR("radio_hal_get_volume error");
1540 MMRADIO_VOLUME_LOCK(radio);
1541 radio->local_volume = volume;
1542 *pVolume = (float)radio->local_volume;
1543 MMRADIO_VOLUME_UNLOCK(radio);
1545 MMRADIO_LOG_FLEAVE();
1550 static int __mmradio_set_media_volume(mm_radio_t *radio, unsigned int level)
1552 int ret = MM_ERROR_NONE;
1554 MMRADIO_LOG_FENTER();
1556 MMRADIO_CHECK_INSTANCE(radio);
1557 MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SET_VOLUME);
1559 MMRADIO_LOG_INFO("Setting %d volume", level);
1561 MMRADIO_VOLUME_LOCK(radio);
1562 radio->media_volume = level;
1563 MMRADIO_VOLUME_UNLOCK(radio);
1565 ret = radio_hal_set_media_volume(radio->hal_inf, level);
1566 if (ret != MM_ERROR_NONE)
1567 MMRADIO_LOG_ERROR("radio_hal_set_media_volume error");
1569 MMRADIO_LOG_FLEAVE();