diff options
author | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-01-31 17:27:30 +0000 |
---|---|---|
committer | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2007-01-31 17:27:30 +0000 |
commit | 92e6d005b1107055cdd62f41fc06bda8e98b14b3 (patch) | |
tree | 530476168181ed67fa632f008cca8ac1040eef0a /zaptel.c | |
parent | ec54d1fb2b09fc3a4027a58317d190a403b148eb (diff) |
merge support for the Digium TC400B hardware transcoder
git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@2057 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'zaptel.c')
-rw-r--r-- | zaptel.c | 52 |
1 files changed, 50 insertions, 2 deletions
@@ -79,6 +79,7 @@ #define FAST_HDLC_NEED_TABLES #include "fasthdlc.h" +#include <linux/types.h> #ifdef STANDALONE_ZAPATA #include "zaptel.h" #else @@ -118,6 +119,7 @@ static char *zt_txlevelnames[] = { "-22.5db (CSU)" } ; +EXPORT_SYMBOL(zt_transcode_fops); EXPORT_SYMBOL(zt_init_tone_state); EXPORT_SYMBOL(zt_dtmf_tone); EXPORT_SYMBOL(zt_register); @@ -154,6 +156,7 @@ static devfs_handle_t channel; static devfs_handle_t pseudo; static devfs_handle_t ctl; static devfs_handle_t timer; +static devfs_handle_t transcode; #endif /* udev necessary data structures. Yeah! */ @@ -249,6 +252,7 @@ static sumtype *conf_sums_prev; static struct zt_span *master; static struct file_operations zt_fops; +struct file_operations *zt_transcode_fops = NULL; static struct { @@ -2316,10 +2320,26 @@ static void zt_free_pseudo(struct zt_chan *pseudo) static int zt_open(struct inode *inode, struct file *file) { int unit = UNIT(file); + int ret = -ENXIO; struct zt_chan *chan; /* Minor 0: Special "control" descriptor */ if (!unit) return zt_ctl_open(inode, file); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (unit == 250) { + if (!zt_transcode_fops) + request_module("zttranscode"); + if (zt_transcode_fops && zt_transcode_fops->open) { + if (try_module_get(zt_transcode_fops->owner)) { + ret = zt_transcode_fops->open(inode, file); + if (ret) + module_put(zt_transcode_fops->owner); + } + return ret; + } + return -ENXIO; + } +#endif if (unit == 253) { if (maxspans) { return zt_timing_open(inode, file); @@ -2644,6 +2664,13 @@ static int zt_release(struct inode *inode, struct file *file) if (unit == 253) { return zt_timer_release(inode, file); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (unit == 250) { + res = zt_transcode_fops->release(inode, file); + module_put(zt_transcode_fops->owner); + return res; + } +#endif if (unit == 254) { chan = file->private_data; if (!chan) @@ -4395,6 +4422,10 @@ static int zt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un if (!unit) return zt_ctl_ioctl(inode, file, cmd, data); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (unit == 250) + return zt_transcode_fops->ioctl(inode, file, cmd, data); +#endif if (unit == 253) { timer = file->private_data; if (timer) @@ -6097,6 +6128,16 @@ zt_chan_poll(struct file *file, struct poll_table_struct *wait_table, int unit) return(ret); /* return what we found */ } +static int zt_mmap(struct file *file, struct vm_area_struct *vm) +{ + int unit = UNIT(file); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (unit == 250) + return zt_transcode_fops->mmap(file, vm); +#endif + return -ENOSYS; +} + static unsigned int zt_poll(struct file *file, struct poll_table_struct *wait_table) { int unit = UNIT(file); @@ -6104,7 +6145,10 @@ static unsigned int zt_poll(struct file *file, struct poll_table_struct *wait_ta if (!unit) return -EINVAL; - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (unit == 250) + return zt_transcode_fops->poll(file, wait_table); +#endif if (unit == 253) return zt_timer_poll(file, wait_table); @@ -6480,7 +6524,7 @@ static struct file_operations zt_fops = { read: zt_read, write: zt_write, poll: zt_poll, - mmap: NULL, + mmap: zt_mmap, flush: NULL, fsync: NULL, fasync: NULL, @@ -6555,6 +6599,7 @@ static int __init zt_init(void) { #ifdef CONFIG_ZAP_UDEV /* udev support functions */ zap_class = class_create(THIS_MODULE, "zaptel"); + CLASS_DEV_CREATE(zap_class, MKDEV(ZT_MAJOR, 250), NULL, "zaptranscode"); CLASS_DEV_CREATE(zap_class, MKDEV(ZT_MAJOR, 253), NULL, "zaptimer"); CLASS_DEV_CREATE(zap_class, MKDEV(ZT_MAJOR, 254), NULL, "zapchannel"); CLASS_DEV_CREATE(zap_class, MKDEV(ZT_MAJOR, 255), NULL, "zappseudo"); @@ -6567,6 +6612,7 @@ static int __init zt_init(void) { devfs_register_chrdev(ZT_MAJOR, "zaptel", &zt_fops); zaptel_devfs_dir = devfs_mk_dir(NULL, "zap", NULL); if (!zaptel_devfs_dir) return -EBUSY; /* This would be bad */ + transcode = devfs_register(zaptel_devfs_dir, "transcode", DEVFS_FL_DEFAULT, ZT_MAJOR, 250, mode, &zt_fops, NULL); timer = devfs_register(zaptel_devfs_dir, "timer", DEVFS_FL_DEFAULT, ZT_MAJOR, 253, mode, &zt_fops, NULL); channel = devfs_register(zaptel_devfs_dir, "channel", DEVFS_FL_DEFAULT, ZT_MAJOR, 254, mode, &zt_fops, NULL); pseudo = devfs_register(zaptel_devfs_dir, "pseudo", DEVFS_FL_DEFAULT, ZT_MAJOR, 255, mode, &zt_fops, NULL); @@ -6606,6 +6652,7 @@ static void __exit zt_cleanup(void) { kfree(tone_zones[x]); #ifdef CONFIG_DEVFS_FS devfs_unregister(timer); + devfs_unregister(transcode); devfs_unregister(channel); devfs_unregister(pseudo); devfs_unregister(ctl); @@ -6614,6 +6661,7 @@ static void __exit zt_cleanup(void) { #else #ifdef CONFIG_ZAP_UDEV class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 253)); /* timer */ + class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 250)); /* transcode */ class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 254)); /* channel */ class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 255)); /* pseudo */ class_device_destroy(zap_class, MKDEV(ZT_MAJOR, 0)); /* ctl */ |