719 lines
21 KiB
C++
719 lines
21 KiB
C++
|
/*
|
||
|
* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are met:
|
||
|
* * Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* * Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
* * Neither the name of The Linux Foundation nor
|
||
|
* the names of its contributors may be used to endorse or promote
|
||
|
* products derived from this software without specific prior written
|
||
|
* permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
|
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*/
|
||
|
|
||
|
#define LOG_TAG "fmradio"
|
||
|
|
||
|
#include "jni.h"
|
||
|
#include "JNIHelp.h"
|
||
|
#include "android_runtime/AndroidRuntime.h"
|
||
|
#include "utils/Log.h"
|
||
|
#include "utils/misc.h"
|
||
|
#include <cutils/properties.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <sys/ioctl.h>
|
||
|
#include <media/tavarua.h>
|
||
|
#include <linux/videodev2.h>
|
||
|
#include <math.h>
|
||
|
|
||
|
#define RADIO "/dev/radio0"
|
||
|
#define FM_JNI_SUCCESS 0L
|
||
|
#define FM_JNI_FAILURE -1L
|
||
|
#define SEARCH_DOWN 0
|
||
|
#define SEARCH_UP 1
|
||
|
#define TUNE_MULT 16000
|
||
|
#define HIGH_BAND 2
|
||
|
#define LOW_BAND 1
|
||
|
#define CAL_DATA_SIZE 71
|
||
|
#define V4L2_CTRL_CLASS_USER 0x00980000
|
||
|
#define V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION (V4L2_CTRL_CLASS_USER + 0x92A)
|
||
|
enum search_dir_t {
|
||
|
SEEK_UP,
|
||
|
SEEK_DN,
|
||
|
SCAN_UP,
|
||
|
SCAN_DN
|
||
|
};
|
||
|
|
||
|
using namespace android;
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_acquireFdNative
|
||
|
(JNIEnv* env, jobject thiz, jstring path)
|
||
|
{
|
||
|
int fd;
|
||
|
int i, retval=0, err;
|
||
|
char value = 0;
|
||
|
char versionStr[40];
|
||
|
int init_success = 0;
|
||
|
jboolean isCopy;
|
||
|
v4l2_capability cap;
|
||
|
const char* radio_path = env->GetStringUTFChars(path, &isCopy);
|
||
|
if(radio_path == NULL){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
fd = open(radio_path, O_RDONLY, O_NONBLOCK);
|
||
|
if(isCopy == JNI_TRUE){
|
||
|
env->ReleaseStringUTFChars(path, radio_path);
|
||
|
}
|
||
|
if(fd < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
//Read the driver verions
|
||
|
err = ioctl(fd, VIDIOC_QUERYCAP, &cap);
|
||
|
LOGD("VIDIOC_QUERYCAP returns :%d: version: %d \n", err , cap.version );
|
||
|
|
||
|
if( err >= 0 ) {
|
||
|
LOGD("Driver Version(Same as ChipId): %x \n", cap.version );
|
||
|
/*Conver the integer to string */
|
||
|
sprintf(versionStr, "%d", cap.version );
|
||
|
property_set("hw.fm.version", versionStr);
|
||
|
} else {
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
|
||
|
/*Set the mode for soc downloader*/
|
||
|
property_set("hw.fm.mode", "normal");
|
||
|
|
||
|
property_set("ctl.start", "fm_dl");
|
||
|
sleep(1);
|
||
|
for(i=0;i<9;i++) {
|
||
|
property_get("hw.fm.init", &value, NULL);
|
||
|
if(value == '1') {
|
||
|
init_success = 1;
|
||
|
break;
|
||
|
} else {
|
||
|
sleep(1);
|
||
|
}
|
||
|
}
|
||
|
LOGE("init_success:%d after %d seconds \n", init_success, i);
|
||
|
if(!init_success) {
|
||
|
property_set("ctl.stop", "fm_dl");
|
||
|
// close the fd(power down)
|
||
|
|
||
|
close(fd);
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
property_set("ctl.stop", "fm_dl");
|
||
|
return fd;
|
||
|
}
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_closeFdNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd)
|
||
|
{
|
||
|
int i = 0;
|
||
|
int cleanup_success = 0;
|
||
|
char value = 0, retval =0;
|
||
|
|
||
|
property_set("ctl.stop", "fm_dl");
|
||
|
close(fd);
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/********************************************************************
|
||
|
* Current JNI
|
||
|
*******************************************************************/
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_getFreqNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd)
|
||
|
{
|
||
|
int err;
|
||
|
struct v4l2_frequency freq;
|
||
|
freq.type = V4L2_TUNER_RADIO;
|
||
|
err = ioctl(fd, VIDIOC_G_FREQUENCY, &freq);
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return ((freq.frequency*1000)/TUNE_MULT);
|
||
|
}
|
||
|
|
||
|
/*native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setFreqNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint freq)
|
||
|
{
|
||
|
int err;
|
||
|
double tune;
|
||
|
struct v4l2_frequency freq_struct;
|
||
|
freq_struct.type = V4L2_TUNER_RADIO;
|
||
|
freq_struct.frequency = (freq*TUNE_MULT/1000);
|
||
|
err = ioctl(fd, VIDIOC_S_FREQUENCY, &freq_struct);
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setControlNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint id, jint value)
|
||
|
{
|
||
|
struct v4l2_control control;
|
||
|
int i;
|
||
|
int err;
|
||
|
LOGE("id(%x) value: %x\n", id, value);
|
||
|
control.value = value;
|
||
|
|
||
|
control.id = id;
|
||
|
for(i=0;i<3;i++) {
|
||
|
err = ioctl(fd,VIDIOC_S_CTRL,&control);
|
||
|
if(err >= 0){
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_SetCalibrationNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jbyteArray buff)
|
||
|
{
|
||
|
|
||
|
struct v4l2_ext_control ext_ctl;
|
||
|
char tmp[CAL_DATA_SIZE] = {0x00};
|
||
|
int err;
|
||
|
FILE* cal_file;
|
||
|
|
||
|
cal_file = fopen("/data/app/Riva_fm_cal", "r" );
|
||
|
if(cal_file != NULL) {
|
||
|
ext_ctl.id = V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION;
|
||
|
if (fread(&tmp[0],1,CAL_DATA_SIZE,cal_file) < CAL_DATA_SIZE)
|
||
|
{
|
||
|
LOGE("File read failed");
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
ext_ctl.string = tmp;
|
||
|
ext_ctl.size = CAL_DATA_SIZE;
|
||
|
struct v4l2_ext_controls v4l2_ctls;
|
||
|
|
||
|
v4l2_ctls.ctrl_class = V4L2_CTRL_CLASS_USER,
|
||
|
v4l2_ctls.count = 1,
|
||
|
v4l2_ctls.controls = &ext_ctl;
|
||
|
err = ioctl(fd, VIDIOC_S_EXT_CTRLS, &v4l2_ctls );
|
||
|
if(err >= 0){
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
}else {
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_getControlNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint id)
|
||
|
{
|
||
|
struct v4l2_control control;
|
||
|
int err;
|
||
|
LOGE("id(%x)\n", id);
|
||
|
|
||
|
control.id = id;
|
||
|
err = ioctl(fd,VIDIOC_G_CTRL,&control);
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return control.value;
|
||
|
}
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_startSearchNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint dir)
|
||
|
{
|
||
|
struct v4l2_hw_freq_seek hw_seek;
|
||
|
int err;
|
||
|
hw_seek.seek_upward = dir;
|
||
|
hw_seek.type = V4L2_TUNER_RADIO;
|
||
|
err = ioctl(fd,VIDIOC_S_HW_FREQ_SEEK,&hw_seek);
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_cancelSearchNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd)
|
||
|
{
|
||
|
struct v4l2_control control;
|
||
|
int err;
|
||
|
control.id=V4L2_CID_PRIVATE_TAVARUA_SRCHON;
|
||
|
control.value=0;
|
||
|
err = ioctl(fd,VIDIOC_S_CTRL,&control);
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_getRSSINative
|
||
|
(JNIEnv * env, jobject thiz, jint fd)
|
||
|
{
|
||
|
struct v4l2_tuner tuner;
|
||
|
int err;
|
||
|
|
||
|
tuner.index = 0;
|
||
|
tuner.signal = 0;
|
||
|
err = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return tuner.signal;
|
||
|
}
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setBandNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint low, jint high)
|
||
|
{
|
||
|
struct v4l2_tuner tuner;
|
||
|
int err;
|
||
|
|
||
|
tuner.index = 0;
|
||
|
tuner.signal = 0;
|
||
|
tuner.rangelow = low * (TUNE_MULT/1000);
|
||
|
tuner.rangehigh = high * (TUNE_MULT/1000);
|
||
|
err = ioctl(fd, VIDIOC_S_TUNER, &tuner);
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_getLowerBandNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd)
|
||
|
{
|
||
|
struct v4l2_tuner tuner;
|
||
|
int err;
|
||
|
tuner.index = 0;
|
||
|
|
||
|
err = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
||
|
if(err < 0){
|
||
|
LOGE("low_band value: <%x> \n", tuner.rangelow);
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return ((tuner.rangelow * 1000)/ TUNE_MULT);
|
||
|
}
|
||
|
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setMonoStereoNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint val)
|
||
|
{
|
||
|
|
||
|
struct v4l2_tuner tuner;
|
||
|
int err;
|
||
|
|
||
|
tuner.index = 0;
|
||
|
err = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
||
|
|
||
|
if(err < 0)
|
||
|
return FM_JNI_FAILURE;
|
||
|
|
||
|
tuner.audmode = val;
|
||
|
err = ioctl(fd, VIDIOC_S_TUNER, &tuner);
|
||
|
|
||
|
if(err < 0)
|
||
|
return FM_JNI_FAILURE;
|
||
|
|
||
|
return FM_JNI_SUCCESS;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_getBufferNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jbooleanArray buff, jint index)
|
||
|
{
|
||
|
int err;
|
||
|
jboolean isCopy;
|
||
|
struct v4l2_requestbuffers reqbuf;
|
||
|
struct v4l2_buffer v4l2_buf;
|
||
|
memset(&reqbuf, 0, sizeof (reqbuf));
|
||
|
enum v4l2_buf_type type = V4L2_BUF_TYPE_PRIVATE;
|
||
|
reqbuf.type = V4L2_BUF_TYPE_PRIVATE;
|
||
|
reqbuf.memory = V4L2_MEMORY_USERPTR;
|
||
|
jboolean *bool_buffer = env->GetBooleanArrayElements(buff,&isCopy);
|
||
|
memset(&v4l2_buf, 0, sizeof (v4l2_buf));
|
||
|
v4l2_buf.index = index;
|
||
|
v4l2_buf.type = type;
|
||
|
v4l2_buf.length = 128;
|
||
|
v4l2_buf.m.userptr = (unsigned long)bool_buffer;
|
||
|
err = ioctl(fd,VIDIOC_DQBUF,&v4l2_buf) ;
|
||
|
if(err < 0){
|
||
|
/* free up the memory in failure case*/
|
||
|
env->ReleaseBooleanArrayElements(buff, bool_buffer, 0);
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Always copy buffer and free up the memory */
|
||
|
env->ReleaseBooleanArrayElements(buff, bool_buffer, 0);
|
||
|
|
||
|
return v4l2_buf.bytesused;
|
||
|
}
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_getRawRdsNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jbooleanArray buff, jint count)
|
||
|
{
|
||
|
|
||
|
return (read (fd, buff, count));
|
||
|
|
||
|
}
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setNotchFilterNative(JNIEnv * env, jobject thiz,jint fd, jint id, jboolean aValue)
|
||
|
{
|
||
|
int i = 0;
|
||
|
char value = 0;
|
||
|
int init_success = 0;
|
||
|
char notch[20] = {0x00};
|
||
|
struct v4l2_control control;
|
||
|
int err;
|
||
|
/*Enable/Disable the WAN avoidance*/
|
||
|
if (aValue)
|
||
|
property_set("hw.fm.mode", "wa_enable");
|
||
|
else
|
||
|
property_set("hw.fm.mode", "wa_disable");
|
||
|
|
||
|
property_set("ctl.start", "fm_dl");
|
||
|
sleep(1);
|
||
|
property_get("hw.fm.init", &value, NULL);
|
||
|
if(value == '1') {
|
||
|
init_success = 1;
|
||
|
}
|
||
|
LOGE("init_success:%d after %d seconds \n", init_success, i);
|
||
|
|
||
|
property_get("notch.value", notch, NULL);
|
||
|
LOGE("Notch = %s",notch);
|
||
|
if(!strncmp("HIGH",notch,strlen("HIGH")))
|
||
|
value = HIGH_BAND;
|
||
|
else if(!strncmp("LOW",notch,strlen("LOW")))
|
||
|
value = LOW_BAND;
|
||
|
else
|
||
|
value = 0;
|
||
|
|
||
|
LOGE("Notch value : %d", value);
|
||
|
control.id = id;
|
||
|
control.value = value;
|
||
|
err = ioctl(fd, VIDIOC_S_CTRL,&control );
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setAnalogModeNative(JNIEnv * env, jobject thiz, jboolean aValue)
|
||
|
{
|
||
|
int i=0;
|
||
|
char value = 0;
|
||
|
char firmwareVersion[80];
|
||
|
|
||
|
/*Enable/Disable Analog Mode FM*/
|
||
|
if (aValue) {
|
||
|
property_set("hw.fm.isAnalog", "true");
|
||
|
} else {
|
||
|
property_set("hw.fm.isAnalog", "false");
|
||
|
}
|
||
|
property_set("hw.fm.mode","config_dac");
|
||
|
property_set("ctl.start", "fm_dl");
|
||
|
sleep(1);
|
||
|
property_get("hw.fm.init", &value, NULL);
|
||
|
if(value == '1') {
|
||
|
return 1;
|
||
|
}
|
||
|
sleep(1);
|
||
|
property_get("hw.fm.init", &value, NULL);
|
||
|
if(value == '1') {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Interfaces added for Tx
|
||
|
*/
|
||
|
|
||
|
/*native interface */
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setPTYNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint pty)
|
||
|
{
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_setPTYNative\n");
|
||
|
struct v4l2_control control;
|
||
|
|
||
|
control.id = V4L2_CID_RDS_TX_PTY;
|
||
|
control.value = pty & MASK_PTY;
|
||
|
|
||
|
int err;
|
||
|
err = ioctl(fd, VIDIOC_S_CTRL,&control );
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setPINative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint pi)
|
||
|
{
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_setPINative\n");
|
||
|
|
||
|
struct v4l2_control control;
|
||
|
|
||
|
control.id = V4L2_CID_RDS_TX_PI;
|
||
|
control.value = pi & MASK_PI;
|
||
|
|
||
|
int err;
|
||
|
err = ioctl(fd, VIDIOC_S_CTRL,&control );
|
||
|
if(err < 0){
|
||
|
LOGE("->pty native failed");
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_startRTNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jstring radio_text, jint count )
|
||
|
{
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_startRTNative\n");
|
||
|
|
||
|
struct v4l2_control control;
|
||
|
struct v4l2_ext_control ext_ctl;
|
||
|
ext_ctl.id = V4L2_CID_RDS_TX_RADIO_TEXT;
|
||
|
|
||
|
jboolean isCopy;
|
||
|
char* rt_string = (char*)env->GetStringUTFChars(radio_text, &isCopy);
|
||
|
if(rt_string == NULL){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
|
||
|
ext_ctl.string = rt_string;
|
||
|
LOGE("Size is %d",count);
|
||
|
ext_ctl.size = count;
|
||
|
|
||
|
|
||
|
//form the ctrls data struct
|
||
|
struct v4l2_ext_controls v4l2_ctls;
|
||
|
|
||
|
v4l2_ctls.ctrl_class = V4L2_CTRL_CLASS_FM_TX,
|
||
|
v4l2_ctls.count = 1,
|
||
|
v4l2_ctls.controls = &ext_ctl;
|
||
|
|
||
|
|
||
|
LOGE("jbArray: %s", rt_string );
|
||
|
|
||
|
int err;
|
||
|
err = ioctl(fd, VIDIOC_S_EXT_CTRLS, &v4l2_ctls );
|
||
|
|
||
|
LOGE("VIDIOC_S_EXT_CTRLS for start RT returned : %d\n", err);
|
||
|
LOGE( "ErrorNo: %d\n", errno );
|
||
|
if(err < 0){
|
||
|
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
|
||
|
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_stopRTNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd )
|
||
|
{
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_stopRTNative\n");
|
||
|
int err;
|
||
|
struct v4l2_control control;
|
||
|
control.id = V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_RT;
|
||
|
|
||
|
err = ioctl(fd, VIDIOC_S_CTRL , &control);
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_stopRTNative is SUCCESS\n");
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_startPSNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jstring buff, jint count )
|
||
|
{
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_startPSNative\n");
|
||
|
LOGE("PS Pointer : %d -> String: %s", buff, buff);
|
||
|
struct v4l2_control control;
|
||
|
struct v4l2_ext_control ext_ctl;
|
||
|
ext_ctl.id = V4L2_CID_RDS_TX_PS_NAME;
|
||
|
|
||
|
jboolean isCopy;
|
||
|
char* ps_string = (char*)env->GetStringUTFChars(buff, &isCopy);
|
||
|
if(ps_string == NULL){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
|
||
|
ext_ctl.string = ps_string;
|
||
|
LOGE("Size is %d",count);
|
||
|
ext_ctl.size = count;
|
||
|
|
||
|
//form the ctrls data struct
|
||
|
struct v4l2_ext_controls v4l2_ctls;
|
||
|
|
||
|
v4l2_ctls.ctrl_class = V4L2_CTRL_CLASS_FM_TX,
|
||
|
v4l2_ctls.count = 1,
|
||
|
v4l2_ctls.controls = &ext_ctl;
|
||
|
|
||
|
int err;
|
||
|
err = ioctl(fd, VIDIOC_S_EXT_CTRLS, &v4l2_ctls );
|
||
|
|
||
|
LOGE("VIDIOC_S_EXT_CTRLS for Start PS returned : %d\n", err);
|
||
|
LOGE( "ErrorNo: %d\n", errno );
|
||
|
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_startPSNative is SUCCESS\n");
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_stopPSNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd)
|
||
|
{
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_stopPSNative\n");
|
||
|
struct v4l2_control control;
|
||
|
control.id = V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_PS_NAME;
|
||
|
|
||
|
int err;
|
||
|
err = ioctl(fd, VIDIOC_S_CTRL , &control);
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_stopPSNative is SUCCESS\n");
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setPSRepeatCountNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint repCount)
|
||
|
{
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_setPSRepeatCountNative\n");
|
||
|
|
||
|
struct v4l2_control control;
|
||
|
|
||
|
control.id = V4L2_CID_PRIVATE_TAVARUA_TX_SETPSREPEATCOUNT;
|
||
|
control.value = repCount & MASK_TXREPCOUNT;
|
||
|
|
||
|
int err;
|
||
|
err = ioctl(fd, VIDIOC_S_CTRL,&control );
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_setPSRepeatCountNative is SUCCESS\n");
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static jint android_hardware_fmradio_FmReceiverJNI_setTxPowerLevelNative
|
||
|
(JNIEnv * env, jobject thiz, jint fd, jint powLevel)
|
||
|
{
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_setTxPowerLevelNative\n");
|
||
|
|
||
|
struct v4l2_control control;
|
||
|
|
||
|
control.id = V4L2_CID_TUNE_POWER_LEVEL;
|
||
|
control.value = powLevel;
|
||
|
|
||
|
int err;
|
||
|
err = ioctl(fd, VIDIOC_S_CTRL,&control );
|
||
|
if(err < 0){
|
||
|
return FM_JNI_FAILURE;
|
||
|
}
|
||
|
|
||
|
LOGE("->android_hardware_fmradio_FmReceiverJNI_setTxPowerLevelNative is SUCCESS\n");
|
||
|
return FM_JNI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* JNI registration.
|
||
|
*/
|
||
|
static JNINativeMethod gMethods[] = {
|
||
|
/* name, signature, funcPtr */
|
||
|
{ "acquireFdNative", "(Ljava/lang/String;)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_acquireFdNative},
|
||
|
{ "closeFdNative", "(I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_closeFdNative},
|
||
|
{ "getFreqNative", "(I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_getFreqNative},
|
||
|
{ "setFreqNative", "(II)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setFreqNative},
|
||
|
{ "getControlNative", "(II)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_getControlNative},
|
||
|
{ "setControlNative", "(III)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setControlNative},
|
||
|
{ "startSearchNative", "(II)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_startSearchNative},
|
||
|
{ "cancelSearchNative", "(I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_cancelSearchNative},
|
||
|
{ "getRSSINative", "(I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_getRSSINative},
|
||
|
{ "setBandNative", "(III)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setBandNative},
|
||
|
{ "getLowerBandNative", "(I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_getLowerBandNative},
|
||
|
{ "getBufferNative", "(I[BI)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_getBufferNative},
|
||
|
{ "setMonoStereoNative", "(II)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setMonoStereoNative},
|
||
|
{ "getRawRdsNative", "(I[BI)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_getRawRdsNative},
|
||
|
{ "setNotchFilterNative", "(IIZ)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setNotchFilterNative},
|
||
|
{ "startRTNative", "(ILjava/lang/String;I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_startRTNative},
|
||
|
{ "stopRTNative", "(I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_stopRTNative},
|
||
|
{ "startPSNative", "(ILjava/lang/String;I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_startPSNative},
|
||
|
{ "stopPSNative", "(I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_stopPSNative},
|
||
|
{ "setPTYNative", "(II)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setPTYNative},
|
||
|
{ "setPINative", "(II)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setPINative},
|
||
|
{ "setPSRepeatCountNative", "(II)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setPSRepeatCountNative},
|
||
|
{ "setTxPowerLevelNative", "(II)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setTxPowerLevelNative},
|
||
|
{ "setAnalogModeNative", "(Z)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_setAnalogModeNative},
|
||
|
{ "SetCalibrationNative", "(I)I",
|
||
|
(void*)android_hardware_fmradio_FmReceiverJNI_SetCalibrationNative},
|
||
|
|
||
|
};
|
||
|
|
||
|
int register_android_hardware_fm_fmradio(JNIEnv* env)
|
||
|
{
|
||
|
return jniRegisterNativeMethods(env, "android/hardware/fmradio/FmReceiverJNI", gMethods, NELEM(gMethods));
|
||
|
}
|