All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Fitzhardinge <jeremy@goop.org>
To: Daniel Nicoletti <dantti12@gmail.com>
Cc: linux-input@vger.kernel.org, Jiri Kosina <jkosina@suse.cz>,
	vojtech@ucw.cz, Przemo Firszt <przemo@firszt.eu>,
	Richard Hughes <richard@hughsie.com>
Subject: Re: [PATCH RFC] hid-input: add support for HID devices reporting Battery Strength
Date: Fri, 02 Dec 2011 09:44:13 -0800	[thread overview]
Message-ID: <4ED90E6D.8090402@goop.org> (raw)
In-Reply-To: <CACo8zOd45i3EnCVMyJoDPP4bx2AnD9mEjDiC=bJKvmX=TWfXGg@mail.gmail.com>

On 12/01/2011 09:52 PM, Daniel Nicoletti wrote:
> I've sent an email earlier asking for help with a GetFeature code, and now I
> have a second patch on top of Jeremy's to provide the battery functionality
> for devices that support reporting it.
>
> If I understood correctly when talking to Jeremy he said his device
> never actually
> reported the status as an input event (sorry if I didn't understand it
> correctly),

No, it does.  When the mouse first connects it reports the battery level
as an Input event.  Without my patch, X sees the battery level as a
strange little absolute axis on the mouse, which it ignores.

I don't know if the mouse also reports the battery later on
spontaneously; I haven't observed it, so I suspect you may be right that
you have to poll it to get further updates.

>  and
> after reading HID specs I believe it's really because it was meant to be probed,
> I have an Apple Keyboard and Magic Trackpad both bluetooth batteries operated,
> so using PacketLogger I saw that Mac OSX always ask the battery status using
> the so called GetFeature.

Could you cite a specific reference?  I don't see any references to
"GetFeature" in HID spec I have.  The closest I see is
"Get_Report(INPUT/OUTPUT/FEATURE)", which specifically says "This
request is not intended to be used for polling the device state on a
regular basis".  Though I'm not at all surprised if device manufacturers
ignore this, or that it is contradictory with some other part of the spec.

> What my patch does is basically:
> - store the report id that matches the battery_strength
> - setup the battery if 0x6.0x20 is found, even if that is reported as a feature
>   (as it was meant to be but only the MagicTrackpad does)
> - when upower or someone access /sys/class/power_supply/hid-*/capacity it
>   will probe the device and return it's status.

How often does usermode read this file?  Does it/can it select on the
file to wait for changes.

Given that battery level shouldn't change that quickly, I wonder if
having a timer poll the device every minute or something of that order
might be useful?

>
> It works great for both devices, but I have two concerns:
> - the report_features function has a duplicated code

Yes, but that's easy to fix.

> - it would be nice if it was possible for specific drivers to provide their own
>   probe as there might be some strange devices... (but maybe it's
> already possible)
I'd wait until there's a device which can't be handled by this mechanism
before trying to generalize it.  Unless we can unify the wacom driver,
but that seems to be in its own little world.

> I've talked to the upower dev and he fixed it to be able to show the
> right percentage.

Cool, but I have some concerns about that (see below).

