All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] drm/sun4i: add CEC support
@ 2017-07-11  6:30 Hans Verkuil
  2017-07-11  6:30 ` [PATCH 01/11] cec: improve transmit timeout logging Hans Verkuil
                   ` (12 more replies)
  0 siblings, 13 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel

From: Hans Verkuil <hans.verkuil@cisco.com>

This patch series adds CEC support for the sun4i HDMI controller.

The CEC hardware support for the A10 is very low-level as it just
controls the CEC pin. Since I also wanted to support GPIO-based CEC
hardware most of this patch series is in the CEC framework to
add a generic low-level CEC pin framework. It is only the final patch
that adds the sun4i support.

This patch series first makes some small changes in the CEC framework
(patches 1-4) to prepare for this CEC pin support.

Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
the CEC core event handling.

Patch 8 adds pin monitoring support (allows userspace to see all
CEC pin transitions as they happen).

Patch 9 adds the core cec-pin implementation that translates low-level
pin transitions into valid CEC messages. Basically this does what any
SoC with a proper CEC hardware implementation does.

Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
which was missing).

Finally patch 11 adds the actual sun4i_hdmi CEC implementation.

I tested this on my cubieboard. There were no errors at all
after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
same time running a 'make -j4' of the v4l-utils git repository and
doing a continuous scp to create network traffic.

This patch series is based on top of the mainline kernel as of
yesterday (so with all the sun4i and cec patches for 4.13 merged).

Maxime, patches 1-10 will go through the media subsystem. How do you
want to handle the final patch? It can either go through the media
subsystem as well, or you can sit on it and handle this yourself during
the 4.14 merge window. Another option is to separate the Kconfig change
into its own patch. That way you can merge the code changes and only
have to handle the Kconfig patch as a final change during the merge
window.

Regards,

	Hans

Hans Verkuil (11):
  cec: improve transmit timeout logging
  cec: add *_ts variants for transmit_done/received_msg
  cec: add adap_free op
  cec-core.rst: document the adap_free callback
  linux/cec.h: add pin monitoring API support
  cec: rework the cec event handling
  cec: document the new CEC pin capability, events and mode
  cec: add core support for low-level CEC pin monitoring
  cec-pin: add low-level pin hardware support
  cec-core.rst: include cec-pin.h and cec-notifier.h
  sun4i_hdmi: add CEC support

 Documentation/media/kapi/cec-core.rst              |  40 ++
 .../media/uapi/cec/cec-ioc-adap-g-caps.rst         |   7 +
 Documentation/media/uapi/cec/cec-ioc-dqevent.rst   |  20 +
 Documentation/media/uapi/cec/cec-ioc-g-mode.rst    |  19 +-
 drivers/gpu/drm/sun4i/Kconfig                      |   9 +
 drivers/gpu/drm/sun4i/sun4i_hdmi.h                 |   8 +
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c             |  57 +-
 drivers/media/Kconfig                              |   3 +
 drivers/media/cec/Makefile                         |   4 +
 drivers/media/cec/cec-adap.c                       | 196 +++--
 drivers/media/cec/cec-api.c                        |  73 +-
 drivers/media/cec/cec-core.c                       |   2 +
 drivers/media/cec/cec-pin.c                        | 794 +++++++++++++++++++++
 include/media/cec-pin.h                            | 183 +++++
 include/media/cec.h                                |  64 +-
 include/uapi/linux/cec.h                           |   8 +-
 16 files changed, 1389 insertions(+), 98 deletions(-)
 create mode 100644 drivers/media/cec/cec-pin.c
 create mode 100644 include/media/cec-pin.h

-- 
2.11.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 01/11] cec: improve transmit timeout logging
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 02/11] cec: add *_ts variants for transmit_done/received_msg Hans Verkuil
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Kernel logging messes up the upcoming low-level CEC monitoring support
which is very time-sensitive. So change the debug level of this message
but keep a counter that is shown in the debugfs status log.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/cec/cec-adap.c | 17 +++++++++++++----
 include/media/cec.h          |  2 ++
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index bf45977b2823..644ce82ea2ed 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -394,13 +394,17 @@ int cec_thread_func(void *_adap)
 
 		if (adap->transmitting && timeout) {
 			/*
-			 * If we timeout, then log that. This really shouldn't
-			 * happen and is an indication of a faulty CEC adapter
-			 * driver, or the CEC bus is in some weird state.
+			 * If we timeout, then log that. Normally this does
+			 * not happen and it is an indication of a faulty CEC
+			 * adapter driver, or the CEC bus is in some weird
+			 * state. On rare occasions it can happen if there is
+			 * so much traffic on the bus that the adapter was
+			 * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s).
 			 */
-			dprintk(0, "%s: message %*ph timed out!\n", __func__,
+			dprintk(1, "%s: message %*ph timed out\n", __func__,
 				adap->transmitting->msg.len,
 				adap->transmitting->msg.msg);
+			adap->tx_timeouts++;
 			/* Just give up on this. */
 			cec_data_cancel(adap->transmitting);
 			goto unlock;
@@ -1941,6 +1945,11 @@ int cec_adap_status(struct seq_file *file, void *priv)
 	if (adap->monitor_all_cnt)
 		seq_printf(file, "file handles in Monitor All mode: %u\n",
 			   adap->monitor_all_cnt);
+	if (adap->tx_timeouts) {
+		seq_printf(file, "transmit timeouts: %u\n",
+			   adap->tx_timeouts);
+		adap->tx_timeouts = 0;
+	}
 	data = adap->transmitting;
 	if (data)
 		seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n",
diff --git a/include/media/cec.h b/include/media/cec.h
index 56643b27e4b8..e32b0e1a81a4 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -174,6 +174,8 @@ struct cec_adapter {
 	bool passthrough;
 	struct cec_log_addrs log_addrs;
 
+	u32 tx_timeouts;
+
 #ifdef CONFIG_CEC_NOTIFIER
 	struct cec_notifier *notifier;
 #endif
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 02/11] cec: add *_ts variants for transmit_done/received_msg
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
  2017-07-11  6:30 ` [PATCH 01/11] cec: improve transmit timeout logging Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 03/11] cec: add adap_free op Hans Verkuil
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Currently the transmit_(attempt_)done and received_msg functions set
the timestamp themselves. For the upcoming low-level pin API we need
to pass this as an argument instead. So make _ts variants that allow
the caller to specify the timestamp.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/cec/cec-adap.c | 35 +++++++++++++++++++----------------
 include/media/cec.h          | 32 ++++++++++++++++++++++++++++----
 2 files changed, 47 insertions(+), 20 deletions(-)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index 644ce82ea2ed..b3163716d95f 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -471,12 +471,12 @@ int cec_thread_func(void *_adap)
 /*
  * Called by the CEC adapter if a transmit finished.
  */
-void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
-		       u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt)
+void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
+			  u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
+			  u8 error_cnt, ktime_t ts)
 {
 	struct cec_data *data;
 	struct cec_msg *msg;
-	u64 ts = ktime_get_ns();
 
 	dprintk(2, "%s: status %02x\n", __func__, status);
 	mutex_lock(&adap->lock);
@@ -496,7 +496,7 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
 
 	/* Drivers must fill in the status! */
 	WARN_ON(status == 0);
-	msg->tx_ts = ts;
+	msg->tx_ts = ktime_to_ns(ts);
 	msg->tx_status |= status;
 	msg->tx_arb_lost_cnt += arb_lost_cnt;
 	msg->tx_nack_cnt += nack_cnt;
@@ -559,25 +559,26 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
 unlock:
 	mutex_unlock(&adap->lock);
 }
-EXPORT_SYMBOL_GPL(cec_transmit_done);
+EXPORT_SYMBOL_GPL(cec_transmit_done_ts);
 
-void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status)
+void cec_transmit_attempt_done_ts(struct cec_adapter *adap,
+				  u8 status, ktime_t ts)
 {
 	switch (status) {
 	case CEC_TX_STATUS_OK:
-		cec_transmit_done(adap, status, 0, 0, 0, 0);
+		cec_transmit_done_ts(adap, status, 0, 0, 0, 0, ts);
 		return;
 	case CEC_TX_STATUS_ARB_LOST:
-		cec_transmit_done(adap, status, 1, 0, 0, 0);
+		cec_transmit_done_ts(adap, status, 1, 0, 0, 0, ts);
 		return;
 	case CEC_TX_STATUS_NACK:
-		cec_transmit_done(adap, status, 0, 1, 0, 0);
+		cec_transmit_done_ts(adap, status, 0, 1, 0, 0, ts);
 		return;
 	case CEC_TX_STATUS_LOW_DRIVE:
-		cec_transmit_done(adap, status, 0, 0, 1, 0);
+		cec_transmit_done_ts(adap, status, 0, 0, 1, 0, ts);
 		return;
 	case CEC_TX_STATUS_ERROR:
-		cec_transmit_done(adap, status, 0, 0, 0, 1);
+		cec_transmit_done_ts(adap, status, 0, 0, 0, 1, ts);
 		return;
 	default:
 		/* Should never happen */
@@ -585,7 +586,7 @@ void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status)
 		return;
 	}
 }
-EXPORT_SYMBOL_GPL(cec_transmit_attempt_done);
+EXPORT_SYMBOL_GPL(cec_transmit_attempt_done_ts);
 
 /*
  * Called when waiting for a reply times out.
@@ -716,7 +717,8 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
 
 	if (msg->timeout)
 		dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n",
-			__func__, msg->len, msg->msg, msg->reply, !block ? ", nb" : "");
+			__func__, msg->len, msg->msg, msg->reply,
+			!block ? ", nb" : "");
 	else
 		dprintk(2, "%s: %*ph%s\n",
 			__func__, msg->len, msg->msg, !block ? " (nb)" : "");
@@ -913,7 +915,8 @@ static const u8 cec_msg_size[256] = {
 };
 
 /* Called by the CEC adapter if a message is received */
-void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg)
+void cec_received_msg_ts(struct cec_adapter *adap,
+			 struct cec_msg *msg, ktime_t ts)
 {
 	struct cec_data *data;
 	u8 msg_init = cec_msg_initiator(msg);
@@ -941,7 +944,7 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg)
 	    cec_has_log_addr(adap, msg_init))
 		return;
 
-	msg->rx_ts = ktime_get_ns();
+	msg->rx_ts = ktime_to_ns(ts);
 	msg->rx_status = CEC_RX_STATUS_OK;
 	msg->sequence = msg->reply = msg->timeout = 0;
 	msg->tx_status = 0;
@@ -1106,7 +1109,7 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg)
 	 */
 	cec_receive_notify(adap, msg, is_reply);
 }
-EXPORT_SYMBOL_GPL(cec_received_msg);
+EXPORT_SYMBOL_GPL(cec_received_msg_ts);
 
 /* Logical Address Handling */
 
diff --git a/include/media/cec.h b/include/media/cec.h
index e32b0e1a81a4..e1e60dbb66c3 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -228,15 +228,39 @@ int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
 		     bool block);
 
 /* Called by the adapter */
-void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
-		       u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
+void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
+			  u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
+			  u8 error_cnt, ktime_t ts);
+
+static inline void cec_transmit_done(struct cec_adapter *adap, u8 status,
+				     u8 arb_lost_cnt, u8 nack_cnt,
+				     u8 low_drive_cnt, u8 error_cnt)
+{
+	cec_transmit_done_ts(adap, status, arb_lost_cnt, nack_cnt,
+			     low_drive_cnt, error_cnt, ktime_get());
+}
 /*
  * Simplified version of cec_transmit_done for hardware that doesn't retry
  * failed transmits. So this is always just one attempt in which case
  * the status is sufficient.
  */
-void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status);
-void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg);
+void cec_transmit_attempt_done_ts(struct cec_adapter *adap,
+				  u8 status, ktime_t ts);
+
+static inline void cec_transmit_attempt_done(struct cec_adapter *adap,
+					     u8 status)
+{
+	cec_transmit_attempt_done_ts(adap, status, ktime_get());
+}
+
+void cec_received_msg_ts(struct cec_adapter *adap,
+			 struct cec_msg *msg, ktime_t ts);
+
+static inline void cec_received_msg(struct cec_adapter *adap,
+				    struct cec_msg *msg)
+{
+	cec_received_msg_ts(adap, msg, ktime_get());
+}
 
 /**
  * cec_get_edid_phys_addr() - find and return the physical address
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 03/11] cec: add adap_free op
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
  2017-07-11  6:30 ` [PATCH 01/11] cec: improve transmit timeout logging Hans Verkuil
  2017-07-11  6:30 ` [PATCH 02/11] cec: add *_ts variants for transmit_done/received_msg Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 04/11] cec-core.rst: document the adap_free callback Hans Verkuil
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

This is needed for CEC adapters that allocate resources that have
to be freed before the cec_adapter is deleted.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/cec/cec-core.c | 2 ++
 include/media/cec.h          | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index b516d599d6c4..2e5765344d07 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -374,6 +374,8 @@ void cec_delete_adapter(struct cec_adapter *adap)
 	kthread_stop(adap->kthread);
 	if (adap->kthread_config)
 		kthread_stop(adap->kthread_config);
+	if (adap->ops->adap_free)
+		adap->ops->adap_free(adap);
 #ifdef CONFIG_MEDIA_CEC_RC
 	rc_free_device(adap->rc);
 #endif
diff --git a/include/media/cec.h b/include/media/cec.h
index e1e60dbb66c3..37768203572d 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -114,6 +114,7 @@ struct cec_adap_ops {
 	int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
 			     u32 signal_free_time, struct cec_msg *msg);
 	void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
+	void (*adap_free)(struct cec_adapter *adap);
 
 	/* High-level CEC message callback */
 	int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 04/11] cec-core.rst: document the adap_free callback
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
                   ` (2 preceding siblings ...)
  2017-07-11  6:30 ` [PATCH 03/11] cec: add adap_free op Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 05/11] linux/cec.h: add pin monitoring API support Hans Verkuil
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Document what this callback does.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 Documentation/media/kapi/cec-core.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst
index 8a65c69ed071..bb066b2b26f8 100644
--- a/Documentation/media/kapi/cec-core.rst
+++ b/Documentation/media/kapi/cec-core.rst
@@ -107,6 +107,7 @@ your driver:
 		int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
 				      u32 signal_free_time, struct cec_msg *msg);
 		void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
+		void (*adap_free)(struct cec_adapter *adap);
 
 		/* High-level callbacks */
 		...
@@ -184,6 +185,14 @@ To log the current CEC hardware status:
 This optional callback can be used to show the status of the CEC hardware.
 The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status
 
+To free any resources when the adapter is deleted:
+
+.. c:function::
+	void (*adap_free)(struct cec_adapter *adap);
+
+This optional callback can be used to free any resources that might have been
+allocated by the driver. It's called from cec_delete_adapter.
+
 
 Your adapter driver will also have to react to events (typically interrupt
 driven) by calling into the framework in the following situations:
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 05/11] linux/cec.h: add pin monitoring API support
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
                   ` (3 preceding siblings ...)
  2017-07-11  6:30 ` [PATCH 04/11] cec-core.rst: document the adap_free callback Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 06/11] cec: rework the cec event handling Hans Verkuil
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Add support for low-level CEC pin monitoring. This adds a new monitor
mode, a new capability and two new events.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 include/uapi/linux/cec.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h
index 44579a24f95d..bba73f33c8aa 100644
--- a/include/uapi/linux/cec.h
+++ b/include/uapi/linux/cec.h
@@ -318,6 +318,7 @@ static inline int cec_is_unconfigured(__u16 log_addr_mask)
 #define CEC_MODE_FOLLOWER		(0x1 << 4)
 #define CEC_MODE_EXCL_FOLLOWER		(0x2 << 4)
 #define CEC_MODE_EXCL_FOLLOWER_PASSTHRU	(0x3 << 4)
+#define CEC_MODE_MONITOR_PIN		(0xd << 4)
 #define CEC_MODE_MONITOR		(0xe << 4)
 #define CEC_MODE_MONITOR_ALL		(0xf << 4)
 #define CEC_MODE_FOLLOWER_MSK		0xf0
@@ -338,6 +339,8 @@ static inline int cec_is_unconfigured(__u16 log_addr_mask)
 #define CEC_CAP_MONITOR_ALL	(1 << 5)
 /* Hardware can use CEC only if the HDMI HPD pin is high. */
 #define CEC_CAP_NEEDS_HPD	(1 << 6)
+/* Hardware can monitor CEC pin transitions */
+#define CEC_CAP_MONITOR_PIN	(1 << 7)
 
 /**
  * struct cec_caps - CEC capabilities structure.
@@ -405,6 +408,8 @@ struct cec_log_addrs {
  * didn't empty the message queue in time
  */
 #define CEC_EVENT_LOST_MSGS		2
+#define CEC_EVENT_PIN_LOW		3
+#define CEC_EVENT_PIN_HIGH		4
 
 #define CEC_EVENT_FL_INITIAL_STATE	(1 << 0)
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 06/11] cec: rework the cec event handling
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
                   ` (4 preceding siblings ...)
  2017-07-11  6:30 ` [PATCH 05/11] linux/cec.h: add pin monitoring API support Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 07/11] cec: document the new CEC pin capability, events and mode Hans Verkuil
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Event handling was always fairly simplistic since there were only
two events. With the addition of pin events this needed to be redesigned.

The state_change and lost_msgs events are now core events with the
guarantee that the last state is always available. The new pin events
are a queue of events (up to 64 for each event) and the oldest event
will be dropped if the application cannot keep up. Lost events are
marked with a new event flag.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/cec/cec-adap.c | 128 +++++++++++++++++++++++++------------------
 drivers/media/cec/cec-api.c  |  48 +++++++++++-----
 include/media/cec.h          |  14 ++++-
 include/uapi/linux/cec.h     |   3 +-
 4 files changed, 124 insertions(+), 69 deletions(-)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index b3163716d95f..67ec66c7c4ff 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -78,42 +78,62 @@ static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr
  * Queue a new event for this filehandle. If ts == 0, then set it
  * to the current time.
  *
- * The two events that are currently defined do not need to keep track
- * of intermediate events, so no actual queue of events is needed,
- * instead just store the latest state and the total number of lost
- * messages.
- *
- * Should new events be added in the future that require intermediate
- * results to be queued as well, then a proper queue data structure is
- * required. But until then, just keep it simple.
+ * We keep a queue of at most max_event events where max_event differs
+ * per event. If the queue becomes full, then drop the oldest event and
+ * keep track of how many events we've dropped.
  */
 void cec_queue_event_fh(struct cec_fh *fh,
 			const struct cec_event *new_ev, u64 ts)
 {
-	struct cec_event *ev = &fh->events[new_ev->event - 1];
+	static const u8 max_events[CEC_NUM_EVENTS] = {
+		1, 1, 64, 64,
+	};
+	struct cec_event_entry *entry;
+	unsigned int ev_idx = new_ev->event - 1;
+
+	if (WARN_ON(ev_idx >= ARRAY_SIZE(fh->events)))
+		return;
 
 	if (ts == 0)
 		ts = ktime_get_ns();
 
 	mutex_lock(&fh->lock);
-	if (new_ev->event == CEC_EVENT_LOST_MSGS &&
-	    fh->pending_events & (1 << new_ev->event)) {
-		/*
-		 * If there is already a lost_msgs event, then just
-		 * update the lost_msgs count. This effectively
-		 * merges the old and new events into one.
-		 */
-		ev->lost_msgs.lost_msgs += new_ev->lost_msgs.lost_msgs;
-		goto unlock;
-	}
+	if (ev_idx < CEC_NUM_CORE_EVENTS)
+		entry = &fh->core_events[ev_idx];
+	else
+		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (entry) {
+		if (new_ev->event == CEC_EVENT_LOST_MSGS &&
+		    fh->queued_events[ev_idx]) {
+			entry->ev.lost_msgs.lost_msgs +=
+				new_ev->lost_msgs.lost_msgs;
+			goto unlock;
+		}
+		entry->ev = *new_ev;
+		entry->ev.ts = ts;
+
+		if (fh->queued_events[ev_idx] < max_events[ev_idx]) {
+			/* Add new msg at the end of the queue */
+			list_add_tail(&entry->list, &fh->events[ev_idx]);
+			fh->queued_events[ev_idx]++;
+			fh->total_queued_events++;
+			goto unlock;
+		}
 
-	/*
-	 * Intermediate states are not interesting, so just
-	 * overwrite any older event.
-	 */
-	*ev = *new_ev;
-	ev->ts = ts;
-	fh->pending_events |= 1 << new_ev->event;
+		if (ev_idx >= CEC_NUM_CORE_EVENTS) {
+			list_add_tail(&entry->list, &fh->events[ev_idx]);
+			/* drop the oldest event */
+			entry = list_first_entry(&fh->events[ev_idx],
+						 struct cec_event_entry, list);
+			list_del(&entry->list);
+			kfree(entry);
+		}
+	}
+	/* Mark that events were lost */
+	entry = list_first_entry_or_null(&fh->events[ev_idx],
+					 struct cec_event_entry, list);
+	if (entry)
+		entry->ev.flags |= CEC_EVENT_FL_DROPPED_EVENTS;
 
 unlock:
 	mutex_unlock(&fh->lock);
@@ -134,46 +154,50 @@ static void cec_queue_event(struct cec_adapter *adap,
 }
 
 /*
- * Queue a new message for this filehandle. If there is no more room
- * in the queue, then send the LOST_MSGS event instead.
+ * Queue a new message for this filehandle.
+ *
+ * We keep a queue of at most CEC_MAX_MSG_RX_QUEUE_SZ messages. If the
+ * queue becomes full, then drop the oldest message and keep track
+ * of how many messages we've dropped.
  */
 static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg)
 {
-	static const struct cec_event ev_lost_msg = {
-		.ts = 0,
+	static const struct cec_event ev_lost_msgs = {
 		.event = CEC_EVENT_LOST_MSGS,
-		.flags = 0,
-		{
-			.lost_msgs.lost_msgs = 1,
-		},
+		.lost_msgs.lost_msgs = 1,
 	};
 	struct cec_msg_entry *entry;
 
 	mutex_lock(&fh->lock);
 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-	if (!entry)
-		goto lost_msgs;
-
-	entry->msg = *msg;
-	/* Add new msg at the end of the queue */
-	list_add_tail(&entry->list, &fh->msgs);
+	if (entry) {
+		entry->msg = *msg;
+		/* Add new msg at the end of the queue */
+		list_add_tail(&entry->list, &fh->msgs);
+
+		if (fh->queued_msgs < CEC_MAX_MSG_RX_QUEUE_SZ) {
+			/* All is fine if there is enough room */
+			fh->queued_msgs++;
+			mutex_unlock(&fh->lock);
+			wake_up_interruptible(&fh->wait);
+			return;
+		}
 
-	/*
-	 * if the queue now has more than CEC_MAX_MSG_RX_QUEUE_SZ
-	 * messages, drop the oldest one and send a lost message event.
-	 */
-	if (fh->queued_msgs == CEC_MAX_MSG_RX_QUEUE_SZ) {
+		/*
+		 * if the message queue is full, then drop the oldest one and
+		 * send a lost message event.
+		 */
+		entry = list_first_entry(&fh->msgs, struct cec_msg_entry, list);
 		list_del(&entry->list);
-		goto lost_msgs;
+		kfree(entry);
 	}
-	fh->queued_msgs++;
 	mutex_unlock(&fh->lock);
-	wake_up_interruptible(&fh->wait);
-	return;
 
-lost_msgs:
-	mutex_unlock(&fh->lock);
-	cec_queue_event_fh(fh, &ev_lost_msg, 0);
+	/*
+	 * We lost a message, either because kmalloc failed or the queue
+	 * was full.
+	 */
+	cec_queue_event_fh(fh, &ev_lost_msgs, ktime_get_ns());
 }
 
 /*
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index f7eb4c54a354..48bef1c718ad 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -57,7 +57,7 @@ static unsigned int cec_poll(struct file *filp,
 		res |= POLLOUT | POLLWRNORM;
 	if (fh->queued_msgs)
 		res |= POLLIN | POLLRDNORM;
-	if (fh->pending_events)
+	if (fh->total_queued_events)
 		res |= POLLPRI;
 	poll_wait(filp, &fh->wait, poll);
 	mutex_unlock(&adap->lock);
@@ -289,15 +289,17 @@ static long cec_receive(struct cec_adapter *adap, struct cec_fh *fh,
 static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh,
 			bool block, struct cec_event __user *parg)
 {
-	struct cec_event *ev = NULL;
+	struct cec_event_entry *ev = NULL;
 	u64 ts = ~0ULL;
 	unsigned int i;
+	unsigned int ev_idx;
 	long err = 0;
 
 	mutex_lock(&fh->lock);
-	while (!fh->pending_events && block) {
+	while (!fh->total_queued_events && block) {
 		mutex_unlock(&fh->lock);
-		err = wait_event_interruptible(fh->wait, fh->pending_events);
+		err = wait_event_interruptible(fh->wait,
+					       fh->total_queued_events);
 		if (err)
 			return err;
 		mutex_lock(&fh->lock);
@@ -305,23 +307,29 @@ static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh,
 
 	/* Find the oldest event */
 	for (i = 0; i < CEC_NUM_EVENTS; i++) {
-		if (fh->pending_events & (1 << (i + 1)) &&
-		    fh->events[i].ts <= ts) {
-			ev = &fh->events[i];
-			ts = ev->ts;
+		struct cec_event_entry *entry =
+			list_first_entry_or_null(&fh->events[i],
+						 struct cec_event_entry, list);
+
+		if (entry && entry->ev.ts <= ts) {
+			ev = entry;
+			ev_idx = i;
+			ts = ev->ev.ts;
 		}
 	}
+
 	if (!ev) {
 		err = -EAGAIN;
 		goto unlock;
 	}
+	list_del(&ev->list);
 
-	if (copy_to_user(parg, ev, sizeof(*ev))) {
+	if (copy_to_user(parg, &ev->ev, sizeof(ev->ev)))
 		err = -EFAULT;
-		goto unlock;
-	}
-
-	fh->pending_events &= ~(1 << ev->event);
+	if (ev_idx >= CEC_NUM_CORE_EVENTS)
+		kfree(ev);
+	fh->queued_events[ev_idx]--;
+	fh->total_queued_events--;
 
 unlock:
 	mutex_unlock(&fh->lock);
@@ -495,6 +503,7 @@ static int cec_open(struct inode *inode, struct file *filp)
 		.event = CEC_EVENT_STATE_CHANGE,
 		.flags = CEC_EVENT_FL_INITIAL_STATE,
 	};
+	unsigned int i;
 	int err;
 
 	if (!fh)
@@ -502,6 +511,8 @@ static int cec_open(struct inode *inode, struct file *filp)
 
 	INIT_LIST_HEAD(&fh->msgs);
 	INIT_LIST_HEAD(&fh->xfer_list);
+	for (i = 0; i < CEC_NUM_EVENTS; i++)
+		INIT_LIST_HEAD(&fh->events[i]);
 	mutex_init(&fh->lock);
 	init_waitqueue_head(&fh->wait);
 
@@ -544,6 +555,7 @@ static int cec_release(struct inode *inode, struct file *filp)
 	struct cec_devnode *devnode = cec_devnode_data(filp);
 	struct cec_adapter *adap = to_cec_adapter(devnode);
 	struct cec_fh *fh = filp->private_data;
+	unsigned int i;
 
 	mutex_lock(&adap->lock);
 	if (adap->cec_initiator == fh)
@@ -585,6 +597,16 @@ static int cec_release(struct inode *inode, struct file *filp)
 		list_del(&entry->list);
 		kfree(entry);
 	}
+	for (i = CEC_NUM_CORE_EVENTS; i < CEC_NUM_EVENTS; i++) {
+		while (!list_empty(&fh->events[i])) {
+			struct cec_event_entry *entry =
+				list_first_entry(&fh->events[i],
+						 struct cec_event_entry, list);
+
+			list_del(&entry->list);
+			kfree(entry);
+		}
+	}
 	kfree(fh);
 
 	cec_put_device(devnode);
diff --git a/include/media/cec.h b/include/media/cec.h
index 37768203572d..6cc862af74e5 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -81,7 +81,13 @@ struct cec_msg_entry {
 	struct cec_msg		msg;
 };
 
-#define CEC_NUM_EVENTS		CEC_EVENT_LOST_MSGS
+struct cec_event_entry {
+	struct list_head	list;
+	struct cec_event	ev;
+};
+
+#define CEC_NUM_CORE_EVENTS 2
+#define CEC_NUM_EVENTS CEC_EVENT_PIN_HIGH
 
 struct cec_fh {
 	struct list_head	list;
@@ -92,9 +98,11 @@ struct cec_fh {
 
 	/* Events */
 	wait_queue_head_t	wait;
-	unsigned int		pending_events;
-	struct cec_event	events[CEC_NUM_EVENTS];
 	struct mutex		lock;
+	struct list_head	events[CEC_NUM_EVENTS]; /* queued events */
+	u8			queued_events[CEC_NUM_EVENTS];
+	unsigned int		total_queued_events;
+	struct cec_event_entry	core_events[CEC_NUM_CORE_EVENTS];
 	struct list_head	msgs; /* queued messages */
 	unsigned int		queued_msgs;
 };
diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h
index bba73f33c8aa..d87a67b0bb06 100644
--- a/include/uapi/linux/cec.h
+++ b/include/uapi/linux/cec.h
@@ -412,6 +412,7 @@ struct cec_log_addrs {
 #define CEC_EVENT_PIN_HIGH		4
 
 #define CEC_EVENT_FL_INITIAL_STATE	(1 << 0)
+#define CEC_EVENT_FL_DROPPED_EVENTS	(1 << 1)
 
 /**
  * struct cec_event_state_change - used when the CEC adapter changes state.
@@ -424,7 +425,7 @@ struct cec_event_state_change {
 };
 
 /**
- * struct cec_event_lost_msgs - tells you how many messages were lost due.
+ * struct cec_event_lost_msgs - tells you how many messages were lost.
  * @lost_msgs: how many messages were lost.
  */
 struct cec_event_lost_msgs {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 07/11] cec: document the new CEC pin capability, events and mode
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
                   ` (5 preceding siblings ...)
  2017-07-11  6:30 ` [PATCH 06/11] cec: rework the cec event handling Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 08/11] cec: add core support for low-level CEC pin monitoring Hans Verkuil
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Document CEC_CAP_MONITOR_PIN, CEC_EVENT_PIN_LOW/HIGH,
CEC_EVENT_FL_DROPPED_EVENTS and CEC_MODE_MONITOR_PIN.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst |  7 +++++++
 Documentation/media/uapi/cec/cec-ioc-dqevent.rst     | 20 ++++++++++++++++++++
 Documentation/media/uapi/cec/cec-ioc-g-mode.rst      | 19 +++++++++++++++++--
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
index 6d7bf7bef3eb..882d6e025747 100644
--- a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
+++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
@@ -121,6 +121,13 @@ returns the information to the application. The ioctl never fails.
         high. This makes it impossible to use CEC to wake up displays that
 	set the HPD pin low when in standby mode, but keep the CEC bus
 	alive.
+    * .. _`CEC-CAP-MONITOR-PIN`:
+
+      - ``CEC_CAP_MONITOR_PIN``
+      - 0x00000080
+      - The CEC hardware can monitor CEC pin changes from low to high voltage
+        and vice versa. When in pin monitoring mode the application will
+	receive ``CEC_EVENT_PIN_LOW`` and ``CEC_EVENT_PIN_HIGH`` events.
 
 
 
diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst
index 4d3570c2e0b3..3e2cd5fefd38 100644
--- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst
+++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst
@@ -146,6 +146,20 @@ it is guaranteed that the state did change in between the two events.
       - 2
       - Generated if one or more CEC messages were lost because the
 	application didn't dequeue CEC messages fast enough.
+    * .. _`CEC-EVENT-PIN-LOW`:
+
+      - ``CEC_EVENT_PIN_LOW``
+      - 3
+      - Generated if the CEC pin goes from a high voltage to a low voltage.
+        Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
+	capability set.
+    * .. _`CEC-EVENT-PIN-HIGH`:
+
+      - ``CEC_EVENT_PIN_HIGH``
+      - 4
+      - Generated if the CEC pin goes from a low voltage to a high voltage.
+        Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
+	capability set.
 
 
 .. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}|
@@ -165,6 +179,12 @@ it is guaranteed that the state did change in between the two events.
 	opened. See the table above for which events do this. This allows
 	applications to learn the initial state of the CEC adapter at
 	open() time.
+    * .. _`CEC-EVENT-FL-DROPPED-EVENTS`:
+
+      - ``CEC_EVENT_FL_DROPPED_EVENTS``
+      - 2
+      - Set if one or more events of the given event type have been dropped.
+        This is an indication that the application cannot keep up.
 
 
 
diff --git a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst
index 664f0d47bbcd..3e907c74338f 100644
--- a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst
+++ b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst
@@ -149,13 +149,28 @@ Available follower modes are:
 	code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT <CEC-CAP-TRANSMIT>`
 	is not set or if :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>` was specified,
 	the ``EINVAL`` error code is returned in that case.
+    * .. _`CEC-MODE-MONITOR-PIN`:
+
+      - ``CEC_MODE_MONITOR_PIN``
+      - 0xd0
+      - Put the file descriptor into pin monitoring mode. Can only be used in
+	combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,
+	otherwise the ``EINVAL`` error code will be returned.
+	This mode requires that the :ref:`CEC_CAP_MONITOR_PIN <CEC-CAP-MONITOR-PIN>`
+	capability is set, otherwise the ``EINVAL`` error code is returned.
+	While in pin monitoring mode this file descriptor can receive the
+	``CEC_EVENT_PIN_LOW`` and ``CEC_EVENT_PIN_HIGH`` events to see the
+	low-level CEC pin transitions. This is very useful for debugging.
+	This mode is only allowed if the process has the ``CAP_NET_ADMIN``
+	capability. If that is not set, then the ``EPERM`` error code is returned.
     * .. _`CEC-MODE-MONITOR`:
 
       - ``CEC_MODE_MONITOR``
       - 0xe0
       - Put the file descriptor into monitor mode. Can only be used in
-	combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`, otherwise EINVAL error
-	code will be returned. In monitor mode all messages this CEC
+	combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,i
+	otherwise the ``EINVAL`` error code will be returned.
+	In monitor mode all messages this CEC
 	device transmits and all messages it receives (both broadcast
 	messages and directed messages for one its logical addresses) will
 	be reported. This is very useful for debugging. This is only
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 08/11] cec: add core support for low-level CEC pin monitoring
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
                   ` (6 preceding siblings ...)
  2017-07-11  6:30 ` [PATCH 07/11] cec: document the new CEC pin capability, events and mode Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 09/11] cec-pin: add low-level pin hardware support Hans Verkuil
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Add support for the new MONITOR_PIN mode.

Add the cec_pin_event function that the CEC pin code will call to queue pin
change events.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/cec/cec-adap.c | 16 ++++++++++++++++
 drivers/media/cec/cec-api.c  | 15 +++++++++++++--
 include/media/cec.h          | 11 +++++++++++
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index 67ec66c7c4ff..cbde6b015ff5 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -153,6 +153,22 @@ static void cec_queue_event(struct cec_adapter *adap,
 	mutex_unlock(&adap->devnode.lock);
 }
 
+/* Notify userspace that the CEC pin changed state at the given time. */
+void cec_queue_pin_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
+{
+	struct cec_event ev = {
+		.event = is_high ? CEC_EVENT_PIN_HIGH : CEC_EVENT_PIN_LOW,
+	};
+	struct cec_fh *fh;
+
+	mutex_lock(&adap->devnode.lock);
+	list_for_each_entry(fh, &adap->devnode.fhs, list)
+		if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
+			cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
+	mutex_unlock(&adap->devnode.lock);
+}
+EXPORT_SYMBOL_GPL(cec_queue_pin_event);
+
 /*
  * Queue a new message for this filehandle.
  *
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 48bef1c718ad..14279958dca1 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -370,6 +370,10 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
 	    !(adap->capabilities & CEC_CAP_MONITOR_ALL))
 		return -EINVAL;
 
+	if (mode_follower == CEC_MODE_MONITOR_PIN &&
+	    !(adap->capabilities & CEC_CAP_MONITOR_PIN))
+		return -EINVAL;
+
 	/* Follower modes should always be able to send CEC messages */
 	if ((mode_initiator == CEC_MODE_NO_INITIATOR ||
 	     !(adap->capabilities & CEC_CAP_TRANSMIT)) &&
@@ -378,11 +382,11 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
 		return -EINVAL;
 
 	/* Monitor modes require CEC_MODE_NO_INITIATOR */
-	if (mode_initiator && mode_follower >= CEC_MODE_MONITOR)
+	if (mode_initiator && mode_follower >= CEC_MODE_MONITOR_PIN)
 		return -EINVAL;
 
 	/* Monitor modes require CAP_NET_ADMIN */
-	if (mode_follower >= CEC_MODE_MONITOR && !capable(CAP_NET_ADMIN))
+	if (mode_follower >= CEC_MODE_MONITOR_PIN && !capable(CAP_NET_ADMIN))
 		return -EPERM;
 
 	mutex_lock(&adap->lock);
@@ -421,8 +425,13 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
 
 	if (fh->mode_follower == CEC_MODE_FOLLOWER)
 		adap->follower_cnt--;
+	if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
+		adap->monitor_pin_cnt--;
 	if (mode_follower == CEC_MODE_FOLLOWER)
 		adap->follower_cnt++;
+	if (mode_follower == CEC_MODE_MONITOR_PIN) {
+		adap->monitor_pin_cnt++;
+	}
 	if (mode_follower == CEC_MODE_EXCL_FOLLOWER ||
 	    mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
 		adap->passthrough =
@@ -566,6 +575,8 @@ static int cec_release(struct inode *inode, struct file *filp)
 	}
 	if (fh->mode_follower == CEC_MODE_FOLLOWER)
 		adap->follower_cnt--;
+	if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
+		adap->monitor_pin_cnt--;
 	if (fh->mode_follower == CEC_MODE_MONITOR_ALL)
 		cec_monitor_all_cnt_dec(adap);
 	mutex_unlock(&adap->lock);
diff --git a/include/media/cec.h b/include/media/cec.h
index 6cc862af74e5..d983960b37ad 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -177,6 +177,7 @@ struct cec_adapter {
 	bool is_configuring;
 	bool is_configured;
 	u32 monitor_all_cnt;
+	u32 monitor_pin_cnt;
 	u32 follower_cnt;
 	struct cec_fh *cec_follower;
 	struct cec_fh *cec_initiator;
@@ -272,6 +273,16 @@ static inline void cec_received_msg(struct cec_adapter *adap,
 }
 
 /**
+ * cec_queue_pin_event() - queue a pin event with a given timestamp.
+ *
+ * @adap:	pointer to the cec adapter
+ * @is_high:	when true the pin is high, otherwise it is low
+ * @ts:		the timestamp for this event
+ *
+ */
+void cec_queue_pin_event(struct cec_adapter *adap, bool is_high, ktime_t ts);
+
+/**
  * cec_get_edid_phys_addr() - find and return the physical address
  *
  * @edid:	pointer to the EDID data
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 09/11] cec-pin: add low-level pin hardware support
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
                   ` (7 preceding siblings ...)
  2017-07-11  6:30 ` [PATCH 08/11] cec: add core support for low-level CEC pin monitoring Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 10/11] cec-core.rst: include cec-pin.h and cec-notifier.h Hans Verkuil
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Add support for CEC hardware that relies on low-level pin polling or
GPIO interrupts.

One example is the Allwinner SoC. But any GPIO-based CEC implementation can
use this as well.

A GPIO implementation is very suitable as well for debugging: it can use
interrupts to detect state changes and report it. Userspace can then verify
if the bus traffic is correct. This also makes error injection possible.

The disadvantage is that it is hard to get the timings right since linux
isn't a hard realtime system.

In general on an idle system it works quite well, but under load the timer
will miss its mark every so often.

The debugfs file /sys/kernel/debug/cec/cecX/status gives some statistics
with respect to the timer overruns.

When the adapter is unconfigured and the low-level driver supports
interrupts, then the interrupt will be used to detect changes. This should
be quite accurate. But when the adapter is configured a hrtimer has to be
used.

The hrtimer implements a state machine where for each state the code will
read the bus or drive the bus and go on to the next state. It will re-arm
the timer with a delay based on the next state.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/Kconfig       |   3 +
 drivers/media/cec/Makefile  |   4 +
 drivers/media/cec/cec-api.c |  10 +
 drivers/media/cec/cec-pin.c | 794 ++++++++++++++++++++++++++++++++++++++++++++
 include/media/cec-pin.h     | 183 ++++++++++
 include/media/cec.h         |   4 +
 6 files changed, 998 insertions(+)
 create mode 100644 drivers/media/cec/cec-pin.c
 create mode 100644 include/media/cec-pin.h

diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 55d9c2b82b7e..94d4e7759127 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -8,6 +8,9 @@ config CEC_CORE
 config CEC_NOTIFIER
 	bool
 
+config CEC_PIN
+	bool
+
 menuconfig MEDIA_SUPPORT
 	tristate "Multimedia support"
 	depends on HAS_IOMEM
diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile
index eaf408e64669..3353c1741961 100644
--- a/drivers/media/cec/Makefile
+++ b/drivers/media/cec/Makefile
@@ -4,4 +4,8 @@ ifeq ($(CONFIG_CEC_NOTIFIER),y)
   cec-objs += cec-notifier.o
 endif
 
+ifeq ($(CONFIG_CEC_PIN),y)
+  cec-objs += cec-pin.o
+endif
+
 obj-$(CONFIG_CEC_CORE) += cec.o
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 14279958dca1..8dd16e263452 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -30,6 +30,7 @@
 #include <linux/uaccess.h>
 #include <linux/version.h>
 
+#include <media/cec-pin.h>
 #include "cec-priv.h"
 
 static inline struct cec_devnode *cec_devnode_data(struct file *filp)
@@ -430,6 +431,15 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
 	if (mode_follower == CEC_MODE_FOLLOWER)
 		adap->follower_cnt++;
 	if (mode_follower == CEC_MODE_MONITOR_PIN) {
+#ifdef CONFIG_CEC_PIN
+		struct cec_event ev = {
+			.flags = CEC_EVENT_FL_INITIAL_STATE,
+		};
+
+		ev.event = adap->pin->cur_value ? CEC_EVENT_PIN_HIGH :
+						  CEC_EVENT_PIN_LOW;
+		cec_queue_event_fh(fh, &ev, 0);
+#endif
 		adap->monitor_pin_cnt++;
 	}
 	if (mode_follower == CEC_MODE_EXCL_FOLLOWER ||
diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c
new file mode 100644
index 000000000000..03f800e5ec1f
--- /dev/null
+++ b/drivers/media/cec/cec-pin.c
@@ -0,0 +1,794 @@
+/*
+ * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/sched/types.h>
+
+#include <media/cec-pin.h>
+
+/* All timings are in microseconds */
+
+/* start bit timings */
+#define CEC_TIM_START_BIT_LOW		3700
+#define CEC_TIM_START_BIT_LOW_MIN	3500
+#define CEC_TIM_START_BIT_LOW_MAX	3900
+#define CEC_TIM_START_BIT_TOTAL		4500
+#define CEC_TIM_START_BIT_TOTAL_MIN	4300
+#define CEC_TIM_START_BIT_TOTAL_MAX	4700
+
+/* data bit timings */
+#define CEC_TIM_DATA_BIT_0_LOW		1500
+#define CEC_TIM_DATA_BIT_0_LOW_MIN	1300
+#define CEC_TIM_DATA_BIT_0_LOW_MAX	1700
+#define CEC_TIM_DATA_BIT_1_LOW		600
+#define CEC_TIM_DATA_BIT_1_LOW_MIN	400
+#define CEC_TIM_DATA_BIT_1_LOW_MAX	800
+#define CEC_TIM_DATA_BIT_TOTAL		2400
+#define CEC_TIM_DATA_BIT_TOTAL_MIN	2050
+#define CEC_TIM_DATA_BIT_TOTAL_MAX	2750
+/* earliest safe time to sample the bit state */
+#define CEC_TIM_DATA_BIT_SAMPLE		850
+/* earliest time the bit is back to 1 (T7 + 50) */
+#define CEC_TIM_DATA_BIT_HIGH		1750
+
+/* when idle, sample once per millisecond */
+#define CEC_TIM_IDLE_SAMPLE		1000
+/* when processing the start bit, sample twice per millisecond */
+#define CEC_TIM_START_BIT_SAMPLE	500
+/* when polling for a state change, sample once every 50 micoseconds */
+#define CEC_TIM_SAMPLE			50
+
+#define CEC_TIM_LOW_DRIVE_ERROR		(1.5 * CEC_TIM_DATA_BIT_TOTAL)
+
+struct cec_state {
+	const char * const name;
+	unsigned int usecs;
+};
+
+static const struct cec_state states[CEC_PIN_STATES] = {
+	{ "Off",		   0 },
+	{ "Idle",		   CEC_TIM_IDLE_SAMPLE },
+	{ "Tx Wait",		   CEC_TIM_SAMPLE },
+	{ "Tx Wait for High",	   CEC_TIM_IDLE_SAMPLE },
+	{ "Tx Start Bit Low",	   CEC_TIM_START_BIT_LOW },
+	{ "Tx Start Bit High",	   CEC_TIM_START_BIT_TOTAL - CEC_TIM_START_BIT_LOW },
+	{ "Tx Data 0 Low",	   CEC_TIM_DATA_BIT_0_LOW },
+	{ "Tx Data 0 High",	   CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_0_LOW },
+	{ "Tx Data 1 Low",	   CEC_TIM_DATA_BIT_1_LOW },
+	{ "Tx Data 1 High",	   CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_1_LOW },
+	{ "Tx Data 1 Pre Sample",  CEC_TIM_DATA_BIT_SAMPLE - CEC_TIM_DATA_BIT_1_LOW },
+	{ "Tx Data 1 Post Sample", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_SAMPLE },
+	{ "Rx Start Bit Low",	   CEC_TIM_SAMPLE },
+	{ "Rx Start Bit High",	   CEC_TIM_SAMPLE },
+	{ "Rx Data Sample",	   CEC_TIM_DATA_BIT_SAMPLE },
+	{ "Rx Data Post Sample",   CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_SAMPLE },
+	{ "Rx Data High",	   CEC_TIM_SAMPLE },
+	{ "Rx Ack Low",		   CEC_TIM_DATA_BIT_0_LOW },
+	{ "Rx Ack Low Post",	   CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_0_LOW },
+	{ "Rx Ack High Post",	   CEC_TIM_DATA_BIT_HIGH },
+	{ "Rx Ack Finish",	   CEC_TIM_DATA_BIT_TOTAL_MIN - CEC_TIM_DATA_BIT_HIGH },
+	{ "Rx Low Drive",	   CEC_TIM_LOW_DRIVE_ERROR },
+	{ "Rx Irq",		   0 },
+};
+
+static void cec_pin_update(struct cec_pin *pin, bool v, bool force)
+{
+	if (!force && v == pin->cur_value)
+		return;
+
+	pin->cur_value = v;
+	if (atomic_read(&pin->work_pin_events) < CEC_NUM_PIN_EVENTS) {
+		pin->work_pin_is_high[pin->work_pin_events_wr] = v;
+		pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get();
+		pin->work_pin_events_wr =
+			(pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS;
+		atomic_inc(&pin->work_pin_events);
+	}
+	wake_up_interruptible(&pin->kthread_waitq);
+}
+
+static bool cec_pin_read(struct cec_pin *pin)
+{
+	bool v = pin->ops->read(pin->adap);
+
+	cec_pin_update(pin, v, false);
+	return v;
+}
+
+static void cec_pin_low(struct cec_pin *pin)
+{
+	pin->ops->low(pin->adap);
+	cec_pin_update(pin, false, false);
+}
+
+static bool cec_pin_high(struct cec_pin *pin)
+{
+	pin->ops->high(pin->adap);
+	return cec_pin_read(pin);
+}
+
+static void cec_pin_to_idle(struct cec_pin *pin)
+{
+	/*
+	 * Reset all status fields, release the bus and
+	 * go to idle state.
+	 */
+	pin->rx_bit = pin->tx_bit = 0;
+	pin->rx_msg.len = 0;
+	memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg));
+	pin->state = CEC_ST_IDLE;
+	pin->ts = 0;
+}
+
+/*
+ * Handle Transmit-related states
+ *
+ * Basic state changes when transmitting:
+ *
+ * Idle -> Tx Wait (waiting for the end of signal free time) ->
+ *	Tx Start Bit Low -> Tx Start Bit High ->
+ *
+ *   Regular data bits + EOM:
+ *	Tx Data 0 Low -> Tx Data 0 High ->
+ *   or:
+ *	Tx Data 1 Low -> Tx Data 1 High ->
+ *
+ *   First 4 data bits or Ack bit:
+ *	Tx Data 0 Low -> Tx Data 0 High ->
+ *   or:
+ *	Tx Data 1 Low -> Tx Data 1 High -> Tx Data 1 Pre Sample ->
+ *		Tx Data 1 Post Sample ->
+ *
+ *   After the last Ack go to Idle.
+ *
+ * If it detects a Low Drive condition then:
+ *	Tx Wait For High -> Idle
+ *
+ * If it loses arbitration, then it switches to state Rx Data Post Sample.
+ */
+static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts)
+{
+	bool v;
+	bool is_ack_bit, ack;
+
+	switch (pin->state) {
+	case CEC_ST_TX_WAIT_FOR_HIGH:
+		if (cec_pin_read(pin))
+			cec_pin_to_idle(pin);
+		break;
+
+	case CEC_ST_TX_START_BIT_LOW:
+		pin->state = CEC_ST_TX_START_BIT_HIGH;
+		/* Generate start bit */
+		cec_pin_high(pin);
+		break;
+
+	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE:
+		/* If the read value is 1, then all is OK */
+		if (!cec_pin_read(pin)) {
+			/*
+			 * It's 0, so someone detected an error and pulled the
+			 * line low for 1.5 times the nominal bit period.
+			 */
+			pin->tx_msg.len = 0;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE;
+			pin->state = CEC_ST_TX_WAIT_FOR_HIGH;
+			wake_up_interruptible(&pin->kthread_waitq);
+			break;
+		}
+		if (pin->tx_nacked) {
+			cec_pin_to_idle(pin);
+			pin->tx_msg.len = 0;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_NACK;
+			wake_up_interruptible(&pin->kthread_waitq);
+			break;
+		}
+		/* fall through */
+	case CEC_ST_TX_DATA_BIT_0_HIGH:
+	case CEC_ST_TX_DATA_BIT_1_HIGH:
+		pin->tx_bit++;
+		/* fall through */
+	case CEC_ST_TX_START_BIT_HIGH:
+		if (pin->tx_bit / 10 >= pin->tx_msg.len) {
+			cec_pin_to_idle(pin);
+			pin->tx_msg.len = 0;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_OK;
+			wake_up_interruptible(&pin->kthread_waitq);
+			break;
+		}
+
+		switch (pin->tx_bit % 10) {
+		default:
+			v = pin->tx_msg.msg[pin->tx_bit / 10] &
+				(1 << (7 - (pin->tx_bit % 10)));
+			pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW :
+				CEC_ST_TX_DATA_BIT_0_LOW;
+			break;
+		case 8:
+			v = pin->tx_bit / 10 == pin->tx_msg.len - 1;
+			pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW :
+				CEC_ST_TX_DATA_BIT_0_LOW;
+			break;
+		case 9:
+			pin->state = CEC_ST_TX_DATA_BIT_1_LOW;
+			break;
+		}
+		cec_pin_low(pin);
+		break;
+
+	case CEC_ST_TX_DATA_BIT_0_LOW:
+	case CEC_ST_TX_DATA_BIT_1_LOW:
+		v = pin->state == CEC_ST_TX_DATA_BIT_1_LOW;
+		pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH :
+			CEC_ST_TX_DATA_BIT_0_HIGH;
+		is_ack_bit = pin->tx_bit % 10 == 9;
+		if (v && (pin->tx_bit < 4 || is_ack_bit))
+			pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE;
+		cec_pin_high(pin);
+		break;
+
+	case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE:
+		/* Read the CEC value at the sample time */
+		v = cec_pin_read(pin);
+		is_ack_bit = pin->tx_bit % 10 == 9;
+		/*
+		 * If v == 0 and we're within the first 4 bits
+		 * of the initiator, then someone else started
+		 * transmitting and we lost the arbitration
+		 * (i.e. the logical address of the other
+		 * transmitter has more leading 0 bits in the
+		 * initiator).
+		 */
+		if (!v && !is_ack_bit) {
+			pin->tx_msg.len = 0;
+			pin->work_tx_ts = ts;
+			pin->work_tx_status = CEC_TX_STATUS_ARB_LOST;
+			wake_up_interruptible(&pin->kthread_waitq);
+			pin->rx_bit = pin->tx_bit;
+			pin->tx_bit = 0;
+			memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg));
+			pin->rx_msg.msg[0] = pin->tx_msg.msg[0];
+			pin->rx_msg.msg[0] &= ~(1 << (7 - pin->rx_bit));
+			pin->rx_msg.len = 0;
+			pin->state = CEC_ST_RX_DATA_POST_SAMPLE;
+			pin->rx_bit++;
+			break;
+		}
+		pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE;
+		if (!is_ack_bit)
+			break;
+		/* Was the message ACKed? */
+		ack = cec_msg_is_broadcast(&pin->tx_msg) ? v : !v;
+		if (!ack) {
+			/*
+			 * Note: the CEC spec is ambiguous regarding
+			 * what action to take when a NACK appears
+			 * before the last byte of the payload was
+			 * transmitted: either stop transmitting
+			 * immediately, or wait until the last byte
+			 * was transmitted.
+			 *
+			 * Most CEC implementations appear to stop
+			 * immediately, and that's what we do here
+			 * as well.
+			 */
+			pin->tx_nacked = true;
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+/*
+ * Handle Receive-related states
+ *
+ * Basic state changes when receiving:
+ *
+ *	Rx Start Bit Low -> Rx Start Bit High ->
+ *   Regular data bits + EOM:
+ *	Rx Data Sample -> Rx Data Post Sample -> Rx Data High ->
+ *   Ack bit 0:
+ *	Rx Ack Low -> Rx Ack Low Post -> Rx Data High ->
+ *   Ack bit 1:
+ *	Rx Ack High Post -> Rx Data High ->
+ *   Ack bit 0 && EOM:
+ *	Rx Ack Low -> Rx Ack Low Post -> Rx Ack Finish -> Idle
+ */
+static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts)
+{
+	s32 delta;
+	bool v;
+	bool ack;
+	bool bcast, for_us;
+	u8 dest;
+
+	switch (pin->state) {
+	/* Receive states */
+	case CEC_ST_RX_START_BIT_LOW:
+		v = cec_pin_read(pin);
+		if (!v)
+			break;
+		pin->state = CEC_ST_RX_START_BIT_HIGH;
+		delta = ktime_us_delta(ts, pin->ts);
+		pin->ts = ts;
+		/* Start bit low is too short, go back to idle */
+		if (delta < CEC_TIM_START_BIT_LOW_MIN -
+			    CEC_TIM_IDLE_SAMPLE) {
+			cec_pin_to_idle(pin);
+		}
+		break;
+
+	case CEC_ST_RX_START_BIT_HIGH:
+		v = cec_pin_read(pin);
+		delta = ktime_us_delta(ts, pin->ts);
+		if (v && delta > CEC_TIM_START_BIT_TOTAL_MAX -
+				 CEC_TIM_START_BIT_LOW_MIN) {
+			cec_pin_to_idle(pin);
+			break;
+		}
+		if (v)
+			break;
+		pin->state = CEC_ST_RX_DATA_SAMPLE;
+		pin->ts = ts;
+		pin->rx_eom = false;
+		break;
+
+	case CEC_ST_RX_DATA_SAMPLE:
+		v = cec_pin_read(pin);
+		pin->state = CEC_ST_RX_DATA_POST_SAMPLE;
+		switch (pin->rx_bit % 10) {
+		default:
+			if (pin->rx_bit / 10 < CEC_MAX_MSG_SIZE)
+				pin->rx_msg.msg[pin->rx_bit / 10] |=
+					v << (7 - (pin->rx_bit % 10));
+			break;
+		case 8:
+			pin->rx_eom = v;
+			pin->rx_msg.len = pin->rx_bit / 10 + 1;
+			break;
+		case 9:
+			break;
+		}
+		pin->rx_bit++;
+		break;
+
+	case CEC_ST_RX_DATA_POST_SAMPLE:
+		pin->state = CEC_ST_RX_DATA_HIGH;
+		break;
+
+	case CEC_ST_RX_DATA_HIGH:
+		v = cec_pin_read(pin);
+		delta = ktime_us_delta(ts, pin->ts);
+		if (v && delta > CEC_TIM_DATA_BIT_TOTAL_MAX) {
+			cec_pin_to_idle(pin);
+			break;
+		}
+		if (v)
+			break;
+		/*
+		 * Go to low drive state when the total bit time is
+		 * too short.
+		 */
+		if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN) {
+			cec_pin_low(pin);
+			pin->state = CEC_ST_LOW_DRIVE;
+			break;
+		}
+		pin->ts = ts;
+		if (pin->rx_bit % 10 != 9) {
+			pin->state = CEC_ST_RX_DATA_SAMPLE;
+			break;
+		}
+
+		dest = cec_msg_destination(&pin->rx_msg);
+		bcast = dest == CEC_LOG_ADDR_BROADCAST;
+		/* for_us == broadcast or directed to us */
+		for_us = bcast || (pin->la_mask & (1 << dest));
+		/* ACK bit value */
+		ack = bcast ? 1 : !for_us;
+
+		if (ack) {
+			/* No need to write to the bus, just wait */
+			pin->state = CEC_ST_RX_ACK_HIGH_POST;
+			break;
+		}
+		cec_pin_low(pin);
+		pin->state = CEC_ST_RX_ACK_LOW;
+		break;
+
+	case CEC_ST_RX_ACK_LOW:
+		cec_pin_high(pin);
+		pin->state = CEC_ST_RX_ACK_LOW_POST;
+		break;
+
+	case CEC_ST_RX_ACK_LOW_POST:
+	case CEC_ST_RX_ACK_HIGH_POST:
+		v = cec_pin_read(pin);
+		if (v && pin->rx_eom) {
+			pin->work_rx_msg = pin->rx_msg;
+			pin->work_rx_msg.rx_ts = ts;
+			wake_up_interruptible(&pin->kthread_waitq);
+			pin->ts = ts;
+			pin->state = CEC_ST_RX_ACK_FINISH;
+			break;
+		}
+		pin->rx_bit++;
+		pin->state = CEC_ST_RX_DATA_HIGH;
+		break;
+
+	case CEC_ST_RX_ACK_FINISH:
+		cec_pin_to_idle(pin);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/*
+ * Main timer function
+ *
+ */
+static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
+{
+	struct cec_pin *pin = container_of(timer, struct cec_pin, timer);
+	struct cec_adapter *adap = pin->adap;
+	ktime_t ts;
+	s32 delta;
+
+	ts = ktime_get();
+	if (pin->timer_ts) {
+		delta = ktime_us_delta(ts, pin->timer_ts);
+		pin->timer_cnt++;
+		if (delta > 100 && pin->state != CEC_ST_IDLE) {
+			/* Keep track of timer overruns */
+			pin->timer_sum_overrun += delta;
+			pin->timer_100ms_overruns++;
+			if (delta > 300)
+				pin->timer_300ms_overruns++;
+			if (delta > pin->timer_max_overrun)
+				pin->timer_max_overrun = delta;
+		}
+	}
+	if (adap->monitor_pin_cnt)
+		cec_pin_read(pin);
+
+	if (pin->wait_usecs) {
+		/*
+		 * If we are monitoring the pin, then we have to
+		 * sample at regular intervals.
+		 */
+		if (pin->wait_usecs > 150) {
+			pin->wait_usecs -= 100;
+			pin->timer_ts = ktime_add_us(ts, 100);
+			hrtimer_forward_now(timer, 100000);
+			return HRTIMER_RESTART;
+		}
+		if (pin->wait_usecs > 100) {
+			pin->wait_usecs /= 2;
+			pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
+			hrtimer_forward_now(timer, pin->wait_usecs * 1000);
+			return HRTIMER_RESTART;
+		}
+		pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
+		hrtimer_forward_now(timer, pin->wait_usecs * 1000);
+		pin->wait_usecs = 0;
+		return HRTIMER_RESTART;
+	}
+
+	switch (pin->state) {
+	/* Transmit states */
+	case CEC_ST_TX_WAIT_FOR_HIGH:
+	case CEC_ST_TX_START_BIT_LOW:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE:
+	case CEC_ST_TX_DATA_BIT_0_HIGH:
+	case CEC_ST_TX_DATA_BIT_1_HIGH:
+	case CEC_ST_TX_START_BIT_HIGH:
+	case CEC_ST_TX_DATA_BIT_0_LOW:
+	case CEC_ST_TX_DATA_BIT_1_LOW:
+	case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE:
+		cec_pin_tx_states(pin, ts);
+		break;
+
+	/* Receive states */
+	case CEC_ST_RX_START_BIT_LOW:
+	case CEC_ST_RX_START_BIT_HIGH:
+	case CEC_ST_RX_DATA_SAMPLE:
+	case CEC_ST_RX_DATA_POST_SAMPLE:
+	case CEC_ST_RX_DATA_HIGH:
+	case CEC_ST_RX_ACK_LOW:
+	case CEC_ST_RX_ACK_LOW_POST:
+	case CEC_ST_RX_ACK_HIGH_POST:
+	case CEC_ST_RX_ACK_FINISH:
+		cec_pin_rx_states(pin, ts);
+		break;
+
+	case CEC_ST_IDLE:
+	case CEC_ST_TX_WAIT:
+		if (!cec_pin_high(pin)) {
+			/* Start bit, switch to receive state */
+			pin->ts = ts;
+			pin->state = CEC_ST_RX_START_BIT_LOW;
+			break;
+		}
+		if (pin->ts == 0)
+			pin->ts = ts;
+		if (pin->tx_msg.len) {
+			/*
+			 * Check if the bus has been free for long enough
+			 * so we can kick off the pending transmit.
+			 */
+			delta = ktime_us_delta(ts, pin->ts);
+			if (delta / CEC_TIM_DATA_BIT_TOTAL >
+			    pin->tx_signal_free_time) {
+				pin->tx_nacked = false;
+				pin->state = CEC_ST_TX_START_BIT_LOW;
+				/* Generate start bit */
+				cec_pin_low(pin);
+				break;
+			}
+			if (delta / CEC_TIM_DATA_BIT_TOTAL >
+			    pin->tx_signal_free_time - 1)
+				pin->state = CEC_ST_TX_WAIT;
+			break;
+		}
+		if (pin->state != CEC_ST_IDLE || pin->ops->enable_irq == NULL ||
+		    pin->enable_irq_failed || adap->is_configuring ||
+		    adap->is_configured || adap->monitor_all_cnt)
+			break;
+		/* Switch to interrupt mode */
+		pin->work_enable_irq = true;
+		pin->state = CEC_ST_RX_IRQ;
+		wake_up_interruptible(&pin->kthread_waitq);
+		return HRTIMER_NORESTART;
+
+	case CEC_ST_LOW_DRIVE:
+		cec_pin_to_idle(pin);
+		break;
+
+	default:
+		break;
+	}
+	if (!adap->monitor_pin_cnt || states[pin->state].usecs <= 150) {
+		pin->wait_usecs = 0;
+		pin->timer_ts = ktime_add_us(ts, states[pin->state].usecs);
+		hrtimer_forward_now(timer, states[pin->state].usecs * 1000);
+		return HRTIMER_RESTART;
+	}
+	pin->wait_usecs = states[pin->state].usecs - 100;
+	pin->timer_ts = ktime_add_us(ts, 100);
+	hrtimer_forward_now(timer, 100000);
+	return HRTIMER_RESTART;
+}
+
+static int cec_pin_thread_func(void *_adap)
+{
+	struct cec_adapter *adap = _adap;
+	struct cec_pin *pin = adap->pin;
+
+	for (;;) {
+		wait_event_interruptible(pin->kthread_waitq,
+			kthread_should_stop() ||
+			pin->work_rx_msg.len ||
+			pin->work_tx_status ||
+			pin->work_enable_irq ||
+			atomic_read(&pin->work_pin_events));
+
+		if (pin->work_rx_msg.len) {
+			cec_received_msg_ts(adap, &pin->work_rx_msg,
+					    pin->work_rx_msg.rx_ts);
+			pin->work_rx_msg.len = 0;
+		}
+		if (pin->work_tx_status) {
+			unsigned int tx_status = pin->work_tx_status;
+
+			pin->work_tx_status = 0;
+			cec_transmit_attempt_done_ts(adap, tx_status,
+						     pin->work_tx_ts);
+		}
+		while (atomic_read(&pin->work_pin_events)) {
+			unsigned int idx = pin->work_pin_events_rd;
+
+			cec_queue_pin_event(adap, pin->work_pin_is_high[idx],
+					    pin->work_pin_ts[idx]);
+			pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS;
+			atomic_dec(&pin->work_pin_events);
+		}
+		if (pin->work_enable_irq) {
+			pin->work_enable_irq = false;
+			pin->enable_irq_failed = !pin->ops->enable_irq(adap);
+			if (pin->enable_irq_failed) {
+				cec_pin_to_idle(pin);
+				hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
+			}
+		}
+		if (kthread_should_stop())
+			break;
+	}
+	return 0;
+}
+
+static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
+{
+	struct cec_pin *pin = adap->pin;
+
+	pin->enabled = enable;
+	if (enable) {
+		atomic_set(&pin->work_pin_events, 0);
+		pin->work_pin_events_rd = pin->work_pin_events_wr = 0;
+		cec_pin_read(pin);
+		cec_pin_to_idle(pin);
+		pin->tx_msg.len = 0;
+		pin->timer_ts = 0;
+		pin->work_enable_irq = false;
+		pin->kthread = kthread_run(cec_pin_thread_func, adap,
+					   "cec-pin");
+		if (IS_ERR(pin->kthread)) {
+			pr_err("cec-pin: kernel_thread() failed\n");
+			return PTR_ERR(pin->kthread);
+		}
+		hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
+	} else {
+		if (pin->ops->disable_irq)
+			pin->ops->disable_irq(adap);
+		hrtimer_cancel(&pin->timer);
+		kthread_stop(pin->kthread);
+		cec_pin_read(pin);
+		cec_pin_to_idle(pin);
+		pin->state = CEC_ST_OFF;
+	}
+	return 0;
+}
+
+static int cec_pin_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
+{
+	struct cec_pin *pin = adap->pin;
+
+	if (log_addr == CEC_LOG_ADDR_INVALID)
+		pin->la_mask = 0;
+	else
+		pin->la_mask |= (1 << log_addr);
+	return 0;
+}
+
+static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts,
+				      u32 signal_free_time, struct cec_msg *msg)
+{
+	struct cec_pin *pin = adap->pin;
+
+	pin->tx_signal_free_time = signal_free_time;
+	pin->tx_msg = *msg;
+	pin->work_tx_status = 0;
+	pin->tx_bit = 0;
+	if (pin->state == CEC_ST_RX_IRQ) {
+		pin->work_enable_irq = false;
+		pin->ops->disable_irq(adap);
+		cec_pin_high(pin);
+		cec_pin_to_idle(pin);
+		hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
+	}
+	return 0;
+}
+
+static void cec_pin_adap_status(struct cec_adapter *adap,
+				       struct seq_file *file)
+{
+	struct cec_pin *pin = adap->pin;
+
+	seq_printf(file, "state:   %s\n", states[pin->state].name);
+	seq_printf(file, "tx_bit:  %d\n", pin->tx_bit);
+	seq_printf(file, "rx_bit:  %d\n", pin->rx_bit);
+	seq_printf(file, "cec pin: %d\n", pin->ops->read(adap));
+	seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed);
+	if (pin->timer_100ms_overruns) {
+		seq_printf(file, "timer overruns > 100ms: %u of %u\n",
+			   pin->timer_100ms_overruns, pin->timer_cnt);
+		seq_printf(file, "timer overruns > 300ms: %u of %u\n",
+			   pin->timer_300ms_overruns, pin->timer_cnt);
+		seq_printf(file, "max timer overrun: %u usecs\n",
+			   pin->timer_max_overrun);
+		seq_printf(file, "avg timer overrun: %u usecs\n",
+			   pin->timer_sum_overrun / pin->timer_100ms_overruns);
+	}
+	pin->timer_cnt = 0;
+	pin->timer_100ms_overruns = 0;
+	pin->timer_300ms_overruns = 0;
+	pin->timer_max_overrun = 0;
+	pin->timer_sum_overrun = 0;
+	if (pin->ops->status)
+		pin->ops->status(adap, file);
+}
+
+static int cec_pin_adap_monitor_all_enable(struct cec_adapter *adap,
+						  bool enable)
+{
+	struct cec_pin *pin = adap->pin;
+
+	pin->monitor_all = enable;
+	return 0;
+}
+
+static void cec_pin_adap_free(struct cec_adapter *adap)
+{
+	struct cec_pin *pin = adap->pin;
+
+	if (pin->ops->free)
+		pin->ops->free(adap);
+	adap->pin = NULL;
+	kfree(pin);
+}
+
+void cec_pin_changed(struct cec_adapter *adap, bool value)
+{
+	struct cec_pin *pin = adap->pin;
+
+	cec_pin_update(pin, value, false);
+	if (!value && (adap->is_configuring || adap->is_configured ||
+		       adap->monitor_all_cnt)) {
+		pin->work_enable_irq = false;
+		pin->ops->disable_irq(adap);
+		cec_pin_high(pin);
+		cec_pin_to_idle(pin);
+		hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
+	}
+}
+EXPORT_SYMBOL_GPL(cec_pin_changed);
+
+static const struct cec_adap_ops cec_pin_adap_ops = {
+	.adap_enable = cec_pin_adap_enable,
+	.adap_monitor_all_enable = cec_pin_adap_monitor_all_enable,
+	.adap_log_addr = cec_pin_adap_log_addr,
+	.adap_transmit = cec_pin_adap_transmit,
+	.adap_status = cec_pin_adap_status,
+	.adap_free = cec_pin_adap_free,
+};
+
+struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops,
+					void *priv, const char *name, u32 caps)
+{
+	struct cec_adapter *adap;
+	struct cec_pin *pin = kzalloc(sizeof(*pin), GFP_KERNEL);
+
+	if (pin == NULL)
+		return ERR_PTR(-ENOMEM);
+	pin->ops = pin_ops;
+	pin->cur_value = true;
+	hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	pin->timer.function = cec_pin_timer;
+	init_waitqueue_head(&pin->kthread_waitq);
+
+	adap = cec_allocate_adapter(&cec_pin_adap_ops, priv, name,
+			    caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN,
+			    CEC_MAX_LOG_ADDRS);
+
+	if (PTR_ERR_OR_ZERO(adap)) {
+		kfree(pin);
+		return adap;
+	}
+
+	adap->pin = pin;
+	pin->adap = adap;
+	cec_pin_update(pin, cec_pin_high(pin), true);
+	return adap;
+}
+EXPORT_SYMBOL_GPL(cec_pin_allocate_adapter);
diff --git a/include/media/cec-pin.h b/include/media/cec-pin.h
new file mode 100644
index 000000000000..44b82d29d480
--- /dev/null
+++ b/include/media/cec-pin.h
@@ -0,0 +1,183 @@
+/*
+ * cec-pin.h - low-level CEC pin control
+ *
+ * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef LINUX_CEC_PIN_H
+#define LINUX_CEC_PIN_H
+
+#include <linux/types.h>
+#include <linux/atomic.h>
+#include <media/cec.h>
+
+enum cec_pin_state {
+	/* CEC is off */
+	CEC_ST_OFF,
+	/* CEC is idle, waiting for Rx or Tx */
+	CEC_ST_IDLE,
+
+	/* Tx states */
+
+	/* Pending Tx, waiting for Signal Free Time to expire */
+	CEC_ST_TX_WAIT,
+	/* Low-drive was detected, wait for bus to go high */
+	CEC_ST_TX_WAIT_FOR_HIGH,
+	/* Drive CEC low for the start bit */
+	CEC_ST_TX_START_BIT_LOW,
+	/* Drive CEC high for the start bit */
+	CEC_ST_TX_START_BIT_HIGH,
+	/* Drive CEC low for the 0 bit */
+	CEC_ST_TX_DATA_BIT_0_LOW,
+	/* Drive CEC high for the 0 bit */
+	CEC_ST_TX_DATA_BIT_0_HIGH,
+	/* Drive CEC low for the 1 bit */
+	CEC_ST_TX_DATA_BIT_1_LOW,
+	/* Drive CEC high for the 1 bit */
+	CEC_ST_TX_DATA_BIT_1_HIGH,
+	/*
+	 * Wait for start of sample time to check for Ack bit or first
+	 * four initiator bits to check for Arbitration Lost.
+	 */
+	CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
+	/* Wait for end of bit period after sampling */
+	CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
+
+	/* Rx states */
+
+	/* Start bit low detected */
+	CEC_ST_RX_START_BIT_LOW,
+	/* Start bit high detected */
+	CEC_ST_RX_START_BIT_HIGH,
+	/* Wait for bit sample time */
+	CEC_ST_RX_DATA_SAMPLE,
+	/* Wait for earliest end of bit period after sampling */
+	CEC_ST_RX_DATA_POST_SAMPLE,
+	/* Wait for CEC to go high (i.e. end of bit period */
+	CEC_ST_RX_DATA_HIGH,
+	/* Drive CEC low to send 0 Ack bit */
+	CEC_ST_RX_ACK_LOW,
+	/* End of 0 Ack time, wait for earliest end of bit period */
+	CEC_ST_RX_ACK_LOW_POST,
+	/* Wait for CEC to go high (i.e. end of bit period */
+	CEC_ST_RX_ACK_HIGH_POST,
+	/* Wait for earliest end of bit period and end of message */
+	CEC_ST_RX_ACK_FINISH,
+
+	/* Start low drive */
+	CEC_ST_LOW_DRIVE,
+	/* Monitor pin using interrupts */
+	CEC_ST_RX_IRQ,
+
+	/* Total number of pin states */
+	CEC_PIN_STATES
+};
+
+/**
+ * struct cec_pin_ops - low-level CEC pin operations
+ * @read:	read the CEC pin. Return true if high, false if low.
+ * @low:	drive the CEC pin low.
+ * @high:	stop driving the CEC pin. The pull-up will drive the pin
+ *		high, unless someone else is driving the pin low.
+ * @enable_irq:	optional, enable the interrupt to detect pin voltage changes.
+ * @disable_irq: optional, disable the interrupt.
+ * @free:	optional. Free any allocated resources. Called when the
+ *		adapter is deleted.
+ * @status:	optional, log status information.
+ *
+ * These operations are used by the cec pin framework to manipulate
+ * the CEC pin.
+ */
+struct cec_pin_ops {
+	bool (*read)(struct cec_adapter *adap);
+	void (*low)(struct cec_adapter *adap);
+	void (*high)(struct cec_adapter *adap);
+	bool (*enable_irq)(struct cec_adapter *adap);
+	void (*disable_irq)(struct cec_adapter *adap);
+	void (*free)(struct cec_adapter *adap);
+	void (*status)(struct cec_adapter *adap, struct seq_file *file);
+};
+
+#define CEC_NUM_PIN_EVENTS 128
+
+struct cec_pin {
+	struct cec_adapter		*adap;
+	const struct cec_pin_ops	*ops;
+	struct task_struct		*kthread;
+	wait_queue_head_t		kthread_waitq;
+	struct hrtimer			timer;
+	ktime_t				ts;
+	unsigned int			wait_usecs;
+	u16				la_mask;
+	bool				enabled;
+	bool				monitor_all;
+	bool				cur_value;
+	bool				rx_eom;
+	bool				enable_irq_failed;
+	enum cec_pin_state		state;
+	struct cec_msg			tx_msg;
+	u32				tx_bit;
+	bool				tx_nacked;
+	u32				tx_signal_free_time;
+	struct cec_msg			rx_msg;
+	u32				rx_bit;
+
+	struct cec_msg			work_rx_msg;
+	u8				work_tx_status;
+	bool				work_enable_irq;
+	ktime_t				work_tx_ts;
+	atomic_t			work_pin_events;
+	unsigned int			work_pin_events_wr;
+	unsigned int			work_pin_events_rd;
+	ktime_t				work_pin_ts[CEC_NUM_PIN_EVENTS];
+	bool				work_pin_is_high[CEC_NUM_PIN_EVENTS];
+	ktime_t				timer_ts;
+	u32				timer_cnt;
+	u32				timer_100ms_overruns;
+	u32				timer_300ms_overruns;
+	u32				timer_max_overrun;
+	u32				timer_sum_overrun;
+};
+
+/**
+ * cec_pin_changed() - update pin state from interrupt
+ *
+ * @adap:	pointer to the cec adapter
+ * @value:	when true the pin is high, otherwise it is low
+ *
+ * If changes of the CEC voltage are detected via an interrupt, then
+ * cec_pin_changed is called from the interrupt with the new value.
+ */
+void cec_pin_changed(struct cec_adapter *adap, bool value);
+
+/**
+ * cec_pin_allocate_adapter() - allocate a pin-based cec adapter
+ *
+ * @pin_ops:	low-level pin operations
+ * @priv:	will be stored in adap->priv and can be used by the adapter ops.
+ *		Use cec_get_drvdata(adap) to get the priv pointer.
+ * @name:	the name of the CEC adapter. Note: this name will be copied.
+ * @caps:	capabilities of the CEC adapter. This will be ORed with
+ *		CEC_CAP_MONITOR_ALL and CEC_CAP_MONITOR_PIN.
+ *
+ * Allocate a cec adapter using the cec pin framework.
+ *
+ * Return: a pointer to the cec adapter or an error pointer
+ */
+struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops,
+					void *priv, const char *name, u32 caps);
+
+#endif
diff --git a/include/media/cec.h b/include/media/cec.h
index d983960b37ad..f9cab1a9f912 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -61,6 +61,7 @@ struct cec_devnode {
 
 struct cec_adapter;
 struct cec_data;
+struct cec_pin;
 
 struct cec_data {
 	struct list_head list;
@@ -189,6 +190,9 @@ struct cec_adapter {
 #ifdef CONFIG_CEC_NOTIFIER
 	struct cec_notifier *notifier;
 #endif
+#ifdef CONFIG_CEC_PIN
+	struct cec_pin *pin;
+#endif
 
 	struct dentry *cec_dir;
 	struct dentry *status_file;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 10/11] cec-core.rst: include cec-pin.h and cec-notifier.h
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
                   ` (8 preceding siblings ...)
  2017-07-11  6:30 ` [PATCH 09/11] cec-pin: add low-level pin hardware support Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11  6:30 ` [PATCH 11/11] sun4i_hdmi: add CEC support Hans Verkuil
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Include the CEC pin framework documentation by reading cec-pin.h.
Include the CEC notifier framework documentation by reading cec-notifier.h.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 Documentation/media/kapi/cec-core.rst | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst
index bb066b2b26f8..dc512bdd43c0 100644
--- a/Documentation/media/kapi/cec-core.rst
+++ b/Documentation/media/kapi/cec-core.rst
@@ -345,3 +345,34 @@ log_addrs->num_log_addrs set to 0. The block argument is ignored when
 unconfiguring. This function will just return if the physical address is
 invalid. Once the physical address becomes valid, then the framework will
 attempt to claim these logical addresses.
+
+CEC Pin framework
+-----------------
+
+Most CEC hardware operates on full CEC messages where the software provides
+the message and the hardware handles the low-level CEC protocol. But some
+hardware only drives the CEC pin and software has to handle the low-level
+CEC protocol. The CEC pin framework was created to handle such devices.
+
+Note that due to the close-to-realtime requirements it can never be guaranteed
+to work 100%. This framework uses highres timers internally, but if a
+timer goes off too late by more than 300 microseconds wrong results can
+occur. In reality it appears to be fairly reliable.
+
+One advantage of this low-level implementation is that it can be used as
+a cheap CEC analyser, especially if interrupts can be used to detect
+CEC pin transitions from low to high or vice versa.
+
+.. kernel-doc:: include/media/cec-pin.h
+
+CEC Notifier framework
+-----------------
+
+Most drm HDMI implementations have an integrated CEC implementation and no
+notifier support is needed. But some have independent CEC implementations
+that have their own driver. This could be an IP block for an SoC or a
+completely separate chip that deals with the CEC pin. For those cases a
+drm driver can install a notifier and use the notifier to inform the
+CEC driver about changes in the physical address.
+
+.. kernel-doc:: include/media/cec-notifier.h
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 11/11] sun4i_hdmi: add CEC support
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
                   ` (9 preceding siblings ...)
  2017-07-11  6:30 ` [PATCH 10/11] cec-core.rst: include cec-pin.h and cec-notifier.h Hans Verkuil
@ 2017-07-11  6:30 ` Hans Verkuil
  2017-07-11 20:10 ` [PATCH 00/11] drm/sun4i: " Hans Verkuil
  2017-07-11 20:39   ` Maxime Ripard
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11  6:30 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Add HDMI CEC support to the Allwinner A10 SoC.

This SoC uses a poor-man's CEC implementation by polling the CEC pin. It is
using the CEC_PIN core implementation for such devices to do the heavy
lifting. It just provides the callbacks to read/drive the CEC pin.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/gpu/drm/sun4i/Kconfig          |  9 ++++++
 drivers/gpu/drm/sun4i/sun4i_hdmi.h     |  8 +++++
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 57 +++++++++++++++++++++++++++++++++-
 3 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
index 5bcad8f5fb4f..e884d265c0b3 100644
--- a/drivers/gpu/drm/sun4i/Kconfig
+++ b/drivers/gpu/drm/sun4i/Kconfig
@@ -21,6 +21,15 @@ config DRM_SUN4I_HDMI
 	  Choose this option if you have an Allwinner SoC with an HDMI
 	  controller.
 
+config DRM_SUN4I_HDMI_CEC
+       bool "Allwinner A10 HDMI CEC Support"
+       depends on DRM_SUN4I_HDMI
+       select CEC_CORE
+       select CEC_PIN
+       help
+	  Choose this option if you have an Allwinner SoC with an HDMI
+	  controller and want to use CEC.
+
 config DRM_SUN4I_BACKEND
 	tristate "Support for Allwinner A10 Display Engine Backend"
 	depends on DRM_SUN4I
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 2f2f2ff1ea63..8263de225b36 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -15,6 +15,8 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_encoder.h>
 
+#include <media/cec-pin.h>
+
 #define SUN4I_HDMI_CTRL_REG		0x004
 #define SUN4I_HDMI_CTRL_ENABLE			BIT(31)
 
@@ -86,6 +88,11 @@
 #define SUN4I_HDMI_PLL_DBG0_TMDS_PARENT_MASK	BIT(21)
 #define SUN4I_HDMI_PLL_DBG0_TMDS_PARENT_SHIFT	21
 
+#define SUN4I_HDMI_CEC			0x214
+#define SUN4I_HDMI_CEC_ENABLE			BIT(11)
+#define SUN4I_HDMI_CEC_TX			BIT(9)
+#define SUN4I_HDMI_CEC_RX			BIT(8)
+
 #define SUN4I_HDMI_PKT_CTRL_REG(n)	(0x2f0 + (4 * (n)))
 #define SUN4I_HDMI_PKT_CTRL_TYPE(n, t)		((t) << (((n) % 4) * 4))
 
@@ -149,6 +156,7 @@ struct sun4i_hdmi {
 	struct sun4i_drv	*drv;
 
 	bool			hdmi_monitor;
+	struct cec_adapter	*cec_adap;
 };
 
 int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk);
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index d3398f6250ef..8b89b4e25893 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -271,6 +271,9 @@ static int sun4i_hdmi_get_modes(struct drm_connector *connector)
 	clk_set_rate(hdmi->ddc_clk, 100000);
 
 	edid = drm_do_get_edid(connector, sun4i_hdmi_read_edid_block, hdmi);
+
+	cec_s_phys_addr_from_edid(hdmi->cec_adap, edid);
+
 	if (!edid)
 		return 0;
 
@@ -299,8 +302,10 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
 
 	if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_HPD_REG, reg,
 			       reg & SUN4I_HDMI_HPD_HIGH,
-			       0, 500000))
+			       0, 500000)) {
+		cec_phys_addr_invalidate(hdmi->cec_adap);
 		return connector_status_disconnected;
+	}
 
 	return connector_status_connected;
 }
