aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-gemtek-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/radio/radio-gemtek-pci.c')
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c253
1 files changed, 146 insertions, 107 deletions
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 74976cba869f..fdf5d6e46eac 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -192,131 +192,158 @@ static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card )
192 return ( inb( card->iobase ) & 0x08 ) ? 0 : 1; 192 return ( inb( card->iobase ) & 0x08 ) ? 0 : 1;
193} 193}
194 194
195static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, 195static int vidioc_querycap(struct file *file, void *priv,
196 unsigned int cmd, void *arg) 196 struct v4l2_capability *v)
197{
198 strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));
199 strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card));
200 sprintf(v->bus_info, "ISA");
201 v->version = RADIO_VERSION;
202 v->capabilities = V4L2_CAP_TUNER;
203 return 0;
204}
205
206static int vidioc_g_tuner(struct file *file, void *priv,
207 struct v4l2_tuner *v)
197{ 208{
198 struct video_device *dev = video_devdata(file); 209 struct video_device *dev = video_devdata(file);
199 struct gemtek_pci_card *card = dev->priv; 210 struct gemtek_pci_card *card = dev->priv;
200 211
201 switch ( cmd ) { 212 if (v->index > 0)
202 case VIDIOC_QUERYCAP: 213 return -EINVAL;
203 { 214
204 struct v4l2_capability *v = arg; 215 strcpy(v->name, "FM");
205 memset(v,0,sizeof(*v)); 216 v->type = V4L2_TUNER_RADIO;
206 strlcpy(v->driver, "radio-gemtek-pci", sizeof (v->driver)); 217 v->rangelow = GEMTEK_PCI_RANGE_LOW;
207 strlcpy(v->card, "GemTek PCI Radio", sizeof (v->card)); 218 v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
208 sprintf(v->bus_info,"ISA"); 219 v->rxsubchans = V4L2_TUNER_SUB_MONO;
209 v->version = RADIO_VERSION; 220 v->capability = V4L2_TUNER_CAP_LOW;
210 v->capabilities = V4L2_CAP_TUNER; 221 v->audmode = V4L2_TUNER_MODE_MONO;
211 222 v->signal = 0xffff * gemtek_pci_getsignal(card);
212 return 0; 223 return 0;
213 } 224}
214 case VIDIOC_G_TUNER:
215 {
216 struct v4l2_tuner *v = arg;
217 225
218 if (v->index > 0) 226static int vidioc_s_tuner(struct file *file, void *priv,
219 return -EINVAL; 227 struct v4l2_tuner *v)
228{
229 if (v->index > 0)
230 return -EINVAL;
231 return 0;
232}
220 233
221 memset(v,0,sizeof(*v)); 234static int vidioc_s_frequency(struct file *file, void *priv,
222 strcpy(v->name, "FM"); 235 struct v4l2_frequency *f)
223 v->type = V4L2_TUNER_RADIO; 236{
237 struct video_device *dev = video_devdata(file);
238 struct gemtek_pci_card *card = dev->priv;
224 239
225 v->rangelow = GEMTEK_PCI_RANGE_LOW; 240 if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
226 v->rangehigh = GEMTEK_PCI_RANGE_HIGH; 241 (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
227 v->rxsubchans =V4L2_TUNER_SUB_MONO; 242 return -EINVAL;
228 v->capability=V4L2_TUNER_CAP_LOW; 243 gemtek_pci_setfrequency(card, f->frequency);
229 v->audmode = V4L2_TUNER_MODE_MONO; 244 card->current_frequency = f->frequency;
230 v->signal=0xFFFF*gemtek_pci_getsignal( card ); 245 card->mute = false;
246 return 0;
247}
231 248
232 return 0; 249static int vidioc_g_frequency(struct file *file, void *priv,
233 } 250 struct v4l2_frequency *f)
234 case VIDIOC_S_TUNER: 251{
235 { 252 struct video_device *dev = video_devdata(file);
236 struct v4l2_tuner *v = arg; 253 struct gemtek_pci_card *card = dev->priv;
237 254
238 if (v->index > 0) 255 f->type = V4L2_TUNER_RADIO;
239 return -EINVAL; 256 f->frequency = card->current_frequency;
257 return 0;
258}
240 259
260static int vidioc_queryctrl(struct file *file, void *priv,
261 struct v4l2_queryctrl *qc)
262{
263 int i;
264 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
265 if (qc->id && qc->id == radio_qctrl[i].id) {
266 memcpy(qc, &(radio_qctrl[i]),
267 sizeof(*qc));
241 return 0; 268 return 0;
242 } 269 }
243 case VIDIOC_S_FREQUENCY: 270 }
244 { 271 return -EINVAL;
245 struct v4l2_frequency *f = arg; 272}
246 273
247 if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) || 274static int vidioc_g_ctrl(struct file *file, void *priv,
248 (f->frequency > GEMTEK_PCI_RANGE_HIGH) ) 275 struct v4l2_control *ctrl)
249 return -EINVAL; 276{
277 struct video_device *dev = video_devdata(file);
278 struct gemtek_pci_card *card = dev->priv;
250 279
280 switch (ctrl->id) {
281 case V4L2_CID_AUDIO_MUTE:
282 ctrl->value = card->mute;
283 return 0;
284 case V4L2_CID_AUDIO_VOLUME:
285 if (card->mute)
286 ctrl->value = 0;
287 else
288 ctrl->value = 65535;
289 return 0;
290 }
291 return -EINVAL;
292}
251 293
252 gemtek_pci_setfrequency( card, f->frequency ); 294static int vidioc_s_ctrl(struct file *file, void *priv,
253 card->current_frequency = f->frequency; 295 struct v4l2_control *ctrl)
254 card->mute = false; 296{
255 return 0; 297 struct video_device *dev = video_devdata(file);
256 } 298 struct gemtek_pci_card *card = dev->priv;
257 case VIDIOC_QUERYCTRL: 299
258 { 300 switch (ctrl->id) {
259 struct v4l2_queryctrl *qc = arg; 301 case V4L2_CID_AUDIO_MUTE:
260 int i; 302 if (ctrl->value)
261 303 gemtek_pci_mute(card);
262 for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { 304 else
263 if (qc->id && qc->id == radio_qctrl[i].id) { 305 gemtek_pci_unmute(card);
264 memcpy(qc, &(radio_qctrl[i]), 306 return 0;
265 sizeof(*qc)); 307 case V4L2_CID_AUDIO_VOLUME:
266 return (0); 308 if (ctrl->value)
267 } 309 gemtek_pci_unmute(card);
268 } 310 else
269 return -EINVAL; 311 gemtek_pci_mute(card);
270 } 312 return 0;
271 case VIDIOC_G_CTRL:
272 {
273 struct v4l2_control *ctrl= arg;
274
275 switch (ctrl->id) {
276 case V4L2_CID_AUDIO_MUTE:
277 ctrl->value=card->mute;
278 return (0);
279 case V4L2_CID_AUDIO_VOLUME:
280 if (card->mute)
281 ctrl->value=0;
282 else
283 ctrl->value=65535;
284 return (0);
285 }
286 return -EINVAL;
287 }
288 case VIDIOC_S_CTRL:
289 {
290 struct v4l2_control *ctrl= arg;
291
292 switch (ctrl->id) {
293 case V4L2_CID_AUDIO_MUTE:
294 if (ctrl->value) {
295 gemtek_pci_mute(card);
296 } else {
297 gemtek_pci_unmute(card);
298 }
299 return (0);
300 case V4L2_CID_AUDIO_VOLUME:
301 if (ctrl->value) {
302 gemtek_pci_unmute(card);
303 } else {
304 gemtek_pci_mute(card);
305 }
306 return (0);
307 }
308 return -EINVAL;
309 }
310 default:
311 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
312 gemtek_pci_do_ioctl);
313 } 313 }
314 return -EINVAL;
314} 315}
315 316
316static int gemtek_pci_ioctl(struct inode *inode, struct file *file, 317static int vidioc_g_audio(struct file *file, void *priv,
317 unsigned int cmd, unsigned long arg) 318 struct v4l2_audio *a)
318{ 319{
319 return video_usercopy(inode, file, cmd, arg, gemtek_pci_do_ioctl); 320 if (a->index > 1)
321 return -EINVAL;
322
323 strcpy(a->name, "Radio");
324 a->capability = V4L2_AUDCAP_STEREO;
325 return 0;
326}
327
328static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
329{
330 *i = 0;
331 return 0;
332}
333
334static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
335{
336 if (i != 0)
337 return -EINVAL;
338 return 0;
339}
340
341static int vidioc_s_audio(struct file *file, void *priv,
342 struct v4l2_audio *a)
343{
344 if (a->index != 0)
345 return -EINVAL;
346 return 0;
320} 347}
321 348
322enum { 349enum {
@@ -342,7 +369,7 @@ static const struct file_operations gemtek_pci_fops = {
342 .owner = THIS_MODULE, 369 .owner = THIS_MODULE,
343 .open = video_exclusive_open, 370 .open = video_exclusive_open,
344 .release = video_exclusive_release, 371 .release = video_exclusive_release,
345 .ioctl = gemtek_pci_ioctl, 372 .ioctl = video_ioctl2,
346 .compat_ioctl = v4l_compat_ioctl32, 373 .compat_ioctl = v4l_compat_ioctl32,
347 .llseek = no_llseek, 374 .llseek = no_llseek,
348}; 375};
@@ -353,6 +380,18 @@ static struct video_device vdev_template = {
353 .type = VID_TYPE_TUNER, 380 .type = VID_TYPE_TUNER,
354 .hardware = 0, 381 .hardware = 0,
355 .fops = &gemtek_pci_fops, 382 .fops = &gemtek_pci_fops,
383 .vidioc_querycap = vidioc_querycap,
384 .vidioc_g_tuner = vidioc_g_tuner,
385 .vidioc_s_tuner = vidioc_s_tuner,
386 .vidioc_g_audio = vidioc_g_audio,
387 .vidioc_s_audio = vidioc_s_audio,
388 .vidioc_g_input = vidioc_g_input,
389 .vidioc_s_input = vidioc_s_input,
390 .vidioc_g_frequency = vidioc_g_frequency,
391 .vidioc_s_frequency = vidioc_s_frequency,
392 .vidioc_queryctrl = vidioc_queryctrl,
393 .vidioc_g_ctrl = vidioc_g_ctrl,
394 .vidioc_s_ctrl = vidioc_s_ctrl,
356}; 395};
357 396
358static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) 397static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )