aboutsummaryrefslogtreecommitdiff
path: root/sys/arm/allwinner/aw_cir.c
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-08-15 11:49:31 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-08-15 11:49:31 +0000
commitde6fc2e39bc1d88511b62ed3a6834a6f0cd6b3a4 (patch)
tree75e7ac246ee145e2bd1c97480e08e1c8bc027dd4 /sys/arm/allwinner/aw_cir.c
parent8460d7540b226f37a2f58b9f652e34e2fb6df3a7 (diff)
parentbec053ffe01ddc571fb09d1758708c407c33ddfd (diff)
downloadsrc-de6fc2e39bc1d88511b62ed3a6834a6f0cd6b3a4.tar.gz
src-de6fc2e39bc1d88511b62ed3a6834a6f0cd6b3a4.zip
Merge ^/head r364082 through r364250.
Notes
Notes: svn path=/projects/clang1100-import/; revision=364251
Diffstat (limited to 'sys/arm/allwinner/aw_cir.c')
-rw-r--r--sys/arm/allwinner/aw_cir.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/sys/arm/allwinner/aw_cir.c b/sys/arm/allwinner/aw_cir.c
index 1531e2fe9d47..eabab4cba8f2 100644
--- a/sys/arm/allwinner/aw_cir.c
+++ b/sys/arm/allwinner/aw_cir.c
@@ -126,16 +126,21 @@ __FBSDID("$FreeBSD$");
#define AW_IR_DMAX 53
/* Active Thresholds */
-#define AW_IR_ACTIVE_T ((0 & 0xff) << 16)
-#define AW_IR_ACTIVE_T_C ((1 & 0xff) << 23)
+#define AW_IR_ACTIVE_T_VAL AW_IR_L1_MIN
+#define AW_IR_ACTIVE_T (((AW_IR_ACTIVE_T_VAL - 1) & 0xff) << 16)
+#define AW_IR_ACTIVE_T_C_VAL 0
+#define AW_IR_ACTIVE_T_C ((AW_IR_ACTIVE_T_C_VAL & 0xff) << 23)
/* Code masks */
#define CODE_MASK 0x00ff00ff
#define INV_CODE_MASK 0xff00ff00
#define VALID_CODE_MASK 0x00ff0000
-#define A10_IR 1
-#define A13_IR 2
+enum {
+ A10_IR = 1,
+ A13_IR,
+ A31_IR,
+};
#define AW_IR_RAW_BUF_SIZE 128
@@ -158,6 +163,7 @@ static struct resource_spec aw_ir_spec[] = {
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-ir", A10_IR },
{ "allwinner,sun5i-a13-ir", A13_IR },
+ { "allwinner,sun6i-a31-ir", A31_IR },
{ NULL, 0 }
};
@@ -196,24 +202,24 @@ aw_ir_read_data(struct aw_ir_softc *sc)
static unsigned long
aw_ir_decode_packets(struct aw_ir_softc *sc)
{
- unsigned long len, code;
- unsigned char val, last;
+ unsigned int len, code;
unsigned int active_delay;
+ unsigned char val, last;
int i, bitcount;
if (bootverbose)
device_printf(sc->dev, "sc->dcnt = %d\n", sc->dcnt);
/* Find Lead 1 (bit separator) */
- active_delay = (AW_IR_ACTIVE_T + 1) * (AW_IR_ACTIVE_T_C != 0 ? 128 : 1);
- len = 0;
- len += (active_delay >> 1);
+ active_delay = AW_IR_ACTIVE_T_VAL *
+ (AW_IR_ACTIVE_T_C_VAL != 0 ? 128 : 1);
+ len = active_delay;
if (bootverbose)
- device_printf(sc->dev, "Initial len: %ld\n", len);
+ device_printf(sc->dev, "Initial len: %d\n", len);
for (i = 0; i < sc->dcnt; i++) {
val = sc->buf[i];
if (val & VAL_MASK)
- len += val & PERIOD_MASK;
+ len += (val & PERIOD_MASK) + 1;
else {
if (len > AW_IR_L1_MIN)
break;
@@ -221,7 +227,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
}
}
if (bootverbose)
- device_printf(sc->dev, "len = %ld\n", len);
+ device_printf(sc->dev, "len = %d\n", len);
if ((val & VAL_MASK) || (len <= AW_IR_L1_MIN)) {
if (bootverbose)
device_printf(sc->dev, "Bit separator error\n");
@@ -237,7 +243,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
break;
len = 0;
} else
- len += val & PERIOD_MASK;
+ len += (val & PERIOD_MASK) + 1;
}
if ((!(val & VAL_MASK)) || (len <= AW_IR_L0_MIN)) {
if (bootverbose)
@@ -254,23 +260,25 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
val = sc->buf[i];
if (last) {
if (val & VAL_MASK)
- len += val & PERIOD_MASK;
+ len += (val & PERIOD_MASK) + 1;
else {
if (len > AW_IR_PMAX) {
if (bootverbose)
device_printf(sc->dev,
- "Pulse error\n");
+ "Pulse error, len=%d\n",
+ len);
goto error_code;
}
last = 0;
- len = val & PERIOD_MASK;
+ len = (val & PERIOD_MASK) + 1;
}
} else {
if (val & VAL_MASK) {
if (len > AW_IR_DMAX) {
if (bootverbose)
device_printf(sc->dev,
- "Distant error\n");
+ "Distance error, len=%d\n",
+ len);
goto error_code;
} else {
if (len > AW_IR_DMID) {
@@ -282,9 +290,9 @@ aw_ir_decode_packets(struct aw_ir_softc *sc)
break; /* Finish decoding */
}
last = 1;
- len = val & PERIOD_MASK;
+ len = (val & PERIOD_MASK) + 1;
} else
- len += val & PERIOD_MASK;
+ len += (val & PERIOD_MASK) + 1;
}
}
return (code);
@@ -364,7 +372,7 @@ aw_ir_intr(void *arg)
device_printf(sc->dev, "IR code status: %d\n",
stat);
}
- sc->dcnt = 0;
+ aw_ir_buf_reset(sc);
}
if (val & AW_IR_RXINT_ROI_EN) {
/* RX FIFO overflow */
@@ -414,6 +422,7 @@ aw_ir_attach(device_t dev)
sc->fifo_size = 16;
break;
case A13_IR:
+ case A31_IR:
sc->fifo_size = 64;
break;
}
@@ -464,7 +473,8 @@ aw_ir_attach(device_t dev)
&sc->intrhand)) {
bus_release_resources(dev, aw_ir_spec, sc->res);
device_printf(dev, "cannot setup interrupt handler\n");
- return (ENXIO);
+ err = ENXIO;
+ goto error;
}
/* Enable CIR Mode */