aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiunn Chang <c0d1n61at3@gmail.com>2019-10-02 22:18:15 -0500
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2019-10-03 08:54:36 +0200
commitf2e3db5ab395a92d9138a57f82068d1c6b4a8a70 (patch)
tree685ae4368d576e4a254e7a5f6b9bc9af6d53ef80
parent406a4b24752e0d4bc6f2903546efd5f1a7506609 (diff)
cec-follower: add tuner step increment/decrement
Tuner step feature will select the next highest or lowest service frequency. There are a total of three possible frequencies given a broadcast type and system for a total of 81 analog channels. Opcodes implemented: - <Tuner Step Increment> - <Tuner Step Decrement> Signed-off-by: Jiunn Chang <c0d1n61at3@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r--utils/cec-follower/cec-follower.cpp2
-rw-r--r--utils/cec-follower/cec-follower.h3
-rw-r--r--utils/cec-follower/cec-tuner.cpp67
3 files changed, 55 insertions, 17 deletions
diff --git a/utils/cec-follower/cec-follower.cpp b/utils/cec-follower/cec-follower.cpp
index 789fef4a..b208d14e 100644
--- a/utils/cec-follower/cec-follower.cpp
+++ b/utils/cec-follower/cec-follower.cpp
@@ -298,7 +298,7 @@ void state_init(struct node &node)
node.state.sac_active = false;
node.state.volume = 50;
node.state.mute = false;
- analog_tuner_init(&node.state.tuner_dev_info);
+ analog_tuner_init(&node.state);
}
int main(int argc, char **argv)
diff --git a/utils/cec-follower/cec-follower.h b/utils/cec-follower/cec-follower.h
index 0bd45452..04019c9a 100644
--- a/utils/cec-follower/cec-follower.h
+++ b/utils/cec-follower/cec-follower.h
@@ -53,6 +53,7 @@ struct state {
unsigned rc_press_hold_count;
unsigned rc_duration_sum;
struct cec_op_tuner_device_info tuner_dev_info;
+ unsigned int freq_idx;
};
struct node {
@@ -222,7 +223,7 @@ std::string opcode2s(const struct cec_msg *msg);
void sad_encode(const struct short_audio_desc *sad, __u32 *descriptor);
// cec-tuner.cpp
-void analog_tuner_init(struct cec_op_tuner_device_info *tuner_dev_info);
+void analog_tuner_init(struct state *state);
void process_tuner_record_timer_msgs(struct node *node, struct cec_msg &msg, unsigned me);
// CEC processing
diff --git a/utils/cec-follower/cec-tuner.cpp b/utils/cec-follower/cec-tuner.cpp
index d74981b2..46acccf4 100644
--- a/utils/cec-follower/cec-tuner.cpp
+++ b/utils/cec-follower/cec-tuner.cpp
@@ -8,7 +8,8 @@
#include "cec-follower.h"
-#define NUM_ANALOG_FREQS 3
+#define NUM_ANALOG_FREQS 3
+#define TOT_ANALOG_FREQS (sizeof(analog_freqs_khz) / sizeof(analog_freqs_khz[0][0][0]))
/*
* This table contains analog television channel frequencies in KHz. There are
@@ -90,10 +91,12 @@ static unsigned int analog_freqs_khz[3][9][NUM_ANALOG_FREQS] =
}
};
-void analog_tuner_init(struct cec_op_tuner_device_info *info)
+void analog_tuner_init(struct state *state)
{
+ struct cec_op_tuner_device_info *info = &state->tuner_dev_info;
unsigned int freq_khz;
+ state->freq_idx = 0;
info->rec_flag = CEC_OP_REC_FLAG_NOT_USED;
info->tuner_display_info = CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE;
info->is_analog = true;
@@ -103,35 +106,52 @@ void analog_tuner_init(struct cec_op_tuner_device_info *info)
info->analog.ana_freq = (freq_khz * 10) / 625;
}
-static unsigned int analog_get_nearest_freq(__u8 ana_bcast_type, __u8 ana_bcast_system,
- int ana_freq_khz)
+static unsigned int analog_get_nearest_freq_idx(__u8 ana_bcast_type, __u8 ana_bcast_system,
+ int ana_freq_khz)
{
int nearest = analog_freqs_khz[ana_bcast_type][ana_bcast_system][0];
+ unsigned int offset = 0;
for (int i = 0; i < NUM_ANALOG_FREQS; i++) {
int freq = analog_freqs_khz[ana_bcast_type][ana_bcast_system][i];
- if (abs(ana_freq_khz - freq) < abs(ana_freq_khz - nearest))
+ if (abs(ana_freq_khz - freq) < abs(ana_freq_khz - nearest)) {
nearest = freq;
+ offset = i;
+ }
}
- return nearest;
+ return NUM_ANALOG_FREQS * ((ana_bcast_type * 9) + ana_bcast_system) + offset;
}
-static bool analog_set_tuner_dev_info(struct node *node, struct cec_msg *msg)
+static void analog_update_tuner_dev_info(struct node *node, unsigned int idx)
{
struct cec_op_tuner_device_info *info = &node->state.tuner_dev_info;
+ unsigned int tot_freqs = NUM_ANALOG_FREQS * 9;
+ unsigned int offset;
+ unsigned int freq_khz;
+
+ node->state.freq_idx = idx;
+ info->analog.ana_bcast_type = node->state.freq_idx / tot_freqs;
+ info->analog.bcast_system =
+ (node->state.freq_idx - (tot_freqs * info->analog.ana_bcast_type)) / NUM_ANALOG_FREQS;
+ offset = node->state.freq_idx % NUM_ANALOG_FREQS;
+ freq_khz = analog_freqs_khz[info->analog.ana_bcast_type][info->analog.bcast_system][offset];
+ info->analog.ana_freq = (freq_khz * 10) / 625;
+}
+
+static bool analog_set_tuner_dev_info(struct node *node, struct cec_msg *msg)
+{
__u8 type;
__u16 freq;
__u8 system;
+ unsigned int idx;
cec_ops_select_analogue_service(msg, &type, &freq, &system);
if (type < 3 && system < 9) {
int freq_khz = (freq * 625) / 10;
- unsigned int nearest = analog_get_nearest_freq(type, system,
- freq_khz);
- info->analog.ana_bcast_type = type;
- info->analog.ana_freq = (nearest * 10) / 625;
- info->analog.bcast_system = system;
+
+ idx = analog_get_nearest_freq_idx(type, system, freq_khz);
+ analog_update_tuner_dev_info(node, idx);
return true;
}
return false;
@@ -180,12 +200,29 @@ void process_tuner_record_timer_msgs(struct node *node, struct cec_msg &msg, uns
return;
case CEC_MSG_SELECT_DIGITAL_SERVICE:
- case CEC_MSG_TUNER_STEP_DECREMENT:
- case CEC_MSG_TUNER_STEP_INCREMENT:
- if (!cec_has_tuner(1 << me))
+ case CEC_MSG_TUNER_STEP_DECREMENT: {
+ if (!cec_has_tuner(1 << me) && !cec_has_tv(1 << me))
break;
+
+ if (node->state.freq_idx == 0)
+ node->state.freq_idx = TOT_ANALOG_FREQS - 1;
+ else
+ node->state.freq_idx--;
+ analog_update_tuner_dev_info(node, node->state.freq_idx);
return;
+ }
+ case CEC_MSG_TUNER_STEP_INCREMENT: {
+ if (!cec_has_tuner(1 << me) && !cec_has_tv(1 << me))
+ break;
+
+ if (node->state.freq_idx == TOT_ANALOG_FREQS - 1)
+ node->state.freq_idx = 0;
+ else
+ node->state.freq_idx++;
+ analog_update_tuner_dev_info(node, node->state.freq_idx);
+ return;
+ }
/*
One Touch Record

Privacy Policy