VIM Sony SIRC Support

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[] = {
 	&reg_nec,
@@ -566,6 +701,9 @@ const struct aml_remote_reg_proto *remote_reg_proto[] = {
 	&reg_rc6,
 	&reg_legacy_nec,
 	&reg_toshiba,
+	&reg_sony_sirc12,
+	&reg_sony_sirc15,
+	&reg_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:

  1. 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 in AO_MF_IR_DEC_REG0[24:12] is set to a longer duration and if AO_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 with AO_MF_IR_DEC_REG2[26:25], AO_MF_IR_DEC_DURATN2, and AO_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).

  2. 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 than AO_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?

I have just created the following pull requests on your repositories:



I have added a workaround for the second issue, and we can live with the first one.

1 Like

Hi @Gouwa,

Can you merge my pull requests?

Hi, BenTh.WS:
Can you recommend a SONY SIRC remote to us, we will buy one for testing first than merge your commit.

Thanks!

Hi @Gouwa,

You can use this remote control with the Sony protocols:
http://www.chunghop.com/en/product_detail.php?ProId=215

Do you know some other models? We search in China online shop, didn’t find RM-316E model.

Thanks!

Any universal IR remote control supporting the Sony protocols with setup codes should be OK. Chunghop or other brands should be fine. Just look at the specifications of the remotes that you find on your online shops.

Thanks.