#ifndef __LINUX_TAPI_H__ #define __LINUX_TAPI_H__ #include #include #include #include #include #include #include #include #include #include struct tapi_device; struct tapi_char_device { struct tapi_device *tdev; struct device dev; struct cdev cdev; }; static inline struct tapi_char_device *cdev_to_tapi_char_device(struct cdev *cdev) { return container_of(cdev, struct tapi_char_device, cdev); } int tapi_char_device_register(struct tapi_device *tdev, struct tapi_char_device *tchrdev, const struct file_operations *fops); struct tapi_endpoint { unsigned int id; void *data; }; static inline void tapi_endpoint_set_data(struct tapi_endpoint *ep, void *data) { ep->data = data; } static inline void *tapi_endpoint_get_data(struct tapi_endpoint *ep) { return ep->data; } struct tapi_port { unsigned int id; struct tapi_endpoint ep; struct input_dev *input; struct tapi_char_device chrdev; }; struct tapi_stream { unsigned int id; struct list_head head; struct tapi_endpoint ep; struct sk_buff_head recv_queue; wait_queue_head_t recv_wait; struct sk_buff_head send_queue; }; struct tapi_link { unsigned int id; struct list_head head; }; enum tapi_codec { TAPI_CODEC_L16, }; struct tapi_stream_config { enum tapi_codec codec; unsigned int buffer_size; }; struct tapi_ops { int (*send_dtmf_events)(struct tapi_device *, struct tapi_port *port, struct tapi_dtmf_event *, size_t num_events, unsigned int dealy); int (*send_dtmf_event)(struct tapi_device *, struct tapi_port *port, struct tapi_dtmf_event *); int (*ring)(struct tapi_device *, struct tapi_port *port, bool ring); struct tapi_stream *(*stream_alloc)(struct tapi_device *); void (*stream_free)(struct tapi_device *, struct tapi_stream *); int (*stream_configure)(struct tapi_device *, struct tapi_stream *, struct tapi_stream_config *); int (*stream_start)(struct tapi_device *, struct tapi_stream *); int (*stream_stop)(struct tapi_device *, struct tapi_stream *); int (*stream_send)(struct tapi_device *, struct tapi_stream *, struct sk_buff *); struct tapi_link *(*link_alloc)(struct tapi_device *, struct tapi_endpoint *ep1, struct tapi_endpoint *ep2); void (*link_free)(struct tapi_device *, struct tapi_link *); int (*link_enable)(struct tapi_device *, struct tapi_link *); int (*link_disable)(struct tapi_device *, struct tapi_link *); int (*sync)(struct tapi_device *); }; int tapi_stream_recv(struct tapi_device *, struct tapi_stream *, struct sk_buff *); struct tapi_device { unsigned int id; const struct tapi_ops *ops; unsigned int num_ports; struct device dev; struct mutex lock; struct tapi_port *ports; struct list_head streams; struct list_head links; atomic_t stream_id; atomic_t link_id; struct tapi_char_device stream_dev; struct tapi_char_device control_dev; }; static inline struct tapi_device *dev_to_tapi(struct device *dev) { return container_of(dev, struct tapi_device, dev); } static inline struct tapi_stream *tapi_stream_from_id(struct tapi_device *tdev, unsigned int id) { struct tapi_stream *stream; mutex_lock(&tdev->lock); list_for_each_entry(stream, &tdev->streams, head) { if (stream->id == id) goto out; } stream = NULL; out: mutex_unlock(&tdev->lock); return stream; } struct tapi_link *tapi_link_alloc(struct tapi_device *, struct tapi_endpoint *, struct tapi_endpoint *); void tapi_link_free(struct tapi_device *, struct tapi_link *); struct tapi_stream *tapi_stream_alloc(struct tapi_device *tdev); void tapi_stream_free(struct tapi_device *tdev, struct tapi_stream *stream); static inline int tapi_sync(struct tapi_device *tdev) { if (!tdev->ops || !tdev->ops->sync) return 0; return tdev->ops->sync(tdev); } static inline int tapi_link_enable(struct tapi_device *tdev, struct tapi_link *link) { if (!tdev->ops || !tdev->ops->link_enable) return 0; return tdev->ops->link_enable(tdev, link); } static inline int tapi_link_disable(struct tapi_device *tdev, struct tapi_link *link) { if (!tdev->ops || !tdev->ops->link_disable) return 0; return tdev->ops->link_disable(tdev, link); } static inline int tapi_port_send_dtmf(struct tapi_device *tdev, struct tapi_port *port, struct tapi_dtmf_event *dtmf) { if (!tdev->ops || !tdev->ops->send_dtmf_event) return -ENOSYS; return tdev->ops->send_dtmf_event(tdev, port, dtmf); } static inline int tapi_port_set_ring(struct tapi_device *tdev, struct tapi_port *port, bool ring) { if (!tdev->ops || !tdev->ops->ring) return -ENOSYS; return tdev->ops->ring(tdev, port, ring); } static inline int tapi_stream_start(struct tapi_device *tdev, struct tapi_stream *stream) { if (!tdev->ops || !tdev->ops->stream_start) return -ENOSYS; return tdev->ops->stream_start(tdev, stream); } static inline int tapi_stream_stop(struct tapi_device *tdev, struct tapi_stream *stream) { if (!tdev->ops || !tdev->ops->stream_stop) return -ENOSYS; return tdev->ops->stream_stop(tdev, stream); } int tapi_device_register(struct tapi_device *tdev, const char *name, struct device *parent); void tapi_device_unregister(struct tapi_device *tdev); struct tapi_sysfs_port; struct tapi_sysfs_port *tapi_port_alloc(struct tapi_device *tdev, unsigned int id); void tapi_port_delete(struct tapi_sysfs_port *); #endif