summaryrefslogtreecommitdiff
path: root/drivers/media/cec/cec-api.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2017-11-05 07:36:36 -0500
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2017-12-08 11:10:00 -0500
commit48ea2e926b5ad29c0747fbd90e605cc56fb78298 (patch)
tree368c7d86ad1cf8640a99f31df7fd5970e14a5ee2 /drivers/media/cec/cec-api.c
parentcc05c0ba23bbc05d34caeb4773b89e1dfc2598b8 (diff)
media: cec: add the adap_monitor_pin_enable op
Some devices can monitor the CEC pin using an interrupt, but you only want to enable the interrupt if you actually switch to pin monitoring mode. So add a new op that is called when pin monitoring needs to be switched on or off. Also fix a small bug where the initial CEC pin event was sent again when calling S_MODE twice with the same CEC_MODE_MONITOR_PIN mode. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/cec/cec-api.c')
-rw-r--r--drivers/media/cec/cec-api.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 3dba3aa34a43..3eb4a069cde8 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -354,6 +354,7 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
u32 mode;
u8 mode_initiator;
u8 mode_follower;
+ bool send_pin_event = false;
long err = 0;
if (copy_from_user(&mode, parg, sizeof(mode)))
@@ -433,6 +434,19 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
}
}
+ if (!err) {
+ bool old_mon_pin = fh->mode_follower == CEC_MODE_MONITOR_PIN;
+ bool new_mon_pin = mode_follower == CEC_MODE_MONITOR_PIN;
+
+ if (old_mon_pin != new_mon_pin) {
+ send_pin_event = new_mon_pin;
+ if (new_mon_pin)
+ err = cec_monitor_pin_cnt_inc(adap);
+ else
+ cec_monitor_pin_cnt_dec(adap);
+ }
+ }
+
if (err) {
mutex_unlock(&adap->lock);
return err;
@@ -440,11 +454,9 @@ 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) {
+ if (send_pin_event) {
struct cec_event ev = {
.flags = CEC_EVENT_FL_INITIAL_STATE,
};
@@ -452,7 +464,6 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
ev.event = adap->cec_pin_is_high ? CEC_EVENT_PIN_CEC_HIGH :
CEC_EVENT_PIN_CEC_LOW;
cec_queue_event_fh(fh, &ev, 0);
- adap->monitor_pin_cnt++;
}
if (mode_follower == CEC_MODE_EXCL_FOLLOWER ||
mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
@@ -608,7 +619,7 @@ 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--;
+ cec_monitor_pin_cnt_dec(adap);
if (fh->mode_follower == CEC_MODE_MONITOR_ALL)
cec_monitor_all_cnt_dec(adap);
mutex_unlock(&adap->lock);