summaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorHans Verkuil2016-11-02 10:41:41 +0100
committerMauro Carvalho Chehab2016-11-16 18:36:03 +0100
commita69a168a1bd470cb8a8c5f2ff4b54463de615226 (patch)
tree4c3610eea028d8f79d3e5b6139ad2e7d2bd97776 /drivers/staging
parent[media] cec: accept two replies for CEC_MSG_INITIATE_ARC (diff)
downloadkernel-qcow2-linux-a69a168a1bd470cb8a8c5f2ff4b54463de615226.tar.gz
kernel-qcow2-linux-a69a168a1bd470cb8a8c5f2ff4b54463de615226.tar.xz
kernel-qcow2-linux-a69a168a1bd470cb8a8c5f2ff4b54463de615226.zip
[media] cec: add proper support for CDC-Only CEC devices
CDC-Only CEC devices are CEC devices that can only handle CDC messages, all other messages are ignored. Add a flag to signal that this is a CDC-Only device and act accordingly. Also add helper functions to identify if a CEC device is configured as a CDC-Only device, a second TV, a switch or a processor, since these variations cannot be determined by the logical address alone. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/cec/TODO4
-rw-r--r--drivers/staging/media/cec/cec-adap.c31
-rw-r--r--drivers/staging/media/cec/cec-api.c9
3 files changed, 38 insertions, 6 deletions
diff --git a/drivers/staging/media/cec/TODO b/drivers/staging/media/cec/TODO
index 5a4cfdf8d15e..504d35c7ae95 100644
--- a/drivers/staging/media/cec/TODO
+++ b/drivers/staging/media/cec/TODO
@@ -1,9 +1,5 @@
TODOs:
-- Should CEC_LOG_ADDR_TYPE_SPECIFIC be replaced by TYPE_2ND_TV and TYPE_PROCESSOR?
- And also TYPE_SWITCH and TYPE_CDC_ONLY in addition to the TYPE_UNREGISTERED?
- This should give the framework more information about the device type
- since SPECIFIC and UNREGISTERED give no useful information.
- Once this is out of staging this should no longer be a separate
config option, instead it should be selected by drivers that want it.
- Revisit the IS_REACHABLE(RC_CORE): perhaps the RC_CORE support should
diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c
index a65d8667b78e..054cd06e2247 100644
--- a/drivers/staging/media/cec/cec-adap.c
+++ b/drivers/staging/media/cec/cec-adap.c
@@ -1233,7 +1233,8 @@ configured:
mutex_unlock(&adap->lock);
for (i = 0; i < las->num_log_addrs; i++) {
- if (las->log_addr[i] == CEC_LOG_ADDR_INVALID)
+ if (las->log_addr[i] == CEC_LOG_ADDR_INVALID ||
+ (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY))
continue;
/*
@@ -1355,6 +1356,29 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
return 0;
}
+ if (log_addrs->flags & CEC_LOG_ADDRS_FL_CDC_ONLY) {
+ /*
+ * Sanitize log_addrs fields if a CDC-Only device is
+ * requested.
+ */
+ log_addrs->num_log_addrs = 1;
+ log_addrs->osd_name[0] = '\0';
+ log_addrs->vendor_id = CEC_VENDOR_ID_NONE;
+ log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
+ /*
+ * This is just an internal convention since a CDC-Only device
+ * doesn't have to be a switch. But switches already use
+ * unregistered, so it makes some kind of sense to pick this
+ * as the primary device. Since a CDC-Only device never sends
+ * any 'normal' CEC messages this primary device type is never
+ * sent over the CEC bus.
+ */
+ log_addrs->primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH;
+ log_addrs->all_device_types[0] = 0;
+ log_addrs->features[0][0] = 0;
+ log_addrs->features[0][1] = 0;
+ }
+
/* Ensure the osd name is 0-terminated */
log_addrs->osd_name[sizeof(log_addrs->osd_name) - 1] = '\0';
@@ -1575,6 +1599,11 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
dprintk(1, "cec_receive_notify: %*ph\n", msg->len, msg->msg);
+ /* If this is a CDC-Only device, then ignore any non-CDC messages */
+ if (cec_is_cdc_only(&adap->log_addrs) &&
+ msg->msg[1] != CEC_MSG_CDC_MESSAGE)
+ return 0;
+
if (adap->ops->received) {
/* Allow drivers to process the message first */
if (adap->ops->received(adap, msg) != -ENOMSG)
diff --git a/drivers/staging/media/cec/cec-api.c b/drivers/staging/media/cec/cec-api.c
index 54148a6b3326..d4bc4ee2c6e5 100644
--- a/drivers/staging/media/cec/cec-api.c
+++ b/drivers/staging/media/cec/cec-api.c
@@ -163,7 +163,8 @@ static long cec_adap_s_log_addrs(struct cec_adapter *adap, struct cec_fh *fh,
if (copy_from_user(&log_addrs, parg, sizeof(log_addrs)))
return -EFAULT;
log_addrs.flags &= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK |
- CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU;
+ CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU |
+ CEC_LOG_ADDRS_FL_CDC_ONLY;
mutex_lock(&adap->lock);
if (!adap->is_configuring &&
(!log_addrs.num_log_addrs || !adap->is_configured) &&
@@ -190,6 +191,12 @@ static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
return -ENOTTY;
if (copy_from_user(&msg, parg, sizeof(msg)))
return -EFAULT;
+
+ /* A CDC-Only device can only send CDC messages */
+ if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) &&
+ (msg.len == 1 || msg.msg[1] != CEC_MSG_CDC_MESSAGE))
+ return -EINVAL;
+
msg.flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS;
mutex_lock(&adap->lock);
if (!adap->is_configured)