V4L/DVB: tm6000: add extension module support
authorStefan Ringel <stefan.ringel@arcor.de>
Mon, 10 May 2010 16:22:51 +0000 (13:22 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 1 Jun 2010 04:21:54 +0000 (01:21 -0300)
add module init over tm6000 extension

Signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/staging/tm6000/tm6000-alsa.c
drivers/staging/tm6000/tm6000-cards.c
drivers/staging/tm6000/tm6000-core.c
drivers/staging/tm6000/tm6000.h

index bc89f9d..ce081cd 100644 (file)
@@ -410,5 +410,28 @@ error:
        snd_card_free(card);
        return rc;
 }
-EXPORT_SYMBOL_GPL(tm6000_audio_init);
 
+static int tm6000_audio_fini(struct tm6000_core *dev)
+{
+       return 0;
+}
+
+struct tm6000_ops audio_ops = {
+       .id     = TM6000_AUDIO,
+       .name   = "TM6000 Audio Extension",
+       .init   = tm6000_audio_init,
+       .fini   = tm6000_audio_fini,
+};
+
+static int __init tm6000_alsa_register(void)
+{
+       return tm6000_register_extension(&audio_ops);
+}
+
+static void __exit tm6000_alsa_unregister(void)
+{
+       tm6000_unregister_extension(&audio_ops);
+}
+
+module_init(tm6000_alsa_register);
+module_exit(tm6000_alsa_unregister);
index 6143e20..ab12291 100644 (file)
@@ -692,6 +692,10 @@ static int tm6000_init_dev(struct tm6000_core *dev)
        if (rc < 0)
                goto err;
 
+       tm6000_add_into_devlist(dev);
+
+       tm6000_init_extension(dev);
+
        if (dev->caps.has_dvb) {
                dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL);
                if (!dev->dvb) {
@@ -931,6 +935,9 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
 
        usb_put_dev(dev->udev);
 
+       tm6000_remove_from_devlist(dev);
+       tm6000_close_extension(dev);
+
        mutex_unlock(&dev->lock);
        kfree(dev);
 }
index bfbc53b..1259ae5 100644 (file)
@@ -600,3 +600,95 @@ printk("Original value=%d\n",val);
        return val;
 }
 EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
+
+static LIST_HEAD(tm6000_devlist);
+static DEFINE_MUTEX(tm6000_devlist_mutex);
+
+/*
+ * tm6000_realease_resource()
+ */
+
+void tm6000_remove_from_devlist(struct tm6000_core *dev)
+{
+       mutex_lock(&tm6000_devlist_mutex);
+       list_del(&dev->devlist);
+       mutex_unlock(&tm6000_devlist_mutex);
+};
+
+void tm6000_add_into_devlist(struct tm6000_core *dev)
+{
+       mutex_lock(&tm6000_devlist_mutex);
+       list_add_tail(&dev->devlist, &tm6000_devlist);
+       mutex_unlock(&tm6000_devlist_mutex);
+};
+
+/*
+ * Extension interface
+ */
+
+static LIST_HEAD(tm6000_extension_devlist);
+static DEFINE_MUTEX(tm6000_extension_devlist_lock);
+
+int tm6000_register_extension(struct tm6000_ops *ops)
+{
+       struct tm6000_core *dev = NULL;
+
+       mutex_lock(&tm6000_devlist_mutex);
+       mutex_lock(&tm6000_extension_devlist_lock);
+       list_add_tail(&ops->next, &tm6000_extension_devlist);
+       list_for_each_entry(dev, &tm6000_devlist, devlist) {
+               if (dev)
+                       ops->init(dev);
+       }
+       printk(KERN_INFO "tm6000: Initialized (%s) extension\n", ops->name);
+       mutex_unlock(&tm6000_extension_devlist_lock);
+       mutex_unlock(&tm6000_devlist_mutex);
+       return 0;
+}
+EXPORT_SYMBOL(tm6000_register_extension);
+
+void tm6000_unregister_extension(struct tm6000_ops *ops)
+{
+       struct tm6000_core *dev = NULL;
+
+       mutex_lock(&tm6000_devlist_mutex);
+       list_for_each_entry(dev, &tm6000_devlist, devlist) {
+               if (dev)
+                       ops->fini(dev);
+       }
+
+       mutex_lock(&tm6000_extension_devlist_lock);
+       printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name);
+       list_del(&ops->next);
+       mutex_unlock(&tm6000_extension_devlist_lock);
+       mutex_unlock(&tm6000_devlist_mutex);
+}
+EXPORT_SYMBOL(tm6000_unregister_extension);
+
+void tm6000_init_extension(struct tm6000_core *dev)
+{
+       struct tm6000_ops *ops = NULL;
+
+       mutex_lock(&tm6000_extension_devlist_lock);
+       if (!list_empty(&tm6000_extension_devlist)) {
+               list_for_each_entry(ops, &tm6000_extension_devlist, next) {
+                       if (ops->init)
+                               ops->init(dev);
+               }
+       }
+       mutex_unlock(&tm6000_extension_devlist_lock);
+}
+
+void tm6000_close_extension(struct tm6000_core *dev)
+{
+       struct tm6000_ops *ops = NULL;
+
+       mutex_lock(&tm6000_extension_devlist_lock);
+       if (!list_empty(&tm6000_extension_devlist)) {
+               list_for_each_entry(ops, &tm6000_extension_devlist, next) {
+                       if (ops->fini)
+                               ops->fini(dev);
+               }
+       }
+       mutex_unlock(&tm6000_extension_devlist_lock);
+}
index 6812d68..79ef72a 100644 (file)
@@ -168,6 +168,10 @@ struct tm6000_core {
        struct i2c_adapter              i2c_adap;
        struct i2c_client               i2c_client;
 
+
+       /* extension */
+       struct list_head                devlist;
+
        /* video for linux */
        int                             users;
 
@@ -203,6 +207,16 @@ struct tm6000_core {
        spinlock_t                   slock;
 };
 
+#define TM6000_AUDIO 0x10
+
+struct tm6000_ops {
+       struct list_head        next;
+       char                    *name;
+       int                     id;
+       int (*init)(struct tm6000_core *);
+       int (*fini)(struct tm6000_core *);
+};
+
 struct tm6000_fh {
        struct tm6000_core           *dev;
 
@@ -246,6 +260,13 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev);
 int tm6000_v4l2_exit(void);
 void tm6000_set_fourcc_format(struct tm6000_core *dev);
 
+void tm6000_remove_from_devlist(struct tm6000_core *dev);
+void tm6000_add_into_devlist(struct tm6000_core *dev);
+int tm6000_register_extension(struct tm6000_ops *ops);
+void tm6000_unregister_extension(struct tm6000_ops *ops);
+void tm6000_init_extension(struct tm6000_core *dev);
+void tm6000_close_extension(struct tm6000_core *dev);
+
 /* In tm6000-stds.c */
 void tm6000_get_std_res(struct tm6000_core *dev);
 int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm);
@@ -275,7 +296,7 @@ unsigned int tm6000_v4l2_poll(struct file *file,
 int tm6000_queue_init(struct tm6000_core *dev);
 
 /* In tm6000-alsa.c */
-int tm6000_audio_init(struct tm6000_core *dev, int idx);
+/*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/
 
 
 /* Debug stuff */