blob: 52ad029e9f3716ff6d9f1b155014984075414397 [file] [log] [blame]
Venkateshwarlu Domakondaacdd9a42015-03-24 10:28:37 +05301/*
2Copyright (c) 2015, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <jni.h>
31#include "JNIHelp.h"
32#include "android_runtime/AndroidRuntime.h"
33#include <utils/Log.h>
34#include "FmRadioController.h"
35#include "FM_Const.h"
36
37static FmRadioController * pFMRadio;
38
39jboolean OpenFd(JNIEnv *env, jobject thiz)
40{
41 int ret = 0;
42 pFMRadio = new FmRadioController();
43 if (pFMRadio)
44 ret = pFMRadio->open_dev();
45 else
46 ret = JNI_FALSE;
47 ALOGD("%s, [ret=%d]\n", __func__, ret);
48 return ret? JNI_FALSE: JNI_TRUE;
49}
50
51jboolean CloseFd(JNIEnv *env, jobject thiz)
52{
53 int ret = 0;
54
55 if (pFMRadio)
56 ret = pFMRadio->close_dev();
57 else
58 ret = JNI_FALSE;
59
60 ALOGD("%s, [ret=%d]\n", __func__, ret);
61 return ret? JNI_FALSE: JNI_TRUE;
62}
63
64jboolean TurnOn(JNIEnv *env, jobject thiz, jfloat freq)
65{
66 int ret = 0;
67 int tmp_freq;
68
69 ALOGI("%s, [freq=%d]\n", __func__, (int)freq);
70 tmp_freq = (int)(freq * FREQ_MULT); //Eg, 87.5 * 1000 --> 87500
71 if (!pFMRadio) {
72 pFMRadio = new FmRadioController();
73 }
74 if (pFMRadio)
75 ret = pFMRadio->Pwr_Up(tmp_freq);
76 else
77 ret = JNI_FALSE;
78
79 ALOGD("%s, [ret=%d]\n", __func__, ret);
80 return ret?JNI_FALSE:JNI_TRUE;
81}
82
83jboolean TurnOff(JNIEnv *env, jobject thiz, jint type)
84{
85 int ret = 0;
86
87 if (pFMRadio)
88 ret = pFMRadio->Pwr_Down();
89 else
90 ret = JNI_FALSE;
91
92 ALOGD("%s, [ret=%d]\n", __func__, ret);
93 if (pFMRadio) {
94 delete pFMRadio;
95 pFMRadio = NULL;
96 }
97 return ret?JNI_FALSE:JNI_TRUE;
98}
99
100jboolean SetFreq(JNIEnv *env, jobject thiz, jfloat freq)
101{
102 int ret = 0;
103 int tmp_freq;
104
105 tmp_freq = (int)(freq * FREQ_MULT); //Eg, 87.5 * 10 --> 875
106 if (pFMRadio)
107 ret = pFMRadio->TuneChannel(tmp_freq);
108 else
109 ret = JNI_FALSE;
110
111 ALOGD("%s, [ret=%d]\n", __func__, ret);
112 return ret?JNI_FALSE:JNI_TRUE;
113}
114
115jfloat Seek(JNIEnv *env, jobject thiz, jfloat freq, jboolean isUp)
116{
Kamal Negi1aab93f2016-03-22 16:57:06 +0530117 int ret = JNI_FALSE;
118 float val = freq;
Venkateshwarlu Domakondaacdd9a42015-03-24 10:28:37 +0530119
Kamal Negi1aab93f2016-03-22 16:57:06 +0530120 if (pFMRadio) {
Venkateshwarlu Domakondaacdd9a42015-03-24 10:28:37 +0530121 ret = pFMRadio->Set_mute(true);
Kamal Negi1aab93f2016-03-22 16:57:06 +0530122 ALOGD("%s, [mute] [ret=%d]\n", __func__, ret);
Venkateshwarlu Domakondaacdd9a42015-03-24 10:28:37 +0530123 ret = pFMRadio->Seek((int)isUp);
Kamal Negi1aab93f2016-03-22 16:57:06 +0530124 ALOGD("%s, [freq=%f] [ret=%d]\n", __func__, freq, ret);
125 if (ret > 0)
126 val = (float)ret/FREQ_MULT; //Eg, 8755 / 100 --> 87.55
Venkateshwarlu Domakondaacdd9a42015-03-24 10:28:37 +0530127 }
128
Venkateshwarlu Domakondaacdd9a42015-03-24 10:28:37 +0530129 return val;
130}
131
132jshortArray ScanList(JNIEnv *env, jobject thiz)
133{
134 int ret = 0;
135 jshortArray scanList;
136 int chl_cnt = FM_SCAN_CH_SIZE_MAX;
137 uint16_t ScanTBL[FM_SCAN_CH_SIZE_MAX];
138
139 if (pFMRadio)
140 ret = pFMRadio->ScanList(ScanTBL, &chl_cnt);
141 else
142 ret = JNI_FALSE;
143 if (ret < 0) {
144 ALOGE("scan failed!\n");
145 scanList = NULL;
146 goto out;
147 }
148 if (chl_cnt > 0) {
149 scanList = env->NewShortArray(chl_cnt);
150 env->SetShortArrayRegion(scanList, 0, chl_cnt, (const jshort*)&ScanTBL[0]);
151 } else {
152 ALOGE("cnt error, [cnt=%d]\n", chl_cnt);
153 scanList = NULL;
154 }
155
156out:
157 ALOGD("%s, [cnt=%d] [ret=%d]\n", __func__, chl_cnt, ret);
158 return scanList;
159}
160
161jshort GetRdsEvent(JNIEnv *env, jobject thiz)
162{
163 int ret = JNI_FALSE;
164
165 if (pFMRadio)
166 ret = pFMRadio->ReadRDS();
167
168 return ret;
169}
170
171jbyteArray GetPsText(JNIEnv *env, jobject thiz)
172{
173 int ret = 0;
174 jbyteArray PS;
175 char ps[MAX_PS_LEN];
176 int ps_len = 0;
177
178 if (pFMRadio)
179 ret = pFMRadio->Get_ps(ps, &ps_len);
180 else
181 ret = JNI_FALSE;
182 if (ret) {
183 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
184 return NULL;
185 }
186 PS = env->NewByteArray(ps_len);
187 env->SetByteArrayRegion(PS, 0, ps_len, (const jbyte*)ps);
188 ALOGD("%s, [ret=%d]\n", __func__, ret);
189 return PS;
190}
191
192jbyteArray GetRtText(JNIEnv *env, jobject thiz)
193{
194 int ret = 0;
195 jbyteArray RadioText;
196 char rt[MAX_RT_LEN];
197 int rt_len = 0;
198
199 if (pFMRadio)
200 ret = pFMRadio->Get_rt(rt, &rt_len);
201 else
202 ret = JNI_FALSE;
203 if (ret) {
204 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
205 return NULL;
206 }
207 RadioText = env->NewByteArray(rt_len);
208 env->SetByteArrayRegion(RadioText, 0, rt_len, (const jbyte*)rt);
209 ALOGD("%s, [ret=%d]\n", __func__, ret);
210 return RadioText;
211}
212
213jshort GetAfFreq(JNIEnv *env, jobject thiz)
214{
215 int ret = 0;
216 jshort ret_freq = 0;
217
218 if (pFMRadio)
219 ret = pFMRadio->Get_AF_freq((uint16_t*)&ret_freq);
220 else
221 ret = JNI_FALSE;
222 if (ret) {
223 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
224 return 0;
225 }
226 ALOGD("%s, [ret_freq=%d]\n", __func__, ret_freq);
227 return ret_freq;
228}
229
230jint SetRds(JNIEnv *env, jobject thiz, jboolean rdson)
231{
232 int ret = 0;
233
234 if (pFMRadio)
235 ret = pFMRadio->Turn_On_Off_Rds(rdson);
236 else
237 ret = JNI_FALSE;
238 if (ret) {
239 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
240 }
241 ALOGD("%s, [rdson=%d] [ret=%d]\n", __func__, rdson, ret);
242 return ret?JNI_FALSE:JNI_TRUE;
243}
244
245jboolean StopSrch(JNIEnv *env, jobject thiz)
246{
247 int ret = 0;
248
249 if (pFMRadio)
250 ret = pFMRadio->Stop_Scan_Seek();
251 else
252 ret = JNI_FALSE;
253 if (ret) {
254 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
255 }
256 ALOGD("%s, [ret=%d]\n", __func__, ret);
257 return ret?JNI_FALSE:JNI_TRUE;
258}
259
260jint SetMute(JNIEnv *env, jobject thiz, jboolean mute)
261{
262 int ret = 0;
263
264 if (pFMRadio)
265 ret = pFMRadio->Set_mute(mute);
266 else
267 ret = JNI_FALSE;
268 if (ret) {
269 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
270 }
271 ALOGD("%s, [mute=%d] [ret=%d]\n", __func__, (int)mute, ret);
272 return ret?JNI_FALSE:JNI_TRUE;
273}
274
275/******************************************
276 * Inquiry if RDS is support in driver.
277 * Parameter:
278 * None
279 *Return Value:
280 * 1: support
281 * 0: NOT support
282 * -1: error
283 ******************************************/
284jint IsRdsSupport(JNIEnv *env, jobject thiz)
285{
286 int ret = 0;
287
288 if (pFMRadio)
289 ret = pFMRadio->IsRds_support();
290 else
291 ret = JNI_FALSE;
292 if (!ret) {
293 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
294 }
295 ALOGD("%s, [ret=%d]\n", __func__, ret);
296 return ret;
297}
298
299/******************************************
300 * SwitchAntenna
301 * Parameter:
302 * antenna:
303 0 : switch to long antenna
304 1: switch to short antenna
305 *Return Value:
306 * 0: Success
307 * 1: Failed
308 * 2: Not support
309 ******************************************/
310jint SetAntenna(JNIEnv *env, jobject thiz, jint antenna)
311{
312 int ret = 0;
313 jint jret = 0;
314 int ana = -1;
315
316 if (0 == antenna) {
317 ana = FM_LONG_ANA;
318 } else if (1 == antenna) {
319 ana = FM_SHORT_ANA;
320 } else {
321 ALOGE("%s:fail, para error\n", __func__);
322 jret = JNI_FALSE;
323 goto out;
324 }
325 if (pFMRadio)
326 ret = pFMRadio->Antenna_Switch(ana);
327 else
328 ret = JNI_FALSE;
329 if (ret) {
330 ALOGE("switchAntenna(), error\n");
331 jret = 1;
332 } else {
333 jret = 0;
334 }
335out:
336 ALOGD("%s: [antenna=%d] [ret=%d]\n", __func__, ana, ret);
337 return jret;
338}
339
340static const char *classPathNameFM = "com/android/fmradio/FmNative";
341
342static JNINativeMethod gMethods[] = {
343 {"openDev", "()Z", (void*)OpenFd },
344 {"closeDev", "()Z", (void*)CloseFd },
345 {"powerUp", "(F)Z", (void*)TurnOn },
346 {"powerDown", "(I)Z", (void*)TurnOff },
347 {"tune", "(F)Z", (void*)SetFreq },
348 {"seek", "(FZ)F", (void*)Seek },
349 {"autoScan", "()[S", (void*)ScanList },
350 {"stopScan", "()Z", (void*)StopSrch },
351 {"setRds", "(Z)I", (void*)SetRds },
352 {"readRds", "()S", (void*)GetRdsEvent },
353 {"getPs", "()[B", (void*)GetPsText },
354 {"getLrText", "()[B", (void*)GetRtText},
355 {"activeAf", "()S", (void*)GetAfFreq},
356 {"setMute", "(Z)I", (void*)SetMute},
357 {"isRdsSupport", "()I", (void*)IsRdsSupport},
358 {"switchAntenna", "(I)I", (void*)SetAntenna},
359};
360
361int register_android_hardware_fm(JNIEnv* env)
362{
363 return jniRegisterNativeMethods(env, classPathNameFM, gMethods, NELEM(gMethods));
364}
365
366jint JNI_OnLoad(JavaVM *jvm, void *reserved)
367{
368 JNIEnv *e;
369 int status;
370 ALOGE("FM : loading FM-JNI\n");
371
372 if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) {
373 ALOGE("JNI version mismatch error");
374 return JNI_ERR;
375 }
376
377 if ((status = register_android_hardware_fm(e)) < 0) {
378 ALOGE("jni adapter service registration failure, status: %d", status);
379 return JNI_ERR;
380 }
381 return JNI_VERSION_1_6;
382}
383