@@ -315,6 +320,40 @@ static const struct drm_connector_funcs sun4i_hdmi_connector_funcs = {
 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
 };
 
+#ifdef CONFIG_DRM_SUN4I_HDMI_CEC
+static bool sun4i_hdmi_cec_pin_read(struct cec_adapter *adap)
+{
+	struct sun4i_hdmi *hdmi = cec_get_drvdata(adap);
+
+	return readl(hdmi->base + SUN4I_HDMI_CEC) & SUN4I_HDMI_CEC_RX;
+}
+
+static void sun4i_hdmi_cec_pin_low(struct cec_adapter *adap)
+{
+	struct sun4i_hdmi *hdmi = cec_get_drvdata(adap);
+
+	/* Start driving the CEC pin low */
+	writel(SUN4I_HDMI_CEC_ENABLE, hdmi->base + SUN4I_HDMI_CEC);
+}
+
+static void sun4i_hdmi_cec_pin_high(struct cec_adapter *adap)
+{
+	struct sun4i_hdmi *hdmi = cec_get_drvdata(adap);
+
+	/*
+	 * Stop driving the CEC pin, the pull up will take over
+	 * unless another CEC device is driving the pin low.
+	 */
+	writel(0, hdmi->base + SUN4I_HDMI_CEC);
+}
+
+static const struct cec_pin_ops sun4i_hdmi_cec_pin_ops = {
+	.read = sun4i_hdmi_cec_pin_read,
+	.low = sun4i_hdmi_cec_pin_low,
+	.high = sun4i_hdmi_cec_pin_high,
+};
+#endif
+
 static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 			   void *data)
 {
@@ -430,6 +469,17 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	if (!hdmi->encoder.possible_crtcs)
 		return -EPROBE_DEFER;
 
+#ifdef CONFIG_DRM_SUN4I_HDMI_CEC
+	hdmi->cec_adap = cec_pin_allocate_adapter(&sun4i_hdmi_cec_pin_ops,
+		hdmi, "sun4i", CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS |
+		CEC_CAP_PASSTHROUGH | CEC_CAP_RC);
+	ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
+	if (ret < 0)
+		goto err_cleanup_connector;
+	writel(readl(hdmi->base + SUN4I_HDMI_CEC) & ~SUN4I_HDMI_CEC_TX,
+	       hdmi->base + SUN4I_HDMI_CEC);
+#endif
+
 	drm_connector_helper_add(&hdmi->connector,
 				 &sun4i_hdmi_connector_helper_funcs);
 	ret = drm_connector_init(drm, &hdmi->connector,
@@ -445,11 +495,15 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
 		DRM_CONNECTOR_POLL_DISCONNECT;
 
+	ret = cec_register_adapter(hdmi->cec_adap, dev);
+	if (ret < 0)
+		goto err_cleanup_connector;
 	drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
 
 	return 0;
 
 err_cleanup_connector:
+	cec_delete_adapter(hdmi->cec_adap);
 	drm_encoder_cleanup(&hdmi->encoder);
 	return ret;
 }
@@ -459,6 +513,7 @@ static void sun4i_hdmi_unbind(struct device *dev, struct device *master,
 {
 	struct sun4i_hdmi *hdmi = dev_get_drvdata(dev);
 
+	cec_unregister_adapter(hdmi->cec_adap);
 	drm_connector_cleanup(&hdmi->connector);
 	drm_encoder_cleanup(&hdmi->encoder);
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
                   ` (10 preceding siblings ...)
  2017-07-11  6:30 ` [PATCH 11/11] sun4i_hdmi: add CEC support Hans Verkuil
@ 2017-07-11 20:10 ` Hans Verkuil
  2017-07-11 20:39   ` Maxime Ripard
  12 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11 20:10 UTC (permalink / raw)
  To: linux-media; +Cc: Maxime Ripard, dri-devel

On 11/07/17 08:30, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> This patch series adds CEC support for the sun4i HDMI controller.
> 
> The CEC hardware support for the A10 is very low-level as it just
> controls the CEC pin. Since I also wanted to support GPIO-based CEC
> hardware most of this patch series is in the CEC framework to
> add a generic low-level CEC pin framework. It is only the final patch
> that adds the sun4i support.
> 
> This patch series first makes some small changes in the CEC framework
> (patches 1-4) to prepare for this CEC pin support.
> 
> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
> the CEC core event handling.
> 
> Patch 8 adds pin monitoring support (allows userspace to see all
> CEC pin transitions as they happen).
> 
> Patch 9 adds the core cec-pin implementation that translates low-level
> pin transitions into valid CEC messages. Basically this does what any
> SoC with a proper CEC hardware implementation does.
> 
> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
> which was missing).
> 
> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
> 
> I tested this on my cubieboard. There were no errors at all
> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
> same time running a 'make -j4' of the v4l-utils git repository and
> doing a continuous scp to create network traffic.
> 
> This patch series is based on top of the mainline kernel as of
> yesterday (so with all the sun4i and cec patches for 4.13 merged).
> 
> Maxime, patches 1-10 will go through the media subsystem. How do you
> want to handle the final patch? It can either go through the media
> subsystem as well, or you can sit on it and handle this yourself during
> the 4.14 merge window. Another option is to separate the Kconfig change
> into its own patch. That way you can merge the code changes and only
> have to handle the Kconfig patch as a final change during the merge
> window.

I forgot to mention that if you want to use pin monitoring, then the
updated cec-ctl is found here:

https://git.linuxtv.org/hverkuil/v4l-utils.git/log/?h=cec-mon-pin2

To start pin monitoring run:

sudo cec-ctl --monitor-pin

Add the -v flag to see each bit transition.

When in pin monitoring mode it will analyze the low-level protocol and
warn for incorrect bit periods, etc. To be really accurate the CPU should
be lightly loaded.

Regards,

	Hans

> 
> Regards,
> 
> 	Hans
> 
> Hans Verkuil (11):
>   cec: improve transmit timeout logging
>   cec: add *_ts variants for transmit_done/received_msg
>   cec: add adap_free op
>   cec-core.rst: document the adap_free callback
>   linux/cec.h: add pin monitoring API support
>   cec: rework the cec event handling
>   cec: document the new CEC pin capability, events and mode
>   cec: add core support for low-level CEC pin monitoring
>   cec-pin: add low-level pin hardware support
>   cec-core.rst: include cec-pin.h and cec-notifier.h
>   sun4i_hdmi: add CEC support
> 
>  Documentation/media/kapi/cec-core.rst              |  40 ++
>  .../media/uapi/cec/cec-ioc-adap-g-caps.rst         |   7 +
>  Documentation/media/uapi/cec/cec-ioc-dqevent.rst   |  20 +
>  Documentation/media/uapi/cec/cec-ioc-g-mode.rst    |  19 +-
>  drivers/gpu/drm/sun4i/Kconfig                      |   9 +
>  drivers/gpu/drm/sun4i/sun4i_hdmi.h                 |   8 +
>  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c             |  57 +-
>  drivers/media/Kconfig                              |   3 +
>  drivers/media/cec/Makefile                         |   4 +
>  drivers/media/cec/cec-adap.c                       | 196 +++--
>  drivers/media/cec/cec-api.c                        |  73 +-
>  drivers/media/cec/cec-core.c                       |   2 +
>  drivers/media/cec/cec-pin.c                        | 794 +++++++++++++++++++++
>  include/media/cec-pin.h                            | 183 +++++
>  include/media/cec.h                                |  64 +-
>  include/uapi/linux/cec.h                           |   8 +-
>  16 files changed, 1389 insertions(+), 98 deletions(-)
>  create mode 100644 drivers/media/cec/cec-pin.c
>  create mode 100644 include/media/cec-pin.h
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
  2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
@ 2017-07-11 20:39   ` Maxime Ripard
  2017-07-11  6:30 ` [PATCH 02/11] cec: add *_ts variants for transmit_done/received_msg Hans Verkuil
                     ` (11 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-07-11 20:39 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, dri-devel

[-- Attachment #1: Type: text/plain, Size: 2545 bytes --]

On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> This patch series adds CEC support for the sun4i HDMI controller.
> 
> The CEC hardware support for the A10 is very low-level as it just
> controls the CEC pin. Since I also wanted to support GPIO-based CEC
> hardware most of this patch series is in the CEC framework to
> add a generic low-level CEC pin framework. It is only the final patch
> that adds the sun4i support.
> 
> This patch series first makes some small changes in the CEC framework
> (patches 1-4) to prepare for this CEC pin support.
> 
> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
> the CEC core event handling.
> 
> Patch 8 adds pin monitoring support (allows userspace to see all
> CEC pin transitions as they happen).
> 
> Patch 9 adds the core cec-pin implementation that translates low-level
> pin transitions into valid CEC messages. Basically this does what any
> SoC with a proper CEC hardware implementation does.
> 
> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
> which was missing).
> 
> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
> 
> I tested this on my cubieboard. There were no errors at all
> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
> same time running a 'make -j4' of the v4l-utils git repository and
> doing a continuous scp to create network traffic.
> 
> This patch series is based on top of the mainline kernel as of
> yesterday (so with all the sun4i and cec patches for 4.13 merged).

For the whole serie:
Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>

> Maxime, patches 1-10 will go through the media subsystem. How do you
> want to handle the final patch? It can either go through the media
> subsystem as well, or you can sit on it and handle this yourself during
> the 4.14 merge window. Another option is to separate the Kconfig change
> into its own patch. That way you can merge the code changes and only
> have to handle the Kconfig patch as a final change during the merge
> window.

We'll probably have a number of reworks for 4.14, so it would be
better if I merged it.

However, I guess if we just switch to a depends on CEC_PIN instead of
a select, everything would just work even if we merge your patches in
a separate tree, right?

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
@ 2017-07-11 20:39   ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-07-11 20:39 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: dri-devel, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 2545 bytes --]

On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> This patch series adds CEC support for the sun4i HDMI controller.
> 
> The CEC hardware support for the A10 is very low-level as it just
> controls the CEC pin. Since I also wanted to support GPIO-based CEC
> hardware most of this patch series is in the CEC framework to
> add a generic low-level CEC pin framework. It is only the final patch
> that adds the sun4i support.
> 
> This patch series first makes some small changes in the CEC framework
> (patches 1-4) to prepare for this CEC pin support.
> 
> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
> the CEC core event handling.
> 
> Patch 8 adds pin monitoring support (allows userspace to see all
> CEC pin transitions as they happen).
> 
> Patch 9 adds the core cec-pin implementation that translates low-level
> pin transitions into valid CEC messages. Basically this does what any
> SoC with a proper CEC hardware implementation does.
> 
> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
> which was missing).
> 
> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
> 
> I tested this on my cubieboard. There were no errors at all
> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
> same time running a 'make -j4' of the v4l-utils git repository and
> doing a continuous scp to create network traffic.
> 
> This patch series is based on top of the mainline kernel as of
> yesterday (so with all the sun4i and cec patches for 4.13 merged).

For the whole serie:
Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>

> Maxime, patches 1-10 will go through the media subsystem. How do you
> want to handle the final patch? It can either go through the media
> subsystem as well, or you can sit on it and handle this yourself during
> the 4.14 merge window. Another option is to separate the Kconfig change
> into its own patch. That way you can merge the code changes and only
> have to handle the Kconfig patch as a final change during the merge
> window.

We'll probably have a number of reworks for 4.14, so it would be
better if I merged it.

However, I guess if we just switch to a depends on CEC_PIN instead of
a select, everything would just work even if we merge your patches in
a separate tree, right?

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
  2017-07-11 20:39   ` Maxime Ripard
@ 2017-07-11 21:06     ` Hans Verkuil
  -1 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11 21:06 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: linux-media, dri-devel

On 11/07/17 22:39, Maxime Ripard wrote:
> On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>
>> This patch series adds CEC support for the sun4i HDMI controller.
>>
>> The CEC hardware support for the A10 is very low-level as it just
>> controls the CEC pin. Since I also wanted to support GPIO-based CEC
>> hardware most of this patch series is in the CEC framework to
>> add a generic low-level CEC pin framework. It is only the final patch
>> that adds the sun4i support.
>>
>> This patch series first makes some small changes in the CEC framework
>> (patches 1-4) to prepare for this CEC pin support.
>>
>> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
>> the CEC core event handling.
>>
>> Patch 8 adds pin monitoring support (allows userspace to see all
>> CEC pin transitions as they happen).
>>
>> Patch 9 adds the core cec-pin implementation that translates low-level
>> pin transitions into valid CEC messages. Basically this does what any
>> SoC with a proper CEC hardware implementation does.
>>
>> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
>> which was missing).
>>
>> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
>>
>> I tested this on my cubieboard. There were no errors at all
>> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
>> same time running a 'make -j4' of the v4l-utils git repository and
>> doing a continuous scp to create network traffic.
>>
>> This patch series is based on top of the mainline kernel as of
>> yesterday (so with all the sun4i and cec patches for 4.13 merged).
> 
> For the whole serie:
> Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> 
>> Maxime, patches 1-10 will go through the media subsystem. How do you
>> want to handle the final patch? It can either go through the media
>> subsystem as well, or you can sit on it and handle this yourself during
>> the 4.14 merge window. Another option is to separate the Kconfig change
>> into its own patch. That way you can merge the code changes and only
>> have to handle the Kconfig patch as a final change during the merge
>> window.
> 
> We'll probably have a number of reworks for 4.14, so it would be
> better if I merged it.
> 
> However, I guess if we just switch to a depends on CEC_PIN instead of
> a select, everything would just work even if we merge your patches in
> a separate tree, right?

This small patch will do it:

diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
index e884d265c0b3..ebad80aefc87 100644
--- a/drivers/gpu/drm/sun4i/Kconfig
+++ b/drivers/gpu/drm/sun4i/Kconfig
@@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
        bool "Allwinner A10 HDMI CEC Support"
        depends on DRM_SUN4I_HDMI
        select CEC_CORE
-       select CEC_PIN
+       depends on CEC_PIN
        help
 	  Choose this option if you have an Allwinner SoC with an HDMI
 	  controller and want to use CEC.
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 8263de225b36..82bc6923b90f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -15,7 +15,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_encoder.h>

-#include <media/cec-pin.h>
+#include <media/cec.h>

 #define SUN4I_HDMI_CTRL_REG		0x004
 #define SUN4I_HDMI_CTRL_ENABLE			BIT(31)


Unfortunately you need to change the header as well since cec-pin.h doesn't
exist without the cec patches. It might be better to

And once the cec patch series and the sun4i_hdmi patch is merged the patch above
can be applied with -R and all will work fine.

This seems a sensible way forward.

Regards,

	Hans

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
@ 2017-07-11 21:06     ` Hans Verkuil
  0 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-11 21:06 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: dri-devel, linux-media

On 11/07/17 22:39, Maxime Ripard wrote:
> On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>
>> This patch series adds CEC support for the sun4i HDMI controller.
>>
>> The CEC hardware support for the A10 is very low-level as it just
>> controls the CEC pin. Since I also wanted to support GPIO-based CEC
>> hardware most of this patch series is in the CEC framework to
>> add a generic low-level CEC pin framework. It is only the final patch
>> that adds the sun4i support.
>>
>> This patch series first makes some small changes in the CEC framework
>> (patches 1-4) to prepare for this CEC pin support.
>>
>> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
>> the CEC core event handling.
>>
>> Patch 8 adds pin monitoring support (allows userspace to see all
>> CEC pin transitions as they happen).
>>
>> Patch 9 adds the core cec-pin implementation that translates low-level
>> pin transitions into valid CEC messages. Basically this does what any
>> SoC with a proper CEC hardware implementation does.
>>
>> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
>> which was missing).
>>
>> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
>>
>> I tested this on my cubieboard. There were no errors at all
>> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
>> same time running a 'make -j4' of the v4l-utils git repository and
>> doing a continuous scp to create network traffic.
>>
>> This patch series is based on top of the mainline kernel as of
>> yesterday (so with all the sun4i and cec patches for 4.13 merged).
> 
> For the whole serie:
> Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> 
>> Maxime, patches 1-10 will go through the media subsystem. How do you
>> want to handle the final patch? It can either go through the media
>> subsystem as well, or you can sit on it and handle this yourself during
>> the 4.14 merge window. Another option is to separate the Kconfig change
>> into its own patch. That way you can merge the code changes and only
>> have to handle the Kconfig patch as a final change during the merge
>> window.
> 
> We'll probably have a number of reworks for 4.14, so it would be
> better if I merged it.
> 
> However, I guess if we just switch to a depends on CEC_PIN instead of
> a select, everything would just work even if we merge your patches in
> a separate tree, right?

This small patch will do it:

diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
index e884d265c0b3..ebad80aefc87 100644
--- a/drivers/gpu/drm/sun4i/Kconfig
+++ b/drivers/gpu/drm/sun4i/Kconfig
@@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
        bool "Allwinner A10 HDMI CEC Support"
        depends on DRM_SUN4I_HDMI
        select CEC_CORE
-       select CEC_PIN
+       depends on CEC_PIN
        help
 	  Choose this option if you have an Allwinner SoC with an HDMI
 	  controller and want to use CEC.
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 8263de225b36..82bc6923b90f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -15,7 +15,7 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_encoder.h>

-#include <media/cec-pin.h>
+#include <media/cec.h>

 #define SUN4I_HDMI_CTRL_REG		0x004
 #define SUN4I_HDMI_CTRL_ENABLE			BIT(31)


Unfortunately you need to change the header as well since cec-pin.h doesn't
exist without the cec patches. It might be better to

And once the cec patch series and the sun4i_hdmi patch is merged the patch above
can be applied with -R and all will work fine.

This seems a sensible way forward.

Regards,

	Hans
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
  2017-07-11 21:06     ` Hans Verkuil
@ 2017-07-18 16:29       ` Maxime Ripard
  -1 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-07-18 16:29 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, dri-devel

[-- Attachment #1: Type: text/plain, Size: 4309 bytes --]

Hi,

On Tue, Jul 11, 2017 at 11:06:52PM +0200, Hans Verkuil wrote:
> On 11/07/17 22:39, Maxime Ripard wrote:
> > On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
> >> From: Hans Verkuil <hans.verkuil@cisco.com>
> >>
> >> This patch series adds CEC support for the sun4i HDMI controller.
> >>
> >> The CEC hardware support for the A10 is very low-level as it just
> >> controls the CEC pin. Since I also wanted to support GPIO-based CEC
> >> hardware most of this patch series is in the CEC framework to
> >> add a generic low-level CEC pin framework. It is only the final patch
> >> that adds the sun4i support.
> >>
> >> This patch series first makes some small changes in the CEC framework
> >> (patches 1-4) to prepare for this CEC pin support.
> >>
> >> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
> >> the CEC core event handling.
> >>
> >> Patch 8 adds pin monitoring support (allows userspace to see all
> >> CEC pin transitions as they happen).
> >>
> >> Patch 9 adds the core cec-pin implementation that translates low-level
> >> pin transitions into valid CEC messages. Basically this does what any
> >> SoC with a proper CEC hardware implementation does.
> >>
> >> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
> >> which was missing).
> >>
> >> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
> >>
> >> I tested this on my cubieboard. There were no errors at all
> >> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
> >> same time running a 'make -j4' of the v4l-utils git repository and
> >> doing a continuous scp to create network traffic.
> >>
> >> This patch series is based on top of the mainline kernel as of
> >> yesterday (so with all the sun4i and cec patches for 4.13 merged).
> > 
> > For the whole serie:
> > Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > 
> >> Maxime, patches 1-10 will go through the media subsystem. How do you
> >> want to handle the final patch? It can either go through the media
> >> subsystem as well, or you can sit on it and handle this yourself during
> >> the 4.14 merge window. Another option is to separate the Kconfig change
> >> into its own patch. That way you can merge the code changes and only
> >> have to handle the Kconfig patch as a final change during the merge
> >> window.
> > 
> > We'll probably have a number of reworks for 4.14, so it would be
> > better if I merged it.
> > 
> > However, I guess if we just switch to a depends on CEC_PIN instead of
> > a select, everything would just work even if we merge your patches in
> > a separate tree, right?
> 
> This small patch will do it:
> 
> diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
> index e884d265c0b3..ebad80aefc87 100644
> --- a/drivers/gpu/drm/sun4i/Kconfig
> +++ b/drivers/gpu/drm/sun4i/Kconfig
> @@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
>         bool "Allwinner A10 HDMI CEC Support"
>         depends on DRM_SUN4I_HDMI
>         select CEC_CORE
> -       select CEC_PIN
> +       depends on CEC_PIN
>         help
>  	  Choose this option if you have an Allwinner SoC with an HDMI
>  	  controller and want to use CEC.
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> index 8263de225b36..82bc6923b90f 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> @@ -15,7 +15,7 @@
>  #include <drm/drm_connector.h>
>  #include <drm/drm_encoder.h>
> 
> -#include <media/cec-pin.h>
> +#include <media/cec.h>
> 
>  #define SUN4I_HDMI_CTRL_REG		0x004
>  #define SUN4I_HDMI_CTRL_ENABLE			BIT(31)
> 
> 
> Unfortunately you need to change the header as well since cec-pin.h doesn't
> exist without the cec patches. It might be better to
> 
> And once the cec patch series and the sun4i_hdmi patch is merged the patch above
> can be applied with -R and all will work fine.
> 
> This seems a sensible way forward.

I just tested this serie, it works just fine. I've applied the patch
11 with my Tested-by and that small patch above.

Thanks a lot!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
@ 2017-07-18 16:29       ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-07-18 16:29 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: dri-devel, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 4309 bytes --]

