diff options
Diffstat (limited to 'drivers/media/radio/radio-gemtek.c')
-rw-r--r-- | drivers/media/radio/radio-gemtek.c | 260 |
1 files changed, 146 insertions, 114 deletions
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 36c4be6622c7..b04b6a7fff7c 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
@@ -161,137 +161,157 @@ static int gemtek_getsigstr(struct gemtek_device *dev) | |||
161 | return 1; /* signal present */ | 161 | return 1; /* signal present */ |
162 | } | 162 | } |
163 | 163 | ||
164 | static int gemtek_do_ioctl(struct inode *inode, struct file *file, | 164 | static int vidioc_querycap(struct file *file, void *priv, |
165 | unsigned int cmd, void *arg) | 165 | struct v4l2_capability *v) |
166 | { | ||
167 | strlcpy(v->driver, "radio-gemtek", sizeof(v->driver)); | ||
168 | strlcpy(v->card, "GemTek", sizeof(v->card)); | ||
169 | sprintf(v->bus_info, "ISA"); | ||
170 | v->version = RADIO_VERSION; | ||
171 | v->capabilities = V4L2_CAP_TUNER; | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int vidioc_g_tuner(struct file *file, void *priv, | ||
176 | struct v4l2_tuner *v) | ||
166 | { | 177 | { |
167 | struct video_device *dev = video_devdata(file); | 178 | struct video_device *dev = video_devdata(file); |
168 | struct gemtek_device *rt=dev->priv; | 179 | struct gemtek_device *rt = dev->priv; |
169 | 180 | ||
170 | switch(cmd) | 181 | if (v->index > 0) |
171 | { | 182 | return -EINVAL; |
172 | case VIDIOC_QUERYCAP: | ||
173 | { | ||
174 | struct v4l2_capability *v = arg; | ||
175 | memset(v,0,sizeof(*v)); | ||
176 | strlcpy(v->driver, "radio-gemtek", sizeof (v->driver)); | ||
177 | strlcpy(v->card, "GemTek", sizeof (v->card)); | ||
178 | sprintf(v->bus_info,"ISA"); | ||
179 | v->version = RADIO_VERSION; | ||
180 | v->capabilities = V4L2_CAP_TUNER; | ||
181 | 183 | ||
182 | return 0; | 184 | strcpy(v->name, "FM"); |
183 | } | 185 | v->type = V4L2_TUNER_RADIO; |
184 | case VIDIOC_G_TUNER: | 186 | v->rangelow = (87*16000); |
185 | { | 187 | v->rangehigh = (108*16000); |
186 | struct v4l2_tuner *v = arg; | 188 | v->rxsubchans = V4L2_TUNER_SUB_MONO; |
189 | v->capability = V4L2_TUNER_CAP_LOW; | ||
190 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
191 | v->signal = 0xffff*gemtek_getsigstr(rt); | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
196 | struct v4l2_tuner *v) | ||
197 | { | ||
198 | if (v->index > 0) | ||
199 | return -EINVAL; | ||
200 | return 0; | ||
201 | } | ||
187 | 202 | ||
188 | if (v->index > 0) | 203 | static int vidioc_s_frequency(struct file *file, void *priv, |
189 | return -EINVAL; | 204 | struct v4l2_frequency *f) |
205 | { | ||
206 | struct video_device *dev = video_devdata(file); | ||
207 | struct gemtek_device *rt = dev->priv; | ||
190 | 208 | ||
191 | memset(v,0,sizeof(*v)); | 209 | rt->curfreq = f->frequency; |
192 | strcpy(v->name, "FM"); | 210 | /* needs to be called twice in order for getsigstr to work */ |
193 | v->type = V4L2_TUNER_RADIO; | 211 | gemtek_setfreq(rt, rt->curfreq); |
212 | gemtek_setfreq(rt, rt->curfreq); | ||
213 | return 0; | ||
214 | } | ||
194 | 215 | ||
195 | v->rangelow=(87*16000); | 216 | static int vidioc_g_frequency(struct file *file, void *priv, |
196 | v->rangehigh=(108*16000); | 217 | struct v4l2_frequency *f) |
197 | v->rxsubchans =V4L2_TUNER_SUB_MONO; | 218 | { |
198 | v->capability=V4L2_TUNER_CAP_LOW; | 219 | struct video_device *dev = video_devdata(file); |
199 | v->audmode = V4L2_TUNER_MODE_MONO; | 220 | struct gemtek_device *rt = dev->priv; |
200 | v->signal=0xFFFF*gemtek_getsigstr(rt); | ||
201 | 221 | ||
202 | return 0; | 222 | f->type = V4L2_TUNER_RADIO; |
203 | } | 223 | f->frequency = rt->curfreq; |
204 | case VIDIOC_S_TUNER: | 224 | return 0; |
205 | { | 225 | } |
206 | struct v4l2_tuner *v = arg; | ||
207 | 226 | ||
208 | if (v->index > 0) | 227 | static int vidioc_queryctrl(struct file *file, void *priv, |
209 | return -EINVAL; | 228 | struct v4l2_queryctrl *qc) |
229 | { | ||
230 | int i; | ||
210 | 231 | ||
232 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
233 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
234 | memcpy(qc, &(radio_qctrl[i]), | ||
235 | sizeof(*qc)); | ||
211 | return 0; | 236 | return 0; |
212 | } | 237 | } |
213 | case VIDIOC_S_FREQUENCY: | 238 | } |
214 | { | 239 | return -EINVAL; |
215 | struct v4l2_frequency *f = arg; | 240 | } |
216 | |||
217 | rt->curfreq = f->frequency; | ||
218 | /* needs to be called twice in order for getsigstr to work */ | ||
219 | gemtek_setfreq(rt, rt->curfreq); | ||
220 | gemtek_setfreq(rt, rt->curfreq); | ||
221 | return 0; | ||
222 | } | ||
223 | case VIDIOC_G_FREQUENCY: | ||
224 | { | ||
225 | struct v4l2_frequency *f = arg; | ||
226 | 241 | ||
227 | f->type = V4L2_TUNER_RADIO; | 242 | static int vidioc_g_ctrl(struct file *file, void *priv, |
228 | f->frequency = rt->curfreq; | 243 | struct v4l2_control *ctrl) |
244 | { | ||
245 | struct video_device *dev = video_devdata(file); | ||
246 | struct gemtek_device *rt = dev->priv; | ||
229 | 247 | ||
230 | return 0; | 248 | switch (ctrl->id) { |
231 | } | 249 | case V4L2_CID_AUDIO_MUTE: |
232 | case VIDIOC_QUERYCTRL: | 250 | ctrl->value = rt->muted; |
233 | { | 251 | return 0; |
234 | struct v4l2_queryctrl *qc = arg; | 252 | case V4L2_CID_AUDIO_VOLUME: |
235 | int i; | 253 | if (rt->muted) |
236 | 254 | ctrl->value = 0; | |
237 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | 255 | else |
238 | if (qc->id && qc->id == radio_qctrl[i].id) { | 256 | ctrl->value = 65535; |
239 | memcpy(qc, &(radio_qctrl[i]), | 257 | return 0; |
240 | sizeof(*qc)); | 258 | } |
241 | return (0); | 259 | return -EINVAL; |
242 | } | 260 | } |
243 | } | 261 | |
244 | return -EINVAL; | 262 | static int vidioc_s_ctrl(struct file *file, void *priv, |
245 | } | 263 | struct v4l2_control *ctrl) |
246 | case VIDIOC_G_CTRL: | 264 | { |
247 | { | 265 | struct video_device *dev = video_devdata(file); |
248 | struct v4l2_control *ctrl= arg; | 266 | struct gemtek_device *rt = dev->priv; |
249 | 267 | ||
250 | switch (ctrl->id) { | 268 | switch (ctrl->id) { |
251 | case V4L2_CID_AUDIO_MUTE: | 269 | case V4L2_CID_AUDIO_MUTE: |
252 | ctrl->value=rt->muted; | 270 | if (ctrl->value) |
253 | return (0); | 271 | gemtek_mute(rt); |
254 | case V4L2_CID_AUDIO_VOLUME: | 272 | else |
255 | if (rt->muted) | 273 | gemtek_unmute(rt); |
256 | ctrl->value=0; | 274 | return 0; |
257 | else | 275 | case V4L2_CID_AUDIO_VOLUME: |
258 | ctrl->value=65535; | 276 | if (ctrl->value) |
259 | return (0); | 277 | gemtek_unmute(rt); |
260 | } | 278 | else |
261 | return -EINVAL; | 279 | gemtek_mute(rt); |
262 | } | 280 | return 0; |
263 | case VIDIOC_S_CTRL: | ||
264 | { | ||
265 | struct v4l2_control *ctrl= arg; | ||
266 | |||
267 | switch (ctrl->id) { | ||
268 | case V4L2_CID_AUDIO_MUTE: | ||
269 | if (ctrl->value) { | ||
270 | gemtek_mute(rt); | ||
271 | } else { | ||
272 | gemtek_unmute(rt); | ||
273 | } | ||
274 | return (0); | ||
275 | case V4L2_CID_AUDIO_VOLUME: | ||
276 | if (ctrl->value) { | ||
277 | gemtek_unmute(rt); | ||
278 | } else { | ||
279 | gemtek_mute(rt); | ||
280 | } | ||
281 | return (0); | ||
282 | } | ||
283 | return -EINVAL; | ||
284 | } | ||
285 | default: | ||
286 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | ||
287 | gemtek_do_ioctl); | ||
288 | } | 281 | } |
282 | return -EINVAL; | ||
289 | } | 283 | } |
290 | 284 | ||
291 | static int gemtek_ioctl(struct inode *inode, struct file *file, | 285 | static int vidioc_g_audio (struct file *file, void *priv, |
292 | unsigned int cmd, unsigned long arg) | 286 | struct v4l2_audio *a) |
293 | { | 287 | { |
294 | return video_usercopy(inode, file, cmd, arg, gemtek_do_ioctl); | 288 | if (a->index > 1) |
289 | return -EINVAL; | ||
290 | |||
291 | strcpy(a->name, "Radio"); | ||
292 | a->capability = V4L2_AUDCAP_STEREO; | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
297 | { | ||
298 | *i = 0; | ||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | ||
303 | { | ||
304 | if (i != 0) | ||
305 | return -EINVAL; | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static int vidioc_s_audio(struct file *file, void *priv, | ||
310 | struct v4l2_audio *a) | ||
311 | { | ||
312 | if (a->index != 0) | ||
313 | return -EINVAL; | ||
314 | return 0; | ||
295 | } | 315 | } |
296 | 316 | ||
297 | static struct gemtek_device gemtek_unit; | 317 | static struct gemtek_device gemtek_unit; |
@@ -300,7 +320,7 @@ static const struct file_operations gemtek_fops = { | |||
300 | .owner = THIS_MODULE, | 320 | .owner = THIS_MODULE, |
301 | .open = video_exclusive_open, | 321 | .open = video_exclusive_open, |
302 | .release = video_exclusive_release, | 322 | .release = video_exclusive_release, |
303 | .ioctl = gemtek_ioctl, | 323 | .ioctl = video_ioctl2, |
304 | .compat_ioctl = v4l_compat_ioctl32, | 324 | .compat_ioctl = v4l_compat_ioctl32, |
305 | .llseek = no_llseek, | 325 | .llseek = no_llseek, |
306 | }; | 326 | }; |
@@ -312,6 +332,18 @@ static struct video_device gemtek_radio= | |||
312 | .type = VID_TYPE_TUNER, | 332 | .type = VID_TYPE_TUNER, |
313 | .hardware = 0, | 333 | .hardware = 0, |
314 | .fops = &gemtek_fops, | 334 | .fops = &gemtek_fops, |
335 | .vidioc_querycap = vidioc_querycap, | ||
336 | .vidioc_g_tuner = vidioc_g_tuner, | ||
337 | .vidioc_s_tuner = vidioc_s_tuner, | ||
338 | .vidioc_g_audio = vidioc_g_audio, | ||
339 | .vidioc_s_audio = vidioc_s_audio, | ||
340 | .vidioc_g_input = vidioc_g_input, | ||
341 | .vidioc_s_input = vidioc_s_input, | ||
342 | .vidioc_g_frequency = vidioc_g_frequency, | ||
343 | .vidioc_s_frequency = vidioc_s_frequency, | ||
344 | .vidioc_queryctrl = vidioc_queryctrl, | ||
345 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
346 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
315 | }; | 347 | }; |
316 | 348 | ||
317 | static int __init gemtek_init(void) | 349 | static int __init gemtek_init(void) |