I have tried to add Sony SIRC 12/15/20 hardware decoding support on Nougat for VIM:
diff --git a/drivers/amlogic/input/remote/remote_regmap.c b/drivers/amlogic/input/remote/remote_regmap.c
index 17a7c62..a3ac239 100644
--- a/drivers/amlogic/input/remote/remote_regmap.c
+++ b/drivers/amlogic/input/remote/remote_regmap.c
@@ -145,6 +145,84 @@ static struct remote_reg_map regs_default_toshiba[] = {
{ REG_DURATN3 , 0x00}
};
+static struct remote_reg_map regs_default_sony_sirc12[] = {
+ /* (4 +/- .5) * 600 us */
+ { REG_LDR_ACTIVE, 135 << 16 | 105 << 0 },
+ /* (1 +/- .5) * 600 us */
+ { REG_LDR_IDLE, 45 << 16 | 15 << 0 },
+ /* No repeat code */
+ { REG_LDR_REPEAT, 0 },
+ /* (2 +/- .5) * 600 us */
+ { REG_BIT_0, 75 << 16 | 45 << 0 },
+ /*
+ * Filter: 140 us, max frame time: (4.5 + 1.5 + 12 * 3.5) * 600 us,
+ * base time: 20 us
+ */
+ { REG_REG0, 7 << 28 | 1440 << 12 | (20 - 1) },
+ /* Logic "1": (3 +/- .5) * 600 us */
+ { REG_STATUS, 1 << 30 | 105 << 20 | 75 << 10 },
+ /* Decoder, 12-bit frame body */
+ { REG_REG1, 1 << 15 | (12 - 1) << 8 },
+ /* Check repeat time, compare frames for repeat, lsb first, Sony SIRC */
+ { REG_REG2, 1 << 12 | 1 << 11 | 0 << 8 | 6 },
+ { REG_DURATN2, 0 },
+ { REG_DURATN3, 0 },
+ /* Repeat max frame interval: 50 ms */
+ { REG_REG3, 500 },
+};
+
+static struct remote_reg_map regs_default_sony_sirc15[] = {
+ /* (4 +/- .5) * 600 us */
+ { REG_LDR_ACTIVE, 135 << 16 | 105 << 0 },
+ /* (1 +/- .5) * 600 us */
+ { REG_LDR_IDLE, 45 << 16 | 15 << 0 },
+ /* No repeat code */
+ { REG_LDR_REPEAT, 0 },
+ /* (2 +/- .5) * 600 us */
+ { REG_BIT_0, 75 << 16 | 45 << 0 },
+ /*
+ * Filter: 140 us, max frame time: (4.5 + 1.5 + 15 * 3.5) * 600 us,
+ * base time: 20 us
+ */
+ { REG_REG0, 7 << 28 | 1755 << 12 | (20 - 1) },
+ /* Logic "1": (3 +/- .5) * 600 us */
+ { REG_STATUS, 1 << 30 | 105 << 20 | 75 << 10 },
+ /* Decoder, 15-bit frame body */
+ { REG_REG1, 1 << 15 | (15 - 1) << 8 },
+ /* Check repeat time, compare frames for repeat, lsb first, Sony SIRC */
+ { REG_REG2, 1 << 12 | 1 << 11 | 0 << 8 | 6 },
+ { REG_DURATN2, 0 },
+ { REG_DURATN3, 0 },
+ /* Repeat max frame interval: 50 ms */
+ { REG_REG3, 500 },
+};
+
+static struct remote_reg_map regs_default_sony_sirc20[] = {
+ /* (4 +/- .5) * 600 us */
+ { REG_LDR_ACTIVE, 135 << 16 | 105 << 0 },
+ /* (1 +/- .5) * 600 us */
+ { REG_LDR_IDLE, 45 << 16 | 15 << 0 },
+ /* No repeat code */
+ { REG_LDR_REPEAT, 0 },
+ /* (2 +/- .5) * 600 us */
+ { REG_BIT_0, 75 << 16 | 45 << 0 },
+ /*
+ * Filter: 140 us, max frame time: (4.5 + 1.5 + 20 * 3.5) * 600 us,
+ * base time: 20 us
+ */
+ { REG_REG0, 7 << 28 | 2280 << 12 | (20 - 1) },
+ /* Logic "1": (3 +/- .5) * 600 us */
+ { REG_STATUS, 1 << 30 | 105 << 20 | 75 << 10 },
+ /* Decoder, 20-bit frame body */
+ { REG_REG1, 1 << 15 | (20 - 1) << 8 },
+ /* Check repeat time, compare frames for repeat, lsb first, Sony SIRC */
+ { REG_REG2, 1 << 12 | 1 << 11 | 0 << 8 | 6 },
+ { REG_DURATN2, 0 },
+ { REG_DURATN3, 0 },
+ /* Repeat max frame interval: 50 ms */
+ { REG_REG3, 500 },
+};
+
void set_hardcode(struct remote_chip *chip, int code)
{
remote_dbg(chip->dev, "framecode=0x%x\n", code);
@@ -462,6 +540,33 @@ static u32 ir_toshiba_get_custom_code(struct remote_chip *chip)
return custom_code;
}
+static int ir_sony_sirc_get_scancode(struct remote_chip *chip)
+{
+ int code = 0;
+ int decode_status = 0;
+ int status = 0;
+
+ remote_reg_read(chip, MULTI_IR_ID, REG_STATUS, &decode_status);
+ if (decode_status & 0x01)
+ status |= REMOTE_REPEAT;
+ chip->decode_status = status; /*set decode status*/
+ remote_reg_read(chip, MULTI_IR_ID, REG_FRAME, &code);
+ remote_dbg(chip->dev, "framecode=0x%x\n", code);
+ chip->r_dev->cur_hardcode = code;
+ code &= 0x7f;
+ return code;
+}
+
+static int ir_sony_sirc_get_decode_status(struct remote_chip *chip)
+{
+ return chip->decode_status;
+}
+
+static u32 ir_sony_sirc_get_custom_code(struct remote_chip *chip)
+{
+ return chip->r_dev->cur_hardcode >> 7;
+}
+
/*legacy IR controller support protocols*/
static struct aml_remote_reg_proto reg_legacy_nec = {
@@ -555,6 +660,36 @@ static struct aml_remote_reg_proto reg_toshiba = {
.get_custom_code = ir_toshiba_get_custom_code,
};
+static struct aml_remote_reg_proto reg_sony_sirc12 = {
+ .protocol = REMOTE_TYPE_SONY_SIRC12,
+ .name = "SONY_SIRC12",
+ .reg_map = regs_default_sony_sirc12,
+ .reg_map_size = ARRAY_SIZE(regs_default_sony_sirc12),
+ .get_scancode = ir_sony_sirc_get_scancode,
+ .get_decode_status = ir_sony_sirc_get_decode_status,
+ .get_custom_code = ir_sony_sirc_get_custom_code,
+};
+
+static struct aml_remote_reg_proto reg_sony_sirc15 = {
+ .protocol = REMOTE_TYPE_SONY_SIRC15,
+ .name = "SONY_SIRC15",
+ .reg_map = regs_default_sony_sirc15,
+ .reg_map_size = ARRAY_SIZE(regs_default_sony_sirc15),
+ .get_scancode = ir_sony_sirc_get_scancode,
+ .get_decode_status = ir_sony_sirc_get_decode_status,
+ .get_custom_code = ir_sony_sirc_get_custom_code,
+};
+
+static struct aml_remote_reg_proto reg_sony_sirc20 = {
+ .protocol = REMOTE_TYPE_SONY_SIRC20,
+ .name = "SONY_SIRC20",
+ .reg_map = regs_default_sony_sirc20,
+ .reg_map_size = ARRAY_SIZE(regs_default_sony_sirc20),
+ .get_scancode = ir_sony_sirc_get_scancode,
+ .get_decode_status = ir_sony_sirc_get_decode_status,
+ .get_custom_code = ir_sony_sirc_get_custom_code,
+};
+
const struct aml_remote_reg_proto *remote_reg_proto[] = {
®_nec,
@@ -566,6 +701,9 @@ const struct aml_remote_reg_proto *remote_reg_proto[] = {
®_rc6,
®_legacy_nec,
®_toshiba,
+ ®_sony_sirc12,
+ ®_sony_sirc15,
+ ®_sony_sirc20,
NULL
};
diff --git a/include/dt-bindings/input/meson_rc.h b/include/dt-bindings/input/meson_rc.h
index 32cb619..7cba3f7 100644
--- a/include/dt-bindings/input/meson_rc.h
+++ b/include/dt-bindings/input/meson_rc.h
@@ -22,6 +22,9 @@
#define REMOTE_TYPE_RC5 0x04
#define REMOTE_TYPE_RC6 0x05
#define REMOTE_TYPE_TOSHIBA 0x06
+#define REMOTE_TYPE_SONY_SIRC12 0x07
+#define REMOTE_TYPE_SONY_SIRC15 0x08
+#define REMOTE_TYPE_SONY_SIRC20 0x09
/*hardware decode one protocol by using legacy IR controller*/
#define REMOTE_TYPE_LEGACY_NEC 0xff
However, there are 2 issues:
-
It does not work with the correct bit length in
AO_MF_IR_DEC_REG1[13:8]
. For example, for SIRC 12, the bit length is 12, so 11 should be written to this bit-field, but this does not work. 10 works fine, but with the msb missing. 11 can be made to work, but with a corrupt final bit (msb) always detected as “1”, if the max frame time inAO_MF_IR_DEC_REG0[24:12]
is set to a longer duration and ifAO_MF_IR_DEC_STATUS[30]
is cleared. As there is no trailer pulse for this protocol, I think that there is a bug in the hardware decoder for this protocol because it measures the time between consecutive pulses instead of taking the pulse durations into account. Can you or Amlogic confirm this or give a workaround? Perhaps it would be possible to hack something withAO_MF_IR_DEC_REG2[26:25]
,AO_MF_IR_DEC_DURATN2
, andAO_MF_IR_DEC_DURATN3
, but there is nothing documented about this for SIRC. If there is no working solution, the only workarounds are to give up the msb or to use the general time measurement mode (software decoder). -
With the bit length set to 11 instead of 12 (i.e.
AO_MF_IR_DEC_REG1[13:8]
set to 10 to work around the first issue), pressing the same key twice results in a repeat event being detected the second time because the frame is the same, despite the frame interval being way greater thanAO_MF_IR_DEC_REG3
. Maybe this is because of the bit length issue, but if not, this is another hardware bug. Any solution other than deactivating the repeat detection or switching to a software decoder?