1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/device.h>
4 #include <linux/list.h>
6 #include <linux/cdev.h>
9 #include <linux/tapi/tapi.h>
12 void tapi_alloc_input(struct tapi_device
*tdev
, struct tapi_port
*port
);
13 int tapi_register_port_device(struct tapi_device
* tdev
, struct tapi_port
*port
);
14 int tapi_register_stream_device(struct tapi_device
* tdev
);
15 int tapi_register_control_device(struct tapi_device
* tdev
);
17 static struct class *tapi_class
;
18 static int tapi_major
;
20 #define TAPI_MAX_MINORS 255
22 static bool tapi_minors
[TAPI_MAX_MINORS
];
24 static int tapi_get_free_minor(void)
27 for (i
= 0; i
< TAPI_MAX_MINORS
; ++i
) {
28 if (!tapi_minors
[i
]) {
29 tapi_minors
[i
] = true;
38 int tapi_port_send_dtmf_events(struct tapi_device *tdev, unsigned int port, struct tapi_dtmf *, size_t num_events, unsigned int dealy)
41 EXPORT_SYMBOL_GPL(tapi_port_send_dtmf_events);
44 void tapi_report_hook_event(struct tapi_device
*tdev
, struct tapi_port
*port
,
47 struct tapi_event event
;
48 event
.type
= TAPI_EVENT_TYPE_HOOK
;
49 event
.port
= port
->id
;
52 tapi_report_event(tdev
, &event
);
54 EXPORT_SYMBOL_GPL(tapi_report_hook_event
);
56 void tapi_report_dtmf_event(struct tapi_device
*tdev
, struct tapi_port
*port
,
59 struct tapi_event event
;
60 event
.type
= TAPI_EVENT_TYPE_DTMF
;
61 event
.port
= port
->id
;
62 event
.dtmf
.code
= code
;
64 tapi_report_event(tdev
, &event
);
66 EXPORT_SYMBOL_GPL(tapi_report_dtmf_event
);
68 struct tapi_stream
*tapi_stream_alloc(struct tapi_device
*tdev
)
70 struct tapi_stream
*stream
;
71 printk("tdev %p\n", tdev
);
73 if (!tdev
->ops
|| !tdev
->ops
->stream_alloc
)
74 return ERR_PTR(-ENOSYS
);
76 stream
= tdev
->ops
->stream_alloc(tdev
);
77 printk("stream %p\n", stream
);
81 stream
->id
= atomic_inc_return(&tdev
->stream_id
) - 1;
82 stream
->ep
.id
= stream
->id
;
84 /* mutex_lock(&tdev->lock);*/
85 list_add_tail(&stream
->head
, &tdev
->streams
);
86 /* mutex_unlock(&tdev->lock);*/
90 EXPORT_SYMBOL_GPL(tapi_stream_alloc
);
92 void tapi_stream_free(struct tapi_device
*tdev
, struct tapi_stream
*stream
)
94 mutex_lock(&tdev
->lock
);
95 list_del(&stream
->head
);
96 mutex_unlock(&tdev
->lock
);
98 tdev
->ops
->stream_free(tdev
, stream
);
100 EXPORT_SYMBOL_GPL(tapi_stream_free
);
102 struct tapi_link
*tapi_link_alloc(struct tapi_device
*tdev
,
103 struct tapi_endpoint
*ep1
, struct tapi_endpoint
*ep2
)
105 struct tapi_link
*link
;
107 if (!tdev
->ops
|| !tdev
->ops
->link_alloc
)
108 return ERR_PTR(-ENOSYS
);
110 link
= tdev
->ops
->link_alloc(tdev
, ep1
, ep2
);
114 link
->id
= atomic_inc_return(&tdev
->link_id
) - 1;
117 mutex_lock(&tdev->lock);
118 list_add_tail(&link->head, &tdev->links);
119 mutex_unlock(&tdev->lock);
123 EXPORT_SYMBOL_GPL(tapi_link_alloc
);
125 void tapi_link_free(struct tapi_device
*tdev
, struct tapi_link
*link
)
128 mutex_lock(&tdev->lock);
129 list_del(&link->head);
130 mutex_unlock(&tdev->lock);
132 tdev
->ops
->link_free(tdev
, link
);
134 EXPORT_SYMBOL_GPL(tapi_link_free
);
136 int tapi_char_device_register(struct tapi_device
*tdev
,
137 struct tapi_char_device
*tchrdev
, const struct file_operations
*fops
)
140 struct device
*dev
= &tchrdev
->dev
;
142 int minor
= tapi_get_free_minor();
144 devt
= MKDEV(tapi_major
, minor
);
147 dev
->class = tapi_class
;
148 dev
->parent
= &tdev
->dev
;
150 tchrdev
->tdev
= tdev
;
152 cdev_init(&tchrdev
->cdev
, fops
);
153 tchrdev
->cdev
.owner
= THIS_MODULE
;
154 ret
= cdev_add(&tchrdev
->cdev
, devt
, 1);
158 ret
= device_register(&tchrdev
->dev
);
165 cdev_del(&tchrdev
->cdev
);
170 int tapi_device_register(struct tapi_device
*tdev
, const char *name
,
171 struct device
*parent
)
173 static atomic_t tapi_device_id
= ATOMIC_INIT(0);
176 tdev
->dev
.class = tapi_class
;
177 tdev
->dev
.parent
= parent
;
178 dev_set_name(&tdev
->dev
, "%s", name
);
180 ret
= device_register(&tdev
->dev
);
184 tdev
->id
= atomic_inc_return(&tapi_device_id
) - 1;
186 mutex_init(&tdev
->lock
);
187 INIT_LIST_HEAD(&tdev
->streams
);
188 INIT_LIST_HEAD(&tdev
->links
);
189 atomic_set(&tdev
->link_id
, 0);
190 atomic_set(&tdev
->stream_id
, tdev
->num_ports
);
192 tapi_register_stream_device(tdev
);
193 tapi_register_control_device(tdev
);
195 for (i
= 0; i
< tdev
->num_ports
; ++i
) {
196 tapi_port_alloc(tdev
, i
);
197 tapi_alloc_input(tdev
, &tdev
->ports
[i
]);
198 tapi_register_port_device(tdev
, &tdev
->ports
[i
]);
199 tdev
->ports
[i
].id
= i
;
200 tdev
->ports
[i
].ep
.id
= i
;
205 EXPORT_SYMBOL_GPL(tapi_device_register
);
207 void tapi_device_unregister(struct tapi_device
*tdev
)
209 device_unregister(&tdev
->dev
);
211 EXPORT_SYMBOL_GPL(tapi_device_unregister
);
213 static int __init
tapi_class_init(void)
218 tapi_class
= class_create(THIS_MODULE
, "tapi");
220 if (IS_ERR(tapi_class
)) {
221 ret
= PTR_ERR(tapi_class
);
222 printk(KERN_ERR
"tapi: Failed to create device class: %d\n", ret
);
226 ret
= alloc_chrdev_region(&dev
, 0, TAPI_MAX_MINORS
, "tapi");
228 printk(KERN_ERR
"tapi: Failed to allocate chrdev region: %d\n", ret
);
229 goto err_class_destory
;
231 tapi_major
= MAJOR(dev
);
235 class_destroy(tapi_class
);
239 subsys_initcall(tapi_class_init
);
241 static void __exit
tapi_class_exit(void)
243 unregister_chrdev_region(MKDEV(tapi_major
, 0), TAPI_MAX_MINORS
);
244 class_destroy(tapi_class
);
246 module_exit(tapi_class_exit
);
248 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
249 MODULE_DESCRIPTION("TAPI class");
250 MODULE_LICENSE("GPL");
This page took 0.055671 seconds and 5 git commands to generate.