Hi,

On Tue, Jul 11, 2017 at 11:06:52PM +0200, Hans Verkuil wrote:
> On 11/07/17 22:39, Maxime Ripard wrote:
> > On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
> >> From: Hans Verkuil <hans.verkuil@cisco.com>
> >>
> >> This patch series adds CEC support for the sun4i HDMI controller.
> >>
> >> The CEC hardware support for the A10 is very low-level as it just
> >> controls the CEC pin. Since I also wanted to support GPIO-based CEC
> >> hardware most of this patch series is in the CEC framework to
> >> add a generic low-level CEC pin framework. It is only the final patch
> >> that adds the sun4i support.
> >>
> >> This patch series first makes some small changes in the CEC framework
> >> (patches 1-4) to prepare for this CEC pin support.
> >>
> >> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
> >> the CEC core event handling.
> >>
> >> Patch 8 adds pin monitoring support (allows userspace to see all
> >> CEC pin transitions as they happen).
> >>
> >> Patch 9 adds the core cec-pin implementation that translates low-level
> >> pin transitions into valid CEC messages. Basically this does what any
> >> SoC with a proper CEC hardware implementation does.
> >>
> >> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
> >> which was missing).
> >>
> >> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
> >>
> >> I tested this on my cubieboard. There were no errors at all
> >> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
> >> same time running a 'make -j4' of the v4l-utils git repository and
> >> doing a continuous scp to create network traffic.
> >>
> >> This patch series is based on top of the mainline kernel as of
> >> yesterday (so with all the sun4i and cec patches for 4.13 merged).
> > 
> > For the whole serie:
> > Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > 
> >> Maxime, patches 1-10 will go through the media subsystem. How do you
> >> want to handle the final patch? It can either go through the media
> >> subsystem as well, or you can sit on it and handle this yourself during
> >> the 4.14 merge window. Another option is to separate the Kconfig change
> >> into its own patch. That way you can merge the code changes and only
> >> have to handle the Kconfig patch as a final change during the merge
> >> window.
> > 
> > We'll probably have a number of reworks for 4.14, so it would be
> > better if I merged it.
> > 
> > However, I guess if we just switch to a depends on CEC_PIN instead of
> > a select, everything would just work even if we merge your patches in
> > a separate tree, right?
> 
> This small patch will do it:
> 
> diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
> index e884d265c0b3..ebad80aefc87 100644
> --- a/drivers/gpu/drm/sun4i/Kconfig
> +++ b/drivers/gpu/drm/sun4i/Kconfig
> @@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
>         bool "Allwinner A10 HDMI CEC Support"
>         depends on DRM_SUN4I_HDMI
>         select CEC_CORE
> -       select CEC_PIN
> +       depends on CEC_PIN
>         help
>  	  Choose this option if you have an Allwinner SoC with an HDMI
>  	  controller and want to use CEC.
> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> index 8263de225b36..82bc6923b90f 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
> @@ -15,7 +15,7 @@
>  #include <drm/drm_connector.h>
>  #include <drm/drm_encoder.h>
> 
> -#include <media/cec-pin.h>
> +#include <media/cec.h>
> 
>  #define SUN4I_HDMI_CTRL_REG		0x004
>  #define SUN4I_HDMI_CTRL_ENABLE			BIT(31)
> 
> 
> Unfortunately you need to change the header as well since cec-pin.h doesn't
> exist without the cec patches. It might be better to
> 
> And once the cec patch series and the sun4i_hdmi patch is merged the patch above
> can be applied with -R and all will work fine.
> 
> This seems a sensible way forward.

