blob: d1a09428e1b2965b726b8b739b52a3c846cf4155 [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{
117 int ret = 0;
118 int tmp_freq;
119 int ret_freq;
120 float val;
121
122 tmp_freq = (int)(freq * FREQ_MULT); //Eg, 87.55 * 100 --> 87550
123 if (pFMRadio)
124 ret = pFMRadio->Set_mute(true);
125 else
126 ret = JNI_FALSE;
127 if (ret) {
128 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
129 }
130 ALOGD("%s, [mute] [ret=%d]\n", __func__, ret);
131 if (pFMRadio)
132 ret = pFMRadio->Seek((int)isUp);
133 else
134 ret = JNI_FALSE;
135 if (ret < 0) {
136 ret_freq = tmp_freq; //seek error, so use original freq
137 }
138
139 ALOGD("%s, [freq=%d] [ret=%d]\n", __func__, ret_freq, ret);
140
141 val = (float)ret/FREQ_MULT; //Eg, 8755 / 100 --> 87.55
142
143 return val;
144}
145
146jshortArray ScanList(JNIEnv *env, jobject thiz)
147{
148 int ret = 0;
149 jshortArray scanList;
150 int chl_cnt = FM_SCAN_CH_SIZE_MAX;
151 uint16_t ScanTBL[FM_SCAN_CH_SIZE_MAX];
152
153 if (pFMRadio)
154 ret = pFMRadio->ScanList(ScanTBL, &chl_cnt);
155 else
156 ret = JNI_FALSE;
157 if (ret < 0) {
158 ALOGE("scan failed!\n");
159 scanList = NULL;
160 goto out;
161 }
162 if (chl_cnt > 0) {
163 scanList = env->NewShortArray(chl_cnt);
164 env->SetShortArrayRegion(scanList, 0, chl_cnt, (const jshort*)&ScanTBL[0]);
165 } else {
166 ALOGE("cnt error, [cnt=%d]\n", chl_cnt);
167 scanList = NULL;
168 }
169
170out:
171 ALOGD("%s, [cnt=%d] [ret=%d]\n", __func__, chl_cnt, ret);
172 return scanList;
173}
174
175jshort GetRdsEvent(JNIEnv *env, jobject thiz)
176{
177 int ret = JNI_FALSE;
178
179 if (pFMRadio)
180 ret = pFMRadio->ReadRDS();
181
182 return ret;
183}
184
185jbyteArray GetPsText(JNIEnv *env, jobject thiz)
186{
187 int ret = 0;
188 jbyteArray PS;
189 char ps[MAX_PS_LEN];
190 int ps_len = 0;
191
192 if (pFMRadio)
193 ret = pFMRadio->Get_ps(ps, &ps_len);
194 else
195 ret = JNI_FALSE;
196 if (ret) {
197 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
198 return NULL;
199 }
200 PS = env->NewByteArray(ps_len);
201 env->SetByteArrayRegion(PS, 0, ps_len, (const jbyte*)ps);
202 ALOGD("%s, [ret=%d]\n", __func__, ret);
203 return PS;
204}
205
206jbyteArray GetRtText(JNIEnv *env, jobject thiz)
207{
208 int ret = 0;
209 jbyteArray RadioText;
210 char rt[MAX_RT_LEN];
211 int rt_len = 0;
212
213 if (pFMRadio)
214 ret = pFMRadio->Get_rt(rt, &rt_len);
215 else
216 ret = JNI_FALSE;
217 if (ret) {
218 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
219 return NULL;
220 }
221 RadioText = env->NewByteArray(rt_len);
222 env->SetByteArrayRegion(RadioText, 0, rt_len, (const jbyte*)rt);
223 ALOGD("%s, [ret=%d]\n", __func__, ret);
224 return RadioText;
225}
226
227jshort GetAfFreq(JNIEnv *env, jobject thiz)
228{
229 int ret = 0;
230 jshort ret_freq = 0;
231
232 if (pFMRadio)
233 ret = pFMRadio->Get_AF_freq((uint16_t*)&ret_freq);
234 else
235 ret = JNI_FALSE;
236 if (ret) {
237 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
238 return 0;
239 }
240 ALOGD("%s, [ret_freq=%d]\n", __func__, ret_freq);
241 return ret_freq;
242}
243
244jint SetRds(JNIEnv *env, jobject thiz, jboolean rdson)
245{
246 int ret = 0;
247
248 if (pFMRadio)
249 ret = pFMRadio->Turn_On_Off_Rds(rdson);
250 else
251 ret = JNI_FALSE;
252 if (ret) {
253 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
254 }
255 ALOGD("%s, [rdson=%d] [ret=%d]\n", __func__, rdson, ret);
256 return ret?JNI_FALSE:JNI_TRUE;
257}
258
259jboolean StopSrch(JNIEnv *env, jobject thiz)
260{
261 int ret = 0;
262
263 if (pFMRadio)
264 ret = pFMRadio->Stop_Scan_Seek();
265 else
266 ret = JNI_FALSE;
267 if (ret) {
268 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
269 }
270 ALOGD("%s, [ret=%d]\n", __func__, ret);
271 return ret?JNI_FALSE:JNI_TRUE;
272}
273
274jint SetMute(JNIEnv *env, jobject thiz, jboolean mute)
275{
276 int ret = 0;
277
278 if (pFMRadio)
279 ret = pFMRadio->Set_mute(mute);
280 else
281 ret = JNI_FALSE;
282 if (ret) {
283 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
284 }
285 ALOGD("%s, [mute=%d] [ret=%d]\n", __func__, (int)mute, ret);
286 return ret?JNI_FALSE:JNI_TRUE;
287}
288
289/******************************************
290 * Inquiry if RDS is support in driver.
291 * Parameter:
292 * None
293 *Return Value:
294 * 1: support
295 * 0: NOT support
296 * -1: error
297 ******************************************/
298jint IsRdsSupport(JNIEnv *env, jobject thiz)
299{
300 int ret = 0;
301
302 if (pFMRadio)
303 ret = pFMRadio->IsRds_support();
304 else
305 ret = JNI_FALSE;
306 if (!ret) {
307 ALOGE("%s, error, [ret=%d]\n", __func__, ret);
308 }
309 ALOGD("%s, [ret=%d]\n", __func__, ret);
310 return ret;
311}
312
313/******************************************
314 * SwitchAntenna
315 * Parameter:
316 * antenna:
317 0 : switch to long antenna
318 1: switch to short antenna
319 *Return Value:
320 * 0: Success
321 * 1: Failed
322 * 2: Not support
323 ******************************************/
324jint SetAntenna(JNIEnv *env, jobject thiz, jint antenna)
325{
326 int ret = 0;
327 jint jret = 0;
328 int ana = -1;
329
330 if (0 == antenna) {
331 ana = FM_LONG_ANA;
332 } else if (1 == antenna) {
333 ana = FM_SHORT_ANA;
334 } else {
335 ALOGE("%s:fail, para error\n", __func__);
336 jret = JNI_FALSE;
337 goto out;
338 }
339 if (pFMRadio)
340 ret = pFMRadio->Antenna_Switch(ana);
341 else
342 ret = JNI_FALSE;
343 if (ret) {
344 ALOGE("switchAntenna(), error\n");
345 jret = 1;
346 } else {
347 jret = 0;
348 }
349out:
350 ALOGD("%s: [antenna=%d] [ret=%d]\n", __func__, ana, ret);
351 return jret;
352}
353
354static const char *classPathNameFM = "com/android/fmradio/FmNative";
355
356static JNINativeMethod gMethods[] = {
357 {"openDev", "()Z", (void*)OpenFd },
358 {"closeDev", "()Z", (void*)CloseFd },
359 {"powerUp", "(F)Z", (void*)TurnOn },
360 {"powerDown", "(I)Z", (void*)TurnOff },
361 {"tune", "(F)Z", (void*)SetFreq },
362 {"seek", "(FZ)F", (void*)Seek },
363 {"autoScan", "()[S", (void*)ScanList },
364 {"stopScan", "()Z", (void*)StopSrch },
365 {"setRds", "(Z)I", (void*)SetRds },
366 {"readRds", "()S", (void*)GetRdsEvent },
367 {"getPs", "()[B", (void*)GetPsText },
368 {"getLrText", "()[B", (void*)GetRtText},
369 {"activeAf", "()S", (void*)GetAfFreq},
370 {"setMute", "(Z)I", (void*)SetMute},
371 {"isRdsSupport", "()I", (void*)IsRdsSupport},
372 {"switchAntenna", "(I)I", (void*)SetAntenna},
373};
374
375int register_android_hardware_fm(JNIEnv* env)
376{
377 return jniRegisterNativeMethods(env, classPathNameFM, gMethods, NELEM(gMethods));
378}
379
380jint JNI_OnLoad(JavaVM *jvm, void *reserved)
381{
382 JNIEnv *e;
383 int status;
384 ALOGE("FM : loading FM-JNI\n");
385
386 if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) {
387 ALOGE("JNI version mismatch error");
388 return JNI_ERR;
389 }
390
391 if ((status = register_android_hardware_fm(e)) < 0) {
392 ALOGE("jni adapter service registration failure, status: %d", status);
393 return JNI_ERR;
394 }
395 return JNI_VERSION_1_6;
396}
397