mirror of
https://github.com/chararomandroid/android_device_samsung_a20
synced 2026-08-22 20:15:32 -04:00
universal7885: fm-aidl: Move ioctl code to hal
This commit is contained in:
parent
983a25b4d2
commit
839dc3ae4c
8 changed files with 325 additions and 506 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
cc_library_shared {
|
||||
name: "libfmnative_jni",
|
||||
cflags: [
|
||||
"-Wno-unused-parameter",
|
||||
],
|
||||
srcs: [
|
||||
"fm_ioctl.cpp",
|
||||
"fm_route.cpp",
|
||||
],
|
||||
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",
|
||||
"libaudiofoundation",
|
||||
"libaudioutils",
|
||||
"libaudioclient",
|
||||
"libutils",
|
||||
"libaudiopolicy",
|
||||
"libaudiomanager",
|
||||
],
|
||||
header_libs: [
|
||||
"libaudioclient_headers",
|
||||
"jni_headers",
|
||||
],
|
||||
}
|
||||
|
|
@ -1,498 +0,0 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <cerrno>
|
||||
#include <iostream>
|
||||
#include "s610_radio.h"
|
||||
#include "v4l2_api.h"
|
||||
#include <algorithm>
|
||||
#include <jni.h>
|
||||
#include <hardware/hardware.h>
|
||||
#include <hidl/HidlSupport.h>
|
||||
#include <hidl/LegacySupport.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <vendor/eureka/hardware/fmradio/1.2/IFMRadio.h>
|
||||
|
||||
|
||||
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 <class C, typename T> 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<IFMRadio> 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<IFMRadio> 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<IFMRadio> 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<IFMRadio> service = IFMRadio::getService();
|
||||
return service->isAvailable() == Status::YES;
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 Soo Hwan Na "Royna"
|
||||
*
|
||||
* 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 <jni.h>
|
||||
#include <media/AudioSystem.h>
|
||||
#include <media/IAudioFlinger.h>
|
||||
|
||||
#define FM_FAILURE (-1)
|
||||
#define FM_SUCCESS 0
|
||||
#define IOHANDLE 13
|
||||
using namespace android;
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_eurekateam_fmradio_NativeFMInterface_setAudioRoute(
|
||||
__unused JNIEnv *env, __unused jobject thiz, jboolean speaker) {
|
||||
const sp<IAudioFlinger> &af = AudioSystem::get_audio_flinger();
|
||||
if (af == 0)
|
||||
return PERMISSION_DENIED;
|
||||
if (speaker) {
|
||||
af->setParameters(IOHANDLE, String8("routing=2"));
|
||||
} else {
|
||||
af->setParameters(IOHANDLE, String8("routing=8"));
|
||||
}
|
||||
return FM_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
#define FM_FAILURE (-1)
|
||||
#define FM_SUCCESS 0
|
||||
|
||||
#define V4L2_CID_USER_S610_BASE (0x00980900 + 0x1070)
|
||||
enum s610_ctrl_id {
|
||||
V4L2_CID_S610_CH_SPACING = (V4L2_CID_USER_S610_BASE + 0x01),
|
||||
V4L2_CID_S610_CH_BAND = (V4L2_CID_USER_S610_BASE + 0x02),
|
||||
V4L2_CID_S610_SOFT_STEREO_BLEND = (V4L2_CID_USER_S610_BASE + 0x03),
|
||||
V4L2_CID_S610_SOFT_STEREO_BLEND_COEFF = (V4L2_CID_USER_S610_BASE + 0x04),
|
||||
V4L2_CID_S610_SOFT_MUTE_COEFF = (V4L2_CID_USER_S610_BASE + 0x5),
|
||||
V4L2_CID_S610_RSSI_CURR = (V4L2_CID_USER_S610_BASE + 0x06),
|
||||
V4L2_CID_S610_SNR_CURR = (V4L2_CID_USER_S610_BASE + 0x07),
|
||||
V4L2_CID_S610_SEEK_CANCEL = (V4L2_CID_USER_S610_BASE + 0x08),
|
||||
V4L2_CID_S610_SEEK_MODE = (V4L2_CID_USER_S610_BASE + 0x09),
|
||||
V4L2_CID_S610_RDS_ON = (V4L2_CID_USER_S610_BASE + 0x0A),
|
||||
V4L2_CID_S610_IF_COUNT1 = (V4L2_CID_USER_S610_BASE + 0x0B),
|
||||
V4L2_CID_S610_IF_COUNT2 = (V4L2_CID_USER_S610_BASE + 0x0C),
|
||||
V4L2_CID_S610_RSSI_TH = (V4L2_CID_USER_S610_BASE + 0x0D),
|
||||
V4L2_CID_S610_KERNEL_VER = (V4L2_CID_USER_S610_BASE + 0x0E),
|
||||
V4L2_CID_S610_SOFT_STEREO_BLEND_REF = (V4L2_CID_USER_S610_BASE + 0x0F),
|
||||
V4L2_CID_S610_REG_RW_ADDR = (V4L2_CID_USER_S610_BASE + 0x10),
|
||||
V4L2_CID_S610_REG_RW = (V4L2_CID_USER_S610_BASE + 0x11),
|
||||
};
|
||||
|
||||
/* Tunner modes */
|
||||
enum fm_tuner_mode {
|
||||
FM_TUNER_STOP_SEARCH_MODE = 0,
|
||||
FM_TUNER_PRESET_MODE = 1,
|
||||
FM_TUNER_AUTONOMOUS_SEARCH_MODE = 2,
|
||||
FM_TUNER_AUTONOMOUS_SEARCH_MODE_NEXT = 10
|
||||
};
|
||||
|
||||
/* channel spacing */
|
||||
enum fm_channel_spacing {
|
||||
FM_CHANNEL_SPACING_50KHZ = 1,
|
||||
FM_CHANNEL_SPACING_100KHZ = 2,
|
||||
FM_CHANNEL_SPACING_200KHZ = 4
|
||||
};
|
||||
|
||||
/* Mute modes */
|
||||
enum fm_mute_mode { FM_MUTE_ON = 0, FM_MUTE_OFF = 1, FM_MUTE_ATTENUATE = 2 };
|
||||
|
||||
/* FM RDS modes */
|
||||
enum fm_rds_mode { FM_RDS_DISABLE = 0, FM_RDS_ENABLE = 1 };
|
||||
|
||||
#define FM_RADIO_RDS_DATA_MAX 48
|
||||
|
||||
enum s610_freq_bands {
|
||||
S610_BAND_FM = 0,
|
||||
S610_BAND_AM = 1,
|
||||
};
|
||||
|
||||
enum s610_aud_mode {
|
||||
S610_AUD_ENABLE = 1,
|
||||
S610_AUD_DISABLE = 0,
|
||||
};
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
|
||||
typedef u_int8_t __u8;
|
||||
typedef int32_t __s32;
|
||||
typedef u_int32_t __u32;
|
||||
|
||||
struct v4l2_tuner {
|
||||
__u32 index;
|
||||
__u8 name[32];
|
||||
__u32 type; /* enum v4l2_tuner_type */
|
||||
__u32 capability;
|
||||
__u32 rangelow;
|
||||
__u32 rangehigh;
|
||||
__u32 rxsubchans;
|
||||
__u32 audmode;
|
||||
__s32 signal;
|
||||
__s32 afc;
|
||||
__u32 reserved[4];
|
||||
};
|
||||
|
||||
struct v4l2_frequency {
|
||||
__u32 tuner;
|
||||
__u32 type; /* enum v4l2_tuner_type */
|
||||
__u32 frequency;
|
||||
__u32 reserved[8];
|
||||
};
|
||||
|
||||
struct v4l2_hw_freq_seek {
|
||||
__u32 tuner;
|
||||
__u32 type; /* enum v4l2_tuner_type */
|
||||
__u32 seek_upward;
|
||||
__u32 wrap_around;
|
||||
__u32 spacing;
|
||||
__u32 rangelow;
|
||||
__u32 rangehigh;
|
||||
__u32 reserved[5];
|
||||
};
|
||||
|
||||
enum v4l2_tuner_type {
|
||||
V4L2_TUNER_RADIO = 1,
|
||||
V4L2_TUNER_ANALOG_TV = 2,
|
||||
V4L2_TUNER_DIGITAL_TV = 3,
|
||||
V4L2_TUNER_SDR = 4,
|
||||
V4L2_TUNER_RF = 5,
|
||||
};
|
||||
struct v4l2_control {
|
||||
__u32 id;
|
||||
__s32 value;
|
||||
};
|
||||
/**
|
||||
* struct v4l2_capability - Describes V4L2 device caps returned by
|
||||
* VIDIOC_QUERYCAP
|
||||
*
|
||||
* @driver: name of the driver module (e.g. "bttv")
|
||||
* @card: name of the card (e.g. "Hauppauge WinTV")
|
||||
* @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) )
|
||||
* @version: KERNEL_VERSION
|
||||
* @capabilities: capabilities of the physical device as a whole
|
||||
* @device_caps: capabilities accessed via this particular device (node)
|
||||
* @reserved: reserved fields for future extensions
|
||||
*/
|
||||
struct v4l2_capability {
|
||||
__u8 driver[16];
|
||||
__u8 card[32];
|
||||
__u8 bus_info[32];
|
||||
__u32 version;
|
||||
__u32 capabilities;
|
||||
__u32 device_caps;
|
||||
__u32 reserved[3];
|
||||
};
|
||||
|
||||
/*
|
||||
* T I M E C O D E
|
||||
*/
|
||||
struct v4l2_timecode {
|
||||
__u32 type;
|
||||
__u32 flags;
|
||||
__u8 frames;
|
||||
__u8 seconds;
|
||||
__u8 minutes;
|
||||
__u8 hours;
|
||||
__u8 userbits[4];
|
||||
};
|
||||
|
||||
struct v4l2_buffer {
|
||||
__u32 index;
|
||||
__u32 type;
|
||||
__u32 bytesused;
|
||||
__u32 flags;
|
||||
__u32 field;
|
||||
struct timeval timestamp;
|
||||
struct v4l2_timecode timecode;
|
||||
__u32 sequence;
|
||||
|
||||
/* memory location */
|
||||
__u32 memory;
|
||||
union {
|
||||
__u32 offset;
|
||||
uint64_t userptr;
|
||||
struct v4l2_plane *planes;
|
||||
__s32 fd;
|
||||
} m;
|
||||
__u32 length;
|
||||
__u32 reserved2;
|
||||
__u32 reserved;
|
||||
};
|
||||
|
||||
#define V4L2_TUNER_MODE_MONO 0x0000
|
||||
#define V4L2_TUNER_MODE_STEREO 0x0001
|
||||
|
||||
// Ioctl
|
||||
#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency)
|
||||
#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency)
|
||||
#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner)
|
||||
#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
|
||||
#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner)
|
||||
#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
|
||||
#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
|
||||
#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
|
||||
|
||||
#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
|
||||
#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
|
||||
#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE + 5)
|
||||
#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE + 9)
|
||||
Loading…
Reference in a new issue