I just tested this serie, it works just fine. I've applied the patch
11 with my Tested-by and that small patch above.

Thanks a lot!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
  2017-07-18 16:29       ` Maxime Ripard
@ 2017-07-19  8:39         ` Hans Verkuil
  -1 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-19  8:39 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: linux-media, dri-devel

On 18/07/17 18:29, Maxime Ripard wrote:
> Hi,
> 
> On Tue, Jul 11, 2017 at 11:06:52PM +0200, Hans Verkuil wrote:
>> On 11/07/17 22:39, Maxime Ripard wrote:
>>> On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
>>>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>>>
>>>> This patch series adds CEC support for the sun4i HDMI controller.
>>>>
>>>> The CEC hardware support for the A10 is very low-level as it just
>>>> controls the CEC pin. Since I also wanted to support GPIO-based CEC
>>>> hardware most of this patch series is in the CEC framework to
>>>> add a generic low-level CEC pin framework. It is only the final patch
>>>> that adds the sun4i support.
>>>>
>>>> This patch series first makes some small changes in the CEC framework
>>>> (patches 1-4) to prepare for this CEC pin support.
>>>>
>>>> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
>>>> the CEC core event handling.
>>>>
>>>> Patch 8 adds pin monitoring support (allows userspace to see all
>>>> CEC pin transitions as they happen).
>>>>
>>>> Patch 9 adds the core cec-pin implementation that translates low-level
>>>> pin transitions into valid CEC messages. Basically this does what any
>>>> SoC with a proper CEC hardware implementation does.
>>>>
>>>> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
>>>> which was missing).
>>>>
>>>> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
>>>>
>>>> I tested this on my cubieboard. There were no errors at all
>>>> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
>>>> same time running a 'make -j4' of the v4l-utils git repository and
>>>> doing a continuous scp to create network traffic.
>>>>
>>>> This patch series is based on top of the mainline kernel as of
>>>> yesterday (so with all the sun4i and cec patches for 4.13 merged).
>>>
>>> For the whole serie:
>>> Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>>>
>>>> Maxime, patches 1-10 will go through the media subsystem. How do you
>>>> want to handle the final patch? It can either go through the media
>>>> subsystem as well, or you can sit on it and handle this yourself during
>>>> the 4.14 merge window. Another option is to separate the Kconfig change
>>>> into its own patch. That way you can merge the code changes and only
>>>> have to handle the Kconfig patch as a final change during the merge
>>>> window.
>>>
>>> We'll probably have a number of reworks for 4.14, so it would be
>>> better if I merged it.
>>>
>>> However, I guess if we just switch to a depends on CEC_PIN instead of
>>> a select, everything would just work even if we merge your patches in
>>> a separate tree, right?
>>
>> This small patch will do it:
>>
>> diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
>> index e884d265c0b3..ebad80aefc87 100644
>> --- a/drivers/gpu/drm/sun4i/Kconfig
>> +++ b/drivers/gpu/drm/sun4i/Kconfig
>> @@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
>>         bool "Allwinner A10 HDMI CEC Support"
>>         depends on DRM_SUN4I_HDMI
>>         select CEC_CORE
>> -       select CEC_PIN
>> +       depends on CEC_PIN
>>         help
>>  	  Choose this option if you have an Allwinner SoC with an HDMI
>>  	  controller and want to use CEC.
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> index 8263de225b36..82bc6923b90f 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> @@ -15,7 +15,7 @@
>>  #include <drm/drm_connector.h>
>>  #include <drm/drm_encoder.h>
>>
>> -#include <media/cec-pin.h>
>> +#include <media/cec.h>
>>
>>  #define SUN4I_HDMI_CTRL_REG		0x004
>>  #define SUN4I_HDMI_CTRL_ENABLE			BIT(31)
>>
>>
>> Unfortunately you need to change the header as well since cec-pin.h doesn't
>> exist without the cec patches. It might be better to
>>
>> And once the cec patch series and the sun4i_hdmi patch is merged the patch above
>> can be applied with -R and all will work fine.
>>
>> This seems a sensible way forward.
> 
> I just tested this serie, it works just fine. I've applied the patch
> 11 with my Tested-by and that small patch above.

