예제 #1
0
static int af9015_rc_query(struct dvb_usb_device *d)
{
	struct af9015_state *priv = d->priv;
	int ret;
	u8 buf[17];

	/* read registers needed to detect remote controller code */
	ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
	if (ret)
		goto error;

	/* If any of these are non-zero, assume invalid data */
	if (buf[1] || buf[2] || buf[3])
		return ret;

	/* Check for repeat of previous code */
	if ((priv->rc_repeat != buf[6] || buf[0]) &&
					!memcmp(&buf[12], priv->rc_last, 4)) {
		deb_rc("%s: key repeated\n", __func__);
		rc_keydown(d->rc_dev, priv->rc_keycode, 0);
		priv->rc_repeat = buf[6];
		return ret;
	}

	/* Only process key if canary killed */
	if (buf[16] != 0xff && buf[0] != 0x01) {
		deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
			buf[12], buf[13], buf[14], buf[15]);

		/* Reset the canary */
		ret = af9015_write_reg(d, 0x98e9, 0xff);
		if (ret)
			goto error;

		/* Remember this key */
		memcpy(priv->rc_last, &buf[12], 4);
		if (buf[14] == (u8) ~buf[15]) {
			if (buf[12] == (u8) ~buf[13]) {
				/* NEC */
				priv->rc_keycode = buf[12] << 8 | buf[14];
			} else {
				/* NEC extended*/
				priv->rc_keycode = buf[12] << 16 |
					buf[13] << 8 | buf[14];
			}
		} else {
			/* 32 bit NEC */
			priv->rc_keycode = buf[12] << 24 | buf[13] << 16 |
					buf[14] << 8 | buf[15];
		}
		rc_keydown(d->rc_dev, priv->rc_keycode, 0);
	} else {
		deb_rc("%s: no key press\n", __func__);
		/* Invalidate last keypress */
		/* Not really needed, but helps with debug */
		priv->rc_last[2] = priv->rc_last[3];
	}

	priv->rc_repeat = buf[6];

error:
	if (ret)
		err("%s: failed:%d", __func__, ret);

	return ret;
}
예제 #2
0
static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
{
	return af9015_read_regs(d, addr, val, 1);
}
예제 #3
0
파일: af9015.c 프로젝트: ChineseDr/linux
static int af9015_rc_query(struct dvb_usb_device *d)
{
    struct af9015_state *state = d_to_priv(d);
    int ret;
    u8 buf[17];

    /* read registers needed to detect remote controller code */
    ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
    if (ret)
        goto error;

    /* If any of these are non-zero, assume invalid data */
    if (buf[1] || buf[2] || buf[3]) {
        dev_dbg(&d->udev->dev, "%s: invalid data\n", __func__);
        return ret;
    }

    /* Check for repeat of previous code */
    if ((state->rc_repeat != buf[6] || buf[0]) &&
            !memcmp(&buf[12], state->rc_last, 4)) {
        dev_dbg(&d->udev->dev, "%s: key repeated\n", __func__);
        rc_repeat(d->rc_dev);
        state->rc_repeat = buf[6];
        return ret;
    }

    /* Only process key if canary killed */
    if (buf[16] != 0xff && buf[0] != 0x01) {
        dev_dbg(&d->udev->dev, "%s: key pressed %*ph\n",
                __func__, 4, buf + 12);

        /* Reset the canary */
        ret = af9015_write_reg(d, 0x98e9, 0xff);
        if (ret)
            goto error;

        /* Remember this key */
        memcpy(state->rc_last, &buf[12], 4);
        if (buf[14] == (u8) ~buf[15]) {
            if (buf[12] == (u8) ~buf[13]) {
                /* NEC */
                state->rc_keycode = RC_SCANCODE_NEC(buf[12],
                                                    buf[14]);
            } else {
                /* NEC extended*/
                state->rc_keycode = RC_SCANCODE_NECX(buf[12] << 8 |
                                                     buf[13],
                                                     buf[14]);
            }
        } else {
            /* 32 bit NEC */
            state->rc_keycode = RC_SCANCODE_NEC32(buf[12] << 24 |
                                                  buf[13] << 16 |
                                                  buf[14] << 8  |
                                                  buf[15]);
        }
        rc_keydown(d->rc_dev, RC_TYPE_NEC, state->rc_keycode, 0);
    } else {
        dev_dbg(&d->udev->dev, "%s: no key press\n", __func__);
        /* Invalidate last keypress */
        /* Not really needed, but helps with debug */
        state->rc_last[2] = state->rc_last[3];
    }

    state->rc_repeat = buf[6];
    state->rc_failed = false;

error:
    if (ret) {
        dev_warn(&d->udev->dev, "%s: rc query failed=%d\n",
                 KBUILD_MODNAME, ret);

        /* allow random errors as dvb-usb will stop polling on error */
        if (!state->rc_failed)
            ret = 0;

        state->rc_failed = true;
    }

    return ret;
}