All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oliver Neukum <oliver@neukum.org>
To: Bastien Nocera <hadess@hadess.net>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	linux-input <linux-input@vger.kernel.org>,
	Jiri Kosina <jkosina@suse.cz>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: Re: [RESEND] [PATCH] Input: add appleir USB driver
Date: Mon, 4 Oct 2010 21:17:41 +0200	[thread overview]
Message-ID: <201010042117.41786.oliver@neukum.org> (raw)
In-Reply-To: <1285844276.26405.26.camel@cookie.hadess.net>

Am Donnerstag, 30. September 2010, 12:57:55 schrieb Bastien Nocera:

> +static int get_key(int data)
> +{
> +	switch (data) {
> +	case 0x02:
> +	case 0x03:
> +		/* menu */
> +		return 1;
> +	case 0x04:
> +	case 0x05:
> +		/* >" */
> +		return 2;
> +	case 0x06:
> +	case 0x07:
> +		/* >> */
> +		return 3;
> +	case 0x08:
> +	case 0x09:
> +		/* << */
> +		return 4;
> +	case 0x0a:
> +	case 0x0b:
> +		/* + */
> +		return 5;
> +	case 0x0c:
> +	case 0x0d:
> +		/* - */
> +		return 6;
> +	case 0x5c:
> +		/* Middle button, on newer remotes,
> +		 * part of a 2 packet-command */
> +		return -7;
> +	default:
> +		return -1;
> +	}

Is this really better than a table lookup?


> +
> +static void new_data(struct appleir *appleir, u8 *data, int len)
> +{
> +	static const u8 keydown[] = { 0x25, 0x87, 0xee };
> +	static const u8 keyrepeat[] = { 0x26, };
> +	static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 };
> +
> +	if (debug)
> +		dump_packet(appleir, "received", data, len);
> +
> +	if (len != 5)
> +		return;
> +
> +	if (!memcmp(data, keydown, sizeof(keydown))) {
> +		int index;
> +
> +		/* If we already have a key down, take it up before marking
> +		   this one down */
> +		if (appleir->current_key)
> +			key_up(appleir, appleir->current_key);

This races with the timer. You can end up with a key reported up twice.

> +		/* Handle dual packet commands */
> +		if (appleir->prev_key_idx > 0)
> +			index = appleir->prev_key_idx;
> +		else
> +			index = get_key(data[4]);
> +
> +		if (index > 0) {
> +			appleir->current_key = appleir->keymap[index];
> +
> +			key_down(appleir, appleir->current_key);
> +			/* Remote doesn't do key up, either pull them up, in the test
> +			   above, or here set a timer which pulls them up after 1/8 s */
> +			mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
> +			appleir->prev_key_idx = 0;
> +			return;
> +		} else if (index == -7) {
> +			/* Remember key for next packet */
> +			appleir->prev_key_idx = 0 - index;
> +			return;
> +		}
> +	}


> +static int appleir_open(struct input_dev *dev)
> +{
> +	struct appleir *appleir = input_get_drvdata(dev);
> +	struct usb_interface *intf = usb_ifnum_to_if(appleir->usbdev, 0);
> +	int r;
> +
> +	r = usb_autopm_get_interface(intf);
> +	if (r) {
> +		dev_err(&intf->dev,
> +			"%s(): usb_autopm_get_interface() = %d\n", __func__, r);
> +		return r;
> +	}
> +
> +	mutex_lock(&appleir_mutex);
> +
> +	if (usb_submit_urb(appleir->urb, GFP_ATOMIC)) {

No need for ATOMIC

> +		r = -EIO;
> +		goto fail;
> +	}
> +
> +	appleir->flags |= APPLEIR_OPENED;
> +
> +	mutex_unlock(&appleir_mutex);
> +
> +	usb_autopm_put_interface(intf);

This does not enable remote wakeup. Why? Looks like a bug.

> +	return 0;
> +fail:
> +	mutex_unlock(&appleir_mutex);
> +	usb_autopm_put_interface(intf);
> +	return r;
> +}
> +
> +static void appleir_close(struct input_dev *dev)
> +{
> +	struct appleir *appleir = input_get_drvdata(dev);
> +
> +	mutex_lock(&appleir_mutex);
> +
> +	if (!(appleir->flags & APPLEIR_SUSPENDED)) {
> +		usb_kill_urb(appleir->urb);
> +		del_timer_sync(&appleir->key_up_timer);

You can close with a key unreleased.

> +	}
> +
> +	appleir->flags &= ~APPLEIR_OPENED;
> +
> +	mutex_unlock(&appleir_mutex);
> +}
> +


> +static int appleir_suspend(struct usb_interface *interface,
> +			   pm_message_t message)
> +{
> +	struct appleir *appleir = usb_get_intfdata(interface);
> +
> +	mutex_lock(&appleir_mutex);
> +	if (appleir->flags & APPLEIR_OPENED)

Why bother checking?

> +		usb_kill_urb(appleir->urb);

If the system goes to sleep you'd better report a pressed key
as released here and kill the timer.
> +
> +	appleir->flags |= APPLEIR_SUSPENDED;
> +
> +	mutex_unlock(&appleir_mutex);
> +
> +	return 0;
> +}
> +
> +static int appleir_resume(struct usb_interface *interface)
> +{
> +	struct appleir *appleir;
> +	int r = 0;
> +
> +	appleir = usb_get_intfdata(interface);
> +
> +	mutex_lock(&appleir_mutex);
> +	if (appleir->flags & APPLEIR_OPENED) {
> +		struct usb_endpoint_descriptor *endpoint;
> +
> +		endpoint = &interface->cur_altsetting->endpoint[0].desc;
> +		usb_fill_int_urb(appleir->urb, appleir->usbdev,
> +				 usb_rcvintpipe(appleir->usbdev, endpoint->bEndpointAddress),
> +				 appleir->data, 8,
> +				 appleir_urb, appleir, endpoint->bInterval);
> +		appleir->urb->transfer_dma = appleir->dma_buf;
> +		appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
> +
> +		/* And reset the USB device */
> +		if (usb_submit_urb(appleir->urb, GFP_ATOMIC))

GFP_NOIO is sufficient.

> +static struct usb_driver appleir_driver = {
> +	.name                 = "appleir",
> +	.probe                = appleir_probe,
> +	.disconnect           = appleir_disconnect,
> +	.suspend              = appleir_suspend,
> +	.resume               = appleir_resume,
> +	.reset_resume         = appleir_resume,
> +	.id_table             = appleir_ids,

If you want runtime power management you need to define
supports_autosuspend.

	Regards
		Oliver

  parent reply	other threads:[~2010-10-04 19:16 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-30 10:57 [RESEND] [PATCH] Input: add appleir USB driver Bastien Nocera
2010-09-30 15:47 ` Dmitry Torokhov
2010-09-30 15:51   ` Bastien Nocera
2010-10-08  0:39     ` Jarod Wilson
2010-11-18  4:18       ` Bastien Nocera
2010-11-19 18:07         ` Jarod Wilson
2010-10-04 19:17 ` Oliver Neukum [this message]
2010-10-05  4:45   ` Dmitry Torokhov
2010-10-05  6:02     ` Oliver Neukum
2010-10-05  6:08       ` Dmitry Torokhov
2010-10-05  6:18         ` Oliver Neukum
2010-10-05 15:55           ` Dmitry Torokhov
2010-10-05 16:07             ` Oliver Neukum
2010-10-05 16:18               ` Dmitry Torokhov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201010042117.41786.oliver@neukum.org \
    --to=oliver@neukum.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=hadess@hadess.net \
    --cc=jkosina@suse.cz \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.