diff options
author | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-02-15 02:26:14 +0000 |
---|---|---|
committer | kpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2006-02-15 02:26:14 +0000 |
commit | a9ababa28c7ccedaf4be1501d009f99d9a7ba580 (patch) | |
tree | b9259934f16b50693c73f9300287a7f92936837c /xpp/xproto.h | |
parent | 590e1c07e60d8564388533bb85deee9531df4893 (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.h | 239 |
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 */ |