Thanks!

The other CEC patches have been merged in the media subsystem as well. I also
committed the low-level pin monitoring code to the cec-ctl utility.

So with 'cec-ctl --monitor-pin' you can do low-level CEC bus monitoring with
the Allwinner!

Regards,

	Hans

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
@ 2017-07-19  8:39         ` Hans Verkuil
  0 siblings, 0 replies; 26+ messages in thread
From: Hans Verkuil @ 2017-07-19  8:39 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: dri-devel, linux-media

On 18/07/17 18:29, Maxime Ripard wrote:
> Hi,
> 
> On Tue, Jul 11, 2017 at 11:06:52PM +0200, Hans Verkuil wrote:
>> On 11/07/17 22:39, Maxime Ripard wrote:
>>> On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
>>>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>>>
>>>> This patch series adds CEC support for the sun4i HDMI controller.
>>>>
>>>> The CEC hardware support for the A10 is very low-level as it just
>>>> controls the CEC pin. Since I also wanted to support GPIO-based CEC
>>>> hardware most of this patch series is in the CEC framework to
>>>> add a generic low-level CEC pin framework. It is only the final patch
>>>> that adds the sun4i support.
>>>>
>>>> This patch series first makes some small changes in the CEC framework
>>>> (patches 1-4) to prepare for this CEC pin support.
>>>>
>>>> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
>>>> the CEC core event handling.
>>>>
>>>> Patch 8 adds pin monitoring support (allows userspace to see all
>>>> CEC pin transitions as they happen).
>>>>
>>>> Patch 9 adds the core cec-pin implementation that translates low-level
>>>> pin transitions into valid CEC messages. Basically this does what any
>>>> SoC with a proper CEC hardware implementation does.
>>>>
>>>> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
>>>> which was missing).
>>>>
>>>> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
>>>>
>>>> I tested this on my cubieboard. There were no errors at all
>>>> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
>>>> same time running a 'make -j4' of the v4l-utils git repository and
>>>> doing a continuous scp to create network traffic.
>>>>
>>>> This patch series is based on top of the mainline kernel as of
>>>> yesterday (so with all the sun4i and cec patches for 4.13 merged).
>>>
>>> For the whole serie:
>>> Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>>>
>>>> Maxime, patches 1-10 will go through the media subsystem. How do you
>>>> want to handle the final patch? It can either go through the media
>>>> subsystem as well, or you can sit on it and handle this yourself during
>>>> the 4.14 merge window. Another option is to separate the Kconfig change
>>>> into its own patch. That way you can merge the code changes and only
>>>> have to handle the Kconfig patch as a final change during the merge
>>>> window.
>>>
>>> We'll probably have a number of reworks for 4.14, so it would be
>>> better if I merged it.
>>>
>>> However, I guess if we just switch to a depends on CEC_PIN instead of
>>> a select, everything would just work even if we merge your patches in
>>> a separate tree, right?
>>
>> This small patch will do it:
>>
>> diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
>> index e884d265c0b3..ebad80aefc87 100644
>> --- a/drivers/gpu/drm/sun4i/Kconfig
>> +++ b/drivers/gpu/drm/sun4i/Kconfig
>> @@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
>>         bool "Allwinner A10 HDMI CEC Support"
>>         depends on DRM_SUN4I_HDMI
>>         select CEC_CORE
>> -       select CEC_PIN
>> +       depends on CEC_PIN
>>         help
>>  	  Choose this option if you have an Allwinner SoC with an HDMI
>>  	  controller and want to use CEC.
>> diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> index 8263de225b36..82bc6923b90f 100644
>> --- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> +++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
>> @@ -15,7 +15,7 @@
>>  #include <drm/drm_connector.h>
>>  #include <drm/drm_encoder.h>
>>
>> -#include <media/cec-pin.h>
>> +#include <media/cec.h>
>>
>>  #define SUN4I_HDMI_CTRL_REG		0x004
>>  #define SUN4I_HDMI_CTRL_ENABLE			BIT(31)
>>
>>
>> Unfortunately you need to change the header as well since cec-pin.h doesn't
>> exist without the cec patches. It might be better to
>>
>> And once the cec patch series and the sun4i_hdmi patch is merged the patch above
>> can be applied with -R and all will work fine.
>>
>> This seems a sensible way forward.
> 
> I just tested this serie, it works just fine. I've applied the patch
> 11 with my Tested-by and that small patch above.

Thanks!

The other CEC patches have been merged in the media subsystem as well. I also
committed the low-level pin monitoring code to the cec-ctl utility.

So with 'cec-ctl --monitor-pin' you can do low-level CEC bus monitoring with
the Allwinner!

Regards,

	Hans

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
  2017-07-18 16:29       ` Maxime Ripard
  (?)
  (?)
@ 2017-09-08 10:59       ` Hans Verkuil
  2017-09-21 20:37           ` Maxime Ripard
  -1 siblings, 1 reply; 26+ messages in thread
From: Hans Verkuil @ 2017-09-08 10:59 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: linux-media, dri-devel

Hi Maxime,

On 07/18/17 18:29, Maxime Ripard wrote:
> Hi,
> 
> On Tue, Jul 11, 2017 at 11:06:52PM +0200, Hans Verkuil wrote:
>> On 11/07/17 22:39, Maxime Ripard wrote:
>>> On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
>>>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>>>
>>>> This patch series adds CEC support for the sun4i HDMI controller.
>>>>
>>>> The CEC hardware support for the A10 is very low-level as it just
>>>> controls the CEC pin. Since I also wanted to support GPIO-based CEC
>>>> hardware most of this patch series is in the CEC framework to
>>>> add a generic low-level CEC pin framework. It is only the final patch
>>>> that adds the sun4i support.
>>>>
>>>> This patch series first makes some small changes in the CEC framework
>>>> (patches 1-4) to prepare for this CEC pin support.
>>>>
>>>> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
>>>> the CEC core event handling.
>>>>
>>>> Patch 8 adds pin monitoring support (allows userspace to see all
>>>> CEC pin transitions as they happen).
>>>>
>>>> Patch 9 adds the core cec-pin implementation that translates low-level
>>>> pin transitions into valid CEC messages. Basically this does what any
>>>> SoC with a proper CEC hardware implementation does.
>>>>
>>>> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
>>>> which was missing).
>>>>
>>>> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
>>>>
>>>> I tested this on my cubieboard. There were no errors at all
>>>> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
>>>> same time running a 'make -j4' of the v4l-utils git repository and
>>>> doing a continuous scp to create network traffic.
>>>>
>>>> This patch series is based on top of the mainline kernel as of
>>>> yesterday (so with all the sun4i and cec patches for 4.13 merged).
>>>
>>> For the whole serie:
>>> Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>>>
>>>> Maxime, patches 1-10 will go through the media subsystem. How do you
>>>> want to handle the final patch? It can either go through the media
>>>> subsystem as well, or you can sit on it and handle this yourself during
>>>> the 4.14 merge window. Another option is to separate the Kconfig change
>>>> into its own patch. That way you can merge the code changes and only
>>>> have to handle the Kconfig patch as a final change during the merge
>>>> window.
>>>
>>> We'll probably have a number of reworks for 4.14, so it would be
>>> better if I merged it.
>>>
>>> However, I guess if we just switch to a depends on CEC_PIN instead of
>>> a select, everything would just work even if we merge your patches in
>>> a separate tree, right?
>>
>> This small patch will do it:
>>
>> diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
>> index e884d265c0b3..ebad80aefc87 100644
>> --- a/drivers/gpu/drm/sun4i/Kconfig
>> +++ b/drivers/gpu/drm/sun4i/Kconfig
>> @@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
>>         bool "Allwinner A10 HDMI CEC Support"
>>         depends on DRM_SUN4I_HDMI
>>         select CEC_CORE
>> -       select CEC_PIN
>> +       depends on CEC_PIN
>>         help
>>  	  Choose this option if you have an Allwinner SoC with an HDMI
>>  	  controller and want to use CEC.

Just a reminder: now that both this driver and the CEC_PIN code has been
merged in 4.14, this 'depends on' can become a 'select' again.

