diff --git a/utils/cec-compliance/cec-test.cpp b/utils/cec-compliance/cec-test.cpp
index fb57d10b..4578dd13 100644
--- a/utils/cec-compliance/cec-test.cpp
+++ b/utils/cec-compliance/cec-test.cpp
@@ -601,10 +601,6 @@ static const vec_remote_subtests dev_menu_ctl_subtests{
 
 /* Deck Control */
 
-/*
-  TODO: These are very rudimentary tests which should be expanded.
- */
-
 static int deck_ctl_give_status(struct node *node, unsigned me, unsigned la, bool interactive)
 {
 	struct cec_msg msg = {};
@@ -613,12 +609,11 @@ static int deck_ctl_give_status(struct node *node, unsigned me, unsigned la, boo
 	cec_msg_give_deck_status(&msg, true, CEC_OP_STATUS_REQ_ONCE);
 	fail_on_test(!transmit_timeout(node, &msg));
 	fail_on_test(timed_out(&msg));
-	if (is_playback_or_rec(la)) {
-		fail_on_test_v2(node->remote[la].cec_version,
-				node->remote[la].has_deck_ctl && cec_msg_status_is_abort(&msg));
-		fail_on_test_v2(node->remote[la].cec_version,
-				!node->remote[la].has_deck_ctl && !unrecognized_op(&msg));
-	}
+
+	fail_on_test_v2(node->remote[la].cec_version,
+	                node->remote[la].has_deck_ctl && cec_msg_status_is_abort(&msg));
+	fail_on_test_v2(node->remote[la].cec_version,
+	                !node->remote[la].has_deck_ctl && !unrecognized_op(&msg));
 	if (unrecognized_op(&msg))
 		return OK_NOT_SUPPORTED;
 	if (refused(&msg))
@@ -626,7 +621,51 @@ static int deck_ctl_give_status(struct node *node, unsigned me, unsigned la, boo
 	if (cec_msg_status_is_abort(&msg))
 		return OK_PRESUMED;
 
-	return 0;
+	__u8 deck_info;
+
+	cec_ops_deck_status(&msg, &deck_info);
+	fail_on_test(deck_info < CEC_OP_DECK_INFO_PLAY || deck_info > CEC_OP_DECK_INFO_OTHER);
+
+	cec_msg_init(&msg, me, la);
+	cec_msg_give_deck_status(&msg, true, CEC_OP_STATUS_REQ_ON);
+	fail_on_test(!transmit_timeout(node, &msg));
+	fail_on_test(timed_out(&msg));
+	cec_ops_deck_status(&msg, &deck_info);
+	fail_on_test(deck_info < CEC_OP_DECK_INFO_PLAY || deck_info > CEC_OP_DECK_INFO_OTHER);
+
+	cec_msg_init(&msg, me, la);
+	cec_msg_give_deck_status(&msg, true, CEC_OP_STATUS_REQ_OFF);
+	/*
+	 * Reply would not normally be expected for CEC_OP_STATUS_REQ_OFF.
+	 * If a reply is received, then the follower failed to turn off
+	 * status reporting as required.
+	 */
+	msg.reply = CEC_MSG_DECK_STATUS;
+	fail_on_test(!transmit_timeout(node, &msg));
+	fail_on_test(!timed_out(&msg));
+
+	return OK;
+}
+
+static int deck_ctl_give_status_invalid(struct node *node, unsigned me, unsigned la, bool interactive)
+{
+	struct cec_msg msg = {};
+
+	cec_msg_init(&msg, me, la);
+	cec_msg_give_deck_status(&msg, true, 0); /* Invalid Operand */
+	fail_on_test(!transmit_timeout(node, &msg));
+	if (unrecognized_op(&msg))
+		return OK_NOT_SUPPORTED;
+	fail_on_test(!cec_msg_status_is_abort(&msg));
+	fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP);
+
+	cec_msg_init(&msg, me, la);
+	cec_msg_give_deck_status(&msg, true, 4); /* Invalid Operand */
+	fail_on_test(!transmit_timeout(node, &msg));
+	fail_on_test(!cec_msg_status_is_abort(&msg));
+	fail_on_test(abort_reason(&msg) != CEC_OP_ABORT_INVALID_OP);
+
+	return OK;
 }
 
 static int deck_ctl_deck_status(struct node *node, unsigned me, unsigned la, bool interactive)
@@ -693,7 +732,16 @@ static int deck_ctl_play(struct node *node, unsigned me, unsigned la, bool inter
 }
 
 static const vec_remote_subtests deck_ctl_subtests{
-	{ "Give Deck Status", CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, deck_ctl_give_status },
+	{
+		"Give Deck Status",
+		CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD,
+		deck_ctl_give_status,
+	},
+	{
+		"Give Deck Status Invalid Operand",
+		CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD,
+		deck_ctl_give_status_invalid,
+	},
 	{ "Deck Status", CEC_LOG_ADDR_MASK_ALL, deck_ctl_deck_status },
 	{ "Deck Control", CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, deck_ctl_deck_ctl },
 	{ "Play", CEC_LOG_ADDR_MASK_PLAYBACK | CEC_LOG_ADDR_MASK_RECORD, deck_ctl_play },
diff --git a/utils/cec-follower/cec-follower.cpp b/utils/cec-follower/cec-follower.cpp
index 1f598fdf..047d7a04 100644
--- a/utils/cec-follower/cec-follower.cpp
+++ b/utils/cec-follower/cec-follower.cpp
@@ -313,6 +313,8 @@ void state_init(struct node &node)
 	node.state.sac_active = false;
 	node.state.volume = 50;
 	node.state.mute = false;
+	node.state.deck_report_changes = false;
+	node.state.deck_state = CEC_OP_DECK_INFO_STOP;
 	tuner_dev_info_init(&node.state);
 	node.state.last_aud_rate_rx_ts = 0;
 }
diff --git a/utils/cec-follower/cec-follower.h b/utils/cec-follower/cec-follower.h
index 391b9ab4..0492faa9 100644
--- a/utils/cec-follower/cec-follower.h
+++ b/utils/cec-follower/cec-follower.h
@@ -50,6 +50,7 @@ struct state {
 	bool service_by_dig_id;
 	bool tuner_report_changes;
 	bool deck_report_changes;
+	__u8 deck_state;
 	unsigned toggle_power_status;
 	__u64 last_aud_rate_rx_ts;
 };
diff --git a/utils/cec-follower/cec-processing.cpp b/utils/cec-follower/cec-processing.cpp
index 5b9db19f..3d2e4a2c 100644
--- a/utils/cec-follower/cec-processing.cpp
+++ b/utils/cec-follower/cec-processing.cpp
@@ -505,36 +505,31 @@ static void processMsg(struct node *node, struct cec_msg &msg, unsigned me)
 		break;
 
 
-		/*
-		  Deck Control
-
-		  This is only a basic implementation.
-
-		  TODO: Device state should reflect whether we are playing,
-		  fast forwarding, etc.
-		*/
+		/* Deck Control */
 
 	case CEC_MSG_GIVE_DECK_STATUS:
-		if (node->has_deck_ctl) {
-			__u8 status_req;
+		if (!node->has_deck_ctl)
+			break;
 
-			cec_ops_give_deck_status(&msg, &status_req);
-			if (status_req < CEC_OP_STATUS_REQ_ON ||
-			    status_req > CEC_OP_STATUS_REQ_ONCE) {
-				reply_feature_abort(node, &msg, CEC_OP_ABORT_INVALID_OP);
-				return;
-			}
-			if (status_req != CEC_OP_STATUS_REQ_ONCE)
-				node->state.deck_report_changes =
-					status_req == CEC_OP_STATUS_REQ_ON;
-			if (status_req == CEC_OP_STATUS_REQ_OFF)
-				return;
+		__u8 status_req;
+		cec_ops_give_deck_status(&msg, &status_req);
+
+		switch (status_req) {
+		case CEC_OP_STATUS_REQ_ON:
+			node->state.deck_report_changes = true;
+			fallthrough;
+		case CEC_OP_STATUS_REQ_ONCE:
 			cec_msg_set_reply_to(&msg, &msg);
-			cec_msg_deck_status(&msg, CEC_OP_DECK_INFO_STOP);
+			cec_msg_deck_status(&msg, node->state.deck_state);
 			transmit(node, &msg);
 			return;
+		case CEC_OP_STATUS_REQ_OFF:
+			node->state.deck_report_changes = false;
+			return;
+		default:
+			reply_feature_abort(node, &msg, CEC_OP_ABORT_INVALID_OP);
+			return;
 		}
-		break;
 	case CEC_MSG_PLAY:
 		if (node->has_deck_ctl)
 			return;