> Here how the uevent file (in /sys/class/power_supply/hid-*/) looks like:
> POWER_SUPPLY_NAME=hid-00:22:41:D9:18:E7-battery
> POWER_SUPPLY_PRESENT=1
> POWER_SUPPLY_ONLINE=1
> POWER_SUPPLY_CAPACITY=66
> POWER_SUPPLY_MODEL_NAME=MacAdmin’s keyboard
> POWER_SUPPLY_STATUS=Discharging
>
> POWER_SUPPLY_NAME=hid-70:CD:60:F5:FF:3F-battery
> POWER_SUPPLY_PRESENT=1
> POWER_SUPPLY_ONLINE=1
> POWER_SUPPLY_CAPACITY=62
> POWER_SUPPLY_MODEL_NAME=nexx’s Trackpad
> POWER_SUPPLY_STATUS=Discharging
>
> and the patch (note that this is my first kernel patch so sorry if
> formatting is not ok, should I attach it?):
> diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
> index b9b8c75..8fac47c 100644
> --- a/drivers/hid/hid-input.c
> +++ b/drivers/hid/hid-input.c
> @@ -277,6 +277,7 @@ static enum power_supply_property
> hidinput_battery_props[] = {
>  	POWER_SUPPLY_PROP_ONLINE,
>  	POWER_SUPPLY_PROP_CAPACITY,
>  	POWER_SUPPLY_PROP_MODEL_NAME,
> +	POWER_SUPPLY_PROP_STATUS
>  };
>
>  static int hidinput_get_battery_property(struct power_supply *psy,
> @@ -285,6 +286,9 @@ static int hidinput_get_battery_property(struct
> power_supply *psy,
>  {
>  	struct hid_device *dev = container_of(psy, struct hid_device, battery);
>  	int ret = 0;
> +	int ret_rep;
> +	__u8 *buf = NULL;
> +	unsigned char report_number = dev->battery_report_id;
>
>  	switch (prop) {
>  	case POWER_SUPPLY_PROP_PRESENT:
> @@ -293,28 +297,45 @@ static int hidinput_get_battery_property(struct
> power_supply *psy,
>  		break;
>
>  	case POWER_SUPPLY_PROP_CAPACITY:
> -		if (dev->battery_min < dev->battery_max &&
> -		    dev->battery_val >= dev->battery_min &&
> -		    dev->battery_val <= dev->battery_max)
> -			val->intval = (100 * (dev->battery_val - dev->battery_min)) /
> -				(dev->battery_max - dev->battery_min);
> -		else
> +		buf = kmalloc(2 * sizeof(__u8), GFP_KERNEL);

Why allocate a two byte buffer?  Why not just put it on the stack?  How
do you know that's the right size?

> +		if (!buf) {
> +			ret = -ENOMEM;
> +			break;
> +		}
> +
> +		memset(buf, 0, sizeof(buf));
> +		ret_rep = dev->hid_get_raw_report(dev, report_number, buf,
> sizeof(buf), HID_FEATURE_REPORT);
> +		if (ret_rep != 2) {
>  			ret = -EINVAL;
> +			break;
> +		}
> +
> +		/* store the returned value */
> +		/* I'm not calculating this using the logical_minimum and maximum */
> +		/* because my device returns 0-100 even though the min and max are 0-255 */
> +		val->intval = buf[1];

That's definitely not the case for my mouse.  I'm not sure what the
range actually is, but I've seen values reported > 100 with fresh
alkaline batteries.  Initially I also thought it was using a 0-100 range
despite the min/max, and I added a per-device quirk mechanism - but
since my device didn't need it, I did't include it in the patch
posting.  I'd reinstate it if there are devices that report 0-100.

>  		break;
>
>  	case POWER_SUPPLY_PROP_MODEL_NAME:
>  		val->strval = dev->name;
>  		break;
>
> +	case POWER_SUPPLY_PROP_STATUS:
> +		val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> +		break;
> +
>  	default:
>  		ret = -EINVAL;
>  		break;
>  	}
>
> +	if (buf) {
> +		kfree(buf);
> +	}
>  	return ret;
>  }
>
> -static void hidinput_setup_battery(struct hid_device *dev, s32 min, s32 max)
> +static void hidinput_setup_battery(struct hid_device *dev, unsigned
> id, s32 min, s32 max)
>  {
>  	struct power_supply *battery = &dev->battery;
>  	int ret;
> @@ -326,7 +347,7 @@ static void hidinput_setup_battery(struct
> hid_device *dev, s32 min, s32 max)
>  	if (battery->name == NULL)
>  		return;
>
> -	battery->type = POWER_SUPPLY_TYPE_BATTERY;
> +	battery->type = POWER_SUPPLY_TYPE_USB;

What's the purpose of this?  Is it to make upower behave in a
different/better way?  My reading is that this means that it's powered
by USB ("Standard Downstream Port").  A bluetooth device doesn't have
any USB involved at all (except if the BT adapter itself is USB, which
is moot).

If upower is getting confused thinking that a "battery" is necessarily a
laptop battery, then I think it needs to be fixed to pay closer
attention to the device tree topology.

(looks up upower) Ah, I see.

The changes in the current upower.git look very suspect to me, if
nothing else because of the hard-coded "magicmouse" and "wacom", and the
use of POWER_SUPPLY_TYPE_USB.  Can upower not look to see if there's a
power-supply hanging off a HID device and report that as peripheral power?

> -	if (!drv->feature_mapping)
> -		return;
> -
>  	rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
>  	list_for_each_entry(rep, &rep_enum->report_list, list)
>  		for (i = 0; i < rep->maxfield; i++)
> -			for (j = 0; j < rep->field[i]->maxusage; j++)
> -				drv->feature_mapping(hid, rep->field[i],
> -						     rep->field[i]->usage + j);
> +			for (j = 0; j < rep->field[i]->maxusage; j++) {
> +				/* Verify if Battery Strength feature is available */
> +				if (((rep->field[i]->usage + j)->hid & HID_USAGE_PAGE) ==
> HID_UP_GENDEVCTRLS &&
> +					((rep->field[i]->usage + j)->hid & HID_USAGE) == 0x20) {
> +					hidinput_setup_battery(hid,
> +							       rep->id,
> +							       rep->field[i]->logical_minimum,
> +							       rep->field[i]->logical_maximum);
> +				}
> +
> +				if (drv->feature_mapping)
> +					drv->feature_mapping(hid, rep->field[i],
> +							     rep->field[i]->usage + j);
> +			}
I'd be inclined to split all this out into a separate function, so that
you can make it common with the code on the input path.

    J
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2011-12-02 17:44 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-11-19  6:52 Supporting Battery Strength from my Bluetooth Mouse Jeremy Fitzhardinge
2011-11-19 11:18 ` Jiri Kosina
2011-11-19 21:34   ` Jeremy Fitzhardinge
2011-11-20 10:26     ` Jiri Kosina
2011-11-21 16:38       ` Jeremy Fitzhardinge
2011-11-21 17:36         ` Dmitry Torokhov
2011-11-21 17:49           ` Jeremy Fitzhardinge
2011-11-21 23:29         ` Jiri Kosina
2011-11-21 23:34           ` Jeremy Fitzhardinge
2011-11-22  0:03             ` Jiri Kosina
2011-11-23  8:49               ` [PATCH RFC] hid-input: add support for HID devices reporting Battery Strength Jeremy Fitzhardinge
2011-11-23 16:36                 ` Chase Douglas
2011-11-23 21:07                   ` Jeremy Fitzhardinge
2011-11-23 21:52                     ` Przemo Firszt
2011-11-28 21:33                 ` Jiri Kosina
2011-12-02  5:52                   ` Daniel Nicoletti
2011-12-02 17:44                     ` Jeremy Fitzhardinge [this message]
2011-12-02 18:29                       ` Daniel Nicoletti
2011-12-03  6:09                         ` Jeremy Fitzhardinge
2011-12-03  6:13                         ` [GIT PULL RFC] directly poll battery strength when reading power_supply Jeremy Fitzhardinge
2011-12-06  9:17                           ` Jiri Kosina
2011-12-08  1:56                             ` Jeremy Fitzhardinge
2012-05-19  4:10                               ` Daniel Nicoletti
2011-12-06  9:56                           ` Richard Hughes
2011-12-06 17:10                             ` Jeremy Fitzhardinge
2011-12-07 12:51                               ` Richard Hughes
2011-12-07 17:25                                 ` Jeremy Fitzhardinge
2011-12-07 17:29                                   ` Richard Hughes
2011-12-07 17:36                                     ` Jeremy Fitzhardinge
2011-12-07 17:41                                       ` Richard Hughes
2011-12-08  1:41                                     ` [GIT PULL] power_supply: add power supply scope Jeremy Fitzhardinge
2011-12-08  1:41                                       ` Jeremy Fitzhardinge
2011-12-08 10:02                                       ` Anton Vorontsov
2011-12-08 10:05                                         ` Richard Hughes
2011-12-08 10:42                                           ` Anton Vorontsov
2011-12-08 10:41                                       ` Anton Vorontsov
2011-12-08 16:53                                         ` Jeremy Fitzhardinge
2011-12-08 23:36                                           ` Anton Vorontsov
2011-12-09  8:18                                             ` Jeremy Fitzhardinge
2011-12-09  9:59                                               ` Anton Vorontsov
2011-12-09 16:58                                                 ` Jeremy Fitzhardinge
2011-12-09 10:17                                       ` Anton Vorontsov
2011-12-09 17:49                                         ` Jeremy Fitzhardinge
2011-12-09 20:00                                           ` Daniel Nicoletti
2011-12-09 20:36                                             ` Jeremy Fitzhardinge
2011-12-02 17:58                     ` [PATCH RFC] hid-input: add support for HID devices reporting Battery Strength Jeremy Fitzhardinge

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=4ED90E6D.8090402@goop.org \
    --to=jeremy@goop.org \
    --cc=dantti12@gmail.com \
    --cc=jkosina@suse.cz \
    --cc=linux-input@vger.kernel.org \
    --cc=przemo@firszt.eu \
    --cc=richard@hughsie.com \
    --cc=vojtech@ucw.cz \
    /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.