Regards,

	Hans

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
  2017-09-08 10:59       ` Hans Verkuil
@ 2017-09-21 20:37           ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-09-21 20:37 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, dri-devel

[-- Attachment #1: Type: text/plain, Size: 3938 bytes --]

Hi Hans,

On Fri, Sep 08, 2017 at 10:59:44AM +0000, Hans Verkuil wrote:
> Hi Maxime,
> 
> On 07/18/17 18:29, Maxime Ripard wrote:
> > Hi,
> > 
> > On Tue, Jul 11, 2017 at 11:06:52PM +0200, Hans Verkuil wrote:
> >> On 11/07/17 22:39, Maxime Ripard wrote:
> >>> On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
> >>>> From: Hans Verkuil <hans.verkuil@cisco.com>
> >>>>
> >>>> This patch series adds CEC support for the sun4i HDMI controller.
> >>>>
> >>>> The CEC hardware support for the A10 is very low-level as it just
> >>>> controls the CEC pin. Since I also wanted to support GPIO-based CEC
> >>>> hardware most of this patch series is in the CEC framework to
> >>>> add a generic low-level CEC pin framework. It is only the final patch
> >>>> that adds the sun4i support.
> >>>>
> >>>> This patch series first makes some small changes in the CEC framework
> >>>> (patches 1-4) to prepare for this CEC pin support.
> >>>>
> >>>> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
> >>>> the CEC core event handling.
> >>>>
> >>>> Patch 8 adds pin monitoring support (allows userspace to see all
> >>>> CEC pin transitions as they happen).
> >>>>
> >>>> Patch 9 adds the core cec-pin implementation that translates low-level
> >>>> pin transitions into valid CEC messages. Basically this does what any
> >>>> SoC with a proper CEC hardware implementation does.
> >>>>
> >>>> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
> >>>> which was missing).
> >>>>
> >>>> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
> >>>>
> >>>> I tested this on my cubieboard. There were no errors at all
> >>>> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
> >>>> same time running a 'make -j4' of the v4l-utils git repository and
> >>>> doing a continuous scp to create network traffic.
> >>>>
> >>>> This patch series is based on top of the mainline kernel as of
> >>>> yesterday (so with all the sun4i and cec patches for 4.13 merged).
> >>>
> >>> For the whole serie:
> >>> Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> >>>
> >>>> Maxime, patches 1-10 will go through the media subsystem. How do you
> >>>> want to handle the final patch? It can either go through the media
> >>>> subsystem as well, or you can sit on it and handle this yourself during
> >>>> the 4.14 merge window. Another option is to separate the Kconfig change
> >>>> into its own patch. That way you can merge the code changes and only
> >>>> have to handle the Kconfig patch as a final change during the merge
> >>>> window.
> >>>
> >>> We'll probably have a number of reworks for 4.14, so it would be
> >>> better if I merged it.
> >>>
> >>> However, I guess if we just switch to a depends on CEC_PIN instead of
> >>> a select, everything would just work even if we merge your patches in
> >>> a separate tree, right?
> >>
> >> This small patch will do it:
> >>
> >> diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
> >> index e884d265c0b3..ebad80aefc87 100644
> >> --- a/drivers/gpu/drm/sun4i/Kconfig
> >> +++ b/drivers/gpu/drm/sun4i/Kconfig
> >> @@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
> >>         bool "Allwinner A10 HDMI CEC Support"
> >>         depends on DRM_SUN4I_HDMI
> >>         select CEC_CORE
> >> -       select CEC_PIN
> >> +       depends on CEC_PIN
> >>         help
> >>  	  Choose this option if you have an Allwinner SoC with an HDMI
> >>  	  controller and want to use CEC.
> 
> Just a reminder: now that both this driver and the CEC_PIN code has been
> merged in 4.14, this 'depends on' can become a 'select' again.

Thanks for the reminder.

Would that commit work for you:
http://code.bulix.org/19o9y6-201254

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
@ 2017-09-21 20:37           ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-09-21 20:37 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: dri-devel, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 3938 bytes --]

Hi Hans,

On Fri, Sep 08, 2017 at 10:59:44AM +0000, Hans Verkuil wrote:
> Hi Maxime,
> 
> On 07/18/17 18:29, Maxime Ripard wrote:
> > Hi,
> > 
> > On Tue, Jul 11, 2017 at 11:06:52PM +0200, Hans Verkuil wrote:
> >> On 11/07/17 22:39, Maxime Ripard wrote:
> >>> On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
> >>>> From: Hans Verkuil <hans.verkuil@cisco.com>
> >>>>
> >>>> This patch series adds CEC support for the sun4i HDMI controller.
> >>>>
> >>>> The CEC hardware support for the A10 is very low-level as it just
> >>>> controls the CEC pin. Since I also wanted to support GPIO-based CEC
> >>>> hardware most of this patch series is in the CEC framework to
> >>>> add a generic low-level CEC pin framework. It is only the final patch
> >>>> that adds the sun4i support.
> >>>>
> >>>> This patch series first makes some small changes in the CEC framework
> >>>> (patches 1-4) to prepare for this CEC pin support.
> >>>>
> >>>> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
> >>>> the CEC core event handling.
> >>>>
> >>>> Patch 8 adds pin monitoring support (allows userspace to see all
> >>>> CEC pin transitions as they happen).
> >>>>
> >>>> Patch 9 adds the core cec-pin implementation that translates low-level
> >>>> pin transitions into valid CEC messages. Basically this does what any
> >>>> SoC with a proper CEC hardware implementation does.
> >>>>
> >>>> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
> >>>> which was missing).
> >>>>
> >>>> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
> >>>>
> >>>> I tested this on my cubieboard. There were no errors at all
> >>>> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
> >>>> same time running a 'make -j4' of the v4l-utils git repository and
> >>>> doing a continuous scp to create network traffic.
> >>>>
> >>>> This patch series is based on top of the mainline kernel as of
> >>>> yesterday (so with all the sun4i and cec patches for 4.13 merged).
> >>>
> >>> For the whole serie:
> >>> Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> >>>
> >>>> Maxime, patches 1-10 will go through the media subsystem. How do you
> >>>> want to handle the final patch? It can either go through the media
> >>>> subsystem as well, or you can sit on it and handle this yourself during
> >>>> the 4.14 merge window. Another option is to separate the Kconfig change
> >>>> into its own patch. That way you can merge the code changes and only
> >>>> have to handle the Kconfig patch as a final change during the merge
> >>>> window.
> >>>
> >>> We'll probably have a number of reworks for 4.14, so it would be
> >>> better if I merged it.
> >>>
> >>> However, I guess if we just switch to a depends on CEC_PIN instead of
> >>> a select, everything would just work even if we merge your patches in
> >>> a separate tree, right?
> >>
> >> This small patch will do it:
> >>
> >> diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
> >> index e884d265c0b3..ebad80aefc87 100644
> >> --- a/drivers/gpu/drm/sun4i/Kconfig
> >> +++ b/drivers/gpu/drm/sun4i/Kconfig
> >> @@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
> >>         bool "Allwinner A10 HDMI CEC Support"
> >>         depends on DRM_SUN4I_HDMI
> >>         select CEC_CORE
> >> -       select CEC_PIN
> >> +       depends on CEC_PIN
> >>         help
> >>  	  Choose this option if you have an Allwinner SoC with an HDMI
> >>  	  controller and want to use CEC.
> 
> Just a reminder: now that both this driver and the CEC_PIN code has been
> merged in 4.14, this 'depends on' can become a 'select' again.

Thanks for the reminder.

Would that commit work for you:
http://code.bulix.org/19o9y6-201254

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
  2017-09-21 20:37           ` Maxime Ripard
  (?)
@ 2017-09-21 21:19           ` Hans Verkuil
  2017-09-22  6:50             ` Maxime Ripard
  -1 siblings, 1 reply; 26+ messages in thread
From: Hans Verkuil @ 2017-09-21 21:19 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: linux-media, dri-devel

On 21/09/17 22:37, Maxime Ripard wrote:
> Hi Hans,
> 
> On Fri, Sep 08, 2017 at 10:59:44AM +0000, Hans Verkuil wrote:
>> Hi Maxime,
>>
>> On 07/18/17 18:29, Maxime Ripard wrote:
>>> Hi,
>>>
>>> On Tue, Jul 11, 2017 at 11:06:52PM +0200, Hans Verkuil wrote:
>>>> On 11/07/17 22:39, Maxime Ripard wrote:
>>>>> On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
>>>>>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>>>>>
>>>>>> This patch series adds CEC support for the sun4i HDMI controller.
>>>>>>
>>>>>> The CEC hardware support for the A10 is very low-level as it just
>>>>>> controls the CEC pin. Since I also wanted to support GPIO-based CEC
>>>>>> hardware most of this patch series is in the CEC framework to
>>>>>> add a generic low-level CEC pin framework. It is only the final patch
>>>>>> that adds the sun4i support.
>>>>>>
>>>>>> This patch series first makes some small changes in the CEC framework
>>>>>> (patches 1-4) to prepare for this CEC pin support.
>>>>>>
>>>>>> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
>>>>>> the CEC core event handling.
>>>>>>
>>>>>> Patch 8 adds pin monitoring support (allows userspace to see all
>>>>>> CEC pin transitions as they happen).
>>>>>>
>>>>>> Patch 9 adds the core cec-pin implementation that translates low-level
>>>>>> pin transitions into valid CEC messages. Basically this does what any
>>>>>> SoC with a proper CEC hardware implementation does.
>>>>>>
>>>>>> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
>>>>>> which was missing).
>>>>>>
>>>>>> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
>>>>>>
>>>>>> I tested this on my cubieboard. There were no errors at all
>>>>>> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
>>>>>> same time running a 'make -j4' of the v4l-utils git repository and
>>>>>> doing a continuous scp to create network traffic.
>>>>>>
>>>>>> This patch series is based on top of the mainline kernel as of
>>>>>> yesterday (so with all the sun4i and cec patches for 4.13 merged).
>>>>>
>>>>> For the whole serie:
>>>>> Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>>>>>
>>>>>> Maxime, patches 1-10 will go through the media subsystem. How do you
>>>>>> want to handle the final patch? It can either go through the media
>>>>>> subsystem as well, or you can sit on it and handle this yourself during
>>>>>> the 4.14 merge window. Another option is to separate the Kconfig change
>>>>>> into its own patch. That way you can merge the code changes and only
>>>>>> have to handle the Kconfig patch as a final change during the merge
>>>>>> window.
>>>>>
>>>>> We'll probably have a number of reworks for 4.14, so it would be
>>>>> better if I merged it.
>>>>>
>>>>> However, I guess if we just switch to a depends on CEC_PIN instead of
>>>>> a select, everything would just work even if we merge your patches in
>>>>> a separate tree, right?
>>>>
>>>> This small patch will do it:
>>>>
>>>> diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
>>>> index e884d265c0b3..ebad80aefc87 100644
>>>> --- a/drivers/gpu/drm/sun4i/Kconfig
>>>> +++ b/drivers/gpu/drm/sun4i/Kconfig
>>>> @@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
>>>>         bool "Allwinner A10 HDMI CEC Support"
>>>>         depends on DRM_SUN4I_HDMI
>>>>         select CEC_CORE
>>>> -       select CEC_PIN
>>>> +       depends on CEC_PIN
>>>>         help
>>>>  	  Choose this option if you have an Allwinner SoC with an HDMI
>>>>  	  controller and want to use CEC.
>>
>> Just a reminder: now that both this driver and the CEC_PIN code has been
>> merged in 4.14, this 'depends on' can become a 'select' again.
> 
> Thanks for the reminder.
> 
> Would that commit work for you:
> http://code.bulix.org/19o9y6-201254

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>

This obviously should be merged for 4.14.

Regards,

	Hans

> 
> Maxime
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/11] drm/sun4i: add CEC support
  2017-09-21 21:19           ` Hans Verkuil
@ 2017-09-22  6:50             ` Maxime Ripard
  0 siblings, 0 replies; 26+ messages in thread
From: Maxime Ripard @ 2017-09-22  6:50 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, dri-devel

[-- Attachment #1: Type: text/plain, Size: 4369 bytes --]

On Thu, Sep 21, 2017 at 09:19:43PM +0000, Hans Verkuil wrote:
> On 21/09/17 22:37, Maxime Ripard wrote:
> > Hi Hans,
> > 
> > On Fri, Sep 08, 2017 at 10:59:44AM +0000, Hans Verkuil wrote:
> >> Hi Maxime,
> >>
> >> On 07/18/17 18:29, Maxime Ripard wrote:
> >>> Hi,
> >>>
> >>> On Tue, Jul 11, 2017 at 11:06:52PM +0200, Hans Verkuil wrote:
> >>>> On 11/07/17 22:39, Maxime Ripard wrote:
> >>>>> On Tue, Jul 11, 2017 at 08:30:33AM +0200, Hans Verkuil wrote:
> >>>>>> From: Hans Verkuil <hans.verkuil@cisco.com>
> >>>>>>
> >>>>>> This patch series adds CEC support for the sun4i HDMI controller.
> >>>>>>
> >>>>>> The CEC hardware support for the A10 is very low-level as it just
> >>>>>> controls the CEC pin. Since I also wanted to support GPIO-based CEC
> >>>>>> hardware most of this patch series is in the CEC framework to
> >>>>>> add a generic low-level CEC pin framework. It is only the final patch
> >>>>>> that adds the sun4i support.
> >>>>>>
> >>>>>> This patch series first makes some small changes in the CEC framework
> >>>>>> (patches 1-4) to prepare for this CEC pin support.
> >>>>>>
> >>>>>> Patch 5-7 adds the new API elements and documents it. Patch 6 reworks
> >>>>>> the CEC core event handling.
> >>>>>>
> >>>>>> Patch 8 adds pin monitoring support (allows userspace to see all
> >>>>>> CEC pin transitions as they happen).
> >>>>>>
> >>>>>> Patch 9 adds the core cec-pin implementation that translates low-level
> >>>>>> pin transitions into valid CEC messages. Basically this does what any
> >>>>>> SoC with a proper CEC hardware implementation does.
> >>>>>>
> >>>>>> Patch 10 documents the cec-pin kAPI (and also the cec-notifier kAPI
> >>>>>> which was missing).
> >>>>>>
> >>>>>> Finally patch 11 adds the actual sun4i_hdmi CEC implementation.
> >>>>>>
> >>>>>> I tested this on my cubieboard. There were no errors at all
> >>>>>> after 126264 calls of 'cec-ctl --give-device-vendor-id' while at the
> >>>>>> same time running a 'make -j4' of the v4l-utils git repository and
> >>>>>> doing a continuous scp to create network traffic.
> >>>>>>
> >>>>>> This patch series is based on top of the mainline kernel as of
> >>>>>> yesterday (so with all the sun4i and cec patches for 4.13 merged).
> >>>>>
> >>>>> For the whole serie:
> >>>>> Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> >>>>>
> >>>>>> Maxime, patches 1-10 will go through the media subsystem. How do you
> >>>>>> want to handle the final patch? It can either go through the media
> >>>>>> subsystem as well, or you can sit on it and handle this yourself during
> >>>>>> the 4.14 merge window. Another option is to separate the Kconfig change
> >>>>>> into its own patch. That way you can merge the code changes and only
> >>>>>> have to handle the Kconfig patch as a final change during the merge
> >>>>>> window.
> >>>>>
> >>>>> We'll probably have a number of reworks for 4.14, so it would be
> >>>>> better if I merged it.
> >>>>>
> >>>>> However, I guess if we just switch to a depends on CEC_PIN instead of
> >>>>> a select, everything would just work even if we merge your patches in
> >>>>> a separate tree, right?
> >>>>
> >>>> This small patch will do it:
> >>>>
> >>>> diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig
> >>>> index e884d265c0b3..ebad80aefc87 100644
> >>>> --- a/drivers/gpu/drm/sun4i/Kconfig
> >>>> +++ b/drivers/gpu/drm/sun4i/Kconfig
> >>>> @@ -25,7 +25,7 @@ config DRM_SUN4I_HDMI_CEC
> >>>>         bool "Allwinner A10 HDMI CEC Support"
> >>>>         depends on DRM_SUN4I_HDMI
> >>>>         select CEC_CORE
> >>>> -       select CEC_PIN
> >>>> +       depends on CEC_PIN
> >>>>         help
> >>>>  	  Choose this option if you have an Allwinner SoC with an HDMI
> >>>>  	  controller and want to use CEC.
> >>
> >> Just a reminder: now that both this driver and the CEC_PIN code has been
> >> merged in 4.14, this 'depends on' can become a 'select' again.
> > 
> > Thanks for the reminder.
> > 
> > Would that commit work for you:
> > http://code.bulix.org/19o9y6-201254
> 
> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
> 
> This obviously should be merged for 4.14.

Yep. I just did, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2017-09-22  6:50 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-11  6:30 [PATCH 00/11] drm/sun4i: add CEC support Hans Verkuil
2017-07-11  6:30 ` [PATCH 01/11] cec: improve transmit timeout logging Hans Verkuil
2017-07-11  6:30 ` [PATCH 02/11] cec: add *_ts variants for transmit_done/received_msg Hans Verkuil
2017-07-11  6:30 ` [PATCH 03/11] cec: add adap_free op Hans Verkuil
2017-07-11  6:30 ` [PATCH 04/11] cec-core.rst: document the adap_free callback Hans Verkuil
2017-07-11  6:30 ` [PATCH 05/11] linux/cec.h: add pin monitoring API support Hans Verkuil
2017-07-11  6:30 ` [PATCH 06/11] cec: rework the cec event handling Hans Verkuil
2017-07-11  6:30 ` [PATCH 07/11] cec: document the new CEC pin capability, events and mode Hans Verkuil
2017-07-11  6:30 ` [PATCH 08/11] cec: add core support for low-level CEC pin monitoring Hans Verkuil
2017-07-11  6:30 ` [PATCH 09/11] cec-pin: add low-level pin hardware support Hans Verkuil
2017-07-11  6:30 ` [PATCH 10/11] cec-core.rst: include cec-pin.h and cec-notifier.h Hans Verkuil
2017-07-11  6:30 ` [PATCH 11/11] sun4i_hdmi: add CEC support Hans Verkuil
2017-07-11 20:10 ` [PATCH 00/11] drm/sun4i: " Hans Verkuil
2017-07-11 20:39 ` Maxime Ripard
2017-07-11 20:39   ` Maxime Ripard
2017-07-11 21:06   ` Hans Verkuil
2017-07-11 21:06     ` Hans Verkuil
2017-07-18 16:29     ` Maxime Ripard
2017-07-18 16:29       ` Maxime Ripard
2017-07-19  8:39       ` Hans Verkuil
2017-07-19  8:39         ` Hans Verkuil
2017-09-08 10:59       ` Hans Verkuil
2017-09-21 20:37         ` Maxime Ripard
2017-09-21 20:37           ` Maxime Ripard
2017-09-21 21:19           ` Hans Verkuil
2017-09-22  6:50             ` Maxime Ripard

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.