/* * Send a packet of bytes to the device
*/ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsignedchar* data)
{ /* Copy data to buffer */ int n = LO(cmd); int c; int empty; int head, tail;
/* * Update head and tail of xmit buffer
*/
scoped_guard(spinlock_irqsave, &iforce->xmit_lock) {
head = iforce->xmit.head;
tail = iforce->xmit.tail;
if (CIRC_SPACE(head, tail, XMIT_SIZE) < n + 2) {
dev_warn(&iforce->dev->dev, "not enough space in xmit buffer to send new packet\n"); return -1;
}
empty = head == tail;
XMIT_INC(iforce->xmit.head, n + 2);
/* * Store packet in xmit buffer
*/
iforce->xmit.buf[head] = HI(cmd);
XMIT_INC(head, 1);
iforce->xmit.buf[head] = LO(cmd);
XMIT_INC(head, 1);
c = CIRC_SPACE_TO_END(head, tail, XMIT_SIZE); if (n < c)
c = n;
memcpy(&iforce->xmit.buf[head], data, c); if (n != c)
memcpy(&iforce->xmit.buf[0], data + c, n - c);
XMIT_INC(head, n);
}
/* * If necessary, start the transmission
*/ if (empty)
iforce->xport_ops->xmit(iforce);
return0;
}
EXPORT_SYMBOL(iforce_send_packet);
/* Start or stop an effect */ int iforce_control_playback(struct iforce* iforce, u16 id, unsignedint value)
{ unsignedchar data[3];
/* Mark an effect that was being updated as ready. That means it can be updated
* again */ staticint mark_core_as_ready(struct iforce *iforce, unsignedshort addr)
{ int i;
if (!iforce->dev->ff) return0;
for (i = 0; i < iforce->dev->ff->max_effects; ++i) { if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
(iforce->core_effects[i].mod1_chunk.start == addr ||
iforce->core_effects[i].mod2_chunk.start == addr)) {
clear_bit(FF_CORE_UPDATE, iforce->core_effects[i].flags); return0;
}
}
dev_warn(&iforce->dev->dev, "unused effect %04x updated !!!\n", addr); return -1;
}
/* Check if an effect was just started or stopped */
i = data[1] & 0x7f; if (data[1] & 0x80) { if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { /* Report play event */
input_report_ff_status(dev, i, FF_STATUS_PLAYING);
}
} elseif (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { /* Report stop event */
input_report_ff_status(dev, i, FF_STATUS_STOPPED);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.