diff options
author | Jiri Slaby <xslaby@fi.muni.cz> | 2006-01-09 23:52:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-10 11:01:41 -0500 |
commit | 89dad8f07fa244d64459ecd9499bc314dc617598 (patch) | |
tree | ac502de4c104c7038257947c72dde569e9b30ad1 | |
parent | a0d50069ed3620e9a4d8939bbc3e0d5a692ab58a (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>
-rw-r--r-- | drivers/media/radio/radio-maestro.c | 175 |
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 | ||
67 | static int radio_ioctl(struct inode *inode, struct file *file, | 63 | static int radio_ioctl(struct inode *inode, struct file *file, |
68 | unsigned int cmd, unsigned long arg); | 64 | unsigned int cmd, unsigned long arg); |
65 | static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent); | ||
66 | static void maestro_remove(struct pci_dev *pdev); | ||
67 | |||
68 | static 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 | }; | ||
77 | MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl); | ||
78 | |||
79 | static 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 | ||
70 | static struct file_operations maestro_fops = { | 86 | static 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 | ||
88 | static struct radio_device | 104 | struct 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 | ||
97 | static __u32 radio_bits_get(struct radio_device *dev) | 113 | static __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 | ||
254 | static __u16 radio_install(struct pci_dev *pcidev); | 270 | static __u16 __devinit radio_power_on(struct radio_device *dev) |
255 | |||
256 | MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl"); | ||
257 | MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio."); | ||
258 | MODULE_LICENSE("GPL"); | ||
259 | |||
260 | static void __exit maestro_radio_exit(void) | ||
261 | { | ||
262 | video_unregister_device(&maestro_radio); | ||
263 | } | ||
264 | |||
265 | static 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 | |||
284 | module_init(maestro_radio_init); | ||
285 | module_exit(maestro_radio_exit); | ||
286 | |||
287 | static 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 | ||
308 | static __u16 radio_install(struct pci_dev *pcidev) | 291 | static 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; | ||
342 | errunr: | ||
343 | video_unregister_device(maestro_radio_inst); | ||
344 | errfr1: | ||
345 | kfree(maestro_radio_inst); | ||
346 | errfr: | ||
347 | kfree(radio_unit); | ||
348 | err: | ||
349 | return retval; | ||
350 | |||
351 | } | ||
352 | |||
353 | static 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 | ||
360 | MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl"); | ||
361 | MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio."); | ||
362 | MODULE_LICENSE("GPL"); | ||
363 | |||
364 | static 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 | |||
374 | static void __exit maestro_radio_exit(void) | ||
375 | { | ||
376 | pci_unregister_driver(&maestro_r_driver); | ||
377 | } | ||
378 | |||
379 | module_init(maestro_radio_init); | ||
380 | module_exit(maestro_radio_exit); | ||