Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48ea2e92 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

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: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent cc05c0ba
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -2053,6 +2053,29 @@ void cec_monitor_all_cnt_dec(struct cec_adapter *adap)
		WARN_ON(call_op(adap, adap_monitor_all_enable, 0));
}

/*
 * Helper functions to keep track of the 'monitor pin' use count.
 *
 * These functions are called with adap->lock held.
 */
int cec_monitor_pin_cnt_inc(struct cec_adapter *adap)
{
	int ret = 0;

	if (adap->monitor_pin_cnt == 0)
		ret = call_op(adap, adap_monitor_pin_enable, 1);
	if (ret == 0)
		adap->monitor_pin_cnt++;
	return ret;
}

void cec_monitor_pin_cnt_dec(struct cec_adapter *adap)
{
	adap->monitor_pin_cnt--;
	if (adap->monitor_pin_cnt == 0)
		WARN_ON(call_op(adap, adap_monitor_pin_enable, 0));
}

#ifdef CONFIG_DEBUG_FS
/*
 * Log the current state of the CEC adapter.
+16 −5
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ void cec_put_device(struct cec_devnode *devnode);
/* cec-adap.c */
int cec_monitor_all_cnt_inc(struct cec_adapter *adap);
void cec_monitor_all_cnt_dec(struct cec_adapter *adap);
int cec_monitor_pin_cnt_inc(struct cec_adapter *adap);
void cec_monitor_pin_cnt_dec(struct cec_adapter *adap);
int cec_adap_status(struct seq_file *file, void *priv);
int cec_thread_func(void *_adap);
void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block);
+1 −0
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ struct cec_adap_ops {
	/* Low-level callbacks */
	int (*adap_enable)(struct cec_adapter *adap, bool enable);
	int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
	int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
	int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
	int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
			     u32 signal_free_time, struct cec_msg *msg);