summaryrefslogtreecommitdiff
path: root/xpp/xproto.h
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-02-15 02:26:14 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-02-15 02:26:14 +0000
commita9ababa28c7ccedaf4be1501d009f99d9a7ba580 (patch)
treeb9259934f16b50693c73f9300287a7f92936837c /xpp/xproto.h
parent590e1c07e60d8564388533bb85deee9531df4893 (diff)
Merged revisions 949 via svnmerge from
https://origsvn.digium.com/svn/zaptel/branches/1.2 ........ r949 | kpfleming | 2006-02-14 20:24:18 -0600 (Tue, 14 Feb 2006) | 2 lines initial import of Xorcom Astribank driver (issue #6452, with minor mods) ........ git-svn-id: http://svn.digium.com/svn/zaptel/trunk@950 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/xproto.h')
-rw-r--r--xpp/xproto.h239
1 files changed, 239 insertions, 0 deletions
diff --git a/xpp/xproto.h b/xpp/xproto.h
new file mode 100644
index 0000000..a369a6b
--- /dev/null
+++ b/xpp/xproto.h
@@ -0,0 +1,239 @@
+#ifndef XPROTO_H
+#define XPROTO_H
+/*
+ * Written by Oron Peled <oron@actcom.co.il>
+ * Copyright (C) 2004-2005, Xorcom
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "xdefs.h"
+
+#ifdef __KERNEL__
+#include <linux/list.h>
+#endif
+
+#define XPD_TYPE(n) XPD_TYPE_ ## n
+#define PROTO_TABLE(n) n ## _protocol_table
+
+typedef enum xpd_type {
+ XPD_TYPE(FXO) = 0x02,
+ XPD_TYPE(FXS) = 0x03,
+ XPD_TYPE(NOMODULE) = 0x0F,
+} xpd_type_t;
+
+#define LINE_BITS (sizeof(xpp_line_t)*8)
+#define PCM_CHUNKSIZE (CHANNELS_PERXPD * 8) /* samples of 8 bytes */
+
+typedef struct xpd_addr {
+ byte card_id:4;
+ byte bank_num:4;
+} __attribute__((packed)) xpd_addr_t;
+
+bool valid_xpd_addr(const xpd_addr_t *addr);
+int xpd_addr2num(const xpd_addr_t *addr);
+void xpd_set_addr(xpd_addr_t *addr, int xpd_num);
+
+#define XPD_NUM(x) xpd_addr2num(&x)
+#define XPD_ADDR_SET(x,val) xpd_set_addr(&x, val)
+#define MAX_XPACKET_DATALEN 100
+
+#define XPROTO_NAME(card,op) card ## _ ## op
+#define XPROTO_HANDLER(card,op) XPROTO_NAME(card,op ## _handler)
+#define XPROTO_CALLER(card,op) XPROTO_NAME(card,op ## _send)
+
+#define HANDLER_DEF(card,op) \
+ int XPROTO_HANDLER(card,op) ( \
+ xbus_t *xbus, \
+ xpd_t *xpd, \
+ const xproto_entry_t *cmd, \
+ xpacket_t *pack)
+
+#define CALL_PROTO(card,op, ...) XPROTO_CALLER(card,op)( __VA_ARGS__ )
+
+#define DECLARE_CMD(card,op, ...) \
+ int CALL_PROTO(card, op, xbus_t *xbus, xpd_t *xpd, ## __VA_ARGS__ )
+
+#define HOSTCMD(card, op, ...) \
+ DECLARE_CMD(card, op, ## __VA_ARGS__ ); \
+ EXPORT_SYMBOL(XPROTO_CALLER(card, op)); \
+ DECLARE_CMD(card, op, ## __VA_ARGS__ )
+
+#define RPACKET_NAME(card,op) XPROTO_NAME(RPACKET_ ## card, op)
+#define RPACKET_TYPE(card,op) struct RPACKET_NAME(card, op)
+
+#define DEF_RPACKET_DATA(card,op, ...) \
+ struct RPACKET_NAME(card,op) { \
+ byte opcode; \
+ xpd_addr_t addr; \
+ __VA_ARGS__ \
+ } __attribute__((packed))
+
+#define RPACKET_CAST(p,card,op) ((RPACKET_TYPE(card,op) *)p)
+#define RPACKET_FIELD(p,card,op,field) (RPACKET_CAST(p,card,op)->field)
+#define RPACKET_SIZE(card,op) sizeof(RPACKET_TYPE(card,op))
+
+#define PACKET_LEN(p) \
+ ((p)->datalen + sizeof(xpd_addr_t) + 1)
+
+#define XENTRY(card,op) \
+ [ XPROTO_NAME(card,op) ] { \
+ .handler = XPROTO_HANDLER(card,op), \
+ .datalen = RPACKET_SIZE(card,op), \
+ .name = #op, \
+ .table = &PROTO_TABLE(card) \
+ }
+
+
+#define XPACKET_INIT(p, card, op) \
+ do { \
+ p->content.opcode = XPROTO_NAME(card,op); \
+ p->datalen = RPACKET_SIZE(card,op); \
+ } while(0)
+
+#define XPACKET_NEW(p, xbus, card, op, to) \
+ do { \
+ p = xbus->ops->packet_new(xbus, GFP_ATOMIC); \
+ if(!p) \
+ return -ENOMEM; \
+ XPACKET_INIT(p, card, op); \
+ XPD_ADDR_SET(p->content.addr, to); \
+ } while(0);
+
+typedef struct xproto_entry xproto_entry_t;
+typedef struct xproto_table xproto_table_t;
+
+typedef int (*xproto_handler_t)(
+ xbus_t *xbus,
+ xpd_t *xpd,
+ const xproto_entry_t *cmd,
+ xpacket_t *pack);
+
+const xproto_entry_t *find_xproto_entry(xpd_t *xpd, byte opcode);
+
+const xproto_table_t *get_xproto_table(xpd_type_t cardtype);
+const xproto_entry_t *xproto_card_entry(const xproto_table_t *table, byte opcode);
+const xproto_handler_t xproto_card_handler(const xproto_table_t *table, byte opcode);
+
+const xproto_entry_t *xproto_global_entry(byte opcode);
+const xproto_handler_t xproto_global_handler(byte opcode);
+
+#define CALL_XMETHOD(name, xbus, xpd, ...) \
+ (xpd)->xops->name(xbus, xpd, ## __VA_ARGS__ )
+
+struct xops {
+ xpd_t *(*card_new)(xbus_t *xbus, int xpd_num, const xproto_table_t *proto_table, byte revision);
+ int (*card_init)(xbus_t *xbus, xpd_t *xpd);
+ int (*card_remove)(xbus_t *xbus, xpd_t *xpd);
+ int (*card_tick)(xbus_t *xbus, xpd_t *xpd);
+
+ int (*SYNC_SOURCE)(xbus_t *xbus, xpd_t *xpd, bool setit, bool is_master);
+ int (*PCM_WRITE)(xbus_t *xbus, xpd_t *xpd, xpp_line_t hookstate, volatile byte *buf);
+
+ int (*CHAN_ENABLE)(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on);
+ int (*CHAN_POWER)(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on);
+ int (*CHAN_CID)(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines);
+ int (*RING)(xbus_t *xbus, xpd_t *xpd, int pos, bool on);
+ int (*SETHOOK)(xbus_t *xbus, xpd_t *xpd, xpp_line_t hook_status);
+ int (*LED)(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, byte which, bool on);
+ int (*RELAY_OUT)(xbus_t *xbus, xpd_t *xpd, byte which, bool on);
+};
+
+const xops_t *get_xops(xpd_type_t xpd_type);
+
+#undef XMETHOD
+
+struct xproto_entry {
+ xproto_handler_t handler;
+ int datalen;
+ const char *name;
+ xproto_table_t *table;
+};
+
+struct xproto_table {
+ xproto_entry_t entries[255]; /* Indexed by opcode */
+ xops_t xops;
+ xpd_type_t type;
+ const char *name;
+ bool (*packet_is_valid)(xpacket_t *pack);
+ void (*packet_dump)(xpacket_t *pack);
+};
+
+#include "card_global.h"
+#include "card_fxs.h"
+
+enum opcodes {
+ XPROTO_NAME(GLOBAL, DESC_REQ) = 0x04,
+ XPROTO_NAME(GLOBAL, DEV_DESC) = 0x05,
+/**/
+ XPROTO_NAME(GLOBAL, PCM_WRITE) = 0x11,
+ XPROTO_NAME(GLOBAL, PCM_READ) = 0x12,
+/**/
+ XPROTO_NAME(GLOBAL, SYNC_SOURCE) = 0x19,
+ XPROTO_NAME(GLOBAL, SYNC_REPLY) = 0x1A,
+
+ XPROTO_NAME(FXS, SIG_CHANGED) = 0x06,
+/**/
+ XPROTO_NAME(FXS, SLIC_WRITE) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, CHAN_ENABLE) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, CHAN_POWER) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, CHAN_CID) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, RING) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, SETHOOK) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, LED) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, RELAY_OUT) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, SLIC_INIT) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, SLIC_QUERY) = 0x0F, /* Write to SLIC */
+/**/
+ XPROTO_NAME(FXS, SLIC_REPLY) = 0x10,
+};
+
+
+#define MEMBER(card,op) RPACKET_TYPE(card,op) RPACKET_NAME(card,op)
+
+struct xpacket_raw {
+ byte opcode;
+ xpd_addr_t addr;
+ union {
+ MEMBER(GLOBAL, DESC_REQ);
+ MEMBER(GLOBAL, DEV_DESC);
+ MEMBER(GLOBAL, PCM_WRITE);
+ MEMBER(GLOBAL, PCM_READ);
+ MEMBER(GLOBAL, SYNC_REPLY);
+
+ MEMBER(FXS, SIG_CHANGED);
+ MEMBER(FXS, SLIC_REPLY);
+
+ byte data[0];
+ };
+} __attribute__((packed));
+
+struct xpacket {
+ xpacket_raw_t content;
+ size_t datalen;
+ struct list_head list;
+};
+
+void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg);
+int packet_receive(xbus_t *xbus, xpacket_t *pack);
+int xproto_register(const xproto_table_t *proto_table);
+void xproto_unregister(const xproto_table_t *proto_table);
+const xproto_entry_t *xproto_global_entry(byte opcode);
+const char *xproto_name(xpd_type_t xpd_type);
+
+#endif /* XPROTO_H */