diff --git a/universal7885-common/apps/FMRadio/Android.bp b/universal7885-common/apps/FMRadio/Android.bp index 0ca1ca9..52ea885 100644 --- a/universal7885-common/apps/FMRadio/Android.bp +++ b/universal7885-common/apps/FMRadio/Android.bp @@ -5,7 +5,6 @@ android_app { ], platform_apis: true, certificate: "platform", - jni_libs: ["libfmnative_jni"], static_libs: [ "androidx.core_core", "androidx.appcompat_appcompat", @@ -14,6 +13,7 @@ android_app { "androidx.transition_transition", "kotlinx_coroutines_android", "androidx.coordinatorlayout_coordinatorlayout", + "vendor.eureka.hardware.fmradio-java", ], required: [ "vendor.eureka.hardware.fmradio-service", diff --git a/universal7885-common/apps/FMRadio/jni/fm_ioctl.cpp b/universal7885-common/apps/FMRadio/jni/fm_ioctl.cpp deleted file mode 100644 index 41bc7a7..0000000 --- a/universal7885-common/apps/FMRadio/jni/fm_ioctl.cpp +++ /dev/null @@ -1,498 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "s610_radio.h" -#include "v4l2_api.h" -#include -#include -#include -#include -#include -#include -#include - - -using android::sp; -using vendor::eureka::hardware::fmradio::V1_0::Direction; -using vendor::eureka::hardware::fmradio::V1_1::Status; -using vendor::eureka::hardware::fmradio::V1_2::IFMRadio; - -// #define DEBUG -#define TRACK_SIZE 30 -int64_t tracks[TRACK_SIZE] = {0}; -bool FMThread = false; - -int open_fm_device() { - int fd; - if ((fd = open("/dev/radio0", O_RDWR | O_CLOEXEC)) < 0) { - printf("Cannot open /dev/radio0.\n"); - return -1; - } - return fd; -} -static int fm_radio_get_frequency(int fd, int64_t *channel) { - struct v4l2_frequency freq {}; - int ret; - - freq.tuner = 0; - freq.type = V4L2_TUNER_RADIO; - - ret = ioctl(fd, VIDIOC_G_FREQUENCY, &freq); - if (ret < 0) { - printf("FmRadioController: failed to get frequency\n"); - return FM_FAILURE; - } - - *channel = (int64_t)freq.frequency / 16000; - - return FM_SUCCESS; -} - -static int fm_radio_set_frequency(int fd, int64_t channel) { - struct v4l2_frequency freq {}; - int ret; - - freq.tuner = 0; - freq.type = V4L2_TUNER_RADIO; - freq.frequency = (unsigned int)channel * 16000; - - ret = ioctl(fd, VIDIOC_S_FREQUENCY, &freq); - if (ret < 0) { - printf("FmRadioController: failed to set frequency\n"); - return FM_FAILURE; - } - - return FM_SUCCESS; -} - -static int fm_radio_set_control(int fd, unsigned int id, int64_t val) { - struct v4l2_control ctrl {}; - int ret; -#ifdef DEBUG - printf("FmRadioController:fm_radio_set_control: id(%d) val(%ld)\n", id, val); -#endif - ctrl.id = id; - if (val) - ctrl.value = (unsigned int)val; - else - ctrl.value = 0; - - ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl); - if (ret < 0) { - printf("FmRadioController: failed to set control\n"); - return FM_FAILURE; - } - - return FM_SUCCESS; -} - -static int fm_radio_seek_frequency(int fd, unsigned int upward, - unsigned int wrap_around, - unsigned int spacing) { - struct v4l2_hw_freq_seek seek {}; - int ret; - - seek.tuner = 0; - seek.type = V4L2_TUNER_RADIO; - seek.seek_upward = upward; - seek.wrap_around = wrap_around; - seek.spacing = spacing; - - ret = ioctl(fd, VIDIOC_S_HW_FREQ_SEEK, &seek); - if (ret < 0) { - printf("FmRadioController: failed to seek frequency\n"); - return FM_FAILURE; - } - - return FM_SUCCESS; -} -static int fm_radio_channel_searching(int fd, unsigned int upward, - unsigned int wrap_around, - unsigned int spacing, int64_t *channel) { - int ret; - - ret = fm_radio_set_control(fd, V4L2_CID_S610_SEEK_MODE, - FM_TUNER_AUTONOMOUS_SEARCH_MODE); - if (ret < 0) - return ret; - - ret = fm_radio_seek_frequency(fd, upward, wrap_around, spacing); - if (ret < 0) - return ret; - - ret = fm_radio_get_frequency(fd, channel); - if (ret < 0) - return ret; - - return ret; -} -static int fm_radio_set_tuner(int fd, unsigned int mode) { - struct v4l2_tuner tuner {}; - int ret; - - tuner.index = 0; - tuner.audmode = mode; - tuner.type = 1; - - ret = ioctl(fd, VIDIOC_S_TUNER, &tuner); - if (ret < 0) { - printf("FmRadioController: failed to set tuner\n"); - return FM_FAILURE; - } - - return FM_SUCCESS; -} -static int fm_radio_get_tuner(int fd) { - struct v4l2_tuner tuner {}; - int ret; - - tuner.index = 0; - tuner.type = 1; - ret = ioctl(fd, VIDIOC_G_TUNER, &tuner); - if (ret < 0) { - printf("FmRadioController: failed to set tuner\n"); - return FM_FAILURE; - } - - return tuner.audmode; -} - -static int fm_radio_set_mute(int fd, bool mute) { - int muteint = 1; - if (mute) - muteint = 0; - int ret = fm_radio_set_control(fd, V4L2_CID_AUDIO_MUTE, muteint); - if (ret < 0) { - printf("FmRadioController: failed to set mute\n"); - return FM_FAILURE; - } - - return FM_SUCCESS; -} - -static int fm_radio_set_volume(int fd, int volume /* 1 ~ 15 */) { - int ret = fm_radio_set_control(fd, V4L2_CID_AUDIO_VOLUME, volume); - if (ret < 0) { - printf("FmRadioController: failed to set volume\n"); - return FM_FAILURE; - } - - return FM_SUCCESS; -} - -template bool contains(C &&c, T e) { - return std::find(std::begin(c), std::end(c), e) != std::end(c); -} - -static int64_t fm_radio_get_freqs(int fd) { - int64_t ret = 0; - fm_radio_set_mute(fd, true); - sp service = IFMRadio::getService(); - bool mSysfs = service->isAvailable() == Status::YES; - for (int64_t &track : tracks) { - if (mSysfs) { - service->adjustFreqByStep(Direction::UP); - ret = (int64_t)service->getFreqFromSysfs(); - } else { - fm_radio_channel_searching(fd, 1, 0, FM_CHANNEL_SPACING_50KHZ, &ret); - } - if (contains(tracks, ret)) - break; - track = ret; -// printf("Found Freq %ld\n", ret); - } - fm_radio_set_mute(fd, false); - return ret; -} - -static int fm_radio_poll(int fd, struct pollfd *poll_fd) { - int ret; - - poll_fd->fd = fd; - poll_fd->events = POLLIN; - poll_fd->revents = 0; - - ret = poll(poll_fd, 1, 360); - if (ret > 0) { - if (poll_fd->revents & POLLIN) { - printf("FmRadioController: ready to read\n"); - return FM_SUCCESS; - } - - printf("FmRadioController: cannot read yet\n"); - return FM_FAILURE; - } - - if (!ret) { - printf("FmRadioController: polling timeout\n"); - return FM_FAILURE; - } - - printf("FmRadioController: pollig fail: %d\n", ret); - return FM_FAILURE - 1; -} - -static int fm_radio_read(int fd, unsigned char *buf) { - int ret; - - ret = read(fd, buf, FM_RADIO_RDS_DATA_MAX); - if (ret < 0) { - printf("FmRadioController: failed to read\n"); - return FM_FAILURE; - } - - return ret; -} - -static int fm_radio_thread(int fd) { - struct pollfd radio_poll {}; - unsigned char read_buf[FM_RADIO_RDS_DATA_MAX]; - int ret; - - while (FMThread) { - ret = fm_radio_poll(fd, &radio_poll); - if (ret < 0) { - if (ret < FM_FAILURE) - break; - else - continue; - } - - ret = fm_radio_read(fd, read_buf); - if (ret < 0) - break; - } - return 0; -} -static unsigned int fm_radio_get_upperband_limit(int fd) { - int ret; - struct v4l2_tuner tuner {}; - unsigned int freq; - tuner.index = 0; - ret = ioctl(fd, VIDIOC_G_TUNER, &tuner); - if (ret < 0) { - return FM_FAILURE; - } else { - freq = (tuner.rangehigh / 16000); - return freq; - } -} - -static unsigned int fm_radio_get_lowerband_limit(int fd) { - int ret; - unsigned int freq; - struct v4l2_tuner tuner {}; - - tuner.index = 0; - ret = ioctl(fd, VIDIOC_G_TUNER, &tuner); - if (ret < 0) { - return FM_FAILURE; - } else { - freq = (tuner.rangelow / 16000); - return freq; - } -} -static int64_t fm_radio_get_rmssi(int fd) { - struct v4l2_tuner tuner {}; - int ret; - int64_t rmssi; - tuner.index = 0; - tuner.signal = 0; - ret = ioctl(fd, VIDIOC_G_TUNER, &tuner); - if (ret < 0) { - ret = FM_FAILURE; - } else { - rmssi = tuner.signal; - ret = rmssi; - } - return ret; -} -static int fm_radio_set_rssi(int fd, int64_t rssi) { - int ret = fm_radio_set_control(fd, V4L2_CID_S610_RSSI_TH, rssi); - if (ret < 0) { - return FM_FAILURE; - } - return FM_SUCCESS; -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_openFMDevice( - __unused JNIEnv *env, __unused jobject thiz) { - return open_fm_device(); -} -extern "C" JNIEXPORT jlong JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_getFMFreq(__unused JNIEnv *env, - __unused jobject thiz, - jint fd) { - int64_t freq; - fm_radio_get_frequency(fd, &freq); - return freq; -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_setFMFreq(__unused JNIEnv *env, - __unused jobject thiz, - jint fd, jint freq) { - return fm_radio_set_frequency(fd, freq); -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_setFMVolume(__unused JNIEnv *env, - __unused jobject thiz, - jint fd, - jint volume) { - return fm_radio_set_volume(fd, volume); -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_setFMMute(__unused JNIEnv *env, - __unused jobject thiz, - jint fd, - jboolean mute) { - return fm_radio_set_mute(fd, mute); -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_getFmUpper(__unused JNIEnv *env, - __unused jobject thiz, - jint fd) { - return fm_radio_get_upperband_limit(fd); -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_getFMLower(__unused JNIEnv *env, - __unused jobject thiz, - jint fd) { - return fm_radio_get_lowerband_limit(fd); -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_getRMSSI(__unused JNIEnv *env, - __unused jobject thiz, - jint fd) { - return fm_radio_get_rmssi(fd); -} -extern "C" JNIEXPORT jlongArray JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_getFMTracks(JNIEnv *env, - __unused jobject thiz, - jint fd) { - fm_radio_get_freqs(fd); - jlongArray result; - result = (*env).NewLongArray(TRACK_SIZE); - if (result == nullptr) { - return nullptr; /* out of memory error thrown */ - } - int i; - // fill a temp structure to use to populate the java int array - int64_t fill[TRACK_SIZE]; - for (i = 0; i < TRACK_SIZE; i++) { - fill[i] = - tracks[i]; // put whatever logic you want to populate the values here. - } - // move from the temp structure to the java structure - (*env).SetLongArrayRegion(result, 0, TRACK_SIZE, fill); - return result; -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_setFMStereo(__unused JNIEnv *env, - __unused jobject thiz, - jint fd) { - return fm_radio_set_tuner(fd, 1); -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_setFMMono(__unused JNIEnv *env, - __unused jobject thiz, - jint fd) { - return fm_radio_set_tuner(fd, 0); -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_setFMThread(__unused JNIEnv *env, - __unused jobject thiz, - jint fd, - jboolean run) { - if (run) { - FMThread = true; - fm_radio_thread(fd); - } else { - FMThread = false; - } - return FM_SUCCESS; -} - -extern "C" JNIEXPORT void JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_setFMBoot(__unused JNIEnv *env, - __unused jobject thiz, - jint fd) { - fm_radio_set_control(fd, V4L2_CID_S610_IF_COUNT1, 4800); // SetIFCount 1 - fm_radio_set_control(fd, V4L2_CID_S610_IF_COUNT2, 5600); // SetIFCount 2 - fm_radio_set_control(fd, V4L2_CID_S610_SOFT_STEREO_BLEND, - 3172); // Set Soft Stereo Blend - fm_radio_set_control(fd, V4L2_CID_S610_SOFT_MUTE_COEFF, - 16); // SetSoftMuteCoeff - fm_radio_set_control(fd, V4L2_CID_S610_CH_BAND, - S610_BAND_FM); // Set Band (To FM) - fm_radio_set_control(fd, V4L2_CID_S610_CH_SPACING, - FM_CHANNEL_SPACING_50KHZ); // Spacing 5kHz - fm_radio_set_control(fd, V4L2_CID_S610_RDS_ON, FM_RDS_ENABLE); // RDS on -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_getNextChannel( - __unused JNIEnv *env, __unused jobject thiz, jint fd) { - int64_t ret; - sp service = IFMRadio::getService(); - bool mSysfs = service->isAvailable() == Status::YES; - if (!mSysfs) { - fm_radio_channel_searching(fd, 1, 0, FM_CHANNEL_SPACING_100KHZ, &ret); - } else { - service->adjustFreqByStep(Direction::UP); - ret = service->getFreqFromSysfs(); - } - return ret; -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_getBeforeChannel( - __unused JNIEnv *env, __unused jobject thiz, jint fd) { - int64_t ret; - sp service = IFMRadio::getService(); - bool mSysfs = service->isAvailable() == Status::YES; - if (!mSysfs) { - fm_radio_channel_searching(fd, 0, 0, FM_CHANNEL_SPACING_100KHZ, &ret); - } else { - service->adjustFreqByStep(Direction::DOWN); - ret = service->getFreqFromSysfs(); - } - return ret; -} - -extern "C" JNIEXPORT jboolean JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_getAudioChannel( - __unused JNIEnv *env, __unused jobject thiz, jint fd) { - int channel = fm_radio_get_tuner(fd); - if (channel == V4L2_TUNER_MODE_STEREO) { - return true; // Is EarPhones - } else { - return false; // Is Speaker - } -} -extern "C" JNIEXPORT void JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_stopSearching( - __unused JNIEnv *env, __unused jobject thiz, jint fd) { - fm_radio_set_control(fd, V4L2_CID_S610_SEEK_CANCEL, 1); -} -extern "C" JNIEXPORT jint JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_setFMRSSI(__unused JNIEnv *env, - __unused jobject thiz, - jint fd, jint rssi) { - return fm_radio_set_rssi(fd, rssi); -} -extern "C" JNIEXPORT void JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_closeFMDevice( - __unused JNIEnv *env, __unused jobject thiz, jint fd) { - close(fd); -} -extern "C" JNIEXPORT jboolean JNICALL -Java_com_eurekateam_fmradio_NativeFMInterface_getSysfsSupport( - __unused JNIEnv *env, __unused jobject thiz) { - sp service = IFMRadio::getService(); - return service->isAvailable() == Status::YES; -} diff --git a/universal7885-common/apps/FMRadio/jni/Android.bp b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/Android.bp similarity index 69% rename from universal7885-common/apps/FMRadio/jni/Android.bp rename to universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/Android.bp index 49b0040..83b3c29 100644 --- a/universal7885-common/apps/FMRadio/jni/Android.bp +++ b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/Android.bp @@ -1,20 +1,18 @@ -cc_library_shared { - name: "libfmnative_jni", +cc_library_static { + name: "libfm_slsi-impl", cflags: [ "-Wno-unused-parameter", ], srcs: [ - "fm_ioctl.cpp", - "fm_route.cpp", + "FM_Device_ctl.cpp", + "FM_AudioRoute_ctl.cpp", ], + export_include_dirs: ["public"], defaults: ["eureka_defaults"], shared_libs: [ "libhidlbase", "liblog", "libutils", - "vendor.eureka.hardware.fmradio@1.0", - "vendor.eureka.hardware.fmradio@1.1", - "vendor.eureka.hardware.fmradio@1.2", "audioflinger-aidl-cpp", "audiopolicy-aidl-cpp", "audiopolicy-types-aidl-cpp", diff --git a/universal7885-common/apps/FMRadio/jni/fm_route.cpp b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_AudioRoute_ctl.cpp similarity index 99% rename from universal7885-common/apps/FMRadio/jni/fm_route.cpp rename to universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_AudioRoute_ctl.cpp index 6b2f630..a70d8b5 100644 --- a/universal7885-common/apps/FMRadio/jni/fm_route.cpp +++ b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_AudioRoute_ctl.cpp @@ -20,6 +20,7 @@ #define FM_FAILURE (-1) #define FM_SUCCESS 0 #define IOHANDLE 13 + using namespace android; extern "C" JNIEXPORT jboolean JNICALL diff --git a/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_Device_ctl.cpp b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_Device_ctl.cpp new file mode 100644 index 0000000..d1c298e --- /dev/null +++ b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/FM_Device_ctl.cpp @@ -0,0 +1,293 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "S610_FMRadio.h" +#include "V4L2_4_4_API.h" +#include +#include + +#include +#include +#include + +namespace fm_radio_slsi { + +constexpr const int TRACK_SIZE = 30; + +static bool FMThread = false; + +int open_device(void) { + int fd; + if ((fd = open("/dev/radio0", O_RDWR | O_CLOEXEC)) < 0) { + printf("Cannot open /dev/radio0.\n"); + return -1; + } + return fd; +} + +int get_frequency(const int fd, int64_t *channel) { + struct v4l2_frequency freq {}; + int ret; + + freq.tuner = 0; + freq.type = V4L2_TUNER_RADIO; + + ret = ioctl(fd, VIDIOC_G_FREQUENCY, &freq); + if (ret < 0) + return FM_FAILURE; + + *channel = static_cast(freq.frequency) / 16000; + + return FM_SUCCESS; +} + +int set_frequency(const int fd, int64_t channel) { + struct v4l2_frequency freq {}; + int ret; + + freq.tuner = 0; + freq.type = V4L2_TUNER_RADIO; + freq.frequency = (unsigned int)channel * 16000; + + ret = ioctl(fd, VIDIOC_S_FREQUENCY, &freq); + if (ret < 0) { + printf("FmRadioController: failed to set frequency\n"); + return FM_FAILURE; + } + + return FM_SUCCESS; +} + +static int set_control(const int fd, unsigned int id, int64_t val) { + struct v4l2_control ctrl {}; + int ret; + ctrl.id = id; + if (val) + ctrl.value = static_cast(val); + else + ctrl.value = 0; + + ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl); + if (ret < 0) { + return FM_FAILURE; + } + return FM_SUCCESS; +} + +int seek_frequency(int fd, unsigned int upward, + unsigned int wrap_around, + unsigned int spacing) { + struct v4l2_hw_freq_seek seek {}; + int ret; + + seek.tuner = 0; + seek.type = V4L2_TUNER_RADIO; + seek.seek_upward = upward; + seek.wrap_around = wrap_around; + seek.spacing = spacing; + + ret = ioctl(fd, VIDIOC_S_HW_FREQ_SEEK, &seek); + if (ret < 0) { + return FM_FAILURE; + } + return FM_SUCCESS; +} + +int channel_search(const int fd, unsigned int upward, + unsigned int wrap_around, + unsigned int spacing, int64_t *channel) { + int ret; + + ret = set_control(fd, V4L2_CID_S610_SEEK_MODE, + FM_TUNER_AUTONOMOUS_SEARCH_MODE); + if (ret < 0) + return ret; + + ret = seek_frequency(fd, upward, wrap_around, spacing); + if (ret < 0) + return ret; + + ret = get_frequency(fd, channel); + if (ret < 0) + return ret; + + return ret; +} + +int set_mute(const int fd, bool mute) { + int ret = set_control(fd, V4L2_CID_AUDIO_MUTE, !mute); + if (ret < 0) { + return FM_FAILURE; + } + return FM_SUCCESS; +} + +int set_volume(int fd, int volume /* 1 ~ 15 */) { + int ret = set_control(fd, V4L2_CID_AUDIO_VOLUME, volume); + if (ret < 0) { + return FM_FAILURE; + } + return FM_SUCCESS; +} + +std::unique_ptr get_freqs(const int fd) { + set_mute(fd, true); + + auto map = std::vector(); + for (int i = 0; i < TRACK_SIZE; i++) { + int64_t found = 0; + channel_search(fd, 1, 0, FM_CHANNEL_SPACING_50KHZ, &found); + for (auto k : map) { + if (k == found) + continue; + } + map.push_back(found); + } + + auto ptr = std::make_unique(map.size()); + for (unsigned long i = 0; i < map.size(); i++) { + ptr[i] = map[i]; + } + + set_mute(fd, false); + return std::move(ptr); +} + +static int fm_poll(int fd, struct pollfd *poll_fd) { + int ret; + + poll_fd->fd = fd; + poll_fd->events = POLLIN; + poll_fd->revents = 0; + + ret = poll(poll_fd, 1, 360); + if (ret > 0) { + if (poll_fd->revents & POLLIN) { + return FM_SUCCESS; + } + return FM_FAILURE; + } + + if (!ret) { + return FM_FAILURE; + } + + return FM_FAILURE - 1; +} + +static int fm_read(int fd, unsigned char *buf) { + int ret; + + ret = read(fd, buf, FM_RADIO_RDS_DATA_MAX); + if (ret < 0) { + printf("FmRadioController: failed to read\n"); + return FM_FAILURE; + } + + return ret; +} + +static void fm_thread(int fd) { + struct pollfd radio_poll {}; + unsigned char read_buf[FM_RADIO_RDS_DATA_MAX]; + int ret; + + while (FMThread) { + ret = fm_poll(fd, &radio_poll); + if (ret < 0) { + if (ret < FM_FAILURE) + break; + else + continue; + } + + ret = fm_read(fd, read_buf); + if (ret < 0) + break; + } +} + +void fm_thread_set(const int fd, const bool enable) { + FMThread = enable; + if (enable) fm_thread(fd); +} + +unsigned int get_upperband_limit(int fd) { + int ret; + struct v4l2_tuner tuner {}; + unsigned int freq; + tuner.index = 0; + ret = ioctl(fd, VIDIOC_G_TUNER, &tuner); + if (ret < 0) { + return FM_FAILURE; + } else { + freq = (tuner.rangehigh / 16000); + return freq; + } +} + +unsigned int get_lowerband_limit(int fd) { + int ret; + unsigned int freq; + struct v4l2_tuner tuner {}; + + tuner.index = 0; + ret = ioctl(fd, VIDIOC_G_TUNER, &tuner); + if (ret < 0) { + return FM_FAILURE; + } else { + freq = (tuner.rangelow / 16000); + return freq; + } +} + +int64_t get_rmssi(int fd) { + struct v4l2_tuner tuner {}; + int ret; + int64_t rmssi; + tuner.index = 0; + tuner.signal = 0; + ret = ioctl(fd, VIDIOC_G_TUNER, &tuner); + if (ret < 0) { + ret = FM_FAILURE; + } else { + rmssi = tuner.signal; + ret = rmssi; + } + return ret; +} + +int set_rssi(int fd, int64_t rssi) { + int ret = set_control(fd, V4L2_CID_S610_RSSI_TH, rssi); + if (ret < 0) { + return FM_FAILURE; + } + return FM_SUCCESS; +} + +void bootctrl(const int fd) { + set_control(fd, V4L2_CID_S610_IF_COUNT1, 4800); // SetIFCount 1 + set_control(fd, V4L2_CID_S610_IF_COUNT2, 5600); // SetIFCount 2 + set_control(fd, V4L2_CID_S610_SOFT_STEREO_BLEND, + 3172); // Set Soft Stereo Blend + set_control(fd, V4L2_CID_S610_SOFT_MUTE_COEFF, + 16); // SetSoftMuteCoeff + set_control(fd, V4L2_CID_S610_CH_BAND, + S610_BAND_FM); // Set Band (To FM) + set_control(fd, V4L2_CID_S610_CH_SPACING, + FM_CHANNEL_SPACING_50KHZ); // Spacing 5kHz + set_control(fd, V4L2_CID_S610_RDS_ON, FM_RDS_ENABLE); // RDS on +} + +void stop_search(const int fd) { + set_control(fd, V4L2_CID_S610_SEEK_CANCEL, 1); +} + +} diff --git a/universal7885-common/apps/FMRadio/jni/s610_radio.h b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/S610_FMRadio.h similarity index 100% rename from universal7885-common/apps/FMRadio/jni/s610_radio.h rename to universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/S610_FMRadio.h diff --git a/universal7885-common/apps/FMRadio/jni/v4l2_api.h b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/V4L2_4_4_API.h similarity index 99% rename from universal7885-common/apps/FMRadio/jni/v4l2_api.h rename to universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/V4L2_4_4_API.h index 7b63d1f..9582ef0 100644 --- a/universal7885-common/apps/FMRadio/jni/v4l2_api.h +++ b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/V4L2_4_4_API.h @@ -1,3 +1,4 @@ +#include typedef u_int8_t __u8; typedef int32_t __s32; diff --git a/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/public/fm_slsi-impl.h b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/public/fm_slsi-impl.h new file mode 100644 index 0000000..729dcee --- /dev/null +++ b/universal7885-common/apps/aidl-support/fm/default/libfm_slsi-impl/public/fm_slsi-impl.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +namespace fm_radio_slsi { + +int open_device(void); +int get_frequency(const int fd, int64_t *channel); +int set_frequency(const int fd, int64_t channel); +int seek_frequency(int fd, unsigned int upward, unsigned int wrap_around, + unsigned int spacing); +int channel_search(const int fd, unsigned int upward, unsigned int wrap_around, + unsigned int spacing, int64_t *channel); +int set_mute(const int fd, bool mute); +int set_volume(int fd, int volume); +std::unique_ptr get_freqs(const int fd); +void fm_thread_set(const int fd, const bool enable); +unsigned int get_upperband_limit(int fd); +unsigned int get_lowerband_limit(int fd); +int64_t get_rmssi(int fd); +int set_rssi(int fd, int64_t rssi); +void bootctrl(const int fd); +void stop_search(const int fd); +} // namespace fm_radio_slsi