blob: 640a90f22b3dbe66c55eb6ec5c834800d9d884ba [file] [log] [blame]
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +05301/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
3
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of The Linux Foundation nor
12 * the names of its contributors may be used to endorse or promote
13 * products derived from this software without specific prior written
14 * permission.
15
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "FmIoctlsInterface.h"
30#include <cstdio>
31#include <cstdlib>
32#include <cstring>
33#include <fcntl.h>
34#include <utils/Log.h>
35#include <cutils/properties.h>
36#include <sys/ioctl.h>
37#include <linux/videodev2.h>
38#include <math.h>
39
40char const * const FmIoctlsInterface::LOGTAG = "FmIoctlsInterface";
41
42int FmIoctlsInterface :: get_cur_freq
43(
44 UINT fd, long &freq
45)
46{
47 int ret;
48 struct v4l2_frequency channel;
49
50 channel.type = V4L2_TUNER_RADIO;
51 ret = ioctl(fd, VIDIOC_G_FREQUENCY, &channel);
52
Satish Kodishalab5b01372014-07-24 19:46:20 +053053 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +053054 return FM_FAILURE;
55 }else {
56 freq = (channel.frequency / TUNE_MULT);
57 return FM_SUCCESS;
58 }
59}
60
61int FmIoctlsInterface :: set_freq
62(
63 UINT fd, ULINT freq
64)
65{
66 int ret;
67 struct v4l2_frequency channel;
68
69 channel.type = V4L2_TUNER_RADIO;
70 channel.frequency = (freq * TUNE_MULT);
71
72 ret = ioctl(fd, VIDIOC_S_FREQUENCY, &channel);
Satish Kodishalab5b01372014-07-24 19:46:20 +053073 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +053074 return FM_FAILURE;
75 }else {
76 return FM_SUCCESS;
77 }
78}
79
80int FmIoctlsInterface :: set_control
81(
82 UINT fd, UINT id, int val
83)
84{
85 int ret;
86 struct v4l2_control control;
87
88 control.value = val;
89 control.id = id;
90
91 for(int i = 0; i < 3; i++) {
92 ret = ioctl(fd, VIDIOC_S_CTRL, &control);
Satish Kodishalab5b01372014-07-24 19:46:20 +053093 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +053094 ret = FM_FAILURE;
95 }else {
96 ret = FM_SUCCESS;
97 break;
98 }
99 }
100 return ret;
101}
102
103int FmIoctlsInterface :: set_calibration
104(
105 UINT fd
106)
107{
108 int ret;
109 FILE *cal_fp;
110 struct v4l2_ext_control ext_ctl;
111 struct v4l2_ext_controls v4l2_ctls;
112 char cal_data[CAL_DATA_SIZE] = {0};
113
Kamal Negi7bb0f622016-11-18 10:39:51 +0530114 memset(&v4l2_ctls, 0, sizeof(v4l2_ctls));
115 memset(&ext_ctl, 0, sizeof(ext_ctl));
116
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530117 cal_fp = fopen(CALIB_DATA_NAME, "r");
118 if(cal_fp != NULL) {
119 if(fread(&cal_data[0], 1, CAL_DATA_SIZE, cal_fp)
120 < CAL_DATA_SIZE) {
121 fclose(cal_fp);
122 ALOGE("%s: calibration file read failed\n", LOGTAG);
123 return FM_FAILURE;
124 }
125 fclose(cal_fp);
126 ext_ctl.id = V4L2_CID_PRV_SET_CALIBRATION;
127 ext_ctl.string = cal_data;
128 ext_ctl.size = CAL_DATA_SIZE;
129 v4l2_ctls.ctrl_class = V4L2_CTRL_CLASS_USER;
130 v4l2_ctls.count = 1;
131 v4l2_ctls.controls = &ext_ctl;
132 ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, &v4l2_ctls);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530133 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530134 ALOGE("%s: ioctl call failed\n", LOGTAG);
135 return FM_FAILURE;
136 }else {
137 return FM_SUCCESS;
138 }
139 }else {
140 return FM_SUCCESS;
141 }
142}
143
144int FmIoctlsInterface :: get_control
145(
146 UINT fd, UINT id, long &val
147)
148{
149 int ret;
150 struct v4l2_control control;
151
152 control.id = id;
153 ret = ioctl(fd, VIDIOC_G_CTRL, &control);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530154 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530155 return FM_FAILURE;
156 }else {
157 val = control.value;
158 return FM_SUCCESS;
159 }
160}
161
162int FmIoctlsInterface :: start_search
163(
164 UINT fd, UINT dir
165)
166{
167 int ret;
168 struct v4l2_hw_freq_seek hw_seek;
169
170 hw_seek.seek_upward = dir;
171 hw_seek.type = V4L2_TUNER_RADIO;
172
173 ret = ioctl(fd, VIDIOC_S_HW_FREQ_SEEK, &hw_seek);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530174 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530175 return FM_FAILURE;
176 }else {
177 return FM_SUCCESS;
178 }
179}
180
181int FmIoctlsInterface :: set_band
182(
183 UINT fd, ULINT low, ULINT high
184)
185{
186 int ret;
187 struct v4l2_tuner tuner;
188
189 tuner.index = 0;
190 tuner.signal = 0;
191 tuner.rangelow = (low * TUNE_MULT);
192 tuner.rangehigh = (high * TUNE_MULT);
193
194 ret = ioctl(fd, VIDIOC_S_TUNER, &tuner);
195 ret = set_control(fd, V4L2_CID_PRV_REGION, 0);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530196 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530197 return FM_FAILURE;
198 }else {
199 return FM_SUCCESS;
200 }
201}
202
203int FmIoctlsInterface :: get_rmssi
204(
205 UINT fd, long &rmssi
206)
207{
208 struct v4l2_tuner tuner;
209 int ret;
210
211 tuner.index = 0;
212 tuner.signal = 0;
213 ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530214 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530215 ret = FM_FAILURE;
216 }else {
217 rmssi = tuner.signal;
218 ret = FM_SUCCESS;
219 }
220 return ret;
221}
222
223int FmIoctlsInterface :: get_upperband_limit
224(
225 UINT fd, ULINT &freq
226)
227{
228 int ret;
229 struct v4l2_tuner tuner;
230
231 tuner.index = 0;
232 ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530233 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530234 return FM_FAILURE;
235 }else {
236 freq = (tuner.rangehigh / TUNE_MULT);
237 return FM_SUCCESS;
238 }
239}
240
241int FmIoctlsInterface :: get_lowerband_limit
242(
243 UINT fd, ULINT &freq
244)
245{
246 int ret;
247 struct v4l2_tuner tuner;
248
249 tuner.index = 0;
250 ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530251 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530252 return FM_FAILURE;
253 }else {
254 freq = (tuner.rangelow / TUNE_MULT);
255 return FM_SUCCESS;
256 }
257}
258
259int FmIoctlsInterface :: set_audio_mode
260(
261 UINT fd, enum AUDIO_MODE mode
262)
263{
264 int ret;
265 struct v4l2_tuner tuner;
266
267 tuner.index = 0;
268 ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530269 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530270 return FM_FAILURE;
271 }else {
272 tuner.audmode = mode;
273 ret = ioctl(fd, VIDIOC_S_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530274 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530275 return FM_FAILURE;
276 }else {
277 return FM_SUCCESS;
278 }
279 }
280}
281
282int FmIoctlsInterface :: get_buffer
283(
284 UINT fd, char *buff, UINT len, UINT index
285)
286{
287 int ret;
288 struct v4l2_buffer v4l2_buf;
289
290 if((len < STD_BUF_SIZE) || (buff == NULL)) {
291 return FM_FAILURE;
292 }else {
293 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
294 v4l2_buf.index = index;
295 v4l2_buf.type = V4L2_BUF_TYPE_PRIVATE;
296 v4l2_buf.length = STD_BUF_SIZE;
297 v4l2_buf.m.userptr = (ULINT)buff;
298 ret = ioctl(fd, VIDIOC_DQBUF, &v4l2_buf);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530299 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530300 return FM_FAILURE;
301 }else {
302 return v4l2_buf.bytesused;
303 }
304 }
305}
306
307int FmIoctlsInterface :: set_ext_control
308(
309 UINT fd,
310 struct v4l2_ext_controls *v4l2_ctls
311)
312{
313 int ret;
314
315 ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, v4l2_ctls);
316
Satish Kodishalab5b01372014-07-24 19:46:20 +0530317 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530318 return FM_FAILURE;
319 }else {
320 return FM_SUCCESS;
321 }
322}
323