aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-maestro.c
diff options
context:
space:
mode:
authorJiri Slaby <xslaby@fi.muni.cz>2006-01-09 23:52:47 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-10 11:01:41 -0500
commit89dad8f07fa244d64459ecd9499bc314dc617598 (patch)
treeac502de4c104c7038257947c72dde569e9b30ad1 /drivers/media/radio/radio-maestro.c
parenta0d50069ed3620e9a4d8939bbc3e0d5a692ab58a (diff)
[PATCH] media-radio: Pci probing for maestro radio
- Pci probing functions added, some functions were rewrited. - Use PCI_DEVICE macro. - dev_* used for printing when pci_dev available. - some static variables changed to dynamicto allow operation with multiple cards. - Deleted macros for DEVICE_IDS, they are in pci_ids.h yet. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/radio/radio-maestro.c')
-rw-r--r--drivers/media/radio/radio-maestro.c175
1 files changed, 111 insertions, 64 deletions
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index c30effdf711f..bf8b5929ae43 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -27,11 +27,7 @@
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/videodev.h> 28#include <linux/videodev.h>
29 29
30#define DRIVER_VERSION "0.04" 30#define DRIVER_VERSION "0.05"
31
32#define PCI_VENDOR_ESS 0x125D
33#define PCI_DEVICE_ID_ESS_ESS1968 0x1968 /* Maestro 2 */
34#define PCI_DEVICE_ID_ESS_ESS1978 0x1978 /* Maestro 2E */
35 31
36#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */ 32#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
37 33
@@ -66,6 +62,26 @@ module_param(radio_nr, int, 0);
66 62
67static int radio_ioctl(struct inode *inode, struct file *file, 63static int radio_ioctl(struct inode *inode, struct file *file,
68 unsigned int cmd, unsigned long arg); 64 unsigned int cmd, unsigned long arg);
65static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
66static void maestro_remove(struct pci_dev *pdev);
67
68static struct pci_device_id maestro_r_pci_tbl[] = {
69 { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
70 .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
71 .class_mask = 0xffff00 },
72 { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
73 .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
74 .class_mask = 0xffff00 },
75 { 0 }
76};
77MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
78
79static struct pci_driver maestro_r_driver = {
80 .name = "maestro_radio",
81 .id_table = maestro_r_pci_tbl,
82 .probe = maestro_probe,
83 .remove = __devexit_p(maestro_remove),
84};
69 85
70static struct file_operations maestro_fops = { 86static struct file_operations maestro_fops = {
71 .owner = THIS_MODULE, 87 .owner = THIS_MODULE,
@@ -85,14 +101,14 @@ static struct video_device maestro_radio=
85 .fops = &maestro_fops, 101 .fops = &maestro_fops,
86}; 102};
87 103
88static struct radio_device 104struct radio_device
89{ 105{
90 __u16 io, /* base of Maestro card radio io (GPIO_DATA)*/ 106 __u16 io, /* base of Maestro card radio io (GPIO_DATA)*/
91 muted, /* VIDEO_AUDIO_MUTE */ 107 muted, /* VIDEO_AUDIO_MUTE */
92 stereo, /* VIDEO_TUNER_STEREO_ON */ 108 stereo, /* VIDEO_TUNER_STEREO_ON */
93 tuned; /* signal strength (0 or 0xffff) */ 109 tuned; /* signal strength (0 or 0xffff) */
94 struct semaphore lock; 110 struct semaphore lock;
95} radio_unit = {0, 0, 0, 0, }; 111};
96 112
97static __u32 radio_bits_get(struct radio_device *dev) 113static __u32 radio_bits_get(struct radio_device *dev)
98{ 114{
@@ -251,40 +267,7 @@ static int radio_ioctl(struct inode *inode, struct file *file,
251 return ret; 267 return ret;
252} 268}
253 269
254static __u16 radio_install(struct pci_dev *pcidev); 270static __u16 __devinit radio_power_on(struct radio_device *dev)
255
256MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
257MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
258MODULE_LICENSE("GPL");
259
260static void __exit maestro_radio_exit(void)
261{
262 video_unregister_device(&maestro_radio);
263}
264
265static int __init maestro_radio_init(void)
266{
267 register __u16 found=0;
268 struct pci_dev *pcidev = NULL;
269 while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS,
270 PCI_DEVICE_ID_ESS_ESS1968,
271 pcidev)))
272 found |= radio_install(pcidev);
273 while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS,
274 PCI_DEVICE_ID_ESS_ESS1978,
275 pcidev)))
276 found |= radio_install(pcidev);
277 if(!found) {
278 printk(KERN_INFO "radio-maestro: no devices found.\n");
279 return -ENODEV;
280 }
281 return 0;
282}
283
284module_init(maestro_radio_init);
285module_exit(maestro_radio_exit);
286
287static inline __u16 radio_power_on(struct radio_device *dev)
288{ 271{
289 register __u16 io=dev->io; 272 register __u16 io=dev->io;
290 register __u32 ofreq; 273 register __u32 ofreq;
@@ -305,29 +288,93 @@ static inline __u16 radio_power_on(struct radio_device *dev)
305 return (ofreq == radio_bits_get(dev)); 288 return (ofreq == radio_bits_get(dev));
306} 289}
307 290
308static __u16 radio_install(struct pci_dev *pcidev) 291static int __devinit maestro_probe(struct pci_dev *pdev,
292 const struct pci_device_id *ent)
309{ 293{
310 if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO) 294 struct radio_device *radio_unit;
311 return 0; 295 struct video_device *maestro_radio_inst;
312 296 int retval;
313 radio_unit.io = pcidev->resource[0].start + GPIO_DATA; 297
314 maestro_radio.priv = &radio_unit; 298 retval = pci_enable_device(pdev);
315 init_MUTEX(&radio_unit.lock); 299 if (retval) {
316 300 dev_err(&pdev->dev, "enabling pci device failed!\n");
317 if(radio_power_on(&radio_unit)) { 301 goto err;
318 if(video_register_device(&maestro_radio, VFL_TYPE_RADIO, radio_nr)==-1) { 302 }
319 printk("radio-maestro: can't register device!"); 303
320 return 0; 304 retval = -ENOMEM;
321 } 305
322 printk(KERN_INFO "radio-maestro: version " 306 radio_unit = kzalloc(sizeof(*radio_unit), GFP_KERNEL);
323 DRIVER_VERSION 307 if (radio_unit == NULL) {
324 " time " 308 dev_err(&pdev->dev, "not enough memory\n");
325 __TIME__ " " 309 goto err;
326 __DATE__ 310 }
327 "\n"); 311
328 printk(KERN_INFO "radio-maestro: radio chip initialized\n"); 312 radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
329 return 1; 313 init_MUTEX(&radio_unit->lock);
330 } else 314
331 return 0; 315 maestro_radio_inst = video_device_alloc();
316 if (maestro_radio_inst == NULL) {
317 dev_err(&pdev->dev, "not enough memory\n");
318 goto errfr;
319 }
320
321 memcpy(maestro_radio_inst, &maestro_radio, sizeof(maestro_radio));
322 video_set_drvdata(maestro_radio_inst, radio_unit);
323 pci_set_drvdata(pdev, maestro_radio_inst);
324
325 retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO,
326 radio_nr);
327 if (retval) {
328 printk(KERN_ERR "can't register video device!\n");
329 goto errfr1;
330 }
331
332 if (!radio_power_on(radio_unit)) {
333 retval = -EIO;
334 goto errunr;
335 }
336
337 dev_info(&pdev->dev, "version " DRIVER_VERSION " time " __TIME__ " "
338 __DATE__ "\n");
339 dev_info(&pdev->dev, "radio chip initialized\n");
340
341 return 0;
342errunr:
343 video_unregister_device(maestro_radio_inst);
344errfr1:
345 kfree(maestro_radio_inst);
346errfr:
347 kfree(radio_unit);
348err:
349 return retval;
350
351}
352
353static void __devexit maestro_remove(struct pci_dev *pdev)
354{
355 struct video_device *vdev = pci_get_drvdata(pdev);
356
357 video_unregister_device(vdev);
332} 358}
333 359
360MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
361MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
362MODULE_LICENSE("GPL");
363
364static int __init maestro_radio_init(void)
365{
366 int retval = pci_register_driver(&maestro_r_driver);
367
368 if (retval)
369 printk(KERN_ERR "error during registration pci driver\n");
370
371 return retval;
372}
373
374static void __exit maestro_radio_exit(void)
375{
376 pci_unregister_driver(&maestro_r_driver);
377}
378
379module_init(maestro_radio_init);
380module_exit(maestro_radio_exit);