diff options
author | Stefan Ringel <stefan.ringel@arcor.de> | 2010-05-10 12:22:51 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-06-01 00:21:54 -0400 |
commit | 0439db75c1fbb28a3b314ae354582e4f180daf52 (patch) | |
tree | 545b05de65e8971d6658ef4b521a26d696f3e33c | |
parent | 9e1d9e7bac5c2bafc3c0c51db88c15f3fbcec83f (diff) |
V4L/DVB: tm6000: add extension module support
add module init over tm6000 extension
Signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/staging/tm6000/tm6000-alsa.c | 25 | ||||
-rw-r--r-- | drivers/staging/tm6000/tm6000-cards.c | 7 | ||||
-rw-r--r-- | drivers/staging/tm6000/tm6000-core.c | 92 | ||||
-rw-r--r-- | drivers/staging/tm6000/tm6000.h | 23 |
4 files changed, 145 insertions, 2 deletions
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c index bc89f9d28002..ce081cd44ad4 100644 --- a/drivers/staging/tm6000/tm6000-alsa.c +++ b/drivers/staging/tm6000/tm6000-alsa.c | |||
@@ -410,5 +410,28 @@ error: | |||
410 | snd_card_free(card); | 410 | snd_card_free(card); |
411 | return rc; | 411 | return rc; |
412 | } | 412 | } |
413 | EXPORT_SYMBOL_GPL(tm6000_audio_init); | ||
414 | 413 | ||
414 | static int tm6000_audio_fini(struct tm6000_core *dev) | ||
415 | { | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | struct tm6000_ops audio_ops = { | ||
420 | .id = TM6000_AUDIO, | ||
421 | .name = "TM6000 Audio Extension", | ||
422 | .init = tm6000_audio_init, | ||
423 | .fini = tm6000_audio_fini, | ||
424 | }; | ||
425 | |||
426 | static int __init tm6000_alsa_register(void) | ||
427 | { | ||
428 | return tm6000_register_extension(&audio_ops); | ||
429 | } | ||
430 | |||
431 | static void __exit tm6000_alsa_unregister(void) | ||
432 | { | ||
433 | tm6000_unregister_extension(&audio_ops); | ||
434 | } | ||
435 | |||
436 | module_init(tm6000_alsa_register); | ||
437 | module_exit(tm6000_alsa_unregister); | ||
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index 6143e20d139d..ab12291e0b42 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c | |||
@@ -692,6 +692,10 @@ static int tm6000_init_dev(struct tm6000_core *dev) | |||
692 | if (rc < 0) | 692 | if (rc < 0) |
693 | goto err; | 693 | goto err; |
694 | 694 | ||
695 | tm6000_add_into_devlist(dev); | ||
696 | |||
697 | tm6000_init_extension(dev); | ||
698 | |||
695 | if (dev->caps.has_dvb) { | 699 | if (dev->caps.has_dvb) { |
696 | dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL); | 700 | dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL); |
697 | if (!dev->dvb) { | 701 | if (!dev->dvb) { |
@@ -931,6 +935,9 @@ static void tm6000_usb_disconnect(struct usb_interface *interface) | |||
931 | 935 | ||
932 | usb_put_dev(dev->udev); | 936 | usb_put_dev(dev->udev); |
933 | 937 | ||
938 | tm6000_remove_from_devlist(dev); | ||
939 | tm6000_close_extension(dev); | ||
940 | |||
934 | mutex_unlock(&dev->lock); | 941 | mutex_unlock(&dev->lock); |
935 | kfree(dev); | 942 | kfree(dev); |
936 | } | 943 | } |
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c index bfbc53bd2912..1259ae550547 100644 --- a/drivers/staging/tm6000/tm6000-core.c +++ b/drivers/staging/tm6000/tm6000-core.c | |||
@@ -600,3 +600,95 @@ printk("Original value=%d\n",val); | |||
600 | return val; | 600 | return val; |
601 | } | 601 | } |
602 | EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); | 602 | EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); |
603 | |||
604 | static LIST_HEAD(tm6000_devlist); | ||
605 | static DEFINE_MUTEX(tm6000_devlist_mutex); | ||
606 | |||
607 | /* | ||
608 | * tm6000_realease_resource() | ||
609 | */ | ||
610 | |||
611 | void tm6000_remove_from_devlist(struct tm6000_core *dev) | ||
612 | { | ||
613 | mutex_lock(&tm6000_devlist_mutex); | ||
614 | list_del(&dev->devlist); | ||
615 | mutex_unlock(&tm6000_devlist_mutex); | ||
616 | }; | ||
617 | |||
618 | void tm6000_add_into_devlist(struct tm6000_core *dev) | ||
619 | { | ||
620 | mutex_lock(&tm6000_devlist_mutex); | ||
621 | list_add_tail(&dev->devlist, &tm6000_devlist); | ||
622 | mutex_unlock(&tm6000_devlist_mutex); | ||
623 | }; | ||
624 | |||
625 | /* | ||
626 | * Extension interface | ||
627 | */ | ||
628 | |||
629 | static LIST_HEAD(tm6000_extension_devlist); | ||
630 | static DEFINE_MUTEX(tm6000_extension_devlist_lock); | ||
631 | |||
632 | int tm6000_register_extension(struct tm6000_ops *ops) | ||
633 | { | ||
634 | struct tm6000_core *dev = NULL; | ||
635 | |||
636 | mutex_lock(&tm6000_devlist_mutex); | ||
637 | mutex_lock(&tm6000_extension_devlist_lock); | ||
638 | list_add_tail(&ops->next, &tm6000_extension_devlist); | ||
639 | list_for_each_entry(dev, &tm6000_devlist, devlist) { | ||
640 | if (dev) | ||
641 | ops->init(dev); | ||
642 | } | ||
643 | printk(KERN_INFO "tm6000: Initialized (%s) extension\n", ops->name); | ||
644 | mutex_unlock(&tm6000_extension_devlist_lock); | ||
645 | mutex_unlock(&tm6000_devlist_mutex); | ||
646 | return 0; | ||
647 | } | ||
648 | EXPORT_SYMBOL(tm6000_register_extension); | ||
649 | |||
650 | void tm6000_unregister_extension(struct tm6000_ops *ops) | ||
651 | { | ||
652 | struct tm6000_core *dev = NULL; | ||
653 | |||
654 | mutex_lock(&tm6000_devlist_mutex); | ||
655 | list_for_each_entry(dev, &tm6000_devlist, devlist) { | ||
656 | if (dev) | ||
657 | ops->fini(dev); | ||
658 | } | ||
659 | |||
660 | mutex_lock(&tm6000_extension_devlist_lock); | ||
661 | printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name); | ||
662 | list_del(&ops->next); | ||
663 | mutex_unlock(&tm6000_extension_devlist_lock); | ||
664 | mutex_unlock(&tm6000_devlist_mutex); | ||
665 | } | ||
666 | EXPORT_SYMBOL(tm6000_unregister_extension); | ||
667 | |||
668 | void tm6000_init_extension(struct tm6000_core *dev) | ||
669 | { | ||
670 | struct tm6000_ops *ops = NULL; | ||
671 | |||
672 | mutex_lock(&tm6000_extension_devlist_lock); | ||
673 | if (!list_empty(&tm6000_extension_devlist)) { | ||
674 | list_for_each_entry(ops, &tm6000_extension_devlist, next) { | ||
675 | if (ops->init) | ||
676 | ops->init(dev); | ||
677 | } | ||
678 | } | ||
679 | mutex_unlock(&tm6000_extension_devlist_lock); | ||
680 | } | ||
681 | |||
682 | void tm6000_close_extension(struct tm6000_core *dev) | ||
683 | { | ||
684 | struct tm6000_ops *ops = NULL; | ||
685 | |||
686 | mutex_lock(&tm6000_extension_devlist_lock); | ||
687 | if (!list_empty(&tm6000_extension_devlist)) { | ||
688 | list_for_each_entry(ops, &tm6000_extension_devlist, next) { | ||
689 | if (ops->fini) | ||
690 | ops->fini(dev); | ||
691 | } | ||
692 | } | ||
693 | mutex_unlock(&tm6000_extension_devlist_lock); | ||
694 | } | ||
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h index 6812d6867d57..79ef72a3f431 100644 --- a/drivers/staging/tm6000/tm6000.h +++ b/drivers/staging/tm6000/tm6000.h | |||
@@ -168,6 +168,10 @@ struct tm6000_core { | |||
168 | struct i2c_adapter i2c_adap; | 168 | struct i2c_adapter i2c_adap; |
169 | struct i2c_client i2c_client; | 169 | struct i2c_client i2c_client; |
170 | 170 | ||
171 | |||
172 | /* extension */ | ||
173 | struct list_head devlist; | ||
174 | |||
171 | /* video for linux */ | 175 | /* video for linux */ |
172 | int users; | 176 | int users; |
173 | 177 | ||
@@ -203,6 +207,16 @@ struct tm6000_core { | |||
203 | spinlock_t slock; | 207 | spinlock_t slock; |
204 | }; | 208 | }; |
205 | 209 | ||
210 | #define TM6000_AUDIO 0x10 | ||
211 | |||
212 | struct tm6000_ops { | ||
213 | struct list_head next; | ||
214 | char *name; | ||
215 | int id; | ||
216 | int (*init)(struct tm6000_core *); | ||
217 | int (*fini)(struct tm6000_core *); | ||
218 | }; | ||
219 | |||
206 | struct tm6000_fh { | 220 | struct tm6000_fh { |
207 | struct tm6000_core *dev; | 221 | struct tm6000_core *dev; |
208 | 222 | ||
@@ -246,6 +260,13 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev); | |||
246 | int tm6000_v4l2_exit(void); | 260 | int tm6000_v4l2_exit(void); |
247 | void tm6000_set_fourcc_format(struct tm6000_core *dev); | 261 | void tm6000_set_fourcc_format(struct tm6000_core *dev); |
248 | 262 | ||
263 | void tm6000_remove_from_devlist(struct tm6000_core *dev); | ||
264 | void tm6000_add_into_devlist(struct tm6000_core *dev); | ||
265 | int tm6000_register_extension(struct tm6000_ops *ops); | ||
266 | void tm6000_unregister_extension(struct tm6000_ops *ops); | ||
267 | void tm6000_init_extension(struct tm6000_core *dev); | ||
268 | void tm6000_close_extension(struct tm6000_core *dev); | ||
269 | |||
249 | /* In tm6000-stds.c */ | 270 | /* In tm6000-stds.c */ |
250 | void tm6000_get_std_res(struct tm6000_core *dev); | 271 | void tm6000_get_std_res(struct tm6000_core *dev); |
251 | int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm); | 272 | int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm); |
@@ -275,7 +296,7 @@ unsigned int tm6000_v4l2_poll(struct file *file, | |||
275 | int tm6000_queue_init(struct tm6000_core *dev); | 296 | int tm6000_queue_init(struct tm6000_core *dev); |
276 | 297 | ||
277 | /* In tm6000-alsa.c */ | 298 | /* In tm6000-alsa.c */ |
278 | int tm6000_audio_init(struct tm6000_core *dev, int idx); | 299 | /*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/ |
279 | 300 | ||
280 | 301 | ||
281 | /* Debug stuff */ | 302 | /* Debug stuff */ |