示例#1
0
static int m920x_rc_core_query(struct dvb_usb_device *d)
{
	int ret = 0;
	u8 *rc_state;
	int state;

	rc_state = kmalloc(2, GFP_KERNEL);
	if (!rc_state)
		return -ENOMEM;

	if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, &rc_state[0], 1)) != 0)
		goto out;

	if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, &rc_state[1], 1)) != 0)
		goto out;

	deb("state=0x%02x keycode=0x%02x\n", rc_state[0], rc_state[1]);

	m920x_parse_rc_state(d, rc_state[0], &state);

	if (state == REMOTE_NO_KEY_PRESSED)
		rc_keyup(d->rc_dev);
	else if (state == REMOTE_KEY_REPEAT)
		rc_repeat(d->rc_dev);
	else
		rc_keydown(d->rc_dev, RC_PROTO_UNKNOWN, rc_state[1], 0);

out:
	kfree(rc_state);
	return ret;
}
示例#2
0
/* I2C */
static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
{
	struct dvb_usb_device *d = i2c_get_adapdata(adap);
	int i, j;
	int ret = 0;

	if (!num)
		return -EINVAL;

	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

	for (i = 0; i < num; i++) {
		if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
			/* For a 0 byte message, I think sending the address
			 * to index 0x80|0x40 would be the correct thing to
			 * do.  However, zero byte messages are only used for
			 * probing, and since we don't know how to get the
			 * slave's ack, we can't probe. */
			ret = -ENOTSUPP;
			goto unlock;
		}
		/* Send START & address/RW bit */
		if (!(msg[i].flags & I2C_M_NOSTART)) {
			if ((ret = m920x_write(d->udev, M9206_I2C,
					(msg[i].addr << 1) |
					(msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
				goto unlock;
			/* Should check for ack here, if we knew how. */
		}
		if (msg[i].flags & I2C_M_RD) {
			for (j = 0; j < msg[i].len; j++) {
				/* Last byte of transaction?
				 * Send STOP, otherwise send ACK. */
				int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;

				if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
						      0x20 | stop,
						      &msg[i].buf[j], 1)) != 0)
					goto unlock;
			}
		} else {
			for (j = 0; j < msg[i].len; j++) {
				/* Last byte of transaction? Then send STOP. */
				int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;

				if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
					goto unlock;
				/* Should check for ack here too. */
			}
		}
	}
	ret = num;

 unlock:
	mutex_unlock(&d->i2c_mutex);

	return ret;
}
示例#3
0
static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
	int i, ret = 0;
	u8 *rc_state;

	rc_state = kmalloc(2, GFP_KERNEL);
	if (!rc_state)
		return -ENOMEM;

	ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE,
			 rc_state, 1);
	if (ret != 0)
		goto out;

	ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY,
			 rc_state + 1, 1);
	if (ret != 0)
		goto out;

	m920x_parse_rc_state(d, rc_state[0], state);

	for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
		if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
			*event = d->props.rc.legacy.rc_map_table[i].keycode;
			goto out;
		}

	if (rc_state[1] != 0)
		deb("Unknown rc key %02x\n", rc_state[1]);

	*state = REMOTE_NO_KEY_PRESSED;

 out:
	kfree(rc_state);
	return ret;
}
示例#4
0
static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
{
	u16 value, index, size;
	u8 *read, *buff;
	int i, pass, ret = 0;

	buff = kmalloc(65536, GFP_KERNEL);
	if (buff == NULL)
		return -ENOMEM;

	read = kmalloc(4, GFP_KERNEL);
	if (!read) {
		kfree(buff);
		return -ENOMEM;
	}

	if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
		goto done;
	deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);

	if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
		goto done;
	deb("%x\n", read[0]);

	for (pass = 0; pass < 2; pass++) {
		for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
			value = get_unaligned_le16(fw->data + i);
			i += sizeof(u16);

			index = get_unaligned_le16(fw->data + i);
			i += sizeof(u16);

			size = get_unaligned_le16(fw->data + i);
			i += sizeof(u16);

			if (pass == 1) {
				/* Will stall if using fw->data ... */
				memcpy(buff, fw->data + i, size);

				ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
						      M9206_FW,
						      USB_TYPE_VENDOR | USB_DIR_OUT,
						      value, index, buff, size, 20);
				if (ret != size) {
					deb("error while uploading fw!\n");
					ret = -EIO;
					goto done;
				}
				msleep(3);
			}
			i += size;
		}
		if (i != fw->size) {
			deb("bad firmware file!\n");
			ret = -EINVAL;
			goto done;
		}
	}

	msleep(36);

	/* m920x will disconnect itself from the bus after this. */
	(void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
	deb("firmware uploaded!\n");

 done:
	kfree(read);
	kfree(buff);

	return ret;
}
示例#5
0
static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
	struct m920x_state *m = d->priv;
	int i, ret = 0;
	u8 *rc_state;

	rc_state = kmalloc(2, GFP_KERNEL);
	if (!rc_state)
		return -ENOMEM;

	if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
		goto out;

	if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
		goto out;

	for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
		if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
			*event = d->props.rc.legacy.rc_map_table[i].keycode;

			switch(rc_state[0]) {
			case 0x80:
				*state = REMOTE_NO_KEY_PRESSED;
				goto out;

			case 0x88: /* framing error or "invalid code" */
			case 0x99:
			case 0xc0:
			case 0xd8:
				*state = REMOTE_NO_KEY_PRESSED;
				m->rep_count = 0;
				goto out;

			case 0x93:
			case 0x92:
			case 0x83: /* pinnacle PCTV310e */
			case 0x82:
				m->rep_count = 0;
				*state = REMOTE_KEY_PRESSED;
				goto out;

			case 0x91:
			case 0x81: /* pinnacle PCTV310e */
				/* prevent immediate auto-repeat */
				if (++m->rep_count > 2)
					*state = REMOTE_KEY_REPEAT;
				else
					*state = REMOTE_NO_KEY_PRESSED;
				goto out;

			default:
				deb("Unexpected rc state %02x\n", rc_state[0]);
				*state = REMOTE_NO_KEY_PRESSED;
				goto out;
			}
		}

	if (rc_state[1] != 0)
		deb("Unknown rc key %02x\n", rc_state[1]);

	*state = REMOTE_NO_KEY_PRESSED;

 out:
	kfree(rc_state);
	return ret;
}