blob: 046ca1e0799ae3714deb0a10675136624a20e192 [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
114 cal_fp = fopen(CALIB_DATA_NAME, "r");
115 if(cal_fp != NULL) {
116 if(fread(&cal_data[0], 1, CAL_DATA_SIZE, cal_fp)
117 < CAL_DATA_SIZE) {
118 fclose(cal_fp);
119 ALOGE("%s: calibration file read failed\n", LOGTAG);
120 return FM_FAILURE;
121 }
122 fclose(cal_fp);
123 ext_ctl.id = V4L2_CID_PRV_SET_CALIBRATION;
124 ext_ctl.string = cal_data;
125 ext_ctl.size = CAL_DATA_SIZE;
126 v4l2_ctls.ctrl_class = V4L2_CTRL_CLASS_USER;
127 v4l2_ctls.count = 1;
128 v4l2_ctls.controls = &ext_ctl;
129 ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, &v4l2_ctls);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530130 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530131 ALOGE("%s: ioctl call failed\n", LOGTAG);
132 return FM_FAILURE;
133 }else {
134 return FM_SUCCESS;
135 }
136 }else {
137 return FM_SUCCESS;
138 }
139}
140
141int FmIoctlsInterface :: get_control
142(
143 UINT fd, UINT id, long &val
144)
145{
146 int ret;
147 struct v4l2_control control;
148
149 control.id = id;
150 ret = ioctl(fd, VIDIOC_G_CTRL, &control);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530151 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530152 return FM_FAILURE;
153 }else {
154 val = control.value;
155 return FM_SUCCESS;
156 }
157}
158
159int FmIoctlsInterface :: start_search
160(
161 UINT fd, UINT dir
162)
163{
164 int ret;
165 struct v4l2_hw_freq_seek hw_seek;
166
167 hw_seek.seek_upward = dir;
168 hw_seek.type = V4L2_TUNER_RADIO;
169
170 ret = ioctl(fd, VIDIOC_S_HW_FREQ_SEEK, &hw_seek);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530171 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530172 return FM_FAILURE;
173 }else {
174 return FM_SUCCESS;
175 }
176}
177
178int FmIoctlsInterface :: set_band
179(
180 UINT fd, ULINT low, ULINT high
181)
182{
183 int ret;
184 struct v4l2_tuner tuner;
185
186 tuner.index = 0;
187 tuner.signal = 0;
188 tuner.rangelow = (low * TUNE_MULT);
189 tuner.rangehigh = (high * TUNE_MULT);
190
191 ret = ioctl(fd, VIDIOC_S_TUNER, &tuner);
192 ret = set_control(fd, V4L2_CID_PRV_REGION, 0);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530193 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530194 return FM_FAILURE;
195 }else {
196 return FM_SUCCESS;
197 }
198}
199
200int FmIoctlsInterface :: get_rmssi
201(
202 UINT fd, long &rmssi
203)
204{
205 struct v4l2_tuner tuner;
206 int ret;
207
208 tuner.index = 0;
209 tuner.signal = 0;
210 ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530211 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530212 ret = FM_FAILURE;
213 }else {
214 rmssi = tuner.signal;
215 ret = FM_SUCCESS;
216 }
217 return ret;
218}
219
220int FmIoctlsInterface :: get_upperband_limit
221(
222 UINT fd, ULINT &freq
223)
224{
225 int ret;
226 struct v4l2_tuner tuner;
227
228 tuner.index = 0;
229 ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530230 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530231 return FM_FAILURE;
232 }else {
233 freq = (tuner.rangehigh / TUNE_MULT);
234 return FM_SUCCESS;
235 }
236}
237
238int FmIoctlsInterface :: get_lowerband_limit
239(
240 UINT fd, ULINT &freq
241)
242{
243 int ret;
244 struct v4l2_tuner tuner;
245
246 tuner.index = 0;
247 ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530248 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530249 return FM_FAILURE;
250 }else {
251 freq = (tuner.rangelow / TUNE_MULT);
252 return FM_SUCCESS;
253 }
254}
255
256int FmIoctlsInterface :: set_audio_mode
257(
258 UINT fd, enum AUDIO_MODE mode
259)
260{
261 int ret;
262 struct v4l2_tuner tuner;
263
264 tuner.index = 0;
265 ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530266 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530267 return FM_FAILURE;
268 }else {
269 tuner.audmode = mode;
270 ret = ioctl(fd, VIDIOC_S_TUNER, &tuner);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530271 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530272 return FM_FAILURE;
273 }else {
274 return FM_SUCCESS;
275 }
276 }
277}
278
279int FmIoctlsInterface :: get_buffer
280(
281 UINT fd, char *buff, UINT len, UINT index
282)
283{
284 int ret;
285 struct v4l2_buffer v4l2_buf;
286
287 if((len < STD_BUF_SIZE) || (buff == NULL)) {
288 return FM_FAILURE;
289 }else {
290 memset(&v4l2_buf, 0, sizeof(v4l2_buf));
291 v4l2_buf.index = index;
292 v4l2_buf.type = V4L2_BUF_TYPE_PRIVATE;
293 v4l2_buf.length = STD_BUF_SIZE;
294 v4l2_buf.m.userptr = (ULINT)buff;
295 ret = ioctl(fd, VIDIOC_DQBUF, &v4l2_buf);
Satish Kodishalab5b01372014-07-24 19:46:20 +0530296 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530297 return FM_FAILURE;
298 }else {
299 return v4l2_buf.bytesused;
300 }
301 }
302}
303
304int FmIoctlsInterface :: set_ext_control
305(
306 UINT fd,
307 struct v4l2_ext_controls *v4l2_ctls
308)
309{
310 int ret;
311
312 ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, v4l2_ctls);
313
Satish Kodishalab5b01372014-07-24 19:46:20 +0530314 if(ret < IOCTL_SUCC) {
Venkateshwarlu Domakonda1c2c4352014-05-26 14:35:12 +0530315 return FM_FAILURE;
316 }else {
317 return FM_SUCCESS;
318 }
319}
320