xpp: refactor struct reg_cmd
Currently we only have REG (register) commands. Refactor it to allow MEM (memory) commands. * A common header * Don't assume a constant size. Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
This commit is contained in:
parent
d9aa82b025
commit
1c68f2ec73
@ -467,8 +467,8 @@ static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
src = REG_XDATA(regcmd);
|
src = REG_XDATA(regcmd);
|
||||||
len = regcmd->bytes;
|
len = regcmd->h.bytes;
|
||||||
eoframe = regcmd->eoframe;
|
eoframe = regcmd->h.eoframe;
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (!SPAN_REGISTERED(xpd)) /* Nowhere to copy data */
|
if (!SPAN_REGISTERED(xpd)) /* Nowhere to copy data */
|
||||||
@ -566,10 +566,10 @@ static void fill_multibyte(xpd_t *xpd, xpacket_t *pack,
|
|||||||
XPACKET_INIT(pack, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx, 0, 0);
|
XPACKET_INIT(pack, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx, 0, 0);
|
||||||
XPACKET_LEN(pack) = RPACKET_SIZE(GLOBAL, REGISTER_REQUEST);
|
XPACKET_LEN(pack) = RPACKET_SIZE(GLOBAL, REGISTER_REQUEST);
|
||||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||||
reg_cmd->bytes = len;
|
reg_cmd->h.bytes = len;
|
||||||
reg_cmd->is_multibyte = 1;
|
reg_cmd->h.is_multibyte = 1;
|
||||||
reg_cmd->portnum = xpd->addr.subunit;
|
reg_cmd->h.portnum = xpd->addr.subunit;
|
||||||
reg_cmd->eoframe = eoframe;
|
reg_cmd->h.eoframe = eoframe;
|
||||||
p = REG_XDATA(reg_cmd);
|
p = REG_XDATA(reg_cmd);
|
||||||
memcpy(p, buf, len);
|
memcpy(p, buf, len);
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -1537,7 +1537,7 @@ static int BRI_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
/* Map UNIT + PORTNUM to XPD */
|
/* Map UNIT + PORTNUM to XPD */
|
||||||
orig_xpd = xpd;
|
orig_xpd = xpd;
|
||||||
addr.unit = orig_xpd->addr.unit;
|
addr.unit = orig_xpd->addr.unit;
|
||||||
addr.subunit = info->portnum;
|
addr.subunit = info->h.portnum;
|
||||||
xpd = xpd_byaddr(xbus, addr.unit, addr.subunit);
|
xpd = xpd_byaddr(xbus, addr.unit, addr.subunit);
|
||||||
if (!xpd) {
|
if (!xpd) {
|
||||||
static int rate_limit;
|
static int rate_limit;
|
||||||
@ -1562,9 +1562,9 @@ static int BRI_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
XPD_DBG(REGS, xpd, "Got SU_RD_STA=%02X\n",
|
XPD_DBG(REGS, xpd, "Got SU_RD_STA=%02X\n",
|
||||||
REG_FIELD(info, data_low));
|
REG_FIELD(info, data_low));
|
||||||
}
|
}
|
||||||
if (info->is_multibyte) {
|
if (info->h.is_multibyte) {
|
||||||
XPD_DBG(REGS, xpd, "Got Multibyte: %d bytes, eoframe: %d\n",
|
XPD_DBG(REGS, xpd, "Got Multibyte: %d bytes, eoframe: %d\n",
|
||||||
info->bytes, info->eoframe);
|
info->h.bytes, info->h.eoframe);
|
||||||
ret = rx_dchan(xpd, info);
|
ret = rx_dchan(xpd, info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
priv->dchan_rx_drops++;
|
priv->dchan_rx_drops++;
|
||||||
|
@ -112,7 +112,7 @@ static int ECHO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
/* Map UNIT + PORTNUM to XPD */
|
/* Map UNIT + PORTNUM to XPD */
|
||||||
orig_xpd = xpd;
|
orig_xpd = xpd;
|
||||||
addr.unit = orig_xpd->addr.unit;
|
addr.unit = orig_xpd->addr.unit;
|
||||||
addr.subunit = info->portnum;
|
addr.subunit = info->h.portnum;
|
||||||
xpd = xpd_byaddr(xbus, addr.unit, addr.subunit);
|
xpd = xpd_byaddr(xbus, addr.unit, addr.subunit);
|
||||||
if (!xpd) {
|
if (!xpd) {
|
||||||
static int rate_limit;
|
static int rate_limit;
|
||||||
|
@ -1246,7 +1246,7 @@ static int FXO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
|
|
||||||
priv = xpd->priv;
|
priv = xpd->priv;
|
||||||
BUG_ON(!priv);
|
BUG_ON(!priv);
|
||||||
portno = info->portnum;
|
portno = info->h.portnum;
|
||||||
switch (REG_FIELD(info, regnum)) {
|
switch (REG_FIELD(info, regnum)) {
|
||||||
case REG_INTERRUPT_SRC:
|
case REG_INTERRUPT_SRC:
|
||||||
got_chip_interrupt(xpd, REG_FIELD(info, data_low), portno);
|
got_chip_interrupt(xpd, REG_FIELD(info, data_low), portno);
|
||||||
@ -1264,7 +1264,7 @@ static int FXO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
LINE_DBG(REGS, xpd, portno, "%c reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
|
LINE_DBG(REGS, xpd, portno, "%c reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
|
||||||
((info->bytes == 3) ? 'I' : 'D'), REG_FIELD(info, regnum),
|
((info->h.bytes == 3) ? 'I' : 'D'), REG_FIELD(info, regnum),
|
||||||
REG_FIELD(info, data_low), REG_FIELD(info, data_high));
|
REG_FIELD(info, data_low), REG_FIELD(info, data_high));
|
||||||
/* Update /proc info only if reply relate to the last slic read request */
|
/* Update /proc info only if reply relate to the last slic read request */
|
||||||
if (REG_FIELD(&xpd->requested_reply, regnum) ==
|
if (REG_FIELD(&xpd->requested_reply, regnum) ==
|
||||||
|
@ -1484,7 +1484,7 @@ static void process_digital_inputs(xpd_t *xpd, const reg_cmd_t *info)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
bool offhook = (REG_FIELD(info, data_low) & 0x1) == 0;
|
bool offhook = (REG_FIELD(info, data_low) & 0x1) == 0;
|
||||||
xpp_line_t lines = BIT(info->portnum);
|
xpp_line_t lines = BIT(info->h.portnum);
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if (!PHONEDEV(xpd).digital_inputs) {
|
if (!PHONEDEV(xpd).digital_inputs) {
|
||||||
@ -1593,7 +1593,7 @@ static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
if (!indirect && regnum == REG_DTMF_DECODE) {
|
if (!indirect && regnum == REG_DTMF_DECODE) {
|
||||||
__u8 val = REG_FIELD(info, data_low);
|
__u8 val = REG_FIELD(info, data_low);
|
||||||
|
|
||||||
process_dtmf(xpd, info->portnum, val);
|
process_dtmf(xpd, info->h.portnum, val);
|
||||||
}
|
}
|
||||||
#ifdef POLL_DIGITAL_INPUTS
|
#ifdef POLL_DIGITAL_INPUTS
|
||||||
/*
|
/*
|
||||||
@ -1604,7 +1604,7 @@ static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
#endif
|
#endif
|
||||||
else if (!indirect && regnum == REG_LOOPCLOSURE) { /* OFFHOOK ? */
|
else if (!indirect && regnum == REG_LOOPCLOSURE) { /* OFFHOOK ? */
|
||||||
__u8 val = REG_FIELD(info, data_low);
|
__u8 val = REG_FIELD(info, data_low);
|
||||||
xpp_line_t mask = BIT(info->portnum);
|
xpp_line_t mask = BIT(info->h.portnum);
|
||||||
xpp_line_t offhook;
|
xpp_line_t offhook;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1613,7 +1613,7 @@ static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
*/
|
*/
|
||||||
if ((val & REG_LOOPCLOSURE_ZERO) == 0) {
|
if ((val & REG_LOOPCLOSURE_ZERO) == 0) {
|
||||||
offhook = (val & REG_LOOPCLOSURE_LCR) ? mask : 0;
|
offhook = (val & REG_LOOPCLOSURE_LCR) ? mask : 0;
|
||||||
LINE_DBG(SIGNAL, xpd, info->portnum,
|
LINE_DBG(SIGNAL, xpd, info->h.portnum,
|
||||||
"REG_LOOPCLOSURE: dataL=0x%X "
|
"REG_LOOPCLOSURE: dataL=0x%X "
|
||||||
"(offhook=0x%X mask=0x%X)\n",
|
"(offhook=0x%X mask=0x%X)\n",
|
||||||
val, offhook, mask);
|
val, offhook, mask);
|
||||||
|
@ -58,10 +58,10 @@ static int send_magic_request(xbus_t *xbus, unsigned unit, xportno_t portno,
|
|||||||
*/
|
*/
|
||||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, unit);
|
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, unit);
|
||||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||||
reg_cmd->bytes = 0;
|
reg_cmd->h.bytes = 0;
|
||||||
reg_cmd->is_multibyte = 1;
|
reg_cmd->h.is_multibyte = 1;
|
||||||
reg_cmd->portnum = portno;
|
reg_cmd->h.portnum = portno;
|
||||||
reg_cmd->eoframe = eoftx;
|
reg_cmd->h.eoframe = eoftx;
|
||||||
PORT_DBG(REGS, xbus, unit, portno, "Magic Packet (eoftx=%d)\n", eoftx);
|
PORT_DBG(REGS, xbus, unit, portno, "Magic Packet (eoftx=%d)\n", eoftx);
|
||||||
if (debug & DBG_REGS)
|
if (debug & DBG_REGS)
|
||||||
dump_xframe(__func__, xbus, xframe, debug);
|
dump_xframe(__func__, xbus, xframe, debug);
|
||||||
@ -380,16 +380,16 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
|
|||||||
data_low, data_high);
|
data_low, data_high);
|
||||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||||
/* do not count the 'bytes' field */
|
/* do not count the 'bytes' field */
|
||||||
reg_cmd->bytes = sizeof(*reg_cmd) - 1;
|
reg_cmd->h.bytes = REG_CMD_SIZE(REG);
|
||||||
reg_cmd->is_multibyte = 0;
|
reg_cmd->h.is_multibyte = 0;
|
||||||
if (portno == PORT_BROADCAST) {
|
if (portno == PORT_BROADCAST) {
|
||||||
reg_cmd->portnum = 0;
|
reg_cmd->h.portnum = 0;
|
||||||
REG_FIELD(reg_cmd, all_ports_broadcast) = 1;
|
REG_FIELD(reg_cmd, all_ports_broadcast) = 1;
|
||||||
} else {
|
} else {
|
||||||
reg_cmd->portnum = portno;
|
reg_cmd->h.portnum = portno;
|
||||||
REG_FIELD(reg_cmd, all_ports_broadcast) = 0;
|
REG_FIELD(reg_cmd, all_ports_broadcast) = 0;
|
||||||
}
|
}
|
||||||
reg_cmd->eoframe = 0;
|
reg_cmd->h.eoframe = 0;
|
||||||
REG_FIELD(reg_cmd, reserved) = 0; /* force reserved bits to 0 */
|
REG_FIELD(reg_cmd, reserved) = 0; /* force reserved bits to 0 */
|
||||||
REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
|
REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
|
||||||
REG_FIELD(reg_cmd, do_subreg) = do_subreg;
|
REG_FIELD(reg_cmd, do_subreg) = do_subreg;
|
||||||
@ -402,7 +402,7 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
|
|||||||
xpd->requested_reply = *reg_cmd;
|
xpd->requested_reply = *reg_cmd;
|
||||||
if (debug & DBG_REGS) {
|
if (debug & DBG_REGS) {
|
||||||
dump_reg_cmd("REG_REQ", 1, xbus, xpd->addr.unit,
|
dump_reg_cmd("REG_REQ", 1, xbus, xpd->addr.unit,
|
||||||
reg_cmd->portnum, reg_cmd);
|
reg_cmd->h.portnum, reg_cmd);
|
||||||
dump_packet("REG_REQ", pack, 1);
|
dump_packet("REG_REQ", pack, 1);
|
||||||
}
|
}
|
||||||
if (!xframe->usec_towait) { /* default processing time of SPI */
|
if (!xframe->usec_towait) { /* default processing time of SPI */
|
||||||
@ -591,7 +591,7 @@ HANDLER_DEF(GLOBAL, REGISTER_REPLY)
|
|||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
}
|
}
|
||||||
if (debug & DBG_REGS) {
|
if (debug & DBG_REGS) {
|
||||||
dump_reg_cmd("REG_REPLY", 0, xbus, xpd->addr.unit, reg->portnum,
|
dump_reg_cmd("REG_REPLY", 0, xbus, xpd->addr.unit, reg->h.portnum,
|
||||||
reg);
|
reg);
|
||||||
dump_packet("REG_REPLY", pack, 1);
|
dump_packet("REG_REPLY", pack, 1);
|
||||||
}
|
}
|
||||||
|
@ -2253,7 +2253,7 @@ static int PRI_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
/* Map UNIT + PORTNUM to XPD */
|
/* Map UNIT + PORTNUM to XPD */
|
||||||
orig_xpd = xpd;
|
orig_xpd = xpd;
|
||||||
addr.unit = orig_xpd->addr.unit;
|
addr.unit = orig_xpd->addr.unit;
|
||||||
addr.subunit = info->portnum;
|
addr.subunit = info->h.portnum;
|
||||||
regnum = REG_FIELD(info, regnum);
|
regnum = REG_FIELD(info, regnum);
|
||||||
data_low = REG_FIELD(info, data_low);
|
data_low = REG_FIELD(info, data_low);
|
||||||
xpd = xpd_byaddr(xbus, addr.unit, addr.subunit);
|
xpd = xpd_byaddr(xbus, addr.unit, addr.subunit);
|
||||||
@ -2267,9 +2267,9 @@ static int PRI_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
|||||||
spin_lock_irqsave(&xpd->lock, flags);
|
spin_lock_irqsave(&xpd->lock, flags);
|
||||||
priv = xpd->priv;
|
priv = xpd->priv;
|
||||||
BUG_ON(!priv);
|
BUG_ON(!priv);
|
||||||
if (info->is_multibyte) {
|
if (info->h.is_multibyte) {
|
||||||
XPD_NOTICE(xpd, "Got Multibyte: %d bytes, eoframe: %d\n",
|
XPD_NOTICE(xpd, "Got Multibyte: %d bytes, eoframe: %d\n",
|
||||||
info->bytes, info->eoframe);
|
info->h.bytes, info->h.eoframe);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (regnum == REG_FRS0 && !REG_FIELD(info, do_subreg))
|
if (regnum == REG_FRS0 && !REG_FIELD(info, do_subreg))
|
||||||
|
@ -524,7 +524,7 @@ static DEVICE_ATTR_READER(chipregs_show, dev, buf)
|
|||||||
(do_datah) ? "\tDH" : "");
|
(do_datah) ? "\tDH" : "");
|
||||||
len +=
|
len +=
|
||||||
sprintf(buf + len, "%2d\tRS\t%02X\t%02X\t%02X%s\n",
|
sprintf(buf + len, "%2d\tRS\t%02X\t%02X\t%02X%s\n",
|
||||||
regs->portnum, REG_FIELD(regs, regnum),
|
regs->h.portnum, REG_FIELD(regs, regnum),
|
||||||
REG_FIELD(regs, subreg), REG_FIELD(regs, data_low),
|
REG_FIELD(regs, subreg), REG_FIELD(regs, data_low),
|
||||||
datah_str);
|
datah_str);
|
||||||
} else {
|
} else {
|
||||||
@ -532,7 +532,7 @@ static DEVICE_ATTR_READER(chipregs_show, dev, buf)
|
|||||||
sprintf(buf + len, "#CH\tOP\tReg.\tDL%s\n",
|
sprintf(buf + len, "#CH\tOP\tReg.\tDL%s\n",
|
||||||
(do_datah) ? "\tDH" : "");
|
(do_datah) ? "\tDH" : "");
|
||||||
len +=
|
len +=
|
||||||
sprintf(buf + len, "%2d\tRD\t%02X\t%02X%s\n", regs->portnum,
|
sprintf(buf + len, "%2d\tRD\t%02X\t%02X%s\n", regs->h.portnum,
|
||||||
REG_FIELD(regs, regnum), REG_FIELD(regs, data_low),
|
REG_FIELD(regs, regnum), REG_FIELD(regs, data_low),
|
||||||
datah_str);
|
datah_str);
|
||||||
}
|
}
|
||||||
|
@ -381,17 +381,17 @@ void dump_reg_cmd(const char msg[], bool writing, xbus_t *xbus,
|
|||||||
char data_buf[MAX_PROC_WRITE];
|
char data_buf[MAX_PROC_WRITE];
|
||||||
|
|
||||||
/* The size byte is not included */
|
/* The size byte is not included */
|
||||||
if (regcmd->bytes > sizeof(*regcmd) - 1) {
|
if (regcmd->h.bytes > sizeof(*regcmd) - 1) {
|
||||||
PORT_NOTICE(xbus, unit, port,
|
PORT_NOTICE(xbus, unit, port,
|
||||||
"%s: %s: Too long: regcmd->bytes = %d\n", __func__,
|
"%s: %s: Too long: regcmd->bytes = %d\n", __func__,
|
||||||
msg, regcmd->bytes);
|
msg, regcmd->h.bytes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (regcmd->is_multibyte) {
|
if (regcmd->h.is_multibyte) {
|
||||||
char buf[MAX_PROC_WRITE + 1];
|
char buf[MAX_PROC_WRITE + 1];
|
||||||
int i;
|
int i;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
size_t len = regcmd->bytes;
|
size_t len = regcmd->h.bytes;
|
||||||
const __u8 *p = REG_XDATA(regcmd);
|
const __u8 *p = REG_XDATA(regcmd);
|
||||||
|
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
@ -401,18 +401,18 @@ void dump_reg_cmd(const char msg[], bool writing, xbus_t *xbus,
|
|||||||
PORT_DBG(REGS, xbus, unit, port,
|
PORT_DBG(REGS, xbus, unit, port,
|
||||||
"UNIT-%d PORT-%d: Multibyte(eoframe=%d) "
|
"UNIT-%d PORT-%d: Multibyte(eoframe=%d) "
|
||||||
"%s[0..%zd]: %s%s\n",
|
"%s[0..%zd]: %s%s\n",
|
||||||
unit, port, regcmd->eoframe, msg, len - 1, buf,
|
unit, port, regcmd->h.eoframe, msg, len - 1, buf,
|
||||||
(n >= MAX_PROC_WRITE) ? "..." : "");
|
(n >= MAX_PROC_WRITE) ? "..." : "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* The size byte is not included */
|
/* The size byte is not included */
|
||||||
if (regcmd->bytes != sizeof(*regcmd) - 1) {
|
if (regcmd->h.bytes != REG_CMD_SIZE(REG)) {
|
||||||
PORT_NOTICE(xbus, unit, port,
|
PORT_NOTICE(xbus, unit, port,
|
||||||
"%s: %s: Wrong size: regcmd->bytes = %d\n",
|
"%s: %s: Wrong size: regcmd->bytes = %d\n",
|
||||||
__func__, msg, regcmd->bytes);
|
__func__, msg, regcmd->h.bytes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
snprintf(port_buf, MAX_PROC_WRITE, "%d%s", regcmd->portnum,
|
snprintf(port_buf, MAX_PROC_WRITE, "%d%s", regcmd->h.portnum,
|
||||||
(REG_FIELD(regcmd, all_ports_broadcast)) ? "*" : "");
|
(REG_FIELD(regcmd, all_ports_broadcast)) ? "*" : "");
|
||||||
action = (REG_FIELD(regcmd, read_request)) ? 'R' : 'W';
|
action = (REG_FIELD(regcmd, read_request)) ? 'R' : 'W';
|
||||||
modifier = 'D';
|
modifier = 'D';
|
||||||
|
@ -167,14 +167,16 @@ bool valid_xpd_addr(const struct xpd_addr *addr);
|
|||||||
|
|
||||||
#define MULTIBYTE_MAX_LEN 5 /* FPGA firmware limitation */
|
#define MULTIBYTE_MAX_LEN 5 /* FPGA firmware limitation */
|
||||||
|
|
||||||
typedef struct reg_cmd {
|
struct reg_cmd_header {
|
||||||
__u8 bytes:3; /* Length (for Multibyte) */
|
__u8 bytes:3; /* Length (for Multibyte) */
|
||||||
__u8 eoframe:1; /* For BRI -- end of frame */
|
__u8 eoframe:1; /* For BRI -- end of frame */
|
||||||
__u8 portnum:3; /* For port specific registers */
|
__u8 portnum:3; /* For port specific registers */
|
||||||
__u8 is_multibyte:1;
|
__u8 is_multibyte:1;
|
||||||
union {
|
} PACKED;
|
||||||
struct {
|
|
||||||
__u8 reserved:4;
|
struct reg_cmd_REG {
|
||||||
|
__u8 reserved:3;
|
||||||
|
__u8 do_expander:1;
|
||||||
__u8 do_datah:1;
|
__u8 do_datah:1;
|
||||||
__u8 do_subreg:1;
|
__u8 do_subreg:1;
|
||||||
__u8 read_request:1;
|
__u8 read_request:1;
|
||||||
@ -183,7 +185,12 @@ typedef struct reg_cmd {
|
|||||||
__u8 subreg;
|
__u8 subreg;
|
||||||
__u8 data_low;
|
__u8 data_low;
|
||||||
__u8 data_high;
|
__u8 data_high;
|
||||||
} PACKED r;
|
} PACKED;
|
||||||
|
|
||||||
|
typedef struct reg_cmd {
|
||||||
|
struct reg_cmd_header h;
|
||||||
|
union {
|
||||||
|
struct reg_cmd_REG r;
|
||||||
/* For Write-Multibyte commands in BRI */
|
/* For Write-Multibyte commands in BRI */
|
||||||
struct {
|
struct {
|
||||||
__u8 xdata[MULTIBYTE_MAX_LEN];
|
__u8 xdata[MULTIBYTE_MAX_LEN];
|
||||||
@ -192,6 +199,7 @@ typedef struct reg_cmd {
|
|||||||
} PACKED reg_cmd_t;
|
} PACKED reg_cmd_t;
|
||||||
|
|
||||||
/* Shortcut access macros */
|
/* Shortcut access macros */
|
||||||
|
#define REG_CMD_SIZE(variant) (sizeof(struct reg_cmd_ ## variant))
|
||||||
#define REG_FIELD(regptr, member) ((regptr)->alt.r.member)
|
#define REG_FIELD(regptr, member) ((regptr)->alt.r.member)
|
||||||
#define REG_XDATA(regptr) ((regptr)->alt.d.xdata)
|
#define REG_XDATA(regptr) ((regptr)->alt.d.xdata)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user