* [PATCH 0/9] mceusb updates per MS docs
@ 2011-07-14 22:09 Jarod Wilson
2011-07-14 22:09 ` [PATCH 1/9] [media] mceusb: command/response updates from " Jarod Wilson
` (18 more replies)
0 siblings, 19 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
This is a stack of updates made based on the Windows Media Center remote
and receiver/transmitter specification and requirements document that
Rafi Rubin recently pointed me at. Its titled
Windows-Media-Center-RC-IR-Collection-Green-Button-Specification-03-08-2011-V2.pdf
which as of this writing, is publicly available from
download.microsoft.com.
Tested with 7 different mceusb devices, with no ill effects. Unfortunately,
for the most part, these chagnes don't actually improve any shortcomings in
the driver, but they do give us a better view of the hardware features and
whatnot, and a few things are better explained now, with most of the command
and response bits lining up with what MS has documented.
Jarod Wilson (9):
[media] mceusb: command/response updates from MS docs
[media] mceusb: give hardware time to reply to cmds
[media] mceusb: set wakeup bits for IR-based resume
[media] mceusb: issue device resume cmd when needed
[media] mceusb: query device for firmware emulator version
[media] mceusb: get misc port data from hardware
[media] mceusb: flash LED (emu v2+ only) to signal end of init
[media] mceusb: report actual tx frequencies
[media] mceusb: update version, copyright, author
drivers/media/rc/mceusb.c | 422 ++++++++++++++++++++++++++++++---------------
1 files changed, 286 insertions(+), 136 deletions(-)
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/9] [media] mceusb: command/response updates from MS docs
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
@ 2011-07-14 22:09 ` Jarod Wilson
2011-07-14 22:09 ` [PATCH 2/9] [media] mceusb: give hardware time to reply to cmds Jarod Wilson
` (17 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
I was recently pointed to the document titled
Windows-Media-Center-RC-IR-Collection-Green-Button-Specification-03-08-2011-V2.pdf
which as of this writing, is publicly available from
download.microsoft.com. It covers a LOT of the gaps in the mceusb
driver, which to this point, was written almost entirely by
reverse-engineering. First up, I'm updating the defines for all the MCE
commands and responses to match their names in the spec. More to come...
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 293 ++++++++++++++++++++++++++------------------
1 files changed, 173 insertions(+), 120 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index ec972dc..111bead 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -63,43 +63,90 @@
#define MCE_PULSE_MASK 0x7f /* Pulse mask */
#define MCE_MAX_PULSE_LENGTH 0x7f /* Longest transmittable pulse symbol */
-#define MCE_HW_CMD_HEADER 0xff /* MCE hardware command header */
-#define MCE_COMMAND_HEADER 0x9f /* MCE command header */
-#define MCE_COMMAND_MASK 0xe0 /* Mask out command bits */
-#define MCE_COMMAND_NULL 0x00 /* These show up various places... */
-/* if buf[i] & MCE_COMMAND_MASK == 0x80 and buf[i] != MCE_COMMAND_HEADER,
- * then we're looking at a raw IR data sample */
-#define MCE_COMMAND_IRDATA 0x80
-#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
-
-/* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */
+/*
+ * The interface between the host and the IR hardware is command-response
+ * based. All commands and responses have a consistent format, where a lead
+ * byte always identifies the type of data following it. The lead byte has
+ * a port value in the 3 highest bits and a length value in the 5 lowest
+ * bits.
+ *
+ * The length field is overloaded, with a value of 11111 indicating that the
+ * following byte is a command or response code, and the length of the entire
+ * message is determined by the code. If the length field is not 11111, then
+ * it specifies the number of bytes of port data that follow.
+ */
+#define MCE_CMD 0x1f
+#define MCE_PORT_IR 0x4 /* (0x4 << 5) | MCE_CMD = 0x9f */
+#define MCE_PORT_SYS 0x7 /* (0x7 << 5) | MCE_CMD = 0xff */
+#define MCE_PORT_SER 0x6 /* 0xc0 thru 0xdf flush & 0x1f bytes */
+#define MCE_PORT_MASK 0xe0 /* Mask out command bits */
+
+/* Command port headers */
+#define MCE_CMD_PORT_IR 0x9f /* IR-related cmd/rsp */
+#define MCE_CMD_PORT_SYS 0xff /* System (non-IR) device cmd/rsp */
+
+/* Commands that set device state (2-4 bytes in length) */
+#define MCE_CMD_RESET 0xfe /* Reset device, 2 bytes */
+#define MCE_CMD_RESUME 0xaa /* Resume device after error, 2 bytes */
+#define MCE_CMD_SETIRCFS 0x06 /* Set tx carrier, 4 bytes */
+#define MCE_CMD_SETIRTIMEOUT 0x0c /* Set timeout, 4 bytes */
+#define MCE_CMD_SETIRTXPORTS 0x08 /* Set tx ports, 3 bytes */
+#define MCE_CMD_SETIRRXPORTEN 0x14 /* Set rx ports, 3 bytes */
+#define MCE_CMD_FLASHLED 0x23 /* Flash receiver LED, 2 bytes */
+
+/* Commands that query device state (all 2 bytes, unless noted) */
+#define MCE_CMD_GETIRCFS 0x07 /* Get carrier */
+#define MCE_CMD_GETIRTIMEOUT 0x0d /* Get timeout */
+#define MCE_CMD_GETIRTXPORTS 0x13 /* Get tx ports */
+#define MCE_CMD_GETIRRXPORTEN 0x15 /* Get rx ports */
+#define MCE_CMD_GETPORTSTATUS 0x11 /* Get tx port status, 3 bytes */
+#define MCE_CMD_GETIRNUMPORTS 0x16 /* Get number of ports */
+#define MCE_CMD_GETWAKESOURCE 0x17 /* Get wake source */
+#define MCE_CMD_GETEMVER 0x22 /* Get emulator interface version */
+#define MCE_CMD_GETDEVDETAILS 0x21 /* Get device details (em ver2 only) */
+#define MCE_CMD_GETWAKESUPPORT 0x20 /* Get wake details (em ver2 only) */
+#define MCE_CMD_GETWAKEVERSION 0x18 /* Get wake pattern (em ver2 only) */
+
+/* Misc commands */
+#define MCE_CMD_NOP 0xff /* No operation */
+
+/* Responses to commands (non-error cases) */
+#define MCE_RSP_EQIRCFS 0x06 /* tx carrier, 4 bytes */
+#define MCE_RSP_EQIRTIMEOUT 0x0c /* rx timeout, 4 bytes */
+#define MCE_RSP_GETWAKESOURCE 0x17 /* wake source, 3 bytes */
+#define MCE_RSP_EQIRTXPORTS 0x08 /* tx port mask, 3 bytes */
+#define MCE_RSP_EQIRRXPORTEN 0x14 /* rx port mask, 3 bytes */
+#define MCE_RSP_GETPORTSTATUS 0x11 /* tx port status, 7 bytes */
+#define MCE_RSP_EQIRRXCFCNT 0x15 /* rx carrier count, 4 bytes */
+#define MCE_RSP_EQIRNUMPORTS 0x16 /* number of ports, 4 bytes */
+#define MCE_RSP_EQWAKESUPPORT 0x20 /* wake capabilities, 3 bytes */
+#define MCE_RSP_EQWAKEVERSION 0x18 /* wake pattern details, 6 bytes */
+#define MCE_RSP_EQDEVDETAILS 0x21 /* device capabilities, 3 bytes */
+#define MCE_RSP_EQEMVER 0x22 /* emulator interface ver, 3 bytes */
+#define MCE_RSP_FLASHLED 0x23 /* success flashing LED, 2 bytes */
+
+/* Responses to error cases, must send MCE_CMD_RESUME to clear them */
+#define MCE_RSP_CMD_ILLEGAL 0xfe /* illegal command for port, 2 bytes */
+#define MCE_RSP_TX_TIMEOUT 0x81 /* tx timed out, 2 bytes */
+
+/* Misc commands/responses not defined in the MCE remote/transceiver spec */
#define MCE_CMD_SIG_END 0x01 /* End of signal */
#define MCE_CMD_PING 0x03 /* Ping device */
#define MCE_CMD_UNKNOWN 0x04 /* Unknown */
#define MCE_CMD_UNKNOWN2 0x05 /* Unknown */
-#define MCE_CMD_S_CARRIER 0x06 /* Set TX carrier frequency */
-#define MCE_CMD_G_CARRIER 0x07 /* Get TX carrier frequency */
-#define MCE_CMD_S_TXMASK 0x08 /* Set TX port bitmask */
#define MCE_CMD_UNKNOWN3 0x09 /* Unknown */
#define MCE_CMD_UNKNOWN4 0x0a /* Unknown */
#define MCE_CMD_G_REVISION 0x0b /* Get hw/sw revision */
-#define MCE_CMD_S_TIMEOUT 0x0c /* Set RX timeout value */
-#define MCE_CMD_G_TIMEOUT 0x0d /* Get RX timeout value */
#define MCE_CMD_UNKNOWN5 0x0e /* Unknown */
#define MCE_CMD_UNKNOWN6 0x0f /* Unknown */
-#define MCE_CMD_G_RXPORTSTS 0x11 /* Get RX port status */
-#define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */
-#define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */
-#define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */
-#define MCE_RSP_PULSE_COUNT 0x15 /* RX pulse count (only if learning) */
-#define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */
-#define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */
-#define MCE_CMD_UNKNOWN7 0x18 /* Unknown */
#define MCE_CMD_UNKNOWN8 0x19 /* Unknown */
#define MCE_CMD_UNKNOWN9 0x1b /* Unknown */
-#define MCE_CMD_DEVICE_RESET 0xaa /* Reset the hardware */
-#define MCE_RSP_CMD_INVALID 0xfe /* Invalid command issued */
+#define MCE_CMD_NULL 0x00 /* These show up various places... */
+/* if buf[i] & MCE_PORT_MASK == 0x80 and buf[i] != MCE_CMD_PORT_IR,
+ * then we're looking at a raw IR data sample */
+#define MCE_COMMAND_IRDATA 0x80
+#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
/* module parameters */
#ifdef CONFIG_USB_DEBUG
@@ -390,46 +437,25 @@ struct mceusb_dev {
enum mceusb_model_type model;
};
-/*
- * MCE Device Command Strings
- * Device command responses vary from device to device...
- * - DEVICE_RESET resets the hardware to its default state
- * - GET_REVISION fetches the hardware/software revision, common
- * replies are ff 0b 45 ff 1b 08 and ff 0b 50 ff 1b 42
- * - GET_CARRIER_FREQ gets the carrier mode and frequency of the
- * device, with replies in the form of 9f 06 MM FF, where MM is 0-3,
- * meaning clk of 10000000, 2500000, 625000 or 156250, and FF is
- * ((clk / frequency) - 1)
- * - GET_RX_TIMEOUT fetches the receiver timeout in units of 50us,
- * response in the form of 9f 0c msb lsb
- * - GET_TX_BITMASK fetches the transmitter bitmask, replies in
- * the form of 9f 08 bm, where bm is the bitmask
- * - GET_RX_SENSOR fetches the RX sensor setting -- long-range
- * general use one or short-range learning one, in the form of
- * 9f 14 ss, where ss is either 01 for long-range or 02 for short
- * - SET_CARRIER_FREQ sets a new carrier mode and frequency
- * - SET_TX_BITMASK sets the transmitter bitmask
- * - SET_RX_TIMEOUT sets the receiver timeout
- * - SET_RX_SENSOR sets which receiver sensor to use
- */
-static char DEVICE_RESET[] = {MCE_COMMAND_NULL, MCE_HW_CMD_HEADER,
- MCE_CMD_DEVICE_RESET};
-static char GET_REVISION[] = {MCE_HW_CMD_HEADER, MCE_CMD_G_REVISION};
-static char GET_UNKNOWN[] = {MCE_HW_CMD_HEADER, MCE_CMD_UNKNOWN7};
-static char GET_UNKNOWN2[] = {MCE_COMMAND_HEADER, MCE_CMD_UNKNOWN2};
-static char GET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, MCE_CMD_G_CARRIER};
-static char GET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TIMEOUT};
-static char GET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TXMASK};
-static char GET_RX_SENSOR[] = {MCE_COMMAND_HEADER, MCE_CMD_G_RXSENSOR};
+/* MCE Device Command Strings, generally a port and command pair */
+static char DEVICE_RESUME[] = {MCE_CMD_NULL, MCE_CMD_PORT_SYS,
+ MCE_CMD_RESUME};
+static char GET_REVISION[] = {MCE_CMD_PORT_SYS, MCE_CMD_G_REVISION};
+static char GET_WAKEVERSION[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETWAKEVERSION};
+static char GET_UNKNOWN2[] = {MCE_CMD_PORT_IR, MCE_CMD_UNKNOWN2};
+static char GET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRCFS};
+static char GET_RX_TIMEOUT[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTIMEOUT};
+static char GET_TX_BITMASK[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTXPORTS};
+static char GET_RX_SENSOR[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRRXPORTEN};
/* sub in desired values in lower byte or bytes for full command */
/* FIXME: make use of these for transmit.
-static char SET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER,
- MCE_CMD_S_CARRIER, 0x00, 0x00};
-static char SET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_S_TXMASK, 0x00};
-static char SET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER,
- MCE_CMD_S_TIMEOUT, 0x00, 0x00};
-static char SET_RX_SENSOR[] = {MCE_COMMAND_HEADER,
- MCE_CMD_S_RXSENSOR, 0x00};
+static char SET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR,
+ MCE_CMD_SETIRCFS, 0x00, 0x00};
+static char SET_TX_BITMASK[] = {MCE_CMD_PORT_IR, MCE_CMD_SETIRTXPORTS, 0x00};
+static char SET_RX_TIMEOUT[] = {MCE_CMD_PORT_IR,
+ MCE_CMD_SETIRTIMEOUT, 0x00, 0x00};
+static char SET_RX_SENSOR[] = {MCE_CMD_PORT_IR,
+ MCE_RSP_EQIRRXPORTEN, 0x00};
*/
static int mceusb_cmdsize(u8 cmd, u8 subcmd)
@@ -437,27 +463,33 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd)
int datasize = 0;
switch (cmd) {
- case MCE_COMMAND_NULL:
- if (subcmd == MCE_HW_CMD_HEADER)
+ case MCE_CMD_NULL:
+ if (subcmd == MCE_CMD_PORT_SYS)
datasize = 1;
break;
- case MCE_HW_CMD_HEADER:
+ case MCE_CMD_PORT_SYS:
switch (subcmd) {
+ case MCE_RSP_EQWAKEVERSION:
+ datasize = 4;
+ break;
case MCE_CMD_G_REVISION:
datasize = 2;
break;
+ case MCE_RSP_EQWAKESUPPORT:
+ datasize = 1;
+ break;
}
- case MCE_COMMAND_HEADER:
+ case MCE_CMD_PORT_IR:
switch (subcmd) {
case MCE_CMD_UNKNOWN:
- case MCE_CMD_S_CARRIER:
- case MCE_CMD_S_TIMEOUT:
- case MCE_RSP_PULSE_COUNT:
+ case MCE_RSP_EQIRCFS:
+ case MCE_RSP_EQIRTIMEOUT:
+ case MCE_RSP_EQIRRXCFCNT:
datasize = 2;
break;
case MCE_CMD_SIG_END:
- case MCE_CMD_S_TXMASK:
- case MCE_CMD_S_RXSENSOR:
+ case MCE_RSP_EQIRTXPORTS:
+ case MCE_RSP_EQIRRXPORTEN:
datasize = 1;
break;
}
@@ -470,7 +502,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
{
char codes[USB_BUFLEN * 3 + 1];
char inout[9];
- u8 cmd, subcmd, data1, data2;
+ u8 cmd, subcmd, data1, data2, data3, data4, data5;
struct device *dev = ir->dev;
int i, start, skip = 0;
@@ -500,18 +532,26 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
subcmd = buf[start + 1] & 0xff;
data1 = buf[start + 2] & 0xff;
data2 = buf[start + 3] & 0xff;
+ data3 = buf[start + 4] & 0xff;
+ data4 = buf[start + 5] & 0xff;
+ data5 = buf[start + 6] & 0xff;
switch (cmd) {
- case MCE_COMMAND_NULL:
- if ((subcmd == MCE_HW_CMD_HEADER) &&
- (data1 == MCE_CMD_DEVICE_RESET))
- dev_info(dev, "Device reset requested\n");
+ case MCE_CMD_NULL:
+ if ((subcmd == MCE_CMD_PORT_SYS) &&
+ (data1 == MCE_CMD_RESUME))
+ dev_info(dev, "Device resume requested\n");
else
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
break;
- case MCE_HW_CMD_HEADER:
+ case MCE_CMD_PORT_SYS:
switch (subcmd) {
+ case MCE_RSP_EQEMVER:
+ if (!out)
+ dev_info(dev, "Emulator interface version %x\n",
+ data1);
+ break;
case MCE_CMD_G_REVISION:
if (len == 2)
dev_info(dev, "Get hw/sw rev?\n");
@@ -520,21 +560,32 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
"0x%02x 0x%02x\n", data1, data2,
buf[start + 4], buf[start + 5]);
break;
- case MCE_CMD_DEVICE_RESET:
- dev_info(dev, "Device reset requested\n");
+ case MCE_CMD_RESUME:
+ dev_info(dev, "Device resume requested\n");
+ break;
+ case MCE_RSP_CMD_ILLEGAL:
+ dev_info(dev, "Illegal PORT_SYS command\n");
+ break;
+ case MCE_RSP_EQWAKEVERSION:
+ if (!out)
+ dev_info(dev, "Wake version, proto: 0x%02x, "
+ "payload: 0x%02x, address: 0x%02x, "
+ "version: 0x%02x\n",
+ data1, data2, data3, data4);
break;
- case MCE_RSP_CMD_INVALID:
- dev_info(dev, "Previous command not supported\n");
+ case MCE_RSP_GETPORTSTATUS:
+ if (!out)
+ /* We use data1 + 1 here, to match hw labels */
+ dev_info(dev, "TX port %d: blaster is%s connected\n",
+ data1 + 1, data4 ? " not" : "");
break;
- case MCE_CMD_UNKNOWN7:
- case MCE_CMD_UNKNOWN9:
default:
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
break;
}
break;
- case MCE_COMMAND_HEADER:
+ case MCE_CMD_PORT_IR:
switch (subcmd) {
case MCE_CMD_SIG_END:
dev_info(dev, "End of signal\n");
@@ -546,47 +597,50 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n",
data1, data2);
break;
- case MCE_CMD_S_CARRIER:
+ case MCE_CMD_SETIRCFS:
dev_info(dev, "%s carrier mode and freq of "
"0x%02x 0x%02x\n", inout, data1, data2);
break;
- case MCE_CMD_G_CARRIER:
+ case MCE_CMD_GETIRCFS:
dev_info(dev, "Get carrier mode and freq\n");
break;
- case MCE_CMD_S_TXMASK:
+ case MCE_RSP_EQIRTXPORTS:
dev_info(dev, "%s transmit blaster mask of 0x%02x\n",
inout, data1);
break;
- case MCE_CMD_S_TIMEOUT:
+ case MCE_RSP_EQIRTIMEOUT:
/* value is in units of 50us, so x*50/1000 ms */
dev_info(dev, "%s receive timeout of %d ms\n",
inout,
((data1 << 8) | data2) * MCE_TIME_UNIT / 1000);
break;
- case MCE_CMD_G_TIMEOUT:
+ case MCE_CMD_GETIRTIMEOUT:
dev_info(dev, "Get receive timeout\n");
break;
- case MCE_CMD_G_TXMASK:
+ case MCE_CMD_GETIRTXPORTS:
dev_info(dev, "Get transmit blaster mask\n");
break;
- case MCE_CMD_S_RXSENSOR:
+ case MCE_RSP_EQIRRXPORTEN:
dev_info(dev, "%s %s-range receive sensor in use\n",
inout, data1 == 0x02 ? "short" : "long");
break;
- case MCE_CMD_G_RXSENSOR:
- /* aka MCE_RSP_PULSE_COUNT */
+ case MCE_CMD_GETIRRXPORTEN:
+ /* aka MCE_RSP_EQIRRXCFCNT */
if (out)
dev_info(dev, "Get receive sensor\n");
else if (ir->learning_enabled)
dev_info(dev, "RX pulse count: %d\n",
((data1 << 8) | data2));
break;
- case MCE_RSP_CMD_INVALID:
- dev_info(dev, "Error! Hardware is likely wedged...\n");
+ case MCE_RSP_EQIRNUMPORTS:
+ if (out)
+ break;
+ dev_info(dev, "Num TX ports: %x, num RX ports: %x\n",
+ data1, data2);
+ break;
+ case MCE_RSP_CMD_ILLEGAL:
+ dev_info(dev, "Illegal PORT_IR command\n");
break;
- case MCE_CMD_UNKNOWN2:
- case MCE_CMD_UNKNOWN3:
- case MCE_CMD_UNKNOWN5:
default:
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
@@ -599,8 +653,8 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
if (cmd == MCE_IRDATA_TRAILER)
dev_info(dev, "End of raw IR data\n");
- else if ((cmd != MCE_COMMAND_HEADER) &&
- ((cmd & MCE_COMMAND_MASK) == MCE_COMMAND_IRDATA))
+ else if ((cmd != MCE_CMD_PORT_IR) &&
+ ((cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA))
dev_info(dev, "Raw IR data, %d pulse/space samples\n", ir->rem);
}
@@ -616,9 +670,6 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs)
if (ir) {
len = urb->actual_length;
- mce_dbg(ir->dev, "callback called (status=%d len=%d)\n",
- urb->status, len);
-
mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true);
}
@@ -710,8 +761,8 @@ static int mceusb_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
return -ENOMEM;
/* MCE tx init header */
- cmdbuf[cmdcount++] = MCE_COMMAND_HEADER;
- cmdbuf[cmdcount++] = MCE_CMD_S_TXMASK;
+ cmdbuf[cmdcount++] = MCE_CMD_PORT_IR;
+ cmdbuf[cmdcount++] = MCE_CMD_SETIRTXPORTS;
cmdbuf[cmdcount++] = ir->tx_mask;
/* Generate mce packet data */
@@ -797,8 +848,8 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
struct mceusb_dev *ir = dev->priv;
int clk = 10000000;
int prescaler = 0, divisor = 0;
- unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER,
- MCE_CMD_S_CARRIER, 0x00, 0x00 };
+ unsigned char cmdbuf[4] = { MCE_CMD_PORT_IR,
+ MCE_CMD_SETIRCFS, 0x00, 0x00 };
/* Carrier has changed */
if (ir->carrier != carrier) {
@@ -847,16 +898,16 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
switch (ir->buf_in[index]) {
/* 2-byte return value commands */
- case MCE_CMD_S_TIMEOUT:
+ case MCE_RSP_EQIRTIMEOUT:
ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT);
break;
/* 1-byte return value commands */
- case MCE_CMD_S_TXMASK:
+ case MCE_RSP_EQIRTXPORTS:
ir->tx_mask = hi;
break;
- case MCE_CMD_S_RXSENSOR:
- ir->learning_enabled = (hi == 0x02);
+ case MCE_RSP_EQIRRXPORTEN:
+ ir->learning_enabled = ((hi & 0x02) == 0x02);
break;
default:
break;
@@ -905,8 +956,8 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
/* decode mce packets of the form (84),AA,BB,CC,DD */
/* IR data packets can span USB messages - rem */
ir->cmd = ir->buf_in[i];
- if ((ir->cmd == MCE_COMMAND_HEADER) ||
- ((ir->cmd & MCE_COMMAND_MASK) !=
+ if ((ir->cmd == MCE_CMD_PORT_IR) ||
+ ((ir->cmd & MCE_PORT_MASK) !=
MCE_COMMAND_IRDATA)) {
ir->parser_state = SUBCMD;
continue;
@@ -1013,8 +1064,8 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
0x0000, 0x0100, NULL, 0, HZ * 3);
mce_dbg(dev, "%s - retC = %d\n", __func__, ret);
- /* device reset */
- mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
+ /* device resume */
+ mce_async_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME));
/* get hw/sw revision? */
mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
@@ -1024,14 +1075,16 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
static void mceusb_gen2_init(struct mceusb_dev *ir)
{
- /* device reset */
- mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
+ /* device resume */
+ mce_async_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME));
/* get hw/sw revision? */
mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
- /* unknown what the next two actually return... */
- mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN));
+ /* get wake version (protocol, key, address) */
+ mce_async_out(ir, GET_WAKEVERSION, sizeof(GET_WAKEVERSION));
+
+ /* unknown what this one actually returns... */
mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2));
}
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 2/9] [media] mceusb: give hardware time to reply to cmds
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
2011-07-14 22:09 ` [PATCH 1/9] [media] mceusb: command/response updates from " Jarod Wilson
@ 2011-07-14 22:09 ` Jarod Wilson
2011-07-14 23:30 ` Mauro Carvalho Chehab
2011-07-14 22:09 ` [PATCH 3/9] [media] mceusb: set wakeup bits for IR-based resume Jarod Wilson
` (16 subsequent siblings)
18 siblings, 1 reply; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Sometimes the init routine is blasting commands out to the hardware
faster than it can reply. Throw a brief delay in there to give the
hardware a chance to reply before we send the next command.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 111bead..13a853b 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -37,6 +37,7 @@
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
+#include <linux/delay.h>
#include <media/rc-core.h>
#define DRIVER_VERSION "1.91"
@@ -735,6 +736,7 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
{
mce_request_packet(ir, data, size, MCEUSB_TX);
+ mdelay(10);
}
static void mce_flush_rx_buffer(struct mceusb_dev *ir, int size)
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 3/9] [media] mceusb: set wakeup bits for IR-based resume
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
2011-07-14 22:09 ` [PATCH 1/9] [media] mceusb: command/response updates from " Jarod Wilson
2011-07-14 22:09 ` [PATCH 2/9] [media] mceusb: give hardware time to reply to cmds Jarod Wilson
@ 2011-07-14 22:09 ` Jarod Wilson
2011-07-14 22:09 ` [PATCH 4/9] [media] mceusb: issue device resume cmd when needed Jarod Wilson
` (15 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Its not uncommon for folks to force these bits enabled, because people
do want to wake their htpc kit via their remote. Lets just set the bits
for 'em.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 13a853b..7ff755f 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -37,6 +37,7 @@
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
+#include <linux/pm_wakeup.h>
#include <linux/delay.h>
#include <media/rc-core.h>
@@ -1290,6 +1291,10 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
usb_set_intfdata(intf, ir);
+ /* enable wake via this device */
+ device_set_wakeup_capable(ir->dev, true);
+ device_set_wakeup_enable(ir->dev, true);
+
dev_info(&intf->dev, "Registered %s on usb%d:%d\n", name,
dev->bus->busnum, dev->devnum);
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 4/9] [media] mceusb: issue device resume cmd when needed
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (2 preceding siblings ...)
2011-07-14 22:09 ` [PATCH 3/9] [media] mceusb: set wakeup bits for IR-based resume Jarod Wilson
@ 2011-07-14 22:09 ` Jarod Wilson
2011-07-14 22:09 ` [PATCH 5/9] [media] mceusb: query device for firmware emulator version Jarod Wilson
` (14 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
According to MS docs, the device firmware may halt after receiving an
unknown instruction, but that it should be possible to tell the firmware
to continue running by simply sending a device resume command. So lets
do that.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 7ff755f..a777623 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -437,6 +437,8 @@ struct mceusb_dev {
char name[128];
char phys[64];
enum mceusb_model_type model;
+
+ bool need_reset; /* flag to issue a device resume cmd */
};
/* MCE Device Command Strings, generally a port and command pair */
@@ -736,6 +738,14 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
{
+ int rsize = sizeof(DEVICE_RESUME);
+
+ if (ir->need_reset) {
+ ir->need_reset = false;
+ mce_request_packet(ir, DEVICE_RESUME, rsize, MCEUSB_TX);
+ mdelay(10);
+ }
+
mce_request_packet(ir, data, size, MCEUSB_TX);
mdelay(10);
}
@@ -912,6 +922,9 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
case MCE_RSP_EQIRRXPORTEN:
ir->learning_enabled = ((hi & 0x02) == 0x02);
break;
+ case MCE_RSP_CMD_ILLEGAL:
+ ir->need_reset = true;
+ break;
default:
break;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 5/9] [media] mceusb: query device for firmware emulator version
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (3 preceding siblings ...)
2011-07-14 22:09 ` [PATCH 4/9] [media] mceusb: issue device resume cmd when needed Jarod Wilson
@ 2011-07-14 22:09 ` Jarod Wilson
2011-07-14 22:09 ` [PATCH 6/9] [media] mceusb: get misc port data from hardware Jarod Wilson
` (13 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Supposedly, there are essentially three different classes of devices
that are compatible with Microsoft's specs. First are the "legacy"
devices, which are built using Microsoft-provided hardware specs and
firmware. Second are "emulator" devices, which are built using custom
hardware and firmware, written to emulate Microsoft's firmware. Third
are "port" devices, which have their own device driver and firmware,
which provides compatible data to higher levels of the stack.
>From what I can tell, things like nuvoton-cir and fintek-cir are
essentially "port" devices -- their raw IR buffer format is very similar
to that of the mceusb devices. Now, within the mceusb driver, we have
three different "generations", which at first, seemed like maybe they
mapped to emulator versions. Unfortuantely, every single device I have
responds "illegal command" to the query to get firmware emulator version
from the hardware, which means they're either all emulator version 1, or
they're legacy devices, and our different "generations" aren't at all
related here. Though in theory, its possible the gen1 devices are
"legacy" devices and the rest are emulator v1. There are some useful
features of the v2 interface I was hoping to play with, but alas...
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 19 +++++++++++++++++--
1 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index a777623..114fb13 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -439,12 +439,14 @@ struct mceusb_dev {
enum mceusb_model_type model;
bool need_reset; /* flag to issue a device resume cmd */
+ u8 emver; /* emulator interface version */
};
/* MCE Device Command Strings, generally a port and command pair */
static char DEVICE_RESUME[] = {MCE_CMD_NULL, MCE_CMD_PORT_SYS,
MCE_CMD_RESUME};
static char GET_REVISION[] = {MCE_CMD_PORT_SYS, MCE_CMD_G_REVISION};
+static char GET_EMVER[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETEMVER};
static char GET_WAKEVERSION[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETWAKEVERSION};
static char GET_UNKNOWN2[] = {MCE_CMD_PORT_IR, MCE_CMD_UNKNOWN2};
static char GET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRCFS};
@@ -916,6 +918,9 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
break;
/* 1-byte return value commands */
+ case MCE_RSP_EQEMVER:
+ ir->emver = hi;
+ break;
case MCE_RSP_EQIRTXPORTS:
ir->tx_mask = hi;
break;
@@ -1038,6 +1043,13 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
usb_submit_urb(urb, GFP_ATOMIC);
}
+static void mceusb_get_emulator_version(struct mceusb_dev *ir)
+{
+ /* If we get no reply or an illegal command reply, its ver 1, says MS */
+ ir->emver = 1;
+ mce_async_out(ir, GET_EMVER, sizeof(GET_EMVER));
+}
+
static void mceusb_gen1_init(struct mceusb_dev *ir)
{
int ret;
@@ -1291,6 +1303,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
mce_dbg(&intf->dev, "Flushing receive buffers\n");
mce_flush_rx_buffer(ir, maxp);
+ /* figure out which firmware/emulator version this hardware has */
+ mceusb_get_emulator_version(ir);
+
/* initialize device */
if (ir->flags.microsoft_gen1)
mceusb_gen1_init(ir);
@@ -1308,8 +1323,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
device_set_wakeup_capable(ir->dev, true);
device_set_wakeup_enable(ir->dev, true);
- dev_info(&intf->dev, "Registered %s on usb%d:%d\n", name,
- dev->bus->busnum, dev->devnum);
+ dev_info(&intf->dev, "Registered %s with mce emulator interface "
+ "version %x\n", name, ir->emver);
return 0;
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 6/9] [media] mceusb: get misc port data from hardware
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (4 preceding siblings ...)
2011-07-14 22:09 ` [PATCH 5/9] [media] mceusb: query device for firmware emulator version Jarod Wilson
@ 2011-07-14 22:09 ` Jarod Wilson
2011-07-14 22:09 ` [PATCH 7/9] [media] mceusb: flash LED (emu v2+ only) to signal end of init Jarod Wilson
` (12 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
According to the specs, you can read the number of tx ports, number of
rx sensors, which tx ports have cables plugged into them, and which rx
sensors are active. In practice, most of my devices do seem to report
sane values for tx ports and rx sensors (but not all -- one without any
tx ports reports having them), and most report the active sensor
correctly, but only one of eight reports cabled tx ports correctly. So
for the most part, this is just for informational purposes.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 51 ++++++++++++++++++++++++++++++++++++++------
1 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 114fb13..e4171f7 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -440,6 +440,10 @@ struct mceusb_dev {
bool need_reset; /* flag to issue a device resume cmd */
u8 emver; /* emulator interface version */
+ u8 num_txports; /* number of transmit ports */
+ u8 num_rxports; /* number of receive sensors */
+ u8 txports_cabled; /* bitmask of transmitters with cable */
+ u8 rxports_active; /* bitmask of active receive sensors */
};
/* MCE Device Command Strings, generally a port and command pair */
@@ -451,6 +455,7 @@ static char GET_WAKEVERSION[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETWAKEVERSION};
static char GET_UNKNOWN2[] = {MCE_CMD_PORT_IR, MCE_CMD_UNKNOWN2};
static char GET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRCFS};
static char GET_RX_TIMEOUT[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTIMEOUT};
+static char GET_NUM_PORTS[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRNUMPORTS};
static char GET_TX_BITMASK[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTXPORTS};
static char GET_RX_SENSOR[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRRXPORTEN};
/* sub in desired values in lower byte or bytes for full command */
@@ -544,6 +549,8 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
switch (cmd) {
case MCE_CMD_NULL:
+ if (subcmd == MCE_CMD_NULL)
+ break;
if ((subcmd == MCE_CMD_PORT_SYS) &&
(data1 == MCE_CMD_RESUME))
dev_info(dev, "Device resume requested\n");
@@ -912,10 +919,20 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
u8 lo = ir->buf_in[index + 2] & 0xff;
switch (ir->buf_in[index]) {
+ /* the one and only 5-byte return value command */
+ case MCE_RSP_GETPORTSTATUS:
+ if ((ir->buf_in[index + 4] & 0xff) == 0x00)
+ ir->txports_cabled |= 1 << hi;
+ break;
+
/* 2-byte return value commands */
case MCE_RSP_EQIRTIMEOUT:
ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT);
break;
+ case MCE_RSP_EQIRNUMPORTS:
+ ir->num_txports = hi;
+ ir->num_rxports = lo;
+ break;
/* 1-byte return value commands */
case MCE_RSP_EQEMVER:
@@ -926,6 +943,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
break;
case MCE_RSP_EQIRRXPORTEN:
ir->learning_enabled = ((hi & 0x02) == 0x02);
+ ir->rxports_active = hi;
break;
case MCE_RSP_CMD_ILLEGAL:
ir->need_reset = true;
@@ -1118,10 +1136,21 @@ static void mceusb_gen2_init(struct mceusb_dev *ir)
static void mceusb_get_parameters(struct mceusb_dev *ir)
{
+ int i;
+ unsigned char cmdbuf[3] = { MCE_CMD_PORT_SYS,
+ MCE_CMD_GETPORTSTATUS, 0x00 };
+
+ /* defaults, if the hardware doesn't support querying */
+ ir->num_txports = 2;
+ ir->num_rxports = 2;
+
+ /* get number of tx and rx ports */
+ mce_async_out(ir, GET_NUM_PORTS, sizeof(GET_NUM_PORTS));
+
/* get the carrier and frequency */
mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
- if (!ir->flags.no_tx)
+ if (ir->num_txports && !ir->flags.no_tx)
/* get the transmitter bitmask */
mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
@@ -1130,6 +1159,11 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
/* get receiver sensor setting */
mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR));
+
+ for (i = 0; i < ir->num_txports; i++) {
+ cmdbuf[2] = i;
+ mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+ }
}
static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
@@ -1161,11 +1195,6 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protos = RC_TYPE_ALL;
rc->timeout = MS_TO_NS(100);
- if (!ir->flags.no_tx) {
- rc->s_tx_mask = mceusb_set_tx_mask;
- rc->s_tx_carrier = mceusb_set_tx_carrier;
- rc->tx_ir = mceusb_tx_ir;
- }
rc->driver_name = DRIVER_NAME;
rc->map_name = mceusb_model[ir->model].rc_map ?
mceusb_model[ir->model].rc_map : RC_MAP_RC6_MCE;
@@ -1314,8 +1343,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
mceusb_get_parameters(ir);
- if (!ir->flags.no_tx)
+ if (ir->num_txports && !ir->flags.no_tx) {
+ ir->rc->s_tx_mask = mceusb_set_tx_mask;
+ ir->rc->s_tx_carrier = mceusb_set_tx_carrier;
+ ir->rc->tx_ir = mceusb_tx_ir;
mceusb_set_tx_mask(ir->rc, MCE_DEFAULT_TX_MASK);
+ }
usb_set_intfdata(intf, ir);
@@ -1325,6 +1358,10 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
dev_info(&intf->dev, "Registered %s with mce emulator interface "
"version %x\n", name, ir->emver);
+ dev_info(&intf->dev, "%x tx ports (0x%x cabled) and "
+ "%x rx sensors (0x%x active)\n",
+ ir->num_txports, ir->txports_cabled,
+ ir->num_rxports, ir->rxports_active);
return 0;
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 7/9] [media] mceusb: flash LED (emu v2+ only) to signal end of init
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (5 preceding siblings ...)
2011-07-14 22:09 ` [PATCH 6/9] [media] mceusb: get misc port data from hardware Jarod Wilson
@ 2011-07-14 22:09 ` Jarod Wilson
2011-07-14 22:09 ` [PATCH 8/9] [media] mceusb: report actual tx frequencies Jarod Wilson
` (11 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index e4171f7..bbd79c0 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -452,6 +452,7 @@ static char DEVICE_RESUME[] = {MCE_CMD_NULL, MCE_CMD_PORT_SYS,
static char GET_REVISION[] = {MCE_CMD_PORT_SYS, MCE_CMD_G_REVISION};
static char GET_EMVER[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETEMVER};
static char GET_WAKEVERSION[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETWAKEVERSION};
+static char FLASH_LED[] = {MCE_CMD_PORT_SYS, MCE_CMD_FLASHLED};
static char GET_UNKNOWN2[] = {MCE_CMD_PORT_IR, MCE_CMD_UNKNOWN2};
static char GET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRCFS};
static char GET_RX_TIMEOUT[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTIMEOUT};
@@ -592,6 +593,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
dev_info(dev, "TX port %d: blaster is%s connected\n",
data1 + 1, data4 ? " not" : "");
break;
+ case MCE_CMD_FLASHLED:
+ dev_info(dev, "Attempting to flash LED\n");
+ break;
default:
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
@@ -1166,6 +1170,14 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
}
}
+static void mceusb_flash_led(struct mceusb_dev *ir)
+{
+ if (ir->emver < 2)
+ return;
+
+ mce_async_out(ir, FLASH_LED, sizeof(FLASH_LED));
+}
+
static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
{
struct device *dev = ir->dev;
@@ -1343,6 +1355,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
mceusb_get_parameters(ir);
+ mceusb_flash_led(ir);
+
if (ir->num_txports && !ir->flags.no_tx) {
ir->rc->s_tx_mask = mceusb_set_tx_mask;
ir->rc->s_tx_carrier = mceusb_set_tx_carrier;
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 8/9] [media] mceusb: report actual tx frequencies
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (6 preceding siblings ...)
2011-07-14 22:09 ` [PATCH 7/9] [media] mceusb: flash LED (emu v2+ only) to signal end of init Jarod Wilson
@ 2011-07-14 22:09 ` Jarod Wilson
2011-07-14 22:09 ` [PATCH 9/9] [media] mceusb: update version, copyright, author Jarod Wilson
` (10 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Rather than dumping out hex values, lets print the actual calculated
frequency and period the hardware has been configured for. After this
change:
[ 2643.276215] mceusb 3-1:1.0: tx data: 9f 07 (length=2)
[ 2643.276218] mceusb 3-1:1.0: Get carrier mode and freq
[ 2643.277206] mceusb 3-1:1.0: rx data: 9f 06 01 42 (length=4)
[ 2643.277209] mceusb 3-1:1.0: Got carrier of 37037 Hz (period 27us)
Matches up perfectly with the table in Microsoft's docs.
Of course, I've noticed on one of my devices that the MS-recommended
default value of 1 for carrier pre-scaler and 66 for carrier period was
butchered, and instead of converting 66 to hex (0x42 like above), they
put in 0x66, so the hardware reports a default carrier of 24390Hz.
Fortunately, I guess, this particular device is rx-only, but I wouldn't
put it past other hw to screw up here too.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 16 +++++++++++-----
1 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index bbd79c0..fa1d182 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -517,6 +517,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
u8 cmd, subcmd, data1, data2, data3, data4, data5;
struct device *dev = ir->dev;
int i, start, skip = 0;
+ u32 carrier, period;
if (!debug)
return;
@@ -614,9 +615,14 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n",
data1, data2);
break;
- case MCE_CMD_SETIRCFS:
- dev_info(dev, "%s carrier mode and freq of "
- "0x%02x 0x%02x\n", inout, data1, data2);
+ case MCE_RSP_EQIRCFS:
+ period = DIV_ROUND_CLOSEST(
+ (1 << data1 * 2) * (data2 + 1), 10);
+ if (!period)
+ break;
+ carrier = (1000 * 1000) / period;
+ dev_info(dev, "%s carrier of %u Hz (period %uus)\n",
+ inout, carrier, period);
break;
case MCE_CMD_GETIRCFS:
dev_info(dev, "Get carrier mode and freq\n");
@@ -627,9 +633,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
break;
case MCE_RSP_EQIRTIMEOUT:
/* value is in units of 50us, so x*50/1000 ms */
+ period = ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000;
dev_info(dev, "%s receive timeout of %d ms\n",
- inout,
- ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000);
+ inout, period);
break;
case MCE_CMD_GETIRTIMEOUT:
dev_info(dev, "Get receive timeout\n");
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 9/9] [media] mceusb: update version, copyright, author
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (7 preceding siblings ...)
2011-07-14 22:09 ` [PATCH 8/9] [media] mceusb: report actual tx frequencies Jarod Wilson
@ 2011-07-14 22:09 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 0/9] mceusb updates per MS docs Jarod Wilson
` (9 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-14 22:09 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Add note about recent updates coming from Microsoft's publicly available
specs on Windows Media Center remotes and receivers/transmitters.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index fa1d182..053d079 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -1,7 +1,7 @@
/*
* Driver for USB Windows Media Center Ed. eHome Infrared Transceivers
*
- * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
+ * Copyright (c) 2010-2011, Jarod Wilson <jarod@redhat.com>
*
* Based on the original lirc_mceusb and lirc_mceusb2 drivers, by Dan
* Conti, Martin Blatter and Daniel Melander, the latter of which was
@@ -15,6 +15,11 @@
* Jon Smirl, which included enhancements and simplifications to the
* incoming IR buffer parsing routines.
*
+ * Updated in July of 2011 with the aid of Microsoft's official
+ * remote/transceiver requirements and specification document, found at
+ * download.microsoft.com, title
+ * Windows-Media-Center-RC-IR-Collection-Green-Button-Specification-03-08-2011-V2.pdf
+ *
*
* 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
@@ -41,8 +46,8 @@
#include <linux/delay.h>
#include <media/rc-core.h>
-#define DRIVER_VERSION "1.91"
-#define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
+#define DRIVER_VERSION "1.92"
+#define DRIVER_AUTHOR "Jarod Wilson <jarod@redhat.com>"
#define DRIVER_DESC "Windows Media Center Ed. eHome Infrared Transceiver " \
"device driver"
#define DRIVER_NAME "mceusb"
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] [media] mceusb: give hardware time to reply to cmds
2011-07-14 22:09 ` [PATCH 2/9] [media] mceusb: give hardware time to reply to cmds Jarod Wilson
@ 2011-07-14 23:30 ` Mauro Carvalho Chehab
2011-07-18 17:47 ` Jarod Wilson
0 siblings, 1 reply; 23+ messages in thread
From: Mauro Carvalho Chehab @ 2011-07-14 23:30 UTC (permalink / raw)
To: Jarod Wilson; +Cc: linux-media
Em 14-07-2011 19:09, Jarod Wilson escreveu:
> Sometimes the init routine is blasting commands out to the hardware
> faster than it can reply. Throw a brief delay in there to give the
> hardware a chance to reply before we send the next command.
>
> Signed-off-by: Jarod Wilson <jarod@redhat.com>
> ---
> drivers/media/rc/mceusb.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
> index 111bead..13a853b 100644
> --- a/drivers/media/rc/mceusb.c
> +++ b/drivers/media/rc/mceusb.c
> @@ -37,6 +37,7 @@
> #include <linux/slab.h>
> #include <linux/usb.h>
> #include <linux/usb/input.h>
> +#include <linux/delay.h>
> #include <media/rc-core.h>
>
> #define DRIVER_VERSION "1.91"
> @@ -735,6 +736,7 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
> static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
> {
> mce_request_packet(ir, data, size, MCEUSB_TX);
> + mdelay(10);
Can't it be a msleep() instead? Delays spend more power, and keeps the CPU busy while
running.
> }
>
> static void mce_flush_rx_buffer(struct mceusb_dev *ir, int size)
Cheers,
Mauro
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] [media] mceusb: give hardware time to reply to cmds
2011-07-14 23:30 ` Mauro Carvalho Chehab
@ 2011-07-18 17:47 ` Jarod Wilson
2011-07-18 18:11 ` Jarod Wilson
0 siblings, 1 reply; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 17:47 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media
Mauro Carvalho Chehab wrote:
> Em 14-07-2011 19:09, Jarod Wilson escreveu:
>> Sometimes the init routine is blasting commands out to the hardware
>> faster than it can reply. Throw a brief delay in there to give the
>> hardware a chance to reply before we send the next command.
>>
>> Signed-off-by: Jarod Wilson<jarod@redhat.com>
>> ---
>> drivers/media/rc/mceusb.c | 2 ++
>> 1 files changed, 2 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
>> index 111bead..13a853b 100644
>> --- a/drivers/media/rc/mceusb.c
>> +++ b/drivers/media/rc/mceusb.c
>> @@ -37,6 +37,7 @@
>> #include<linux/slab.h>
>> #include<linux/usb.h>
>> #include<linux/usb/input.h>
>> +#include<linux/delay.h>
>> #include<media/rc-core.h>
>>
>> #define DRIVER_VERSION "1.91"
>> @@ -735,6 +736,7 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
>> static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
>> {
>> mce_request_packet(ir, data, size, MCEUSB_TX);
>> + mdelay(10);
>
> Can't it be a msleep() instead? Delays spend more power, and keeps the CPU busy while
> running.
I think I was thinking we'd end up sleeping in an interrupt handler when
we shouldn't be, but upon closer code inspection and actual testing,
that's not the case, so yeah, those can be msleeps. While testing all
code paths, I also discovered that patch 6 in the series breaks lirc tx
support (the lirc dev is registered before the tx function pointers are
filled in), so I'll resend at least patches 2 and 6...
--
Jarod Wilson
jarod@redhat.com
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] [media] mceusb: give hardware time to reply to cmds
2011-07-18 17:47 ` Jarod Wilson
@ 2011-07-18 18:11 ` Jarod Wilson
0 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 18:11 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media
Jarod Wilson wrote:
> Mauro Carvalho Chehab wrote:
>> Em 14-07-2011 19:09, Jarod Wilson escreveu:
>>> Sometimes the init routine is blasting commands out to the hardware
>>> faster than it can reply. Throw a brief delay in there to give the
>>> hardware a chance to reply before we send the next command.
>>>
>>> Signed-off-by: Jarod Wilson<jarod@redhat.com>
>>> ---
>>> drivers/media/rc/mceusb.c | 2 ++
>>> 1 files changed, 2 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
>>> index 111bead..13a853b 100644
>>> --- a/drivers/media/rc/mceusb.c
>>> +++ b/drivers/media/rc/mceusb.c
>>> @@ -37,6 +37,7 @@
>>> #include<linux/slab.h>
>>> #include<linux/usb.h>
>>> #include<linux/usb/input.h>
>>> +#include<linux/delay.h>
>>> #include<media/rc-core.h>
>>>
>>> #define DRIVER_VERSION "1.91"
>>> @@ -735,6 +736,7 @@ static void mce_request_packet(struct mceusb_dev
>>> *ir, unsigned char *data,
>>> static void mce_async_out(struct mceusb_dev *ir, unsigned char *data,
>>> int size)
>>> {
>>> mce_request_packet(ir, data, size, MCEUSB_TX);
>>> + mdelay(10);
>>
>> Can't it be a msleep() instead? Delays spend more power, and keeps the
>> CPU busy while
>> running.
>
> I think I was thinking we'd end up sleeping in an interrupt handler when
> we shouldn't be, but upon closer code inspection and actual testing,
> that's not the case, so yeah, those can be msleeps. While testing all
> code paths, I also discovered that patch 6 in the series breaks lirc tx
> support (the lirc dev is registered before the tx function pointers are
> filled in), so I'll resend at least patches 2 and 6...
I'll just resend an entire v2 series, the changes to patch 2 have
cascading impact on multiple patches in the rest of the series.
--
Jarod Wilson
jarod@redhat.com
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 0/9] mceusb updates per MS docs
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (8 preceding siblings ...)
2011-07-14 22:09 ` [PATCH 9/9] [media] mceusb: update version, copyright, author Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 1/9] [media] mceusb: command/response updates from " Jarod Wilson
` (8 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
This is a stack of updates made based on the Windows Media Center remote
and receiver/transmitter specification and requirements document that
Rafi Rubin recently pointed me at. Its titled
Windows-Media-Center-RC-IR-Collection-Green-Button-Specification-03-08-2011-V2.pdf
which as of this writing, is publicly available from
download.microsoft.com.
Tested with 7 different mceusb devices, with no ill effects. Unfortunately,
for the most part, these chagnes don't actually improve any shortcomings in
the driver, but they do give us a better view of the hardware features and
whatnot, and a few things are better explained now, with most of the command
and response bits lining up with what MS has documented.
v2: use msleep instead of mdelay, and fix a tx regression in v1
Jarod Wilson (9):
[media] mceusb: command/response updates from MS docs
[media] mceusb: give hardware time to reply to cmds
[media] mceusb: set wakeup bits for IR-based resume
[media] mceusb: issue device resume cmd when needed
[media] mceusb: query device for firmware emulator version
[media] mceusb: get misc port data from hardware
[media] mceusb: flash LED (emu v2+ only) to signal end of init
[media] mceusb: report actual tx frequencies
[media] mceusb: update version, copyright, author
drivers/media/rc/mceusb.c | 410 +++++++++++++++++++++++++++++++--------------
1 files changed, 280 insertions(+), 130 deletions(-)
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v2 1/9] [media] mceusb: command/response updates from MS docs
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (9 preceding siblings ...)
2011-07-18 19:54 ` [PATCH v2 0/9] mceusb updates per MS docs Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 2/9] [media] mceusb: give hardware time to reply to cmds Jarod Wilson
` (7 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
I was recently pointed to the document titled
Windows-Media-Center-RC-IR-Collection-Green-Button-Specification-03-08-2011-V2.pdf
which as of this writing, is publicly available from
download.microsoft.com. It covers a LOT of the gaps in the mceusb
driver, which to this point, was written almost entirely by
reverse-engineering. First up, I'm updating the defines for all the MCE
commands and responses to match their names in the spec. More to come...
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 293 ++++++++++++++++++++++++++------------------
1 files changed, 173 insertions(+), 120 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index ec972dc..111bead 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -63,43 +63,90 @@
#define MCE_PULSE_MASK 0x7f /* Pulse mask */
#define MCE_MAX_PULSE_LENGTH 0x7f /* Longest transmittable pulse symbol */
-#define MCE_HW_CMD_HEADER 0xff /* MCE hardware command header */
-#define MCE_COMMAND_HEADER 0x9f /* MCE command header */
-#define MCE_COMMAND_MASK 0xe0 /* Mask out command bits */
-#define MCE_COMMAND_NULL 0x00 /* These show up various places... */
-/* if buf[i] & MCE_COMMAND_MASK == 0x80 and buf[i] != MCE_COMMAND_HEADER,
- * then we're looking at a raw IR data sample */
-#define MCE_COMMAND_IRDATA 0x80
-#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
-
-/* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */
+/*
+ * The interface between the host and the IR hardware is command-response
+ * based. All commands and responses have a consistent format, where a lead
+ * byte always identifies the type of data following it. The lead byte has
+ * a port value in the 3 highest bits and a length value in the 5 lowest
+ * bits.
+ *
+ * The length field is overloaded, with a value of 11111 indicating that the
+ * following byte is a command or response code, and the length of the entire
+ * message is determined by the code. If the length field is not 11111, then
+ * it specifies the number of bytes of port data that follow.
+ */
+#define MCE_CMD 0x1f
+#define MCE_PORT_IR 0x4 /* (0x4 << 5) | MCE_CMD = 0x9f */
+#define MCE_PORT_SYS 0x7 /* (0x7 << 5) | MCE_CMD = 0xff */
+#define MCE_PORT_SER 0x6 /* 0xc0 thru 0xdf flush & 0x1f bytes */
+#define MCE_PORT_MASK 0xe0 /* Mask out command bits */
+
+/* Command port headers */
+#define MCE_CMD_PORT_IR 0x9f /* IR-related cmd/rsp */
+#define MCE_CMD_PORT_SYS 0xff /* System (non-IR) device cmd/rsp */
+
+/* Commands that set device state (2-4 bytes in length) */
+#define MCE_CMD_RESET 0xfe /* Reset device, 2 bytes */
+#define MCE_CMD_RESUME 0xaa /* Resume device after error, 2 bytes */
+#define MCE_CMD_SETIRCFS 0x06 /* Set tx carrier, 4 bytes */
+#define MCE_CMD_SETIRTIMEOUT 0x0c /* Set timeout, 4 bytes */
+#define MCE_CMD_SETIRTXPORTS 0x08 /* Set tx ports, 3 bytes */
+#define MCE_CMD_SETIRRXPORTEN 0x14 /* Set rx ports, 3 bytes */
+#define MCE_CMD_FLASHLED 0x23 /* Flash receiver LED, 2 bytes */
+
+/* Commands that query device state (all 2 bytes, unless noted) */
+#define MCE_CMD_GETIRCFS 0x07 /* Get carrier */
+#define MCE_CMD_GETIRTIMEOUT 0x0d /* Get timeout */
+#define MCE_CMD_GETIRTXPORTS 0x13 /* Get tx ports */
+#define MCE_CMD_GETIRRXPORTEN 0x15 /* Get rx ports */
+#define MCE_CMD_GETPORTSTATUS 0x11 /* Get tx port status, 3 bytes */
+#define MCE_CMD_GETIRNUMPORTS 0x16 /* Get number of ports */
+#define MCE_CMD_GETWAKESOURCE 0x17 /* Get wake source */
+#define MCE_CMD_GETEMVER 0x22 /* Get emulator interface version */
+#define MCE_CMD_GETDEVDETAILS 0x21 /* Get device details (em ver2 only) */
+#define MCE_CMD_GETWAKESUPPORT 0x20 /* Get wake details (em ver2 only) */
+#define MCE_CMD_GETWAKEVERSION 0x18 /* Get wake pattern (em ver2 only) */
+
+/* Misc commands */
+#define MCE_CMD_NOP 0xff /* No operation */
+
+/* Responses to commands (non-error cases) */
+#define MCE_RSP_EQIRCFS 0x06 /* tx carrier, 4 bytes */
+#define MCE_RSP_EQIRTIMEOUT 0x0c /* rx timeout, 4 bytes */
+#define MCE_RSP_GETWAKESOURCE 0x17 /* wake source, 3 bytes */
+#define MCE_RSP_EQIRTXPORTS 0x08 /* tx port mask, 3 bytes */
+#define MCE_RSP_EQIRRXPORTEN 0x14 /* rx port mask, 3 bytes */
+#define MCE_RSP_GETPORTSTATUS 0x11 /* tx port status, 7 bytes */
+#define MCE_RSP_EQIRRXCFCNT 0x15 /* rx carrier count, 4 bytes */
+#define MCE_RSP_EQIRNUMPORTS 0x16 /* number of ports, 4 bytes */
+#define MCE_RSP_EQWAKESUPPORT 0x20 /* wake capabilities, 3 bytes */
+#define MCE_RSP_EQWAKEVERSION 0x18 /* wake pattern details, 6 bytes */
+#define MCE_RSP_EQDEVDETAILS 0x21 /* device capabilities, 3 bytes */
+#define MCE_RSP_EQEMVER 0x22 /* emulator interface ver, 3 bytes */
+#define MCE_RSP_FLASHLED 0x23 /* success flashing LED, 2 bytes */
+
+/* Responses to error cases, must send MCE_CMD_RESUME to clear them */
+#define MCE_RSP_CMD_ILLEGAL 0xfe /* illegal command for port, 2 bytes */
+#define MCE_RSP_TX_TIMEOUT 0x81 /* tx timed out, 2 bytes */
+
+/* Misc commands/responses not defined in the MCE remote/transceiver spec */
#define MCE_CMD_SIG_END 0x01 /* End of signal */
#define MCE_CMD_PING 0x03 /* Ping device */
#define MCE_CMD_UNKNOWN 0x04 /* Unknown */
#define MCE_CMD_UNKNOWN2 0x05 /* Unknown */
-#define MCE_CMD_S_CARRIER 0x06 /* Set TX carrier frequency */
-#define MCE_CMD_G_CARRIER 0x07 /* Get TX carrier frequency */
-#define MCE_CMD_S_TXMASK 0x08 /* Set TX port bitmask */
#define MCE_CMD_UNKNOWN3 0x09 /* Unknown */
#define MCE_CMD_UNKNOWN4 0x0a /* Unknown */
#define MCE_CMD_G_REVISION 0x0b /* Get hw/sw revision */
-#define MCE_CMD_S_TIMEOUT 0x0c /* Set RX timeout value */
-#define MCE_CMD_G_TIMEOUT 0x0d /* Get RX timeout value */
#define MCE_CMD_UNKNOWN5 0x0e /* Unknown */
#define MCE_CMD_UNKNOWN6 0x0f /* Unknown */
-#define MCE_CMD_G_RXPORTSTS 0x11 /* Get RX port status */
-#define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */
-#define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */
-#define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */
-#define MCE_RSP_PULSE_COUNT 0x15 /* RX pulse count (only if learning) */
-#define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */
-#define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */
-#define MCE_CMD_UNKNOWN7 0x18 /* Unknown */
#define MCE_CMD_UNKNOWN8 0x19 /* Unknown */
#define MCE_CMD_UNKNOWN9 0x1b /* Unknown */
-#define MCE_CMD_DEVICE_RESET 0xaa /* Reset the hardware */
-#define MCE_RSP_CMD_INVALID 0xfe /* Invalid command issued */
+#define MCE_CMD_NULL 0x00 /* These show up various places... */
+/* if buf[i] & MCE_PORT_MASK == 0x80 and buf[i] != MCE_CMD_PORT_IR,
+ * then we're looking at a raw IR data sample */
+#define MCE_COMMAND_IRDATA 0x80
+#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
/* module parameters */
#ifdef CONFIG_USB_DEBUG
@@ -390,46 +437,25 @@ struct mceusb_dev {
enum mceusb_model_type model;
};
-/*
- * MCE Device Command Strings
- * Device command responses vary from device to device...
- * - DEVICE_RESET resets the hardware to its default state
- * - GET_REVISION fetches the hardware/software revision, common
- * replies are ff 0b 45 ff 1b 08 and ff 0b 50 ff 1b 42
- * - GET_CARRIER_FREQ gets the carrier mode and frequency of the
- * device, with replies in the form of 9f 06 MM FF, where MM is 0-3,
- * meaning clk of 10000000, 2500000, 625000 or 156250, and FF is
- * ((clk / frequency) - 1)
- * - GET_RX_TIMEOUT fetches the receiver timeout in units of 50us,
- * response in the form of 9f 0c msb lsb
- * - GET_TX_BITMASK fetches the transmitter bitmask, replies in
- * the form of 9f 08 bm, where bm is the bitmask
- * - GET_RX_SENSOR fetches the RX sensor setting -- long-range
- * general use one or short-range learning one, in the form of
- * 9f 14 ss, where ss is either 01 for long-range or 02 for short
- * - SET_CARRIER_FREQ sets a new carrier mode and frequency
- * - SET_TX_BITMASK sets the transmitter bitmask
- * - SET_RX_TIMEOUT sets the receiver timeout
- * - SET_RX_SENSOR sets which receiver sensor to use
- */
-static char DEVICE_RESET[] = {MCE_COMMAND_NULL, MCE_HW_CMD_HEADER,
- MCE_CMD_DEVICE_RESET};
-static char GET_REVISION[] = {MCE_HW_CMD_HEADER, MCE_CMD_G_REVISION};
-static char GET_UNKNOWN[] = {MCE_HW_CMD_HEADER, MCE_CMD_UNKNOWN7};
-static char GET_UNKNOWN2[] = {MCE_COMMAND_HEADER, MCE_CMD_UNKNOWN2};
-static char GET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER, MCE_CMD_G_CARRIER};
-static char GET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TIMEOUT};
-static char GET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_G_TXMASK};
-static char GET_RX_SENSOR[] = {MCE_COMMAND_HEADER, MCE_CMD_G_RXSENSOR};
+/* MCE Device Command Strings, generally a port and command pair */
+static char DEVICE_RESUME[] = {MCE_CMD_NULL, MCE_CMD_PORT_SYS,
+ MCE_CMD_RESUME};
+static char GET_REVISION[] = {MCE_CMD_PORT_SYS, MCE_CMD_G_REVISION};
+static char GET_WAKEVERSION[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETWAKEVERSION};
+static char GET_UNKNOWN2[] = {MCE_CMD_PORT_IR, MCE_CMD_UNKNOWN2};
+static char GET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRCFS};
+static char GET_RX_TIMEOUT[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTIMEOUT};
+static char GET_TX_BITMASK[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTXPORTS};
+static char GET_RX_SENSOR[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRRXPORTEN};
/* sub in desired values in lower byte or bytes for full command */
/* FIXME: make use of these for transmit.
-static char SET_CARRIER_FREQ[] = {MCE_COMMAND_HEADER,
- MCE_CMD_S_CARRIER, 0x00, 0x00};
-static char SET_TX_BITMASK[] = {MCE_COMMAND_HEADER, MCE_CMD_S_TXMASK, 0x00};
-static char SET_RX_TIMEOUT[] = {MCE_COMMAND_HEADER,
- MCE_CMD_S_TIMEOUT, 0x00, 0x00};
-static char SET_RX_SENSOR[] = {MCE_COMMAND_HEADER,
- MCE_CMD_S_RXSENSOR, 0x00};
+static char SET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR,
+ MCE_CMD_SETIRCFS, 0x00, 0x00};
+static char SET_TX_BITMASK[] = {MCE_CMD_PORT_IR, MCE_CMD_SETIRTXPORTS, 0x00};
+static char SET_RX_TIMEOUT[] = {MCE_CMD_PORT_IR,
+ MCE_CMD_SETIRTIMEOUT, 0x00, 0x00};
+static char SET_RX_SENSOR[] = {MCE_CMD_PORT_IR,
+ MCE_RSP_EQIRRXPORTEN, 0x00};
*/
static int mceusb_cmdsize(u8 cmd, u8 subcmd)
@@ -437,27 +463,33 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd)
int datasize = 0;
switch (cmd) {
- case MCE_COMMAND_NULL:
- if (subcmd == MCE_HW_CMD_HEADER)
+ case MCE_CMD_NULL:
+ if (subcmd == MCE_CMD_PORT_SYS)
datasize = 1;
break;
- case MCE_HW_CMD_HEADER:
+ case MCE_CMD_PORT_SYS:
switch (subcmd) {
+ case MCE_RSP_EQWAKEVERSION:
+ datasize = 4;
+ break;
case MCE_CMD_G_REVISION:
datasize = 2;
break;
+ case MCE_RSP_EQWAKESUPPORT:
+ datasize = 1;
+ break;
}
- case MCE_COMMAND_HEADER:
+ case MCE_CMD_PORT_IR:
switch (subcmd) {
case MCE_CMD_UNKNOWN:
- case MCE_CMD_S_CARRIER:
- case MCE_CMD_S_TIMEOUT:
- case MCE_RSP_PULSE_COUNT:
+ case MCE_RSP_EQIRCFS:
+ case MCE_RSP_EQIRTIMEOUT:
+ case MCE_RSP_EQIRRXCFCNT:
datasize = 2;
break;
case MCE_CMD_SIG_END:
- case MCE_CMD_S_TXMASK:
- case MCE_CMD_S_RXSENSOR:
+ case MCE_RSP_EQIRTXPORTS:
+ case MCE_RSP_EQIRRXPORTEN:
datasize = 1;
break;
}
@@ -470,7 +502,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
{
char codes[USB_BUFLEN * 3 + 1];
char inout[9];
- u8 cmd, subcmd, data1, data2;
+ u8 cmd, subcmd, data1, data2, data3, data4, data5;
struct device *dev = ir->dev;
int i, start, skip = 0;
@@ -500,18 +532,26 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
subcmd = buf[start + 1] & 0xff;
data1 = buf[start + 2] & 0xff;
data2 = buf[start + 3] & 0xff;
+ data3 = buf[start + 4] & 0xff;
+ data4 = buf[start + 5] & 0xff;
+ data5 = buf[start + 6] & 0xff;
switch (cmd) {
- case MCE_COMMAND_NULL:
- if ((subcmd == MCE_HW_CMD_HEADER) &&
- (data1 == MCE_CMD_DEVICE_RESET))
- dev_info(dev, "Device reset requested\n");
+ case MCE_CMD_NULL:
+ if ((subcmd == MCE_CMD_PORT_SYS) &&
+ (data1 == MCE_CMD_RESUME))
+ dev_info(dev, "Device resume requested\n");
else
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
break;
- case MCE_HW_CMD_HEADER:
+ case MCE_CMD_PORT_SYS:
switch (subcmd) {
+ case MCE_RSP_EQEMVER:
+ if (!out)
+ dev_info(dev, "Emulator interface version %x\n",
+ data1);
+ break;
case MCE_CMD_G_REVISION:
if (len == 2)
dev_info(dev, "Get hw/sw rev?\n");
@@ -520,21 +560,32 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
"0x%02x 0x%02x\n", data1, data2,
buf[start + 4], buf[start + 5]);
break;
- case MCE_CMD_DEVICE_RESET:
- dev_info(dev, "Device reset requested\n");
+ case MCE_CMD_RESUME:
+ dev_info(dev, "Device resume requested\n");
+ break;
+ case MCE_RSP_CMD_ILLEGAL:
+ dev_info(dev, "Illegal PORT_SYS command\n");
+ break;
+ case MCE_RSP_EQWAKEVERSION:
+ if (!out)
+ dev_info(dev, "Wake version, proto: 0x%02x, "
+ "payload: 0x%02x, address: 0x%02x, "
+ "version: 0x%02x\n",
+ data1, data2, data3, data4);
break;
- case MCE_RSP_CMD_INVALID:
- dev_info(dev, "Previous command not supported\n");
+ case MCE_RSP_GETPORTSTATUS:
+ if (!out)
+ /* We use data1 + 1 here, to match hw labels */
+ dev_info(dev, "TX port %d: blaster is%s connected\n",
+ data1 + 1, data4 ? " not" : "");
break;
- case MCE_CMD_UNKNOWN7:
- case MCE_CMD_UNKNOWN9:
default:
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
break;
}
break;
- case MCE_COMMAND_HEADER:
+ case MCE_CMD_PORT_IR:
switch (subcmd) {
case MCE_CMD_SIG_END:
dev_info(dev, "End of signal\n");
@@ -546,47 +597,50 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n",
data1, data2);
break;
- case MCE_CMD_S_CARRIER:
+ case MCE_CMD_SETIRCFS:
dev_info(dev, "%s carrier mode and freq of "
"0x%02x 0x%02x\n", inout, data1, data2);
break;
- case MCE_CMD_G_CARRIER:
+ case MCE_CMD_GETIRCFS:
dev_info(dev, "Get carrier mode and freq\n");
break;
- case MCE_CMD_S_TXMASK:
+ case MCE_RSP_EQIRTXPORTS:
dev_info(dev, "%s transmit blaster mask of 0x%02x\n",
inout, data1);
break;
- case MCE_CMD_S_TIMEOUT:
+ case MCE_RSP_EQIRTIMEOUT:
/* value is in units of 50us, so x*50/1000 ms */
dev_info(dev, "%s receive timeout of %d ms\n",
inout,
((data1 << 8) | data2) * MCE_TIME_UNIT / 1000);
break;
- case MCE_CMD_G_TIMEOUT:
+ case MCE_CMD_GETIRTIMEOUT:
dev_info(dev, "Get receive timeout\n");
break;
- case MCE_CMD_G_TXMASK:
+ case MCE_CMD_GETIRTXPORTS:
dev_info(dev, "Get transmit blaster mask\n");
break;
- case MCE_CMD_S_RXSENSOR:
+ case MCE_RSP_EQIRRXPORTEN:
dev_info(dev, "%s %s-range receive sensor in use\n",
inout, data1 == 0x02 ? "short" : "long");
break;
- case MCE_CMD_G_RXSENSOR:
- /* aka MCE_RSP_PULSE_COUNT */
+ case MCE_CMD_GETIRRXPORTEN:
+ /* aka MCE_RSP_EQIRRXCFCNT */
if (out)
dev_info(dev, "Get receive sensor\n");
else if (ir->learning_enabled)
dev_info(dev, "RX pulse count: %d\n",
((data1 << 8) | data2));
break;
- case MCE_RSP_CMD_INVALID:
- dev_info(dev, "Error! Hardware is likely wedged...\n");
+ case MCE_RSP_EQIRNUMPORTS:
+ if (out)
+ break;
+ dev_info(dev, "Num TX ports: %x, num RX ports: %x\n",
+ data1, data2);
+ break;
+ case MCE_RSP_CMD_ILLEGAL:
+ dev_info(dev, "Illegal PORT_IR command\n");
break;
- case MCE_CMD_UNKNOWN2:
- case MCE_CMD_UNKNOWN3:
- case MCE_CMD_UNKNOWN5:
default:
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
@@ -599,8 +653,8 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
if (cmd == MCE_IRDATA_TRAILER)
dev_info(dev, "End of raw IR data\n");
- else if ((cmd != MCE_COMMAND_HEADER) &&
- ((cmd & MCE_COMMAND_MASK) == MCE_COMMAND_IRDATA))
+ else if ((cmd != MCE_CMD_PORT_IR) &&
+ ((cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA))
dev_info(dev, "Raw IR data, %d pulse/space samples\n", ir->rem);
}
@@ -616,9 +670,6 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs)
if (ir) {
len = urb->actual_length;
- mce_dbg(ir->dev, "callback called (status=%d len=%d)\n",
- urb->status, len);
-
mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true);
}
@@ -710,8 +761,8 @@ static int mceusb_tx_ir(struct rc_dev *dev, int *txbuf, u32 n)
return -ENOMEM;
/* MCE tx init header */
- cmdbuf[cmdcount++] = MCE_COMMAND_HEADER;
- cmdbuf[cmdcount++] = MCE_CMD_S_TXMASK;
+ cmdbuf[cmdcount++] = MCE_CMD_PORT_IR;
+ cmdbuf[cmdcount++] = MCE_CMD_SETIRTXPORTS;
cmdbuf[cmdcount++] = ir->tx_mask;
/* Generate mce packet data */
@@ -797,8 +848,8 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
struct mceusb_dev *ir = dev->priv;
int clk = 10000000;
int prescaler = 0, divisor = 0;
- unsigned char cmdbuf[4] = { MCE_COMMAND_HEADER,
- MCE_CMD_S_CARRIER, 0x00, 0x00 };
+ unsigned char cmdbuf[4] = { MCE_CMD_PORT_IR,
+ MCE_CMD_SETIRCFS, 0x00, 0x00 };
/* Carrier has changed */
if (ir->carrier != carrier) {
@@ -847,16 +898,16 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
switch (ir->buf_in[index]) {
/* 2-byte return value commands */
- case MCE_CMD_S_TIMEOUT:
+ case MCE_RSP_EQIRTIMEOUT:
ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT);
break;
/* 1-byte return value commands */
- case MCE_CMD_S_TXMASK:
+ case MCE_RSP_EQIRTXPORTS:
ir->tx_mask = hi;
break;
- case MCE_CMD_S_RXSENSOR:
- ir->learning_enabled = (hi == 0x02);
+ case MCE_RSP_EQIRRXPORTEN:
+ ir->learning_enabled = ((hi & 0x02) == 0x02);
break;
default:
break;
@@ -905,8 +956,8 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
/* decode mce packets of the form (84),AA,BB,CC,DD */
/* IR data packets can span USB messages - rem */
ir->cmd = ir->buf_in[i];
- if ((ir->cmd == MCE_COMMAND_HEADER) ||
- ((ir->cmd & MCE_COMMAND_MASK) !=
+ if ((ir->cmd == MCE_CMD_PORT_IR) ||
+ ((ir->cmd & MCE_PORT_MASK) !=
MCE_COMMAND_IRDATA)) {
ir->parser_state = SUBCMD;
continue;
@@ -1013,8 +1064,8 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
0x0000, 0x0100, NULL, 0, HZ * 3);
mce_dbg(dev, "%s - retC = %d\n", __func__, ret);
- /* device reset */
- mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
+ /* device resume */
+ mce_async_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME));
/* get hw/sw revision? */
mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
@@ -1024,14 +1075,16 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
static void mceusb_gen2_init(struct mceusb_dev *ir)
{
- /* device reset */
- mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
+ /* device resume */
+ mce_async_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME));
/* get hw/sw revision? */
mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
- /* unknown what the next two actually return... */
- mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN));
+ /* get wake version (protocol, key, address) */
+ mce_async_out(ir, GET_WAKEVERSION, sizeof(GET_WAKEVERSION));
+
+ /* unknown what this one actually returns... */
mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2));
}
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 2/9] [media] mceusb: give hardware time to reply to cmds
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (10 preceding siblings ...)
2011-07-18 19:54 ` [PATCH v2 1/9] [media] mceusb: command/response updates from " Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 3/9] [media] mceusb: set wakeup bits for IR-based resume Jarod Wilson
` (6 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Sometimes the init routine is blasting commands out to the hardware
faster than it can reply. Throw a brief delay in there to give the
hardware a chance to reply before we send the next command.
v2: use msleep instead of mdelay per Mauro's suggestion
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 111bead..b1ea485 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -735,6 +735,7 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
{
mce_request_packet(ir, data, size, MCEUSB_TX);
+ msleep(10);
}
static void mce_flush_rx_buffer(struct mceusb_dev *ir, int size)
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 3/9] [media] mceusb: set wakeup bits for IR-based resume
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (11 preceding siblings ...)
2011-07-18 19:54 ` [PATCH v2 2/9] [media] mceusb: give hardware time to reply to cmds Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 4/9] [media] mceusb: issue device resume cmd when needed Jarod Wilson
` (5 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Its not uncommon for folks to force these bits enabled, because people
do want to wake their htpc kit via their remote. Lets just set the bits
for 'em.
v2: rebase for mdelay->msleep changes
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index b1ea485..ab074a3 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -37,6 +37,7 @@
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
+#include <linux/pm_wakeup.h>
#include <media/rc-core.h>
#define DRIVER_VERSION "1.91"
@@ -1289,6 +1290,10 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
usb_set_intfdata(intf, ir);
+ /* enable wake via this device */
+ device_set_wakeup_capable(ir->dev, true);
+ device_set_wakeup_enable(ir->dev, true);
+
dev_info(&intf->dev, "Registered %s on usb%d:%d\n", name,
dev->bus->busnum, dev->devnum);
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 4/9] [media] mceusb: issue device resume cmd when needed
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (12 preceding siblings ...)
2011-07-18 19:54 ` [PATCH v2 3/9] [media] mceusb: set wakeup bits for IR-based resume Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 5/9] [media] mceusb: query device for firmware emulator version Jarod Wilson
` (4 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
According to MS docs, the device firmware may halt after receiving an
unknown instruction, but that it should be possible to tell the firmware
to continue running by simply sending a device resume command. So lets
do that.
v2: use msleep instead of mdelay per Mauro's suggestion
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index ab074a3..f1fc11d 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -436,6 +436,8 @@ struct mceusb_dev {
char name[128];
char phys[64];
enum mceusb_model_type model;
+
+ bool need_reset; /* flag to issue a device resume cmd */
};
/* MCE Device Command Strings, generally a port and command pair */
@@ -735,6 +737,14 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
{
+ int rsize = sizeof(DEVICE_RESUME);
+
+ if (ir->need_reset) {
+ ir->need_reset = false;
+ mce_request_packet(ir, DEVICE_RESUME, rsize, MCEUSB_TX);
+ msleep(10);
+ }
+
mce_request_packet(ir, data, size, MCEUSB_TX);
msleep(10);
}
@@ -911,6 +921,9 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
case MCE_RSP_EQIRRXPORTEN:
ir->learning_enabled = ((hi & 0x02) == 0x02);
break;
+ case MCE_RSP_CMD_ILLEGAL:
+ ir->need_reset = true;
+ break;
default:
break;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 5/9] [media] mceusb: query device for firmware emulator version
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (13 preceding siblings ...)
2011-07-18 19:54 ` [PATCH v2 4/9] [media] mceusb: issue device resume cmd when needed Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 6/9] [media] mceusb: get misc port data from hardware Jarod Wilson
` (3 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Supposedly, there are essentially three different classes of devices
that are compatible with Microsoft's specs. First are the "legacy"
devices, which are built using Microsoft-provided hardware specs and
firmware. Second are "emulator" devices, which are built using custom
hardware and firmware, written to emulate Microsoft's firmware. Third
are "port" devices, which have their own device driver and firmware,
which provides compatible data to higher levels of the stack.
>From what I can tell, things like nuvoton-cir and fintek-cir are
essentially "port" devices -- their raw IR buffer format is very similar
to that of the mceusb devices. Now, within the mceusb driver, we have
three different "generations", which at first, seemed like maybe they
mapped to emulator versions. Unfortuantely, every single device I have
responds "illegal command" to the query to get firmware emulator version
from the hardware, which means they're either all emulator version 1, or
they're legacy devices, and our different "generations" aren't at all
related here. Though in theory, its possible the gen1 devices are
"legacy" devices and the rest are emulator v1. There are some useful
features of the v2 interface I was hoping to play with, but alas...
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 19 +++++++++++++++++--
1 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index f1fc11d..fb2fa9d 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -438,12 +438,14 @@ struct mceusb_dev {
enum mceusb_model_type model;
bool need_reset; /* flag to issue a device resume cmd */
+ u8 emver; /* emulator interface version */
};
/* MCE Device Command Strings, generally a port and command pair */
static char DEVICE_RESUME[] = {MCE_CMD_NULL, MCE_CMD_PORT_SYS,
MCE_CMD_RESUME};
static char GET_REVISION[] = {MCE_CMD_PORT_SYS, MCE_CMD_G_REVISION};
+static char GET_EMVER[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETEMVER};
static char GET_WAKEVERSION[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETWAKEVERSION};
static char GET_UNKNOWN2[] = {MCE_CMD_PORT_IR, MCE_CMD_UNKNOWN2};
static char GET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRCFS};
@@ -915,6 +917,9 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
break;
/* 1-byte return value commands */
+ case MCE_RSP_EQEMVER:
+ ir->emver = hi;
+ break;
case MCE_RSP_EQIRTXPORTS:
ir->tx_mask = hi;
break;
@@ -1037,6 +1042,13 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
usb_submit_urb(urb, GFP_ATOMIC);
}
+static void mceusb_get_emulator_version(struct mceusb_dev *ir)
+{
+ /* If we get no reply or an illegal command reply, its ver 1, says MS */
+ ir->emver = 1;
+ mce_async_out(ir, GET_EMVER, sizeof(GET_EMVER));
+}
+
static void mceusb_gen1_init(struct mceusb_dev *ir)
{
int ret;
@@ -1290,6 +1302,9 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
mce_dbg(&intf->dev, "Flushing receive buffers\n");
mce_flush_rx_buffer(ir, maxp);
+ /* figure out which firmware/emulator version this hardware has */
+ mceusb_get_emulator_version(ir);
+
/* initialize device */
if (ir->flags.microsoft_gen1)
mceusb_gen1_init(ir);
@@ -1307,8 +1322,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
device_set_wakeup_capable(ir->dev, true);
device_set_wakeup_enable(ir->dev, true);
- dev_info(&intf->dev, "Registered %s on usb%d:%d\n", name,
- dev->bus->busnum, dev->devnum);
+ dev_info(&intf->dev, "Registered %s with mce emulator interface "
+ "version %x\n", name, ir->emver);
return 0;
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 6/9] [media] mceusb: get misc port data from hardware
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (14 preceding siblings ...)
2011-07-18 19:54 ` [PATCH v2 5/9] [media] mceusb: query device for firmware emulator version Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 7/9] [media] mceusb: flash LED (emu v2+ only) to signal end of init Jarod Wilson
` (2 subsequent siblings)
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
According to the specs, you can read the number of tx ports, number of
rx sensors, which tx ports have cables plugged into them, and which rx
sensors are active. In practice, most of my devices do seem to report
sane values for tx ports and rx sensors (but not all -- one without any
tx ports reports having them), and most report the active sensor
correctly, but only one of eight reports cabled tx ports correctly. So
for the most part, this is just for informational purposes.
v2: put tx function wiring back where it was to un-break lirc tx
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 files changed, 39 insertions(+), 1 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index fb2fa9d..9e71aef 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -439,6 +439,10 @@ struct mceusb_dev {
bool need_reset; /* flag to issue a device resume cmd */
u8 emver; /* emulator interface version */
+ u8 num_txports; /* number of transmit ports */
+ u8 num_rxports; /* number of receive sensors */
+ u8 txports_cabled; /* bitmask of transmitters with cable */
+ u8 rxports_active; /* bitmask of active receive sensors */
};
/* MCE Device Command Strings, generally a port and command pair */
@@ -450,6 +454,7 @@ static char GET_WAKEVERSION[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETWAKEVERSION};
static char GET_UNKNOWN2[] = {MCE_CMD_PORT_IR, MCE_CMD_UNKNOWN2};
static char GET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRCFS};
static char GET_RX_TIMEOUT[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTIMEOUT};
+static char GET_NUM_PORTS[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRNUMPORTS};
static char GET_TX_BITMASK[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTXPORTS};
static char GET_RX_SENSOR[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRRXPORTEN};
/* sub in desired values in lower byte or bytes for full command */
@@ -543,6 +548,8 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
switch (cmd) {
case MCE_CMD_NULL:
+ if (subcmd == MCE_CMD_NULL)
+ break;
if ((subcmd == MCE_CMD_PORT_SYS) &&
(data1 == MCE_CMD_RESUME))
dev_info(dev, "Device resume requested\n");
@@ -911,10 +918,20 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
u8 lo = ir->buf_in[index + 2] & 0xff;
switch (ir->buf_in[index]) {
+ /* the one and only 5-byte return value command */
+ case MCE_RSP_GETPORTSTATUS:
+ if ((ir->buf_in[index + 4] & 0xff) == 0x00)
+ ir->txports_cabled |= 1 << hi;
+ break;
+
/* 2-byte return value commands */
case MCE_RSP_EQIRTIMEOUT:
ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT);
break;
+ case MCE_RSP_EQIRNUMPORTS:
+ ir->num_txports = hi;
+ ir->num_rxports = lo;
+ break;
/* 1-byte return value commands */
case MCE_RSP_EQEMVER:
@@ -925,6 +942,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
break;
case MCE_RSP_EQIRRXPORTEN:
ir->learning_enabled = ((hi & 0x02) == 0x02);
+ ir->rxports_active = hi;
break;
case MCE_RSP_CMD_ILLEGAL:
ir->need_reset = true;
@@ -1117,10 +1135,21 @@ static void mceusb_gen2_init(struct mceusb_dev *ir)
static void mceusb_get_parameters(struct mceusb_dev *ir)
{
+ int i;
+ unsigned char cmdbuf[3] = { MCE_CMD_PORT_SYS,
+ MCE_CMD_GETPORTSTATUS, 0x00 };
+
+ /* defaults, if the hardware doesn't support querying */
+ ir->num_txports = 2;
+ ir->num_rxports = 2;
+
+ /* get number of tx and rx ports */
+ mce_async_out(ir, GET_NUM_PORTS, sizeof(GET_NUM_PORTS));
+
/* get the carrier and frequency */
mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
- if (!ir->flags.no_tx)
+ if (ir->num_txports && !ir->flags.no_tx)
/* get the transmitter bitmask */
mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
@@ -1129,6 +1158,11 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
/* get receiver sensor setting */
mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR));
+
+ for (i = 0; i < ir->num_txports; i++) {
+ cmdbuf[2] = i;
+ mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+ }
}
static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
@@ -1324,6 +1358,10 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
dev_info(&intf->dev, "Registered %s with mce emulator interface "
"version %x\n", name, ir->emver);
+ dev_info(&intf->dev, "%x tx ports (0x%x cabled) and "
+ "%x rx sensors (0x%x active)\n",
+ ir->num_txports, ir->txports_cabled,
+ ir->num_rxports, ir->rxports_active);
return 0;
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 7/9] [media] mceusb: flash LED (emu v2+ only) to signal end of init
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (15 preceding siblings ...)
2011-07-18 19:54 ` [PATCH v2 6/9] [media] mceusb: get misc port data from hardware Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 8/9] [media] mceusb: report actual tx frequencies Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 9/9] [media] mceusb: update version, copyright, author Jarod Wilson
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
v2: rebase for mdelay->msleep changes and tx fix
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 9e71aef..160409e 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -451,6 +451,7 @@ static char DEVICE_RESUME[] = {MCE_CMD_NULL, MCE_CMD_PORT_SYS,
static char GET_REVISION[] = {MCE_CMD_PORT_SYS, MCE_CMD_G_REVISION};
static char GET_EMVER[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETEMVER};
static char GET_WAKEVERSION[] = {MCE_CMD_PORT_SYS, MCE_CMD_GETWAKEVERSION};
+static char FLASH_LED[] = {MCE_CMD_PORT_SYS, MCE_CMD_FLASHLED};
static char GET_UNKNOWN2[] = {MCE_CMD_PORT_IR, MCE_CMD_UNKNOWN2};
static char GET_CARRIER_FREQ[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRCFS};
static char GET_RX_TIMEOUT[] = {MCE_CMD_PORT_IR, MCE_CMD_GETIRTIMEOUT};
@@ -591,6 +592,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
dev_info(dev, "TX port %d: blaster is%s connected\n",
data1 + 1, data4 ? " not" : "");
break;
+ case MCE_CMD_FLASHLED:
+ dev_info(dev, "Attempting to flash LED\n");
+ break;
default:
dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
cmd, subcmd);
@@ -1165,6 +1169,14 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
}
}
+static void mceusb_flash_led(struct mceusb_dev *ir)
+{
+ if (ir->emver < 2)
+ return;
+
+ mce_async_out(ir, FLASH_LED, sizeof(FLASH_LED));
+}
+
static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
{
struct device *dev = ir->dev;
@@ -1347,6 +1359,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
mceusb_get_parameters(ir);
+ mceusb_flash_led(ir);
+
if (!ir->flags.no_tx)
mceusb_set_tx_mask(ir->rc, MCE_DEFAULT_TX_MASK);
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 8/9] [media] mceusb: report actual tx frequencies
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (16 preceding siblings ...)
2011-07-18 19:54 ` [PATCH v2 7/9] [media] mceusb: flash LED (emu v2+ only) to signal end of init Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 9/9] [media] mceusb: update version, copyright, author Jarod Wilson
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Rather than dumping out hex values, lets print the actual calculated
frequency and period the hardware has been configured for. After this
change:
[ 2643.276215] mceusb 3-1:1.0: tx data: 9f 07 (length=2)
[ 2643.276218] mceusb 3-1:1.0: Get carrier mode and freq
[ 2643.277206] mceusb 3-1:1.0: rx data: 9f 06 01 42 (length=4)
[ 2643.277209] mceusb 3-1:1.0: Got carrier of 37037 Hz (period 27us)
Matches up perfectly with the table in Microsoft's docs.
Of course, I've noticed on one of my devices that the MS-recommended
default value of 1 for carrier pre-scaler and 66 for carrier period was
butchered, and instead of converting 66 to hex (0x42 like above), they
put in 0x66, so the hardware reports a default carrier of 24390Hz.
Fortunately, I guess, this particular device is rx-only, but I wouldn't
put it past other hw to screw up here too.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 16 +++++++++++-----
1 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 160409e..b0c8bd2 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -516,6 +516,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
u8 cmd, subcmd, data1, data2, data3, data4, data5;
struct device *dev = ir->dev;
int i, start, skip = 0;
+ u32 carrier, period;
if (!debug)
return;
@@ -613,9 +614,14 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n",
data1, data2);
break;
- case MCE_CMD_SETIRCFS:
- dev_info(dev, "%s carrier mode and freq of "
- "0x%02x 0x%02x\n", inout, data1, data2);
+ case MCE_RSP_EQIRCFS:
+ period = DIV_ROUND_CLOSEST(
+ (1 << data1 * 2) * (data2 + 1), 10);
+ if (!period)
+ break;
+ carrier = (1000 * 1000) / period;
+ dev_info(dev, "%s carrier of %u Hz (period %uus)\n",
+ inout, carrier, period);
break;
case MCE_CMD_GETIRCFS:
dev_info(dev, "Get carrier mode and freq\n");
@@ -626,9 +632,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
break;
case MCE_RSP_EQIRTIMEOUT:
/* value is in units of 50us, so x*50/1000 ms */
+ period = ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000;
dev_info(dev, "%s receive timeout of %d ms\n",
- inout,
- ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000);
+ inout, period);
break;
case MCE_CMD_GETIRTIMEOUT:
dev_info(dev, "Get receive timeout\n");
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v2 9/9] [media] mceusb: update version, copyright, author
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
` (17 preceding siblings ...)
2011-07-18 19:54 ` [PATCH v2 8/9] [media] mceusb: report actual tx frequencies Jarod Wilson
@ 2011-07-18 19:54 ` Jarod Wilson
18 siblings, 0 replies; 23+ messages in thread
From: Jarod Wilson @ 2011-07-18 19:54 UTC (permalink / raw)
To: linux-media; +Cc: Jarod Wilson
Add note about recent updates coming from Microsoft's publicly available
specs on Windows Media Center remotes and receivers/transmitters.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/media/rc/mceusb.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index b0c8bd2..c4a41f1 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -1,7 +1,7 @@
/*
* Driver for USB Windows Media Center Ed. eHome Infrared Transceivers
*
- * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
+ * Copyright (c) 2010-2011, Jarod Wilson <jarod@redhat.com>
*
* Based on the original lirc_mceusb and lirc_mceusb2 drivers, by Dan
* Conti, Martin Blatter and Daniel Melander, the latter of which was
@@ -15,6 +15,11 @@
* Jon Smirl, which included enhancements and simplifications to the
* incoming IR buffer parsing routines.
*
+ * Updated in July of 2011 with the aid of Microsoft's official
+ * remote/transceiver requirements and specification document, found at
+ * download.microsoft.com, title
+ * Windows-Media-Center-RC-IR-Collection-Green-Button-Specification-03-08-2011-V2.pdf
+ *
*
* 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
@@ -40,8 +45,8 @@
#include <linux/pm_wakeup.h>
#include <media/rc-core.h>
-#define DRIVER_VERSION "1.91"
-#define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
+#define DRIVER_VERSION "1.92"
+#define DRIVER_AUTHOR "Jarod Wilson <jarod@redhat.com>"
#define DRIVER_DESC "Windows Media Center Ed. eHome Infrared Transceiver " \
"device driver"
#define DRIVER_NAME "mceusb"
--
1.7.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
end of thread, other threads:[~2011-07-18 19:55 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-14 22:09 [PATCH 0/9] mceusb updates per MS docs Jarod Wilson
2011-07-14 22:09 ` [PATCH 1/9] [media] mceusb: command/response updates from " Jarod Wilson
2011-07-14 22:09 ` [PATCH 2/9] [media] mceusb: give hardware time to reply to cmds Jarod Wilson
2011-07-14 23:30 ` Mauro Carvalho Chehab
2011-07-18 17:47 ` Jarod Wilson
2011-07-18 18:11 ` Jarod Wilson
2011-07-14 22:09 ` [PATCH 3/9] [media] mceusb: set wakeup bits for IR-based resume Jarod Wilson
2011-07-14 22:09 ` [PATCH 4/9] [media] mceusb: issue device resume cmd when needed Jarod Wilson
2011-07-14 22:09 ` [PATCH 5/9] [media] mceusb: query device for firmware emulator version Jarod Wilson
2011-07-14 22:09 ` [PATCH 6/9] [media] mceusb: get misc port data from hardware Jarod Wilson
2011-07-14 22:09 ` [PATCH 7/9] [media] mceusb: flash LED (emu v2+ only) to signal end of init Jarod Wilson
2011-07-14 22:09 ` [PATCH 8/9] [media] mceusb: report actual tx frequencies Jarod Wilson
2011-07-14 22:09 ` [PATCH 9/9] [media] mceusb: update version, copyright, author Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 0/9] mceusb updates per MS docs Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 1/9] [media] mceusb: command/response updates from " Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 2/9] [media] mceusb: give hardware time to reply to cmds Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 3/9] [media] mceusb: set wakeup bits for IR-based resume Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 4/9] [media] mceusb: issue device resume cmd when needed Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 5/9] [media] mceusb: query device for firmware emulator version Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 6/9] [media] mceusb: get misc port data from hardware Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 7/9] [media] mceusb: flash LED (emu v2+ only) to signal end of init Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 8/9] [media] mceusb: report actual tx frequencies Jarod Wilson
2011-07-18 19:54 ` [PATCH v2 9/9] [media] mceusb: update version, copyright, author Jarod Wilson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).