* [PATCH 0/5] Pulse-Eight USB CEC driver
@ 2016-07-10 13:11 Hans Verkuil
2016-07-10 13:11 ` [PATCH 1/5] cec: add check if adapter is unregistered Hans Verkuil
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Hans Verkuil @ 2016-07-10 13:11 UTC (permalink / raw)
To: linux-media; +Cc: lars
From: Hans Verkuil <hans.verkuil@cisco.com>
This adds support for the Pulse-Eight USB CEC dongle. It has been tested
with both v4 and v5 firmware.
It is still in staging because 1) the CEC framework it depends on is still in
staging, 2) the code needs to be refactored a bit and 3) it needs more testing.
That said, it's in pretty decent shape. It's pretty neat, but I do wish it
would support a CEC bus snooping mode: that would make it an ideal CEC bus
sniffer. But I don't see any support for it, unfortunately.
If anyone knows how this can be achieved then please let me know!
Please note that this needs support from inputattach (part of linuxconsoletools),
a patch is included in the TODO file.
Regards,
Hans
Hans Verkuil (5):
cec: add check if adapter is unregistered.
serio.h: add new define for the Pulse-Eight USB-CEC Adapter
pulse8-cec: new driver for the Pulse-Eight USB-CEC Adapter
MAINTAINERS: add entry for the pulse8-cec driver
pulse8-cec: add TODO file
MAINTAINERS | 7 +
drivers/staging/media/Kconfig | 2 +
drivers/staging/media/Makefile | 1 +
drivers/staging/media/cec/cec-adap.c | 5 +-
drivers/staging/media/pulse8-cec/Kconfig | 10 +
drivers/staging/media/pulse8-cec/Makefile | 1 +
drivers/staging/media/pulse8-cec/TODO | 35 ++
drivers/staging/media/pulse8-cec/pulse8-cec.c | 502 ++++++++++++++++++++++++++
include/uapi/linux/serio.h | 1 +
9 files changed, 563 insertions(+), 1 deletion(-)
create mode 100644 drivers/staging/media/pulse8-cec/Kconfig
create mode 100644 drivers/staging/media/pulse8-cec/Makefile
create mode 100644 drivers/staging/media/pulse8-cec/TODO
create mode 100644 drivers/staging/media/pulse8-cec/pulse8-cec.c
--
2.8.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/5] cec: add check if adapter is unregistered.
2016-07-10 13:11 [PATCH 0/5] Pulse-Eight USB CEC driver Hans Verkuil
@ 2016-07-10 13:11 ` Hans Verkuil
2016-07-10 13:11 ` [PATCH 2/5] serio.h: add new define for the Pulse-Eight USB-CEC Adapter Hans Verkuil
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2016-07-10 13:11 UTC (permalink / raw)
To: linux-media; +Cc: lars, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
CEC USB dongles can be unplugged at any time, and at that point they will
be unregistered. Make sure that any attempt afterwards to set the physical
or logical addresses will be ignored.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/staging/media/cec/cec-adap.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c
index 7df6187..2cd656b 100644
--- a/drivers/staging/media/cec/cec-adap.c
+++ b/drivers/staging/media/cec/cec-adap.c
@@ -1104,7 +1104,7 @@ static void cec_claim_log_addrs(struct cec_adapter *adap, bool block)
*/
void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
{
- if (phys_addr == adap->phys_addr)
+ if (phys_addr == adap->phys_addr || adap->devnode.unregistered)
return;
if (phys_addr == CEC_PHYS_ADDR_INVALID ||
@@ -1158,6 +1158,9 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
u16 type_mask = 0;
int i;
+ if (adap->devnode.unregistered)
+ return -ENODEV;
+
if (!log_addrs || log_addrs->num_log_addrs == 0) {
adap->log_addrs.num_log_addrs = 0;
cec_adap_unconfigure(adap);
--
2.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/5] serio.h: add new define for the Pulse-Eight USB-CEC Adapter
2016-07-10 13:11 [PATCH 0/5] Pulse-Eight USB CEC driver Hans Verkuil
2016-07-10 13:11 ` [PATCH 1/5] cec: add check if adapter is unregistered Hans Verkuil
@ 2016-07-10 13:11 ` Hans Verkuil
2016-07-10 13:20 ` Hans Verkuil
2016-07-11 17:00 ` Dmitry Torokhov
2016-07-10 13:11 ` [PATCH 3/5] pulse8-cec: new driver " Hans Verkuil
` (3 subsequent siblings)
5 siblings, 2 replies; 10+ messages in thread
From: Hans Verkuil @ 2016-07-10 13:11 UTC (permalink / raw)
To: linux-media; +Cc: lars, Hans Verkuil, Dmitry Torokhov
From: Hans Verkuil <hans.verkuil@cisco.com>
This is for the new pulse8-cec staging driver.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
include/uapi/linux/serio.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h
index c2ea169..f2447a8 100644
--- a/include/uapi/linux/serio.h
+++ b/include/uapi/linux/serio.h
@@ -78,5 +78,6 @@
#define SERIO_TSC40 0x3d
#define SERIO_WACOM_IV 0x3e
#define SERIO_EGALAX 0x3f
+#define SERIO_PULSE8_CEC 0x40
#endif /* _UAPI_SERIO_H */
--
2.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/5] pulse8-cec: new driver for the Pulse-Eight USB-CEC Adapter
2016-07-10 13:11 [PATCH 0/5] Pulse-Eight USB CEC driver Hans Verkuil
2016-07-10 13:11 ` [PATCH 1/5] cec: add check if adapter is unregistered Hans Verkuil
2016-07-10 13:11 ` [PATCH 2/5] serio.h: add new define for the Pulse-Eight USB-CEC Adapter Hans Verkuil
@ 2016-07-10 13:11 ` Hans Verkuil
2016-07-10 13:11 ` [PATCH 4/5] MAINTAINERS: add entry for the pulse8-cec driver Hans Verkuil
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2016-07-10 13:11 UTC (permalink / raw)
To: linux-media; +Cc: lars, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
This supports the Pulse-Eight USB-CEC Adapter.
It has been tested with firmware versions 4 and 5, but it should
hopefully work fine with older firmwares as well.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/staging/media/Kconfig | 2 +
drivers/staging/media/Makefile | 1 +
drivers/staging/media/pulse8-cec/Kconfig | 10 +
drivers/staging/media/pulse8-cec/Makefile | 1 +
drivers/staging/media/pulse8-cec/pulse8-cec.c | 502 ++++++++++++++++++++++++++
5 files changed, 516 insertions(+)
create mode 100644 drivers/staging/media/pulse8-cec/Kconfig
create mode 100644 drivers/staging/media/pulse8-cec/Makefile
create mode 100644 drivers/staging/media/pulse8-cec/pulse8-cec.c
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 5670789..cae42e5 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -29,6 +29,8 @@ source "drivers/staging/media/davinci_vpfe/Kconfig"
source "drivers/staging/media/omap4iss/Kconfig"
+source "drivers/staging/media/pulse8-cec/Kconfig"
+
source "drivers/staging/media/tw686x-kh/Kconfig"
source "drivers/staging/media/s5p-cec/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 989c844..87ce8ad 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_DVB_CXD2099) += cxd2099/
obj-$(CONFIG_LIRC_STAGING) += lirc/
obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
+obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/
obj-$(CONFIG_VIDEO_TW686X_KH) += tw686x-kh/
diff --git a/drivers/staging/media/pulse8-cec/Kconfig b/drivers/staging/media/pulse8-cec/Kconfig
new file mode 100644
index 0000000..c6aa2d1
--- /dev/null
+++ b/drivers/staging/media/pulse8-cec/Kconfig
@@ -0,0 +1,10 @@
+config USB_PULSE8_CEC
+ tristate "Pulse Eight HDMI CEC"
+ depends on USB_ACM && MEDIA_CEC
+ select SERIO
+ select SERIO_SERPORT
+ ---help---
+ This is a cec driver for the Pulse Eight HDMI CEC device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pulse8-cec.
diff --git a/drivers/staging/media/pulse8-cec/Makefile b/drivers/staging/media/pulse8-cec/Makefile
new file mode 100644
index 0000000..9800690
--- /dev/null
+++ b/drivers/staging/media/pulse8-cec/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec.o
diff --git a/drivers/staging/media/pulse8-cec/pulse8-cec.c b/drivers/staging/media/pulse8-cec/pulse8-cec.c
new file mode 100644
index 0000000..e07d2ff
--- /dev/null
+++ b/drivers/staging/media/pulse8-cec/pulse8-cec.c
@@ -0,0 +1,502 @@
+/*
+ * Pulse Eight HDMI CEC driver
+ *
+ * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version of 2 of the License, or (at your
+ * option) any later version. See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/completion.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/serio.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <media/cec.h>
+
+MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
+MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver");
+MODULE_LICENSE("GPL");
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-1)");
+
+enum pulse8_msgcodes {
+ MSGCODE_NOTHING = 0,
+ MSGCODE_PING,
+ MSGCODE_TIMEOUT_ERROR,
+ MSGCODE_HIGH_ERROR,
+ MSGCODE_LOW_ERROR,
+ MSGCODE_FRAME_START,
+ MSGCODE_FRAME_DATA,
+ MSGCODE_RECEIVE_FAILED,
+ MSGCODE_COMMAND_ACCEPTED, /* 0x08 */
+ MSGCODE_COMMAND_REJECTED,
+ MSGCODE_SET_ACK_MASK,
+ MSGCODE_TRANSMIT,
+ MSGCODE_TRANSMIT_EOM,
+ MSGCODE_TRANSMIT_IDLETIME,
+ MSGCODE_TRANSMIT_ACK_POLARITY,
+ MSGCODE_TRANSMIT_LINE_TIMEOUT,
+ MSGCODE_TRANSMIT_SUCCEEDED, /* 0x10 */
+ MSGCODE_TRANSMIT_FAILED_LINE,
+ MSGCODE_TRANSMIT_FAILED_ACK,
+ MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA,
+ MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE,
+ MSGCODE_FIRMWARE_VERSION,
+ MSGCODE_START_BOOTLOADER,
+ MSGCODE_GET_BUILDDATE,
+ MSGCODE_SET_CONTROLLED, /* 0x18 */
+ MSGCODE_GET_AUTO_ENABLED,
+ MSGCODE_SET_AUTO_ENABLED,
+ MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS,
+ MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS,
+ MSGCODE_GET_LOGICAL_ADDRESS_MASK,
+ MSGCODE_SET_LOGICAL_ADDRESS_MASK,
+ MSGCODE_GET_PHYSICAL_ADDRESS,
+ MSGCODE_SET_PHYSICAL_ADDRESS, /* 0x20 */
+ MSGCODE_GET_DEVICE_TYPE,
+ MSGCODE_SET_DEVICE_TYPE,
+ MSGCODE_GET_HDMI_VERSION,
+ MSGCODE_SET_HDMI_VERSION,
+ MSGCODE_GET_OSD_NAME,
+ MSGCODE_SET_OSD_NAME,
+ MSGCODE_WRITE_EEPROM,
+ MSGCODE_GET_ADAPTER_TYPE, /* 0x28 */
+ MSGCODE_SET_ACTIVE_SOURCE,
+
+ MSGCODE_FRAME_EOM = 0x80,
+ MSGCODE_FRAME_ACK = 0x40,
+};
+
+#define DATA_SIZE 256
+
+struct pulse8 {
+ struct device *dev;
+ struct serio *serio;
+ struct cec_adapter *adap;
+ struct completion cmd_done;
+ struct work_struct work;
+ struct cec_msg rx_msg;
+ u8 data[DATA_SIZE];
+ unsigned int len;
+ u8 buf[DATA_SIZE];
+ unsigned int idx;
+ bool escape;
+ bool started;
+};
+
+void pulse8_irq_work_handler(struct work_struct *work)
+{
+ struct pulse8 *pulse8 =
+ container_of(work, struct pulse8, work);
+
+ switch (pulse8->data[0] & 0x3f) {
+ case MSGCODE_FRAME_DATA:
+ cec_received_msg(pulse8->adap, &pulse8->rx_msg);
+ break;
+ case MSGCODE_TRANSMIT_SUCCEEDED:
+ cec_transmit_done(pulse8->adap, CEC_TX_STATUS_OK,
+ 0, 0, 0, 0);
+ break;
+ case MSGCODE_TRANSMIT_FAILED_LINE:
+ cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ARB_LOST,
+ 1, 0, 0, 0);
+ break;
+ case MSGCODE_TRANSMIT_FAILED_ACK:
+ cec_transmit_done(pulse8->adap, CEC_TX_STATUS_NACK,
+ 0, 1, 0, 0);
+ break;
+ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
+ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
+ cec_transmit_done(pulse8->adap, CEC_TX_STATUS_ERROR,
+ 0, 0, 0, 1);
+ break;
+ }
+}
+
+static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data,
+ unsigned int flags)
+{
+ struct pulse8 *pulse8 = serio_get_drvdata(serio);
+
+ if (!pulse8->started && data != 0xff)
+ return IRQ_HANDLED;
+ if (data == 0xfd) {
+ pulse8->escape = true;
+ return IRQ_HANDLED;
+ }
+ if (pulse8->escape) {
+ data += 0xfd;
+ pulse8->escape = false;
+ } else if (data == 0xfe) {
+ struct cec_msg *msg = &pulse8->rx_msg;
+
+ if (debug)
+ dev_info(pulse8->dev, "received: %*ph\n",
+ pulse8->idx, pulse8->buf);
+ pulse8->data[0] = pulse8->buf[0];
+ switch (pulse8->buf[0] & 0x3f) {
+ case MSGCODE_FRAME_START:
+ msg->len = 1;
+ msg->msg[0] = pulse8->buf[1];
+ break;
+ case MSGCODE_FRAME_DATA:
+ if (msg->len == CEC_MAX_MSG_SIZE)
+ break;
+ msg->msg[msg->len++] = pulse8->buf[1];
+ if (pulse8->buf[0] & MSGCODE_FRAME_EOM)
+ schedule_work(&pulse8->work);
+ break;
+ case MSGCODE_TRANSMIT_SUCCEEDED:
+ case MSGCODE_TRANSMIT_FAILED_LINE:
+ case MSGCODE_TRANSMIT_FAILED_ACK:
+ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
+ case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
+ schedule_work(&pulse8->work);
+ break;
+ case MSGCODE_TIMEOUT_ERROR:
+ break;
+ case MSGCODE_COMMAND_ACCEPTED:
+ case MSGCODE_COMMAND_REJECTED:
+ default:
+ if (pulse8->idx == 0)
+ break;
+ memcpy(pulse8->data, pulse8->buf, pulse8->idx);
+ pulse8->len = pulse8->idx;
+ complete(&pulse8->cmd_done);
+ break;
+ }
+ pulse8->idx = 0;
+ pulse8->started = false;
+ return IRQ_HANDLED;
+ } else if (data == 0xff) {
+ pulse8->idx = 0;
+ pulse8->started = true;
+ return IRQ_HANDLED;
+ }
+
+ if (pulse8->idx >= DATA_SIZE) {
+ dev_dbg(pulse8->dev,
+ "throwing away %d bytes of garbage\n", pulse8->idx);
+ pulse8->idx = 0;
+ }
+ pulse8->buf[pulse8->idx++] = data;
+ return IRQ_HANDLED;
+}
+
+static void pulse8_disconnect(struct serio *serio)
+{
+ struct pulse8 *pulse8 = serio_get_drvdata(serio);
+
+ cec_unregister_adapter(pulse8->adap);
+ dev_info(&serio->dev, "disconnected\n");
+ serio_close(serio);
+ serio_set_drvdata(serio, NULL);
+ kfree(pulse8);
+}
+
+static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len)
+{
+ int err = 0;
+
+ err = serio_write(serio, 0xff);
+ if (err)
+ return err;
+ for (; !err && cmd_len; command++, cmd_len--) {
+ if (*command >= 0xfd) {
+ err = serio_write(serio, 0xfd);
+ if (!err)
+ err = serio_write(serio, *command - 0xfd);
+ } else {
+ err = serio_write(serio, *command);
+ }
+ }
+ if (!err)
+ err = serio_write(serio, 0xfe);
+
+ return err;
+}
+
+static int pulse8_send_and_wait(struct pulse8 *pulse8,
+ const u8 *cmd, u8 cmd_len, u8 response, u8 size)
+{
+ int err;
+
+ /*dev_info(pulse8->dev, "transmit: %*ph\n", cmd_len, cmd);*/
+ init_completion(&pulse8->cmd_done);
+
+ err = pulse8_send(pulse8->serio, cmd, cmd_len);
+ if (err)
+ return err;
+
+ if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ))
+ return -ETIMEDOUT;
+ if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED &&
+ cmd[0] != MSGCODE_SET_CONTROLLED &&
+ cmd[0] != MSGCODE_SET_AUTO_ENABLED &&
+ cmd[0] != MSGCODE_GET_BUILDDATE) {
+ u8 cmd_sc[2];
+
+ cmd_sc[0] = MSGCODE_SET_CONTROLLED;
+ cmd_sc[1] = 1;
+ err = pulse8_send_and_wait(pulse8, cmd_sc, 2,
+ MSGCODE_COMMAND_ACCEPTED, 1);
+ if (err)
+ return err;
+ init_completion(&pulse8->cmd_done);
+
+ err = pulse8_send(pulse8->serio, cmd, cmd_len);
+ if (err)
+ return err;
+
+ if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ))
+ return -ETIMEDOUT;
+ }
+ if (response &&
+ ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) {
+ dev_info(pulse8->dev, "transmit: failed %02x\n",
+ pulse8->data[0] & 0x3f);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio)
+{
+ u8 *data = pulse8->data + 1;
+ unsigned int count = 0;
+ unsigned int vers = 0;
+ u8 cmd[2];
+ int err;
+
+ cmd[0] = MSGCODE_PING;
+ err = pulse8_send_and_wait(pulse8, cmd, 1,
+ MSGCODE_COMMAND_ACCEPTED, 0);
+ cmd[0] = MSGCODE_FIRMWARE_VERSION;
+ if (!err)
+ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2);
+ if (!err) {
+ vers = (data[0] << 8) | data[1];
+
+ dev_info(pulse8->dev, "Firmware version %04x\n", vers);
+ if (vers < 2)
+ return 0;
+ }
+
+ cmd[0] = MSGCODE_GET_BUILDDATE;
+ if (!err)
+ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4);
+ if (!err) {
+ time_t date = (data[0] << 24) | (data[1] << 16) |
+ (data[2] << 8) | data[3];
+ struct tm tm;
+
+ time_to_tm(date, 0, &tm);
+
+ dev_info(pulse8->dev, "Firmware build date %04ld.%02d.%02d %02d:%02d:%02d\n",
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ }
+
+ if (vers < 2)
+ return err;
+
+ do {
+ if (count)
+ msleep(500);
+ cmd[0] = MSGCODE_SET_AUTO_ENABLED;
+ cmd[1] = 0;
+ err = pulse8_send_and_wait(pulse8, cmd, 2,
+ MSGCODE_COMMAND_ACCEPTED, 1);
+ if (err && count == 0) {
+ dev_info(pulse8->dev, "No Auto Enabled supported\n");
+ return 0;
+ }
+
+ cmd[0] = MSGCODE_GET_AUTO_ENABLED;
+ if (!err)
+ err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
+ if (!err && !data[0]) {
+ cmd[0] = MSGCODE_WRITE_EEPROM;
+ err = pulse8_send_and_wait(pulse8, cmd, 1,
+ MSGCODE_COMMAND_ACCEPTED, 1);
+ cmd[0] = MSGCODE_GET_AUTO_ENABLED;
+ if (!err)
+ err = pulse8_send_and_wait(pulse8, cmd, 1,
+ cmd[0], 1);
+ }
+ } while (!err && data[0] && count++ < 5);
+
+ if (!err && data[0])
+ err = -EIO;
+
+ return err;
+}
+
+static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable)
+{
+ struct pulse8 *pulse8 = adap->priv;
+ u8 cmd[16];
+ int err;
+
+ cmd[0] = MSGCODE_SET_CONTROLLED;
+ cmd[1] = enable;
+ err = pulse8_send_and_wait(pulse8, cmd, 2,
+ MSGCODE_COMMAND_ACCEPTED, 1);
+ return enable ? err : 0;
+}
+
+static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
+{
+ struct pulse8 *pulse8 = adap->priv;
+ u16 mask = 0;
+ u8 cmd[3];
+ int err;
+
+ if (log_addr != CEC_LOG_ADDR_INVALID)
+ mask = 1 << log_addr;
+ cmd[0] = MSGCODE_SET_ACK_MASK;
+ cmd[1] = mask >> 8;
+ cmd[2] = mask & 0xff;
+ err = pulse8_send_and_wait(pulse8, cmd, 3,
+ MSGCODE_COMMAND_ACCEPTED, 0);
+ if (mask == 0)
+ return 0;
+ return err;
+}
+
+static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg)
+{
+ struct pulse8 *pulse8 = adap->priv;
+ u8 cmd[2];
+ unsigned int i;
+ int err;
+
+ cmd[0] = MSGCODE_TRANSMIT_IDLETIME;
+ cmd[1] = 3;
+ err = pulse8_send_and_wait(pulse8, cmd, 2,
+ MSGCODE_COMMAND_ACCEPTED, 1);
+ cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY;
+ cmd[1] = cec_msg_is_broadcast(msg);
+ if (!err)
+ err = pulse8_send_and_wait(pulse8, cmd, 2,
+ MSGCODE_COMMAND_ACCEPTED, 1);
+ cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
+ cmd[1] = msg->msg[0];
+ if (!err)
+ err = pulse8_send_and_wait(pulse8, cmd, 2,
+ MSGCODE_COMMAND_ACCEPTED, 1);
+ if (!err && msg->len > 1) {
+ cmd[0] = msg->len == 2 ? MSGCODE_TRANSMIT_EOM :
+ MSGCODE_TRANSMIT;
+ cmd[1] = msg->msg[1];
+ err = pulse8_send_and_wait(pulse8, cmd, 2,
+ MSGCODE_COMMAND_ACCEPTED, 1);
+ for (i = 0; !err && i + 2 < msg->len; i++) {
+ cmd[0] = (i + 2 == msg->len - 1) ?
+ MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
+ cmd[1] = msg->msg[i + 2];
+ err = pulse8_send_and_wait(pulse8, cmd, 2,
+ MSGCODE_COMMAND_ACCEPTED, 1);
+ }
+ }
+
+ return err;
+}
+
+static int pulse8_received(struct cec_adapter *adap, struct cec_msg *msg)
+{
+ return -ENOMSG;
+}
+
+const struct cec_adap_ops pulse8_cec_adap_ops = {
+ .adap_enable = pulse8_cec_adap_enable,
+ .adap_log_addr = pulse8_cec_adap_log_addr,
+ .adap_transmit = pulse8_cec_adap_transmit,
+ .received = pulse8_received,
+};
+
+static int pulse8_connect(struct serio *serio, struct serio_driver *drv)
+{
+ u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR |
+ CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL;
+ struct pulse8 *pulse8;
+ int err = -ENOMEM;
+
+ pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL);
+
+ if (!pulse8)
+ return -ENOMEM;
+
+ pulse8->serio = serio;
+ pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8,
+ "HDMI CEC", caps, 1, &serio->dev);
+ err = PTR_ERR_OR_ZERO(pulse8->adap);
+ if (err < 0)
+ goto free_device;
+
+ pulse8->dev = &serio->dev;
+ serio_set_drvdata(serio, pulse8);
+ INIT_WORK(&pulse8->work, pulse8_irq_work_handler);
+
+ err = serio_open(serio, drv);
+ if (err)
+ goto delete_adap;
+
+ err = pulse8_setup(pulse8, serio);
+ if (err)
+ goto close_serio;
+
+ err = cec_register_adapter(pulse8->adap);
+ if (err < 0)
+ goto close_serio;
+
+ pulse8->dev = &pulse8->adap->devnode.dev;
+ return 0;
+
+close_serio:
+ serio_close(serio);
+delete_adap:
+ cec_delete_adapter(pulse8->adap);
+ serio_set_drvdata(serio, NULL);
+free_device:
+ kfree(pulse8);
+ return err;
+}
+
+static struct serio_device_id pulse8_serio_ids[] = {
+ {
+ .type = SERIO_RS232,
+ .proto = SERIO_PULSE8_CEC,
+ .id = SERIO_ANY,
+ .extra = SERIO_ANY,
+ },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, pulse8_serio_ids);
+
+static struct serio_driver pulse8_drv = {
+ .driver = {
+ .name = "pulse8-cec",
+ },
+ .description = "Pulse Eight HDMI CEC driver",
+ .id_table = pulse8_serio_ids,
+ .interrupt = pulse8_interrupt,
+ .connect = pulse8_connect,
+ .disconnect = pulse8_disconnect,
+};
+
+module_serio_driver(pulse8_drv);
--
2.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/5] MAINTAINERS: add entry for the pulse8-cec driver
2016-07-10 13:11 [PATCH 0/5] Pulse-Eight USB CEC driver Hans Verkuil
` (2 preceding siblings ...)
2016-07-10 13:11 ` [PATCH 3/5] pulse8-cec: new driver " Hans Verkuil
@ 2016-07-10 13:11 ` Hans Verkuil
2016-07-10 13:11 ` [PATCH 5/5] pulse8-cec: add TODO file Hans Verkuil
2016-07-11 7:34 ` [PATCH 0/5] Pulse-Eight USB CEC driver Lars Op den Kamp
5 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2016-07-10 13:11 UTC (permalink / raw)
To: linux-media; +Cc: lars, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
Add entry for the pulse8-cec driver.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
MAINTAINERS | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index a975b8e..7486757 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9258,6 +9258,13 @@ F: include/linux/tracehook.h
F: include/uapi/linux/ptrace.h
F: kernel/ptrace.c
+PULSE8-CEC DRIVER
+M: Hans Verkuil <hverkuil@xs4all.nl>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/staging/media/pulse8-cec
+
PVRUSB2 VIDEO4LINUX DRIVER
M: Mike Isely <isely@pobox.com>
L: pvrusb2@isely.net (subscribers-only)
--
2.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/5] pulse8-cec: add TODO file
2016-07-10 13:11 [PATCH 0/5] Pulse-Eight USB CEC driver Hans Verkuil
` (3 preceding siblings ...)
2016-07-10 13:11 ` [PATCH 4/5] MAINTAINERS: add entry for the pulse8-cec driver Hans Verkuil
@ 2016-07-10 13:11 ` Hans Verkuil
2016-07-11 7:34 ` [PATCH 0/5] Pulse-Eight USB CEC driver Lars Op den Kamp
5 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2016-07-10 13:11 UTC (permalink / raw)
To: linux-media; +Cc: lars, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
Explain what needs to be done to move this driver out of staging.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/staging/media/pulse8-cec/TODO | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 drivers/staging/media/pulse8-cec/TODO
diff --git a/drivers/staging/media/pulse8-cec/TODO b/drivers/staging/media/pulse8-cec/TODO
new file mode 100644
index 0000000..6860a33
--- /dev/null
+++ b/drivers/staging/media/pulse8-cec/TODO
@@ -0,0 +1,35 @@
+This driver needs to mature a bit more and another round of
+code cleanups.
+
+Otherwise it looks to be in good shape. And of course the fact
+that the CEC framework is in staging at the moment also prevents
+this driver from being mainlined.
+
+To use this driver you also need to patch the inputattach utility,
+this patch will be submitted once this driver is moved out of staging.
+
+diff -urN linuxconsoletools-1.4.9/utils/inputattach.c linuxconsoletools-1.4.9.new/utils/inputattach.c
+--- linuxconsoletools-1.4.9/utils/inputattach.c 2016-01-09 16:27:02.000000000 +0100
++++ linuxconsoletools-1.4.9.new/utils/inputattach.c 2016-03-20 11:35:31.707788967 +0100
+@@ -861,6 +861,9 @@
+ { "--wacom_iv", "-wacom_iv", "Wacom protocol IV tablet",
+ B9600, CS8 | CRTSCTS,
+ SERIO_WACOM_IV, 0x00, 0x00, 0, wacom_iv_init },
++{ "--pulse8-cec", "-pulse8-cec", "Pulse Eight HDMI CEC dongle",
++ B9600, CS8,
++ SERIO_PULSE8_CEC, 0x00, 0x00, 0, NULL },
+ { NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL }
+ };
+
+diff -urN linuxconsoletools-1.4.9/utils/serio-ids.h linuxconsoletools-1.4.9.new/utils/serio-ids.h
+--- linuxconsoletools-1.4.9/utils/serio-ids.h 2015-04-26 18:29:42.000000000 +0200
++++ linuxconsoletools-1.4.9.new/utils/serio-ids.h 2016-03-20 11:41:00.153558539 +0100
+@@ -131,5 +131,8 @@
+ #ifndef SERIO_EASYPEN
+ # define SERIO_EASYPEN 0x3f
+ #endif
++#ifndef SERIO_PULSE8_CEC
++# define SERIO_PULSE8_CEC 0x40
++#endif
+
+ #endif
--
2.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/5] serio.h: add new define for the Pulse-Eight USB-CEC Adapter
2016-07-10 13:11 ` [PATCH 2/5] serio.h: add new define for the Pulse-Eight USB-CEC Adapter Hans Verkuil
@ 2016-07-10 13:20 ` Hans Verkuil
2016-07-11 17:00 ` Dmitry Torokhov
1 sibling, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2016-07-10 13:20 UTC (permalink / raw)
To: linux-media; +Cc: lars, linux-input, Dmitry Torokhov
Added linux-input to the Cc list.
Dmitry, it probably makes the most sense if this goes through the media
tree with your Ack, unless you know there will be a conflict.
Regards,
Hans
On 07/10/2016 03:11 PM, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verkuil@cisco.com>
>
> This is for the new pulse8-cec staging driver.
>
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
> include/uapi/linux/serio.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h
> index c2ea169..f2447a8 100644
> --- a/include/uapi/linux/serio.h
> +++ b/include/uapi/linux/serio.h
> @@ -78,5 +78,6 @@
> #define SERIO_TSC40 0x3d
> #define SERIO_WACOM_IV 0x3e
> #define SERIO_EGALAX 0x3f
> +#define SERIO_PULSE8_CEC 0x40
>
> #endif /* _UAPI_SERIO_H */
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/5] Pulse-Eight USB CEC driver
2016-07-10 13:11 [PATCH 0/5] Pulse-Eight USB CEC driver Hans Verkuil
` (4 preceding siblings ...)
2016-07-10 13:11 ` [PATCH 5/5] pulse8-cec: add TODO file Hans Verkuil
@ 2016-07-11 7:34 ` Lars Op den Kamp
2016-07-11 8:57 ` Hans Verkuil
5 siblings, 1 reply; 10+ messages in thread
From: Lars Op den Kamp @ 2016-07-11 7:34 UTC (permalink / raw)
To: Hans Verkuil, linux-media
Hi Hans,
I'm subscribed to this mailing list, though haven't been participating
in discussions here (no time). I work for Pulse-Eight and did most of
the CEC software.
There's no difference between firmware v4 and v5 for the USB model of
the adapter. v5 just adds support for the new Intel NUC internal CEC
adapter.
You can snoop the bus by setting the ack mask to 0 and just read what
comes in (MSGCODE_SET_ACK_MASK 0)
This is the same as "cec-client -m" does when using libCEC:
https://github.com/Pulse-Eight/libcec/blob/master/src/libcec/adapter/Pulse-Eight/USBCECAdapterCommands.cpp#L584
Let me know if you need more help, or send an email to
support@pulse-eight.com (which will likely end up in my inbox anyway
eventually).
thanks, Lars
On 10-07-16 15:11, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verkuil@cisco.com>
>
> This adds support for the Pulse-Eight USB CEC dongle. It has been tested
> with both v4 and v5 firmware.
>
> It is still in staging because 1) the CEC framework it depends on is still in
> staging, 2) the code needs to be refactored a bit and 3) it needs more testing.
>
> That said, it's in pretty decent shape. It's pretty neat, but I do wish it
> would support a CEC bus snooping mode: that would make it an ideal CEC bus
> sniffer. But I don't see any support for it, unfortunately.
>
> If anyone knows how this can be achieved then please let me know!
>
> Please note that this needs support from inputattach (part of linuxconsoletools),
> a patch is included in the TODO file.
>
> Regards,
>
> Hans
>
> Hans Verkuil (5):
> cec: add check if adapter is unregistered.
> serio.h: add new define for the Pulse-Eight USB-CEC Adapter
> pulse8-cec: new driver for the Pulse-Eight USB-CEC Adapter
> MAINTAINERS: add entry for the pulse8-cec driver
> pulse8-cec: add TODO file
>
> MAINTAINERS | 7 +
> drivers/staging/media/Kconfig | 2 +
> drivers/staging/media/Makefile | 1 +
> drivers/staging/media/cec/cec-adap.c | 5 +-
> drivers/staging/media/pulse8-cec/Kconfig | 10 +
> drivers/staging/media/pulse8-cec/Makefile | 1 +
> drivers/staging/media/pulse8-cec/TODO | 35 ++
> drivers/staging/media/pulse8-cec/pulse8-cec.c | 502 ++++++++++++++++++++++++++
> include/uapi/linux/serio.h | 1 +
> 9 files changed, 563 insertions(+), 1 deletion(-)
> create mode 100644 drivers/staging/media/pulse8-cec/Kconfig
> create mode 100644 drivers/staging/media/pulse8-cec/Makefile
> create mode 100644 drivers/staging/media/pulse8-cec/TODO
> create mode 100644 drivers/staging/media/pulse8-cec/pulse8-cec.c
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/5] Pulse-Eight USB CEC driver
2016-07-11 7:34 ` [PATCH 0/5] Pulse-Eight USB CEC driver Lars Op den Kamp
@ 2016-07-11 8:57 ` Hans Verkuil
0 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2016-07-11 8:57 UTC (permalink / raw)
To: Lars Op den Kamp, linux-media
On 07/11/2016 09:34 AM, Lars Op den Kamp wrote:
> Hi Hans,
>
> I'm subscribed to this mailing list, though haven't been participating
> in discussions here (no time). I work for Pulse-Eight and did most of
> the CEC software.
>
> There's no difference between firmware v4 and v5 for the USB model of
> the adapter. v5 just adds support for the new Intel NUC internal CEC
> adapter.
>
> You can snoop the bus by setting the ack mask to 0 and just read what
> comes in (MSGCODE_SET_ACK_MASK 0)
It turned out to be two small bugs (one in the CEC framework and one in the
cec-ctl utility) that prevented this from working. The driver was actually
fine.
Thanks for the reply, it forced me to look more closely at the code.
Regards,
Hans
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/5] serio.h: add new define for the Pulse-Eight USB-CEC Adapter
2016-07-10 13:11 ` [PATCH 2/5] serio.h: add new define for the Pulse-Eight USB-CEC Adapter Hans Verkuil
2016-07-10 13:20 ` Hans Verkuil
@ 2016-07-11 17:00 ` Dmitry Torokhov
1 sibling, 0 replies; 10+ messages in thread
From: Dmitry Torokhov @ 2016-07-11 17:00 UTC (permalink / raw)
To: Hans Verkuil; +Cc: linux-media, lars, Hans Verkuil
On Sun, Jul 10, 2016 at 03:11:18PM +0200, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verkuil@cisco.com>
>
> This is for the new pulse8-cec staging driver.
>
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Please feel free to merge through media tree. If you could change the
subject to read:
Input: serio - add new protocol for the Pulse-Eight USB-CEC Adapter
That would be great.
Thanks!
> ---
> include/uapi/linux/serio.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h
> index c2ea169..f2447a8 100644
> --- a/include/uapi/linux/serio.h
> +++ b/include/uapi/linux/serio.h
> @@ -78,5 +78,6 @@
> #define SERIO_TSC40 0x3d
> #define SERIO_WACOM_IV 0x3e
> #define SERIO_EGALAX 0x3f
> +#define SERIO_PULSE8_CEC 0x40
>
> #endif /* _UAPI_SERIO_H */
> --
> 2.8.1
>
--
Dmitry
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2016-07-11 17:00 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-10 13:11 [PATCH 0/5] Pulse-Eight USB CEC driver Hans Verkuil
2016-07-10 13:11 ` [PATCH 1/5] cec: add check if adapter is unregistered Hans Verkuil
2016-07-10 13:11 ` [PATCH 2/5] serio.h: add new define for the Pulse-Eight USB-CEC Adapter Hans Verkuil
2016-07-10 13:20 ` Hans Verkuil
2016-07-11 17:00 ` Dmitry Torokhov
2016-07-10 13:11 ` [PATCH 3/5] pulse8-cec: new driver " Hans Verkuil
2016-07-10 13:11 ` [PATCH 4/5] MAINTAINERS: add entry for the pulse8-cec driver Hans Verkuil
2016-07-10 13:11 ` [PATCH 5/5] pulse8-cec: add TODO file Hans Verkuil
2016-07-11 7:34 ` [PATCH 0/5] Pulse-Eight USB CEC driver Lars Op den Kamp
2016-07-11 8:57 ` Hans Verkuil
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.