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>
This commit is contained in:
Stefan Ringel 2010-05-10 13:22:51 -03:00 committed by Mauro Carvalho Chehab
parent 9e1d9e7bac
commit 0439db75c1
4 changed files with 145 additions and 2 deletions

View File

@ -410,5 +410,28 @@ int tm6000_audio_init(struct tm6000_core *dev, int idx)
snd_card_free(card); snd_card_free(card);
return rc; 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);

View File

@ -692,6 +692,10 @@ static int tm6000_init_dev(struct tm6000_core *dev)
if (rc < 0) if (rc < 0)
goto err; goto err;
tm6000_add_into_devlist(dev);
tm6000_init_extension(dev);
if (dev->caps.has_dvb) { if (dev->caps.has_dvb) {
dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL); dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL);
if (!dev->dvb) { if (!dev->dvb) {
@ -931,6 +935,9 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
usb_put_dev(dev->udev); usb_put_dev(dev->udev);
tm6000_remove_from_devlist(dev);
tm6000_close_extension(dev);
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
kfree(dev); kfree(dev);
} }

View File

@ -600,3 +600,95 @@ printk("Original value=%d\n",val);
return val; return val;
} }
EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); 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);
}

View File

@ -168,6 +168,10 @@ struct tm6000_core {
struct i2c_adapter i2c_adap; struct i2c_adapter i2c_adap;
struct i2c_client i2c_client; struct i2c_client i2c_client;
/* extension */
struct list_head devlist;
/* video for linux */ /* video for linux */
int users; int users;
@ -203,6 +207,16 @@ struct tm6000_core {
spinlock_t slock; 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_fh {
struct tm6000_core *dev; struct tm6000_core *dev;
@ -246,6 +260,13 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev);
int tm6000_v4l2_exit(void); int tm6000_v4l2_exit(void);
void tm6000_set_fourcc_format(struct tm6000_core *dev); 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 */ /* In tm6000-stds.c */
void tm6000_get_std_res(struct tm6000_core *dev); void tm6000_get_std_res(struct tm6000_core *dev);
int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm); 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); int tm6000_queue_init(struct tm6000_core *dev);
/* In tm6000-alsa.c */ /* 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 */ /* Debug stuff */