* Re: [PATCH] typo fixes (coordiante -> coordinate) in am335x
From: Jan Lübbe @ 2013-10-19 16:02 UTC (permalink / raw)
To: Tony Lindgren, Samuel Ortiz, Lee Jones
Cc: linux-doc, linux-kernel, Zubair Lutfullah, linux-input,
linux-omap, linux-arm-kernel
In-Reply-To: <20130821075828.GZ7656@atomide.com>
On Wed, 2013-08-21 at 00:58 -0700, Tony Lindgren wrote:
> * Zubair Lutfullah <zubair.lutfullah@gmail.com> [130715 08:33]:
> > Did a grep for coordiante and replaced them all
> > with coordinate.
> >
> > This applies to the mfd-next tree.
>
> This should be safe to apply via the MFD tree as a non-critical
> fix assuming the bootloaders are not yet using this:
>
> Acked-by: Tony Lindgren <tony@atomide.com>
It seems this didn't get applied. It fixes the touchscreen on a
BeagleBone black with the 7" LCD and we should avoid having people use
the wrong binding.
Samuel or Lee: Could you take this patch?
Thanks,
Jan Lübbe
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] Input: move name/timer init to input_alloc_dev()
From: David Herrmann @ 2013-10-19 10:37 UTC (permalink / raw)
To: open list:HID CORE LAYER; +Cc: Dmitry Torokhov, David Herrmann
In-Reply-To: <1380731263-20962-1-git-send-email-dh.herrmann@gmail.com>
ping
On Wed, Oct 2, 2013 at 6:27 PM, David Herrmann <dh.herrmann@gmail.com> wrote:
> We want to allow drivers to call input_event() at any time after the
> device got allocated. This means input_event() and input_register_device()
> must be allowed to run in parallel.
>
> The only conflicting calls in input_register_device() are init_timer() and
> dev_set_name(). Both can safely be moved to device allocation and we're
> good to go.
>
> Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
> ---
> drivers/input/input.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index c044699..e75d015 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -1734,6 +1734,7 @@ EXPORT_SYMBOL_GPL(input_class);
> */
> struct input_dev *input_allocate_device(void)
> {
> + static atomic_t input_no = ATOMIC_INIT(0);
> struct input_dev *dev;
>
> dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
> @@ -1743,9 +1744,13 @@ struct input_dev *input_allocate_device(void)
> device_initialize(&dev->dev);
> mutex_init(&dev->mutex);
> spin_lock_init(&dev->event_lock);
> + init_timer(&dev->timer);
> INIT_LIST_HEAD(&dev->h_list);
> INIT_LIST_HEAD(&dev->node);
>
> + dev_set_name(&dev->dev, "input%ld",
> + (unsigned long) atomic_inc_return(&input_no) - 1);
> +
> __module_get(THIS_MODULE);
> }
>
> @@ -2019,7 +2024,6 @@ static void devm_input_device_unregister(struct device *dev, void *res)
> */
> int input_register_device(struct input_dev *dev)
> {
> - static atomic_t input_no = ATOMIC_INIT(0);
> struct input_devres *devres = NULL;
> struct input_handler *handler;
> unsigned int packet_size;
> @@ -2059,7 +2063,6 @@ int input_register_device(struct input_dev *dev)
> * If delay and period are pre-set by the driver, then autorepeating
> * is handled by the driver itself and we don't do it in input.c.
> */
> - init_timer(&dev->timer);
> if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
> dev->timer.data = (long) dev;
> dev->timer.function = input_repeat_key;
> @@ -2073,9 +2076,6 @@ int input_register_device(struct input_dev *dev)
> if (!dev->setkeycode)
> dev->setkeycode = input_default_setkeycode;
>
> - dev_set_name(&dev->dev, "input%ld",
> - (unsigned long) atomic_inc_return(&input_no) - 1);
> -
> error = device_add(&dev->dev);
> if (error)
> goto err_free_vals;
> --
> 1.8.4
>
^ permalink raw reply
* Re: [PATCH 1/1] HID: wiimote: invert Y-Axis and add automatic calibration for Wii U Pro Controller
From: David Herrmann @ 2013-10-19 10:35 UTC (permalink / raw)
To: Rafael Brune; +Cc: open list:HID CORE LAYER
In-Reply-To: <121A2CAD-9706-4A86-AF20-60B25DF00101@rbrune.de>
Hi
On Thu, Oct 10, 2013 at 5:46 PM, Rafael Brune <mail@rbrune.de> wrote:
> Hi
>
> On Oct 10, 2013, at 11:16 AM, David Herrmann wrote:
>
>> Hi
>>
>> On Sun, Oct 6, 2013 at 8:44 PM, Rafael Brune <mail@rbrune.de> wrote:
>>> With these changes the Wii U Pro Controller fully complies
>>> to the gamepad-API and with the calibration is fully usable
>>> out-of-the-box without any user-space tools. This potentially
>>> breaks compatibility with software that relies on the two
>>> inverted Y-Axis but since current bluez 4.x and 5.x versions
>>> don't even support pairing with the controller yet the amount
>>> of people affected should be rather small.
>>
>> Did anyone try to read the calibration values from the EEPROM? Doing
>> calibration in the kernel is fine, but I'd rather have the
>> hardware-calibration values instead. Even if we cannot figure it out
>> now, we should try to stay as compatible to the real values as we can.
>>
>> So how about keeping the min/max and neutral point as we have it know
>> and instead adjusting the reported values by scaling/moving them?
>>
>
> After googling a little bit it seems like their might actually be no
> calibration data for the Classic Controller and Wii U Pro Controller. The
> midpoint is supposedly just detected when the device connects.
> http://wiibrew.org/wiki/Classic_Controller
I tried to digg into the EEPROM data and indeed, there seems to be no
calibration data. The pro-controller doesn't even provide a classic
EEPROM (it fails on EEPROM read/write).
> My code did not change what we output as the min/max/mid values it's
> still -0x800,0x000,0x800. As you suggest it scales/moves the raw values
> so that the reported values fall into that range.
Yepp, sorry, misread the patch.
>
>>> Signed-off-by: Rafael Brune <mail@rbrune.de>
>>> ---
>>> drivers/hid/hid-wiimote-modules.c | 45 +++++++++++++++++++++++++++++++++++----
>>> 1 file changed, 41 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
>>> index 2e7d644..1422b0b 100644
>>> --- a/drivers/hid/hid-wiimote-modules.c
>>> +++ b/drivers/hid/hid-wiimote-modules.c
>>> @@ -1640,10 +1640,41 @@ static void wiimod_pro_in_ext(struct wiimote_data *wdata, const __u8 *ext)
>>> ly = (ext[4] & 0xff) | ((ext[5] & 0x0f) << 8);
>>> ry = (ext[6] & 0xff) | ((ext[7] & 0x0f) << 8);
>>>
>>> - input_report_abs(wdata->extension.input, ABS_X, lx - 0x800);
>>> - input_report_abs(wdata->extension.input, ABS_Y, ly - 0x800);
>>> - input_report_abs(wdata->extension.input, ABS_RX, rx - 0x800);
>>> - input_report_abs(wdata->extension.input, ABS_RY, ry - 0x800);
>>> + /* Calibrating the sticks by saving the global min/max per axis */
>>> + if (lx < wdata->state.calib_bboard[0][0])
>>> + wdata->state.calib_bboard[0][0] = lx;
>>> + if (lx > wdata->state.calib_bboard[0][1])
>>> + wdata->state.calib_bboard[0][1] = lx;
>>> +
>>> + if (ly < wdata->state.calib_bboard[1][0])
>>> + wdata->state.calib_bboard[1][0] = ly;
>>> + if (ly > wdata->state.calib_bboard[1][1])
>>> + wdata->state.calib_bboard[1][1] = ly;
>>> +
>>> + if (rx < wdata->state.calib_bboard[2][0])
>>> + wdata->state.calib_bboard[2][0] = rx;
>>> + if (rx > wdata->state.calib_bboard[2][1])
>>> + wdata->state.calib_bboard[2][1] = rx;
>>> +
>>> + if (ry < wdata->state.calib_bboard[3][0])
>>> + wdata->state.calib_bboard[3][0] = ry;
>>> + if (ry > wdata->state.calib_bboard[3][1])
>>> + wdata->state.calib_bboard[3][1] = ry;
>>> +
>>> + /* Normalize using int math to prevent conversion to/from float */
>>> + lx = -2048 + (((__s32)(lx - wdata->state.calib_bboard[0][0]) * 4096)/
>>> + (wdata->state.calib_bboard[0][1]-wdata->state.calib_bboard[0][0]));
>>> + ly = -2048 + (((__s32)(ly - wdata->state.calib_bboard[1][0]) * 4096)/
>>> + (wdata->state.calib_bboard[1][1]-wdata->state.calib_bboard[1][0]));
>>> + rx = -2048 + (((__s32)(rx - wdata->state.calib_bboard[2][0]) * 4096)/
>>> + (wdata->state.calib_bboard[2][1]-wdata->state.calib_bboard[2][0]));
>>> + ry = -2048 + (((__s32)(ry - wdata->state.calib_bboard[3][0]) * 4096)/
>>> + (wdata->state.calib_bboard[3][1]-wdata->state.calib_bboard[3][0]));
>>
>> Don't use calib_bboard. Add a new array (or use a union). This is confusing.
>
> I agree, will do that.
>
>
>>> +
>>> + input_report_abs(wdata->extension.input, ABS_X, lx);
>>> + input_report_abs(wdata->extension.input, ABS_Y, -ly);
>>> + input_report_abs(wdata->extension.input, ABS_RX, rx);
>>> + input_report_abs(wdata->extension.input, ABS_RY, -ry);
>>>
>>> input_report_key(wdata->extension.input,
>>> wiimod_pro_map[WIIMOD_PRO_KEY_RIGHT],
>>> @@ -1760,6 +1791,12 @@ static int wiimod_pro_probe(const struct wiimod_ops *ops,
>>> if (!wdata->extension.input)
>>> return -ENOMEM;
>>>
>>> + /* Initialize min/max values for all Axis with reasonable values */
>>> + for (i = 0; i < 4; ++i) {
>>> + wdata->state.calib_bboard[i][0] = 0x780;
>>> + wdata->state.calib_bboard[i][1] = 0x880;
>>
>> Ugh, these values look weird. We have a reported range of -0x400 to
>> +0x400 but you limit it to a virtual range of 0x100. That's a loss of
>> precision of 80%. Where are these values from?
>
> I picked these values arbitrarily as starting points since they will update
> during use of the gamepad as soon as lower/higher values are observed.
> As soon as the sticks have been moved to their extreme positions once
> everything is perfect.
>
> We could also set those values in a similar fashion as to what Nintendo
> seems to be doing. Wait for a first report of raw values, use them as the
> mid point and set these min/max values as midpoint +/- ~0x800.
There is no "first report". There is no guarantee that the first
report I receive in the driver is really the first report from the
device (unreliable transmission).
That leaves us with heuristics to detect the neutral point.
>
>>> + }
>>> +
>>> set_bit(FF_RUMBLE, wdata->extension.input->ffbit);
>>> input_set_drvdata(wdata->extension.input, wdata);
>>
>> Thanks for hacking this up. Could you give me some values from your
>> device so I can see how big the deviation is? My device reports:
>>
>> Range: 0-4095 (0x0fff)
>> Neutral-Point: 2048 (0x800)
>>
>> I haven't seen any big deviations from these values. I can try to take
>> this over if you want, just let me know.
>>
>> Thanks
>> David
>
>
> When I write out the observed raw min/max values of all Axis I get these:
> LX: 1033 - 3326 (center~=2179 (0x883))
> LY: 857 - 3211 (center~=2034 (0x7F2))
> RX: 944 - 3176 (center~=2060 (0x80C))
> RY: 853 - 3159 (center~=2006 (0x7D6))
>
> So not really the whole range of 0x0FFF is actually used and offsets due
> to manufacturing differences are present.
Ok, so you have the same values as I do, just some different offsets.
So what I'd do is first swap the axes, then change the min/max to 1200
(or something like that) instead of 2048 and then add heuristics for
neutral-point detection.
For neutral-point detection, I would add a dynamic offset to the
driver which is adjusted during runtime. Some heuristics like if a
report stays the same for 5 continuous reports and is in the range
1700-2300, I'd take it as new neutral-point (or shift the neutral
point in its direction). I will try to get something working.. Ideas
welcome. But I don't like the "first report" approach, as it may be
_way_ off.
Thanks
David
^ permalink raw reply
* Re: [patch] HID: logitech-dj: small cleanup in rdcat()
From: walter harms @ 2013-10-19 9:46 UTC (permalink / raw)
To: Dan Carpenter; +Cc: Jiri Kosina, linux-input, kernel-janitors
In-Reply-To: <20131019090859.GD9312@longonot.mountain>
Am 19.10.2013 11:08, schrieb Dan Carpenter:
> We could pass the "rdsec" pointer instead of the address of the "rdesc"
> and it's a little simpler.
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
>
> diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
> index 2e53024..a7947d8 100644
> --- a/drivers/hid/hid-logitech-dj.c
> +++ b/drivers/hid/hid-logitech-dj.c
> @@ -542,9 +542,9 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
> return 0;
> }
>
> -static void rdcat(char **rdesc, unsigned int *rsize, const char *data, unsigned int size)
> +static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size)
> {
> - memcpy(*rdesc + *rsize, data, size);
> + memcpy(rdesc + *rsize, data, size);
> *rsize += size;
> }
That improves readability nicely, an other point is that the function hides the change of rsize.
IMHO it would be better either to return the new address or do the whole add on the caller
side:
suggestion 1:
rsize = rdcat();
suggestion 2:
rsize += rdcat();
Here you see immediately the new offset.
i know it is a matter of taste, it is just what i would do.
re,
wh
>
> @@ -567,31 +567,31 @@ static int logi_dj_ll_parse(struct hid_device *hid)
> if (djdev->reports_supported & STD_KEYBOARD) {
> dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n",
> __func__, djdev->reports_supported);
> - rdcat(&rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
> + rdcat(rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
> }
>
> if (djdev->reports_supported & STD_MOUSE) {
> dbg_hid("%s: sending a mouse descriptor, reports_supported: "
> "%x\n", __func__, djdev->reports_supported);
> - rdcat(&rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor));
> + rdcat(rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor));
> }
>
> if (djdev->reports_supported & MULTIMEDIA) {
> dbg_hid("%s: sending a multimedia report descriptor: %x\n",
> __func__, djdev->reports_supported);
> - rdcat(&rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
> + rdcat(rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
> }
>
> if (djdev->reports_supported & POWER_KEYS) {
> dbg_hid("%s: sending a power keys report descriptor: %x\n",
> __func__, djdev->reports_supported);
> - rdcat(&rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
> + rdcat(rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
> }
>
> if (djdev->reports_supported & MEDIA_CENTER) {
> dbg_hid("%s: sending a media center report descriptor: %x\n",
> __func__, djdev->reports_supported);
> - rdcat(&rdesc, &rsize, media_descriptor, sizeof(media_descriptor));
> + rdcat(rdesc, &rsize, media_descriptor, sizeof(media_descriptor));
> }
>
> if (djdev->reports_supported & KBD_LEDS) {
> --
> To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [patch] HID: logitech-dj: small cleanup in rdcat()
From: Dan Carpenter @ 2013-10-19 9:08 UTC (permalink / raw)
To: Jiri Kosina; +Cc: linux-input, kernel-janitors
We could pass the "rdsec" pointer instead of the address of the "rdesc"
and it's a little simpler.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 2e53024..a7947d8 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -542,9 +542,9 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
return 0;
}
-static void rdcat(char **rdesc, unsigned int *rsize, const char *data, unsigned int size)
+static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size)
{
- memcpy(*rdesc + *rsize, data, size);
+ memcpy(rdesc + *rsize, data, size);
*rsize += size;
}
@@ -567,31 +567,31 @@ static int logi_dj_ll_parse(struct hid_device *hid)
if (djdev->reports_supported & STD_KEYBOARD) {
dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n",
__func__, djdev->reports_supported);
- rdcat(&rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
+ rdcat(rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
}
if (djdev->reports_supported & STD_MOUSE) {
dbg_hid("%s: sending a mouse descriptor, reports_supported: "
"%x\n", __func__, djdev->reports_supported);
- rdcat(&rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor));
+ rdcat(rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor));
}
if (djdev->reports_supported & MULTIMEDIA) {
dbg_hid("%s: sending a multimedia report descriptor: %x\n",
__func__, djdev->reports_supported);
- rdcat(&rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
+ rdcat(rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
}
if (djdev->reports_supported & POWER_KEYS) {
dbg_hid("%s: sending a power keys report descriptor: %x\n",
__func__, djdev->reports_supported);
- rdcat(&rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
+ rdcat(rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
}
if (djdev->reports_supported & MEDIA_CENTER) {
dbg_hid("%s: sending a media center report descriptor: %x\n",
__func__, djdev->reports_supported);
- rdcat(&rdesc, &rsize, media_descriptor, sizeof(media_descriptor));
+ rdcat(rdesc, &rsize, media_descriptor, sizeof(media_descriptor));
}
if (djdev->reports_supported & KBD_LEDS) {
^ permalink raw reply related
* [PATCH] Input: wacom - add support for ISDv4 0x10E sensor
From: Jason Gerecke @ 2013-10-18 17:41 UTC (permalink / raw)
To: linux-input, linuxwacom-devel, dmitry.torokhov; +Cc: Jason Gerecke
Used in the Fujitsu T732
Signed-off-by: Jason Gerecke <killertofu@gmail.com>
---
drivers/input/tablet/wacom_wac.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 1cbc4bb..782c253 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -2126,6 +2126,9 @@ static const struct wacom_features wacom_features_0x101 =
static const struct wacom_features wacom_features_0x10D =
{ "Wacom ISDv4 10D", WACOM_PKGLEN_MTTPC, 26202, 16325, 255,
0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x10E =
+ { "Wacom ISDv4 10E", WACOM_PKGLEN_MTTPC, 27760, 15694, 255,
+ 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x10F =
{ "Wacom ISDv4 10F", WACOM_PKGLEN_MTTPC, 27760, 15694, 255,
0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -2330,6 +2333,7 @@ const struct usb_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x100) },
{ USB_DEVICE_WACOM(0x101) },
{ USB_DEVICE_WACOM(0x10D) },
+ { USB_DEVICE_WACOM(0x10E) },
{ USB_DEVICE_WACOM(0x10F) },
{ USB_DEVICE_WACOM(0x300) },
{ USB_DEVICE_WACOM(0x301) },
--
1.8.4
^ permalink raw reply related
* [PATCH] HID: hid-sensor-hub: fix report size
From: Srinivas Pandruvada @ 2013-10-18 16:48 UTC (permalink / raw)
To: jkosina; +Cc: linux-input, Srinivas Pandruvada
The number of bytes in a field needs to take account of report_count
field. Need to multiply report_size and report_count to get total
number of bytes.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
drivers/hid/hid-sensor-hub.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 88fc5ae..a184e19 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -326,7 +326,8 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
field->logical == attr_usage_id) {
sensor_hub_fill_attr_info(info, i, report->id,
field->unit, field->unit_exponent,
- field->report_size);
+ field->report_size *
+ field->report_count);
ret = 0;
} else {
for (j = 0; j < field->maxusage; ++j) {
@@ -338,7 +339,8 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
i, report->id,
field->unit,
field->unit_exponent,
- field->report_size);
+ field->report_size *
+ field->report_count);
ret = 0;
break;
}
@@ -425,9 +427,10 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
hid_dbg(hdev, "%d collection_index:%x hid:%x sz:%x\n",
i, report->field[i]->usage->collection_index,
report->field[i]->usage->hid,
- report->field[i]->report_size/8);
-
- sz = report->field[i]->report_size/8;
+ (report->field[i]->report_size *
+ report->field[i]->report_count)/8);
+ sz = (report->field[i]->report_size *
+ report->field[i]->report_count)/8;
if (pdata->pending.status && pdata->pending.attr_usage_id ==
report->field[i]->usage->hid) {
hid_dbg(hdev, "data was pending ...\n");
--
1.8.3.2
^ permalink raw reply related
* [PATCH] HID: wiimote: add LEGO-wiimote VID
From: David Herrmann @ 2013-10-18 14:26 UTC (permalink / raw)
To: linux-input; +Cc: Jiri Kosina, David Herrmann, stable
The LEGO-wiimote uses a different VID than the Nintendo ID. The device is
technically the same so add the ID.
Cc: <stable@vger.kernel.org> # 3.11+
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
drivers/hid/hid-core.c | 1 +
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-wiimote-core.c | 5 ++++-
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 95d2dff..e6c3a03 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1871,6 +1871,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO2, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
{ }
};
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index ac803c5..000e0df 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -639,6 +639,7 @@
#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
#define USB_VENDOR_ID_NINTENDO 0x057e
+#define USB_VENDOR_ID_NINTENDO2 0x054c
#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306
#define USB_DEVICE_ID_NINTENDO_WIIMOTE2 0x0330
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index abb20db..1446f52 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -834,7 +834,8 @@ static void wiimote_init_set_type(struct wiimote_data *wdata,
goto done;
}
- if (vendor == USB_VENDOR_ID_NINTENDO) {
+ if (vendor == USB_VENDOR_ID_NINTENDO ||
+ vendor == USB_VENDOR_ID_NINTENDO2) {
if (product == USB_DEVICE_ID_NINTENDO_WIIMOTE) {
devtype = WIIMOTE_DEV_GEN10;
goto done;
@@ -1855,6 +1856,8 @@ static void wiimote_hid_remove(struct hid_device *hdev)
static const struct hid_device_id wiimote_hid_devices[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
USB_DEVICE_ID_NINTENDO_WIIMOTE) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO2,
+ USB_DEVICE_ID_NINTENDO_WIIMOTE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
{ }
--
1.8.4
^ permalink raw reply related
* Re: [PATCH 1/1] HID: Fix unit exponent parsing again
From: Jiri Kosina @ 2013-10-18 13:14 UTC (permalink / raw)
To: Nikolai Kondrashov; +Cc: Benjamin Tissoires, linux-input
In-Reply-To: <526132B4.2000008@gmail.com>
On Fri, 18 Oct 2013, Nikolai Kondrashov wrote:
> > I am about to apply it, just a minor thing -- you seem to have forgotten
> > your Signed-off-by: line in the patch. Could you please send it to me, so
> > that I can ammend it to the patch and apply it?
>
> Sure, sorry, haven't sent any kernel patches in a while.
>
> Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
Thanks, applied.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 1/1] HID: Fix unit exponent parsing again
From: Nikolai Kondrashov @ 2013-10-18 13:08 UTC (permalink / raw)
To: Jiri Kosina; +Cc: Benjamin Tissoires, linux-input
In-Reply-To: <alpine.LNX.2.00.1310181456500.31790@pobox.suse.cz>
Hi Jiri,
On 10/18/2013 03:58 PM, Jiri Kosina wrote:
> I am about to apply it, just a minor thing -- you seem to have forgotten
> your Signed-off-by: line in the patch. Could you please send it to me, so
> that I can ammend it to the patch and apply it?
Sure, sorry, haven't sent any kernel patches in a while.
Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com>
Sincerely,
Nick
^ permalink raw reply
* Re: [PATCH 1/1] HID: Fix unit exponent parsing again
From: Jiri Kosina @ 2013-10-18 12:58 UTC (permalink / raw)
To: Benjamin Tissoires; +Cc: Nikolai Kondrashov, linux-input
In-Reply-To: <CAN+gG=FC8Zvkt+9wcaMyo+akmqY-mm=xSPDqWOqGHEPwZx3XTQ@mail.gmail.com>
On Thu, 17 Oct 2013, Benjamin Tissoires wrote:
> > Revert some changes done in 774638386826621c984ab6994439f474709cac5e.
> >
> > Revert all changes done in hidinput_calc_abs_res as it mistakingly used
> > "Unit" item exponent nibbles to affect resolution value. This wasn't
> > breaking resolution calculation of relevant axes of any existing
> > devices, though, as they have only one dimension to their units and thus
> > 1 in the corresponding nible.
> >
> > Revert to reading "Unit Exponent" item value as a signed integer in
> > hid_parser_global to fix reading specification-complying values. This
> > fixes resolution calculation of devices complying to the HID standard,
> > including Huion, KYE, Waltop and UC-Logic graphics tablets which have
> > their report descriptors fixed by the drivers.
> >
> > Explanations follow.
[ ... snip ... ]
> I finally understood what you mean here, and why I introduced such a change.
> I have weird report descriptors available in the field which are
> making a funny use of units:
Ok, it took me quite some time to figure this all out. Good work Nikolai,
thanks.
I am about to apply it, just a minor thing -- you seem to have forgotten
your Signed-off-by: line in the patch. Could you please send it to me, so
that I can ammend it to the patch and apply it?
Thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [Patch v2][ 15/37] Input: tsc2007: Add device tree support.
From: Lothar Waßmann @ 2013-10-18 8:36 UTC (permalink / raw)
To: Denis Carikli
Cc: Sascha Hauer, Mark Rutland, devicetree, Dmitry Torokhov,
Pawel Moll, Stephen Warren, Ian Campbell, Rob Herring,
Eric Bénard, linux-input, linux-arm-kernel
In-Reply-To: <1382022155-21954-16-git-send-email-denis@eukrea.com>
Hi,
Denis Carikli <denis@eukrea.com> wrote:
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
> new file mode 100644
> index 0000000..d67b33f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
> @@ -0,0 +1,44 @@
> +* Texas Instruments tsc2007 touchscreen controller
> +
> +Required properties:
> +- compatible: must be "ti,tsc2007".
> +- reg: I2C address of the chip.
> +- pinctrl-0: Should specify pin control groups used for this controller
> + (see pinctrl bindings[0]).
> +- pinctrl-names: Should contain only one value - "default"
> + (see pinctrl bindings[0]).
> +- interrupt-parent: the phandle for the interrupt controller
> + (see interrupt binding[1]).
> +- interrupts: interrupt to which the chip is connected
> + (see interrupt binding[1]).
> +- x-plate-ohms: X-plate resistance in ohms.
> +
There is already a property 'ti,x-plate-ohms' (used for ads7846).
Should this be used here too instead of inventing a new one?
[...]
> @@ -175,10 +192,10 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
>
> /* pen is down, continue with the measurement */
> tsc2007_read_values(ts, &tc);
> -
> rt = tsc2007_calculate_pressure(ts, &tc);
>
> - if (rt == 0 && !ts->get_pendown_state) {
> + if ((ts->of && rt == 0 && ts->gpio < 0) ||
... && !gpio_is_valid(ts->gpio)) ||
for consistency?
> @@ -273,34 +294,64 @@ static void tsc2007_close(struct input_dev *input_dev)
> tsc2007_stop(ts);
> }
>
> -static int tsc2007_probe(struct i2c_client *client,
> - const struct i2c_device_id *id)
> +#ifdef CONFIG_OF
> +static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts,
> + struct device_node *np)
> {
> - struct tsc2007 *ts;
> - struct tsc2007_platform_data *pdata = client->dev.platform_data;
> - struct input_dev *input_dev;
> - int err;
> -
> - if (!pdata) {
> - dev_err(&client->dev, "platform data is required!\n");
> + int err = 0;
> + u32 val32;
> + u64 val64;
> +
> + if (!of_property_read_u32(np, "max-rt", &val32))
> + ts->max_rt = val32;
> + else
> + ts->max_rt = MAX_12BIT;
> +
> + if (!of_property_read_u32(np, "fuzzy", &val32))
> + ts->fuzzy = val32;
> +
> + if (!of_property_read_u64(np, "poll-period", &val64))
> + ts->poll_period = val64;
> + else
> + ts->poll_period = 1;
> +
> + if (!of_property_read_u32(np, "x-plate-ohms", &val32)) {
> + ts->x_plate_ohms = val32;
> + } else {
> + dev_err(&client->dev,
> + "x-plate-ohms is not set up in the devicetree."
> + " (err %d).", err);
>
It's a bad habit to split messages like this, since it makes it harder
to grep the kernel source for a message in a logfile.
> return -EINVAL;
> }
>
> - if (!i2c_check_functionality(client->adapter,
> - I2C_FUNC_SMBUS_READ_WORD_DATA))
> - return -EIO;
> + ts->gpio = of_get_gpio(np, 0);
> + if (!gpio_is_valid(ts->gpio))
> + dev_err(&client->dev, "GPIO not found "
> + "(of_get_gpio returned %d)\n", ts->gpio);
>
dito (at least you should be consistent putting the space either in the
end of the first line or in the beginning of the next line!)
[...]
> @@ -309,13 +360,59 @@ static int tsc2007_probe(struct i2c_client *client,
> ts->poll_period = pdata->poll_period ? : 1;
> ts->get_pendown_state = pdata->get_pendown_state;
> ts->clear_penirq = pdata->clear_penirq;
> + ts->fuzzy = pdata->fuzzy;
>
> if (pdata->x_plate_ohms == 0) {
> dev_err(&client->dev, "x_plate_ohms is not set up in platform data");
> - err = -EINVAL;
> + return -EINVAL;
> + }
> +
> + /* Used to detect if it is probed trough the device tree,
> + * in order to be able to use that information in the IRQ handler.
> + */
> + ts->of = 0;
> +
> + return 0;
> +}
> +
> +static int tsc2007_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct device_node *np = client->dev.of_node;
> + struct tsc2007_platform_data *pdata = client->dev.platform_data;
> + struct tsc2007 *ts;
> + struct input_dev *input_dev;
> + int err = 0;
> +
> + ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL);
>
devm_kzalloc()?
> @@ -389,10 +494,19 @@ static const struct i2c_device_id tsc2007_idtable[] = {
>
> MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id tsc2007_of_match[] = {
> + { .compatible = "ti,tsc2007" },
> + { /* sentinel */ },
>
the redundant comma after the last entry in a struct initializer is
useful to ease adding more entries lateron. Since the empty entry
always has to be the last one, the comma doesn't make any sense here.
Lothar Waßmann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________
--
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
^ permalink raw reply
* Re: Problem with Mighty Mouse
From: Bastien Nocera @ 2013-10-17 22:43 UTC (permalink / raw)
To: Benjamin Tissoires; +Cc: linux-input
In-Reply-To: <CAN+gG=E3JgUZ9vGY7N-D3OYLGcRqy5OXu8w5WXjJ2YLuYW4UWw@mail.gmail.com>
On Thu, 2013-10-17 at 15:30 -0400, Benjamin Tissoires wrote:
> Hi Bastien,
>
> On Sat, Oct 12, 2013 at 7:48 PM, Bastien Nocera <hadess@hadess.net> wrote:
> > Heya,
> >
> > I've tested a Bluetooth Apple Mighty Mouse (AA1197) and though I can
> > move the cursor without a problem, none of the buttons work. evtest
> > doesn't see any button events.
> >
> > Any ideas what I should look at, or which tool I could use to capture
> > the raw data?
>
> you can use hid-recorder[1] to retrieve the raw events from hidraw (it
> mainly does a hexdump on /dev/hidrawX or you can use the kernel
> debugfs interface for some devices which are preventing hidraw to
> forward the events).
>
> Ideally, you should give the output of evtest (or evemu) and
> hid-recorder at the same time so we can have an idea of the input and
> the output of the kernel driver.
Colour me confused, it works again. I'll bear those advices in mind if
and when it happens again.
Cheers
^ permalink raw reply
* Re: Problem with Mighty Mouse
From: Benjamin Tissoires @ 2013-10-17 19:30 UTC (permalink / raw)
To: Bastien Nocera; +Cc: linux-input
In-Reply-To: <1381621726.21761.7.camel@nuvo>
Hi Bastien,
On Sat, Oct 12, 2013 at 7:48 PM, Bastien Nocera <hadess@hadess.net> wrote:
> Heya,
>
> I've tested a Bluetooth Apple Mighty Mouse (AA1197) and though I can
> move the cursor without a problem, none of the buttons work. evtest
> doesn't see any button events.
>
> Any ideas what I should look at, or which tool I could use to capture
> the raw data?
you can use hid-recorder[1] to retrieve the raw events from hidraw (it
mainly does a hexdump on /dev/hidrawX or you can use the kernel
debugfs interface for some devices which are preventing hidraw to
forward the events).
Ideally, you should give the output of evtest (or evemu) and
hid-recorder at the same time so we can have an idea of the input and
the output of the kernel driver.
Cheers,
Benjamin
[1] http://bentiss.github.io/hid-replay-docs/
>
> Cheers
>
> --
> 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
^ permalink raw reply
* Re: [PATCH 1/1] HID: Fix unit exponent parsing again
From: Benjamin Tissoires @ 2013-10-17 18:56 UTC (permalink / raw)
To: Nikolai Kondrashov; +Cc: Jiri Kosina, linux-input
In-Reply-To: <1381666192-25309-1-git-send-email-spbnick@gmail.com>
Hi Nikolai,
On Sun, Oct 13, 2013 at 8:09 AM, Nikolai Kondrashov <spbnick@gmail.com> wrote:
> Revert some changes done in 774638386826621c984ab6994439f474709cac5e.
>
> Revert all changes done in hidinput_calc_abs_res as it mistakingly used
> "Unit" item exponent nibbles to affect resolution value. This wasn't
> breaking resolution calculation of relevant axes of any existing
> devices, though, as they have only one dimension to their units and thus
> 1 in the corresponding nible.
>
> Revert to reading "Unit Exponent" item value as a signed integer in
> hid_parser_global to fix reading specification-complying values. This
> fixes resolution calculation of devices complying to the HID standard,
> including Huion, KYE, Waltop and UC-Logic graphics tablets which have
> their report descriptors fixed by the drivers.
>
> Explanations follow.
>
> There are two "unit exponents" in HID specification and it is important
> not to mix them. One is the global "Unit Exponent" item and another is
> nibble values in the global "Unit" item. See 6.2.2.7 Global Items.
>
> The "Unit Exponent" value is just a signed integer and is used to scale
> the integer resolution unit values, so fractions can be expressed.
>
> The nibbles of "Unit" value are used to select the unit system (nibble
> 0), and presence of a particular basic unit type in the unit formula and
> its *exponent* (or power, nibbles 1-6). And yes, the latter is in two
> complement and zero means absence of the unit type.
>
> Taking the representation example of (integer) joules from the
> specification:
>
> [mass(grams)][length(centimeters)^2][time(seconds)^-2] * 10^-7
>
> the "Unit Exponent" would be -7 (or 0xF9, if stored as a byte) and the
> "Unit" value would be 0xE121, signifying:
>
> Nibble Part Value Meaning
> ----- ---- ----- -------
> 0 System 1 SI Linear
> 1 Length 2 Centimeters^2
> 2 Mass 1 Grams
> 3 Time -2 Seconds^-2
>
> To give the resolution in e.g. hundredth of joules the "Unit Exponent"
> item value should have been -9.
>
> See also the examples of "Unit" values for some common units in the same
> chapter.
>
> However, there is a common misunderstanding about the "Unit Exponent"
> value encoding, where it is assumed to be stored the same as nibbles in
> "Unit" item. This is most likely due to the specification being a bit
> vague and overloading the term "unit exponent". This also was and still
> is proliferated by the official "HID Descriptor Tool", which makes this
> mistake and stores "Unit Exponent" as such. This format is also
> mentioned in books such as "USB Complete" and in Microsoft's hardware
> design guides.
>
> As a result many devices currently on the market use this encoding and
> so the driver should support them.
> ---
> drivers/hid/hid-core.c | 11 ++++++-----
> drivers/hid/hid-input.c | 13 ++++---------
> 2 files changed, 10 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index b8470b1..013cad0 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -319,7 +319,7 @@ static s32 item_sdata(struct hid_item *item)
>
> static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
> {
> - __u32 raw_value;
> + __s32 raw_value;
> switch (item->tag) {
> case HID_GLOBAL_ITEM_TAG_PUSH:
>
> @@ -370,10 +370,11 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
> return 0;
>
> case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
> - /* Units exponent negative numbers are given through a
> - * two's complement.
> - * See "6.2.2.7 Global Items" for more information. */
> - raw_value = item_udata(item);
> + /* Many devices provide unit exponent as a two's complement
> + * nibble due to the common misunderstanding of HID
> + * specification 1.11, 6.2.2.7 Global Items. Attempt to handle
> + * both this and the standard encoding. */
> + raw_value = item_sdata(item);
> if (!(raw_value & 0xfffffff0))
> parser->global.unit_exponent = hid_snto32(raw_value, 4);
> else
> diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
> index 8741d95..d97f232 100644
> --- a/drivers/hid/hid-input.c
> +++ b/drivers/hid/hid-input.c
> @@ -192,6 +192,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
> return -EINVAL;
> }
>
> +
> /**
> * hidinput_calc_abs_res - calculate an absolute axis resolution
> * @field: the HID report field to calculate resolution for
> @@ -234,23 +235,17 @@ __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
> case ABS_MT_TOOL_Y:
> case ABS_MT_TOUCH_MAJOR:
> case ABS_MT_TOUCH_MINOR:
> - if (field->unit & 0xffffff00) /* Not a length */
> - return 0;
> - unit_exponent += hid_snto32(field->unit >> 4, 4) - 1;
> - switch (field->unit & 0xf) {
> - case 0x1: /* If centimeters */
> + if (field->unit == 0x11) { /* If centimeters */
> /* Convert to millimeters */
> unit_exponent += 1;
> - break;
> - case 0x3: /* If inches */
> + } else if (field->unit == 0x13) { /* If inches */
> /* Convert to millimeters */
> prev = physical_extents;
> physical_extents *= 254;
> if (physical_extents < prev)
> return 0;
> unit_exponent -= 1;
> - break;
> - default:
> + } else {
I finally understood what you mean here, and why I introduced such a change.
I have weird report descriptors available in the field which are
making a funny use of units:
3M multitouch devices declare:
0x05, 0x01, // Usage Page (Generic Desktop) 148
0x26, 0xff, 0x7f, // Logical Maximum (32767) 150
0x75, 0x10, // Report Size (16) 153
0x55, 0x0e, // Unit Exponent (-2) 155
0x65, 0x33, // Unit (Inch^3,EngLinear) 157
0x09, 0x30, // Usage (X) 159
0x35, 0x00, // Physical Minimum (0) 161
0x46, 0x3a, 0x06, // Physical Maximum (1594) 163
0x81, 0x02, // Input (Data,Var,Abs) 166
which became fine with the non reverted code -> the unit exponent
became 1 ( = -2 + 3). However this is wrong according to the spec as
you mentioned because X and Y are not volumes (Inch^3), but Length
(Inch^1).
Even stranger, I have some eGalax devices which declares:
0x05, 0x01, // Usage Page (Generic Desktop) 58
0x09, 0x30, // Usage (X) 60
0x75, 0x10, // Report Size (16) 62
0x95, 0x01, // Report Count (1) 64
0x55, 0x0d, // Unit Exponent (-3) 66
0x65, 0x33, // Unit (Inch^3,EngLinear) 68
0x35, 0x00, // Physical Minimum (0) 70
0x46, 0xc1, 0x20, // Physical Maximum (8385) 72
0x26, 0xff, 0x7f, // Logical Maximum (32767) 75
0x81, 0x02, // Input (Data,Var,Abs) 78
X is a volume, but if you compute in the way it is currently
implemented, it leads to a non unit value :)
Fortunately, latest Win 8 specification for multitouch screens,
requires the unit and unit exponent fields to be correctly
implemented, which I can see on the reports I have.
So I was trying to fix a wrong and fancy interpretation of the spec,
based on some devices which did this bad interpretation.
To sum up:
acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cheers,
Benjamin
> return 0;
> }
> break;
> --
> 1.8.4.rc3
>
^ permalink raw reply
* Re: [PATCH] HID: i2c-hid: Stop querying for init reports
From: Benjamin Tissoires @ 2013-10-17 17:57 UTC (permalink / raw)
To: Bibek Basu; +Cc: Jiri Kosina, linux-input, linux-kernel@vger.kernel.org
In-Reply-To: <1381825709-5098-1-git-send-email-bbasu@nvidia.com>
Hi Bibek,
On Tue, Oct 15, 2013 at 4:28 AM, Bibek Basu <bbasu@nvidia.com> wrote:
> According to specifications, HID over I2C devices
> are not bound to respond to query for INPUT
> REPORTS. Thus dropping the call during init
> as many devices does not respond causing error
> messages during boot.
>
This time, the patch is removing too many things that are correct. :)
see below to know what to remove and what to keep:
> Signed-off-by: Bibek Basu <bbasu@nvidia.com>
> ---
> drivers/hid/i2c-hid/i2c-hid.c | 59 -------------------------------------------
> 1 file changed, 59 deletions(-)
>
> diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
> index fd7ce37..58a4f12 100644
> --- a/drivers/hid/i2c-hid/i2c-hid.c
> +++ b/drivers/hid/i2c-hid/i2c-hid.c
> @@ -409,62 +409,6 @@ static int i2c_hid_get_report_length(struct hid_report *report)
> report->device->report_enum[report->type].numbered + 2;
> }
>
> -static void i2c_hid_init_report(struct hid_report *report, u8 *buffer,
> - size_t bufsize)
> -{
> - struct hid_device *hid = report->device;
> - struct i2c_client *client = hid->driver_data;
> - struct i2c_hid *ihid = i2c_get_clientdata(client);
> - unsigned int size, ret_size;
> -
> - size = i2c_hid_get_report_length(report);
> - if (i2c_hid_get_report(client,
> - report->type == HID_FEATURE_REPORT ? 0x03 : 0x01,
> - report->id, buffer, size))
> - return;
> -
> - i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, ihid->inbuf);
> -
> - ret_size = buffer[0] | (buffer[1] << 8);
> -
> - if (ret_size != size) {
> - dev_err(&client->dev, "error in %s size:%d / ret_size:%d\n",
> - __func__, size, ret_size);
> - return;
> - }
> -
> - /* hid->driver_lock is held as we are in probe function,
> - * we just need to setup the input fields, so using
> - * hid_report_raw_event is safe. */
> - hid_report_raw_event(hid, report->type, buffer + 2, size - 2, 1);
> -}
This function should be kept
> -
> -/*
> - * Initialize all reports
> - */
> -static void i2c_hid_init_reports(struct hid_device *hid)
> -{
> - struct hid_report *report;
> - struct i2c_client *client = hid->driver_data;
> - struct i2c_hid *ihid = i2c_get_clientdata(client);
> - u8 *inbuf = kzalloc(ihid->bufsize, GFP_KERNEL);
> -
> - if (!inbuf) {
> - dev_err(&client->dev, "can not retrieve initial reports\n");
> - return;
> - }
> -
Above should be kept
> - list_for_each_entry(report,
> - &hid->report_enum[HID_INPUT_REPORT].report_list, list)
> - i2c_hid_init_report(report, inbuf, ihid->bufsize);
> -
these for lines should be removed (they are the one giving the errors
in the logs)
and please keep the rest of the code as is.
> - list_for_each_entry(report,
> - &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
> - i2c_hid_init_report(report, inbuf, ihid->bufsize);
Actually, this part is very important because we have no spontaneous
events emitted by features, so we don't know the value of the feature
until we probed it. So please keep this part as mentioned above.
Cheers,
Benjamin
> -
> - kfree(inbuf);
> -}
> -
> /*
> * Traverse the supplied list of reports and find the longest
> */
> @@ -683,9 +627,6 @@ static int i2c_hid_start(struct hid_device *hid)
> return ret;
> }
>
> - if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
> - i2c_hid_init_reports(hid);
> -
> return 0;
> }
>
> --
> 1.8.1.5
>
^ permalink raw reply
* Re: [PATCH v2] drivers: input: mouse: Remove useless casting in cypress_ps2.c
From: Dmitry Torokhov @ 2013-10-17 17:19 UTC (permalink / raw)
To: Geyslan G. Bem
Cc: dudl, kamal, mario_limonciello, git, linux-input, linux-kernel,
kernel-br
In-Reply-To: <1381962675-26876-1-git-send-email-geyslan@gmail.com>
On Wed, Oct 16, 2013 at 07:31:15PM -0300, Geyslan G. Bem wrote:
> Get rid of unnecessary (void *) casting in 'cypress_init' function.
>
> Signed-off-by: Geyslan G. Bem <geyslan@gmail.com>
Applied, thank you.
> ---
> drivers/input/mouse/cypress_ps2.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c
> index f51765f..b87d7ba 100644
> --- a/drivers/input/mouse/cypress_ps2.c
> +++ b/drivers/input/mouse/cypress_ps2.c
> @@ -680,7 +680,7 @@ int cypress_init(struct psmouse *psmouse)
> struct cytp_data *cytp;
>
> cytp = (struct cytp_data *)kzalloc(sizeof(struct cytp_data), GFP_KERNEL);
> - psmouse->private = (void *)cytp;
> + psmouse->private = cytp;
> if (cytp == NULL)
> return -ENOMEM;
>
> --
> 1.8.4
>
--
Dmitry
^ permalink raw reply
* [Patch v2][ 15/37] Input: tsc2007: Add device tree support.
From: Denis Carikli @ 2013-10-17 15:02 UTC (permalink / raw)
To: Sascha Hauer
Cc: linux-arm-kernel, Eric Bénard, Denis Carikli, Rob Herring,
Pawel Moll, Mark Rutland, Stephen Warren, Ian Campbell,
devicetree, Dmitry Torokhov, linux-input
In-Reply-To: <1382022155-21954-1-git-send-email-denis@eukrea.com>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: devicetree@vger.kernel.org
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: linux-input@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
.../bindings/input/touchscreen/tsc2007.txt | 44 +++++
drivers/input/touchscreen/tsc2007.c | 200 +++++++++++++++-----
2 files changed, 201 insertions(+), 43 deletions(-)
create mode 100644 Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
new file mode 100644
index 0000000..d67b33f
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt
@@ -0,0 +1,44 @@
+* Texas Instruments tsc2007 touchscreen controller
+
+Required properties:
+- compatible: must be "ti,tsc2007".
+- reg: I2C address of the chip.
+- pinctrl-0: Should specify pin control groups used for this controller
+ (see pinctrl bindings[0]).
+- pinctrl-names: Should contain only one value - "default"
+ (see pinctrl bindings[0]).
+- interrupt-parent: the phandle for the interrupt controller
+ (see interrupt binding[1]).
+- interrupts: interrupt to which the chip is connected
+ (see interrupt binding[1]).
+- x-plate-ohms: X-plate resistance in ohms.
+
+Optional properties:
+- gpios: the interrupt gpio the chip is connected to (trough the penirq pin)
+ (see GPIO binding[2] for more details).
+- max-rt: maximum pressure.
+- fuzzy: specifies the fuzz value that is used to filter noise from the event
+ stream.
+- poll-period: how much time to wait(in millisecond) before reading again the
+ values from the tsc2007.
+
+[0]: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+[1]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+[2]: Documentation/devicetree/bindings/gpio/gpio.txt
+
+Example:
+ &i2c1 {
+ /* ... */
+ tsc2007@49 {
+ compatible = "ti,tsc2007";
+ reg = <0x49>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tsc2007_1>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <0x0 0x8>;
+ gpios = <&gpio4 0 0>;
+ x-plate-ohms = <180>;
+ };
+
+ /* ... */
+ };
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 0b67ba4..b1ab6c0 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -26,6 +26,9 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
#define TSC2007_MEASURE_TEMP0 (0x0 << 4)
#define TSC2007_MEASURE_AUX (0x2 << 4)
@@ -74,7 +77,10 @@ struct tsc2007 {
u16 max_rt;
unsigned long poll_delay;
unsigned long poll_period;
+ int fuzzy;
+ char of;
+ unsigned gpio;
int irq;
wait_queue_head_t wait;
@@ -84,6 +90,14 @@ struct tsc2007 {
void (*clear_penirq)(void);
};
+static int tsc2007_get_pendown_state_dt(struct tsc2007 *ts)
+{
+ if (gpio_is_valid(ts->gpio))
+ return !gpio_get_value(ts->gpio);
+ else
+ return true;
+}
+
static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
{
s32 data;
@@ -158,6 +172,9 @@ static bool tsc2007_is_pen_down(struct tsc2007 *ts)
* to fall back on the pressure reading.
*/
+ if (ts->of)
+ return tsc2007_get_pendown_state_dt(ts);
+
if (!ts->get_pendown_state)
return true;
@@ -175,10 +192,10 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
/* pen is down, continue with the measurement */
tsc2007_read_values(ts, &tc);
-
rt = tsc2007_calculate_pressure(ts, &tc);
- if (rt == 0 && !ts->get_pendown_state) {
+ if ((ts->of && rt == 0 && ts->gpio < 0) ||
+ (!ts->of && rt == 0 && !ts->get_pendown_state)) {
/*
* If pressure reported is 0 and we don't have
* callback to check pendown state, we have to
@@ -198,7 +215,6 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
input_report_abs(input, ABS_PRESSURE, rt);
input_sync(input);
-
} else {
/*
* Sample found inconsistent by debouncing or pressure is
@@ -217,7 +233,6 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
input_report_key(input, BTN_TOUCH, 0);
input_report_abs(input, ABS_PRESSURE, 0);
input_sync(input);
-
if (ts->clear_penirq)
ts->clear_penirq();
@@ -228,11 +243,17 @@ static irqreturn_t tsc2007_hard_irq(int irq, void *handle)
{
struct tsc2007 *ts = handle;
- if (!ts->get_pendown_state || likely(ts->get_pendown_state()))
- return IRQ_WAKE_THREAD;
+ if (!ts->of) {
+ if (!ts->get_pendown_state || likely(ts->get_pendown_state()))
+ return IRQ_WAKE_THREAD;
- if (ts->clear_penirq)
- ts->clear_penirq();
+ if (ts->clear_penirq)
+ ts->clear_penirq();
+ } else {
+ if ((!gpio_is_valid(ts->gpio)) ||
+ likely(tsc2007_get_pendown_state_dt(ts)))
+ return IRQ_WAKE_THREAD;
+ }
return IRQ_HANDLED;
}
@@ -273,34 +294,64 @@ static void tsc2007_close(struct input_dev *input_dev)
tsc2007_stop(ts);
}
-static int tsc2007_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+#ifdef CONFIG_OF
+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts,
+ struct device_node *np)
{
- struct tsc2007 *ts;
- struct tsc2007_platform_data *pdata = client->dev.platform_data;
- struct input_dev *input_dev;
- int err;
-
- if (!pdata) {
- dev_err(&client->dev, "platform data is required!\n");
+ int err = 0;
+ u32 val32;
+ u64 val64;
+
+ if (!of_property_read_u32(np, "max-rt", &val32))
+ ts->max_rt = val32;
+ else
+ ts->max_rt = MAX_12BIT;
+
+ if (!of_property_read_u32(np, "fuzzy", &val32))
+ ts->fuzzy = val32;
+
+ if (!of_property_read_u64(np, "poll-period", &val64))
+ ts->poll_period = val64;
+ else
+ ts->poll_period = 1;
+
+ if (!of_property_read_u32(np, "x-plate-ohms", &val32)) {
+ ts->x_plate_ohms = val32;
+ } else {
+ dev_err(&client->dev,
+ "x-plate-ohms is not set up in the devicetree."
+ " (err %d).", err);
return -EINVAL;
}
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_WORD_DATA))
- return -EIO;
+ ts->gpio = of_get_gpio(np, 0);
+ if (!gpio_is_valid(ts->gpio))
+ dev_err(&client->dev, "GPIO not found "
+ "(of_get_gpio returned %d)\n", ts->gpio);
- ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ts || !input_dev) {
- err = -ENOMEM;
- goto err_free_mem;
- }
+ /* Used to detect if it is probed trough the device tree,
+ * in order to be able to use that information in the IRQ handler.
+ */
+ ts->of = 1;
- ts->client = client;
- ts->irq = client->irq;
- ts->input = input_dev;
- init_waitqueue_head(&ts->wait);
+ return 0;
+}
+#else
+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts,
+ struct device_node *np)
+{
+ return -ENODEV;
+}
+#endif
+
+static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
+ struct tsc2007_platform_data *pdata,
+ const struct i2c_device_id *id)
+{
+ if (!pdata) {
+ dev_err(&client->dev, "platform data is required!\n");
+ return -EINVAL;
+ }
ts->model = pdata->model;
ts->x_plate_ohms = pdata->x_plate_ohms;
@@ -309,13 +360,59 @@ static int tsc2007_probe(struct i2c_client *client,
ts->poll_period = pdata->poll_period ? : 1;
ts->get_pendown_state = pdata->get_pendown_state;
ts->clear_penirq = pdata->clear_penirq;
+ ts->fuzzy = pdata->fuzzy;
if (pdata->x_plate_ohms == 0) {
dev_err(&client->dev, "x_plate_ohms is not set up in platform data");
- err = -EINVAL;
+ return -EINVAL;
+ }
+
+ /* Used to detect if it is probed trough the device tree,
+ * in order to be able to use that information in the IRQ handler.
+ */
+ ts->of = 0;
+
+ return 0;
+}
+
+static int tsc2007_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device_node *np = client->dev.of_node;
+ struct tsc2007_platform_data *pdata = client->dev.platform_data;
+ struct tsc2007 *ts;
+ struct input_dev *input_dev;
+ int err = 0;
+
+ ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ if (np)
+ err = tsc2007_probe_dt(client, ts, np);
+ else
+ err = tsc2007_probe_pdev(client, ts, pdata, id);
+
+ if (err)
+ goto err_free_mem;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_WORD_DATA)) {
+ err = -EIO;
goto err_free_mem;
}
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ err = -ENOMEM;
+ goto err_free_input;
+ };
+
+ ts->client = client;
+ ts->irq = client->irq;
+ ts->input = input_dev;
+ init_waitqueue_head(&ts->wait);
+
snprintf(ts->phys, sizeof(ts->phys),
"%s/input0", dev_name(&client->dev));
@@ -331,19 +428,21 @@ static int tsc2007_probe(struct i2c_client *client,
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
- input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0);
+ input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzy, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
- pdata->fuzzz, 0);
+ ts->fuzzy, 0);
- if (pdata->init_platform_hw)
- pdata->init_platform_hw();
+ if (!np) {
+ if (pdata->init_platform_hw)
+ pdata->init_platform_hw();
+ }
err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq,
IRQF_ONESHOT, client->dev.driver->name, ts);
if (err < 0) {
dev_err(&client->dev, "irq %d busy?\n", ts->irq);
- goto err_free_mem;
+ goto err_free_input;
}
tsc2007_stop(ts);
@@ -358,23 +457,29 @@ static int tsc2007_probe(struct i2c_client *client,
err_free_irq:
free_irq(ts->irq, ts);
- if (pdata->exit_platform_hw)
- pdata->exit_platform_hw();
- err_free_mem:
+ if (!np) {
+ if (pdata->exit_platform_hw)
+ pdata->exit_platform_hw();
+ }
+ err_free_input:
input_free_device(input_dev);
+ err_free_mem:
kfree(ts);
return err;
}
static int tsc2007_remove(struct i2c_client *client)
{
+ struct device_node *np = client->dev.of_node;
struct tsc2007 *ts = i2c_get_clientdata(client);
struct tsc2007_platform_data *pdata = client->dev.platform_data;
free_irq(ts->irq, ts);
- if (pdata->exit_platform_hw)
- pdata->exit_platform_hw();
+ if (!np) {
+ if (pdata->exit_platform_hw)
+ pdata->exit_platform_hw();
+ }
input_unregister_device(ts->input);
kfree(ts);
@@ -389,10 +494,19 @@ static const struct i2c_device_id tsc2007_idtable[] = {
MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);
+#ifdef CONFIG_OF
+static const struct of_device_id tsc2007_of_match[] = {
+ { .compatible = "ti,tsc2007" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, tsc2007_of_match);
+#endif
+
static struct i2c_driver tsc2007_driver = {
.driver = {
.owner = THIS_MODULE,
- .name = "tsc2007"
+ .name = "tsc2007",
+ .of_match_table = of_match_ptr(tsc2007_of_match),
},
.id_table = tsc2007_idtable,
.probe = tsc2007_probe,
--
1.7.9.5
--
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
^ permalink raw reply related
* Re: [PATCH 3/3] iio: at91: introduce touch screen support in iio adc driver
From: Josh Wu @ 2013-10-17 5:20 UTC (permalink / raw)
To: dmitry.torokhov
Cc: thomas.petazzoni, mark.rutland, devicetree, linux-iio,
nicolas.ferre, b.brezillon, Jonathan Cameron, linux-input,
maxime.ripard, plagnioj, linux-arm-kernel
In-Reply-To: <5255B918.2020705@kernel.org>
Hi, Dimitry
Could give some feedback for this v4 patch if you have time? Since It
has been stuck for a while.
Thanks.
Best Regards,
Josh Wu
On 10/10/2013 4:14 AM, Jonathan Cameron wrote:
> On 10/08/13 04:48, Josh Wu wrote:
>> AT91 ADC hardware integrate touch screen support. So this patch add touch
>> screen support for at91 adc iio driver.
>> To enable touch screen support in adc, you need to add the dt parameters:
>> 1. which type of touch are used? (4 or 5 wires), sample period time.
>> 2. correct pressure detect threshold value.
>>
>> In the meantime, since touch screen will use a interal period trigger of adc,
>> so it is conflict to other hardware triggers. Driver will disable the hardware
>> trigger support if touch screen is enabled.
>>
>> This driver has been tested in AT91SAM9X5-EK and SAMA5D3x-EK.
>>
>> Signed-off-by: Josh Wu <josh.wu@atmel.com>
>> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
>> CC: devicetree@vger.kernel.org
> Hi Josh. I am not going to take this for now both because I want to have
> a close read of it when I have more time and because I want input from
> Dmitry on this one.
>
> Thanks,
>
> Jonathan
>> ---
>> .../devicetree/bindings/arm/atmel-adc.txt | 7 +
>> arch/arm/mach-at91/include/mach/at91_adc.h | 34 ++
>> drivers/iio/adc/at91_adc.c | 388 ++++++++++++++++++--
>> 3 files changed, 405 insertions(+), 24 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/atmel-adc.txt b/Documentation/devicetree/bindings/arm/atmel-adc.txt
>> index 0e65e01..d106146 100644
>> --- a/Documentation/devicetree/bindings/arm/atmel-adc.txt
>> +++ b/Documentation/devicetree/bindings/arm/atmel-adc.txt
>> @@ -23,6 +23,13 @@ Optional properties:
>> resolution will be used.
>> - atmel,adc-sleep-mode: Boolean to enable sleep mode when no conversion
>> - atmel,adc-sample-hold-time: Sample and Hold Time in microseconds
>> + - atmel,adc-ts-wires: Number of touch screen wires. Should be 4 or 5. If this
>> + value is set, then adc driver will enable touch screen
>> + support.
>> + NOTE: when adc touch screen enabled, the adc hardware trigger will be
>> + disabled. Since touch screen will occupied the trigger register.
>> + - atmel,adc-ts-pressure-threshold: a pressure threshold for touchscreen. It
>> + make touch detect more precision.
>>
>> Optional trigger Nodes:
>> - Required properties:
>> diff --git a/arch/arm/mach-at91/include/mach/at91_adc.h b/arch/arm/mach-at91/include/mach/at91_adc.h
>> index 048a57f..c287307 100644
>> --- a/arch/arm/mach-at91/include/mach/at91_adc.h
>> +++ b/arch/arm/mach-at91/include/mach/at91_adc.h
>> @@ -60,14 +60,48 @@
>> #define AT91_ADC_IER 0x24 /* Interrupt Enable Register */
>> #define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */
>> #define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */
>> +#define AT91_ADC_IER_PEN (1 << 29)
>> +#define AT91_ADC_IER_NOPEN (1 << 30)
>> +#define AT91_ADC_IER_XRDY (1 << 20)
>> +#define AT91_ADC_IER_YRDY (1 << 21)
>> +#define AT91_ADC_IER_PRDY (1 << 22)
>> +#define AT91_ADC_ISR_PENS (1 << 31)
>>
>> #define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */
>> #define AT91_ADC_DATA (0x3ff)
>>
>> #define AT91_ADC_CDR0_9X5 (0x50) /* Channel Data Register 0 for 9X5 */
>>
>> +#define AT91_ADC_ACR 0x94 /* Analog Control Register */
>> +#define AT91_ADC_ACR_PENDETSENS (0x3 << 0) /* pull-up resistor */
>> +
>> +#define AT91_ADC_TSMR 0xB0
>> +#define AT91_ADC_TSMR_TSMODE (3 << 0) /* Touch Screen Mode */
>> +#define AT91_ADC_TSMR_TSMODE_NONE (0 << 0)
>> +#define AT91_ADC_TSMR_TSMODE_4WIRE_NO_PRESS (1 << 0)
>> +#define AT91_ADC_TSMR_TSMODE_4WIRE_PRESS (2 << 0)
>> +#define AT91_ADC_TSMR_TSMODE_5WIRE (3 << 0)
>> +#define AT91_ADC_TSMR_TSAV (3 << 4) /* Averages samples */
>> +#define AT91_ADC_TSMR_TSAV_(x) ((x) << 4)
>> +#define AT91_ADC_TSMR_SCTIM (0x0f << 16) /* Switch closure time */
>> +#define AT91_ADC_TSMR_PENDBC (0x0f << 28) /* Pen Debounce time */
>> +#define AT91_ADC_TSMR_PENDBC_(x) ((x) << 28)
>> +#define AT91_ADC_TSMR_NOTSDMA (1 << 22) /* No Touchscreen DMA */
>> +#define AT91_ADC_TSMR_PENDET_DIS (0 << 24) /* Pen contact detection disable */
>> +#define AT91_ADC_TSMR_PENDET_ENA (1 << 24) /* Pen contact detection enable */
>> +
>> +#define AT91_ADC_TSXPOSR 0xB4
>> +#define AT91_ADC_TSYPOSR 0xB8
>> +#define AT91_ADC_TSPRESSR 0xBC
>> +
>> #define AT91_ADC_TRGR_9260 AT91_ADC_MR
>> #define AT91_ADC_TRGR_9G45 0x08
>> #define AT91_ADC_TRGR_9X5 0xC0
>>
>> +/* Trigger Register bit field */
>> +#define AT91_ADC_TRGR_TRGPER (0xffff << 16)
>> +#define AT91_ADC_TRGR_TRGPER_(x) ((x) << 16)
>> +#define AT91_ADC_TRGR_TRGMOD (0x7 << 0)
>> +#define AT91_ADC_TRGR_MOD_PERIOD_TRIG (5 << 0)
>> +
>> #endif
>> diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
>> index 22cf61d2..68ddd7f 100644
>> --- a/drivers/iio/adc/at91_adc.c
>> +++ b/drivers/iio/adc/at91_adc.c
>> @@ -11,6 +11,7 @@
>> #include <linux/clk.h>
>> #include <linux/err.h>
>> #include <linux/io.h>
>> +#include <linux/input.h>
>> #include <linux/interrupt.h>
>> #include <linux/jiffies.h>
>> #include <linux/kernel.h>
>> @@ -39,7 +40,23 @@
>> #define at91_adc_writel(st, reg, val) \
>> (writel_relaxed(val, st->reg_base + reg))
>>
>> +#define DRIVER_NAME "at91_adc"
>> +#define MAX_POS_BITS 12
>> +
>> +#define TOUCH_SAMPLE_PERIOD_US 2000 /* 2ms */
>> +#define TOUCH_PEN_DETECT_DEBOUNCE_US 200
>> +
>> struct at91_adc_caps {
>> + bool has_ts; /* Support touch screen */
>> + bool has_tsmr; /* only at91sam9x5, sama5d3 have TSMR reg */
>> + /*
>> + * Numbers of sampling data will be averaged. Can be 0~3.
>> + * Hardware can average (2 ^ ts_filter_average) sample data.
>> + */
>> + u8 ts_filter_average;
>> + /* Pen Detection input pull-up resistor, can be 0~3 */
>> + u8 ts_pen_detect_sensitivity;
>> +
>> /* startup time calculate function */
>> u32 (*calc_startup_ticks)(u8 startup_time, u32 adc_clk_khz);
>>
>> @@ -47,6 +64,12 @@ struct at91_adc_caps {
>> struct at91_adc_reg_desc registers;
>> };
>>
>> +enum atmel_adc_ts_type {
>> + ATMEL_ADC_TOUCHSCREEN_NONE = 0,
>> + ATMEL_ADC_TOUCHSCREEN_4WIRE = 4,
>> + ATMEL_ADC_TOUCHSCREEN_5WIRE = 5,
>> +};
>> +
>> struct at91_adc_state {
>> struct clk *adc_clk;
>> u16 *buffer;
>> @@ -71,6 +94,26 @@ struct at91_adc_state {
>> bool low_res; /* the resolution corresponds to the lowest one */
>> wait_queue_head_t wq_data_avail;
>> struct at91_adc_caps *caps;
>> +
>> + /*
>> + * Following ADC channels are shared by touchscreen:
>> + *
>> + * CH0 -- Touch screen XP/UL
>> + * CH1 -- Touch screen XM/UR
>> + * CH2 -- Touch screen YP/LL
>> + * CH3 -- Touch screen YM/Sense
>> + * CH4 -- Touch screen LR(5-wire only)
>> + *
>> + * The bitfields below represents the reserved channel in the
>> + * touchscreen mode.
>> + */
>> +#define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 0)
>> +#define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 0)
>> + enum atmel_adc_ts_type touchscreen_type;
>> + struct input_dev *ts_input;
>> +
>> + u16 ts_sample_period_val;
>> + u32 ts_pressure_threshold;
>> };
>>
>> static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
>> @@ -105,14 +148,10 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
>> return IRQ_HANDLED;
>> }
>>
>> -static irqreturn_t at91_adc_eoc_trigger(int irq, void *private)
>> +/* Handler for classic adc channel eoc trigger */
>> +void handle_adc_eoc_trigger(int irq, struct iio_dev *idev)
>> {
>> - struct iio_dev *idev = private;
>> struct at91_adc_state *st = iio_priv(idev);
>> - u32 status = at91_adc_readl(st, st->registers->status_register);
>> -
>> - if (!(status & st->registers->drdy_mask))
>> - return IRQ_HANDLED;
>>
>> if (iio_buffer_enabled(idev)) {
>> disable_irq_nosync(irq);
>> @@ -122,6 +161,115 @@ static irqreturn_t at91_adc_eoc_trigger(int irq, void *private)
>> st->done = true;
>> wake_up_interruptible(&st->wq_data_avail);
>> }
>> +}
>> +
>> +static int at91_ts_sample(struct at91_adc_state *st)
>> +{
>> + unsigned int xscale, yscale, reg, z1, z2;
>> + unsigned int x, y, pres, xpos, ypos;
>> + unsigned int rxp = 1;
>> + unsigned int factor = 1000;
>> + struct iio_dev *idev = iio_priv_to_dev(st);
>> +
>> + unsigned int xyz_mask_bits = st->res;
>> + unsigned int xyz_mask = (1 << xyz_mask_bits) - 1;
>> +
>> + /* calculate position */
>> + /* x position = (x / xscale) * max, max = 2^MAX_POS_BITS - 1 */
>> + reg = at91_adc_readl(st, AT91_ADC_TSXPOSR);
>> + xpos = reg & xyz_mask;
>> + x = (xpos << MAX_POS_BITS) - xpos;
>> + xscale = (reg >> 16) & xyz_mask;
>> + if (xscale == 0) {
>> + dev_err(&idev->dev, "Error: xscale == 0!\n");
>> + return -1;
>> + }
>> + x /= xscale;
>> +
>> + /* y position = (y / yscale) * max, max = 2^MAX_POS_BITS - 1 */
>> + reg = at91_adc_readl(st, AT91_ADC_TSYPOSR);
>> + ypos = reg & xyz_mask;
>> + y = (ypos << MAX_POS_BITS) - ypos;
>> + yscale = (reg >> 16) & xyz_mask;
>> + if (yscale == 0) {
>> + dev_err(&idev->dev, "Error: yscale == 0!\n");
>> + return -1;
>> + }
>> + y /= yscale;
>> +
>> + /* calculate the pressure */
>> + reg = at91_adc_readl(st, AT91_ADC_TSPRESSR);
>> + z1 = reg & xyz_mask;
>> + z2 = (reg >> 16) & xyz_mask;
>> +
>> + if (z1 != 0)
>> + pres = rxp * (x * factor / 1024) * (z2 * factor / z1 - factor)
>> + / factor;
>> + else
>> + pres = st->ts_pressure_threshold; /* no pen contacted */
>> +
>> + dev_dbg(&idev->dev, "xpos = %d, xscale = %d, ypos = %d, yscale = %d, z1 = %d, z2 = %d, press = %d\n",
>> + xpos, xscale, ypos, yscale, z1, z2, pres);
>> +
>> + if (pres < st->ts_pressure_threshold) {
>> + dev_dbg(&idev->dev, "x = %d, y = %d, pressure = %d\n",
>> + x, y, pres / factor);
>> + input_report_abs(st->ts_input, ABS_X, x);
>> + input_report_abs(st->ts_input, ABS_Y, y);
>> + input_report_abs(st->ts_input, ABS_PRESSURE, pres);
>> + input_report_key(st->ts_input, BTN_TOUCH, 1);
>> + input_sync(st->ts_input);
>> + } else {
>> + dev_dbg(&idev->dev, "pressure too low: not reporting\n");
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static irqreturn_t at91_adc_interrupt(int irq, void *private)
>> +{
>> + struct iio_dev *idev = private;
>> + struct at91_adc_state *st = iio_priv(idev);
>> + u32 status = at91_adc_readl(st, st->registers->status_register);
>> + const uint32_t ts_data_irq_mask =
>> + AT91_ADC_IER_XRDY |
>> + AT91_ADC_IER_YRDY |
>> + AT91_ADC_IER_PRDY;
>> +
>> + if (status & st->registers->drdy_mask)
>> + handle_adc_eoc_trigger(irq, idev);
>> +
>> + if (status & AT91_ADC_IER_PEN) {
>> + at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN);
>> + at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_NOPEN |
>> + ts_data_irq_mask);
>> + /* Set up period trigger for sampling */
>> + at91_adc_writel(st, st->registers->trigger_register,
>> + AT91_ADC_TRGR_MOD_PERIOD_TRIG |
>> + AT91_ADC_TRGR_TRGPER_(st->ts_sample_period_val));
>> + } else if (status & AT91_ADC_IER_NOPEN) {
>> + at91_adc_writel(st, st->registers->trigger_register, 0);
>> + at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_NOPEN |
>> + ts_data_irq_mask);
>> + at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN);
>> +
>> + input_report_key(st->ts_input, BTN_TOUCH, 0);
>> + input_sync(st->ts_input);
>> + } else if ((status & ts_data_irq_mask) == ts_data_irq_mask) {
>> + /* Now all touchscreen data is ready */
>> +
>> + if (status & AT91_ADC_ISR_PENS) {
>> + /* validate data by pen contact */
>> + at91_ts_sample(st);
>> + } else {
>> + /* triggered by event that is no pen contact, just read
>> + * them to clean the interrupt and discard all.
>> + */
>> + at91_adc_readl(st, AT91_ADC_TSXPOSR);
>> + at91_adc_readl(st, AT91_ADC_TSYPOSR);
>> + at91_adc_readl(st, AT91_ADC_TSPRESSR);
>> + }
>> + }
>>
>> return IRQ_HANDLED;
>> }
>> @@ -131,6 +279,16 @@ static int at91_adc_channel_init(struct iio_dev *idev)
>> struct at91_adc_state *st = iio_priv(idev);
>> struct iio_chan_spec *chan_array, *timestamp;
>> int bit, idx = 0;
>> + unsigned long rsvd_mask = 0;
>> +
>> + /* If touchscreen is enable, then reserve the adc channels */
>> + if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE)
>> + rsvd_mask = CHAN_MASK_TOUCHSCREEN_4WIRE;
>> + else if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_5WIRE)
>> + rsvd_mask = CHAN_MASK_TOUCHSCREEN_5WIRE;
>> +
>> + /* set up the channel mask to reserve touchscreen channels */
>> + st->channels_mask &= ~rsvd_mask;
>>
>> idev->num_channels = bitmap_weight(&st->channels_mask,
>> st->num_channels) + 1;
>> @@ -479,6 +637,39 @@ static u32 calc_startup_ticks_9x5(u8 startup_time, u32 adc_clk_khz)
>>
>> static const struct of_device_id at91_adc_dt_ids[];
>>
>> +static int at91_adc_probe_dt_ts(struct device_node *node,
>> + struct at91_adc_state *st, struct device *dev)
>> +{
>> + int ret;
>> + u32 prop;
>> +
>> + ret = of_property_read_u32(node, "atmel,adc-ts-wires", &prop);
>> + if (ret) {
>> + dev_info(dev, "ADC Touch screen is disabled.\n");
>> + return 0;
>> + }
>> +
>> + switch (prop) {
>> + case 4:
>> + case 5:
>> + st->touchscreen_type = prop;
>> + break;
>> + default:
>> + dev_err(dev, "Unsupported number of touchscreen wires (%d). Should be 4 or 5.\n", prop);
>> + return -EINVAL;
>> + }
>> +
>> + prop = 0;
>> + of_property_read_u32(node, "atmel,adc-ts-pressure-threshold", &prop);
>> + st->ts_pressure_threshold = prop;
>> + if (st->ts_pressure_threshold) {
>> + return 0;
>> + } else {
>> + dev_err(dev, "Invalid pressure threshold for the touchscreen\n");
>> + return -EINVAL;
>> + }
>> +}
>> +
>> static int at91_adc_probe_dt(struct at91_adc_state *st,
>> struct platform_device *pdev)
>> {
>> @@ -560,6 +751,12 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
>> i++;
>> }
>>
>> + /* Check if touchscreen is supported. */
>> + if (st->caps->has_ts)
>> + return at91_adc_probe_dt_ts(node, st, &idev->dev);
>> + else
>> + dev_info(&idev->dev, "not support touchscreen in the adc compatible string.\n");
>> +
>> return 0;
>>
>> error_ret:
>> @@ -591,6 +788,114 @@ static const struct iio_info at91_adc_info = {
>> .read_raw = &at91_adc_read_raw,
>> };
>>
>> +/* Touchscreen related functions */
>> +static int atmel_ts_open(struct input_dev *dev)
>> +{
>> + struct at91_adc_state *st = input_get_drvdata(dev);
>> +
>> + at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN);
>> + return 0;
>> +}
>> +
>> +static void atmel_ts_close(struct input_dev *dev)
>> +{
>> + struct at91_adc_state *st = input_get_drvdata(dev);
>> +
>> + at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN);
>> +}
>> +
>> +static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz)
>> +{
>> + u32 reg = 0, pendbc;
>> + int i = 0;
>> +
>> + if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE)
>> + reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS;
>> + else
>> + reg = AT91_ADC_TSMR_TSMODE_5WIRE;
>> +
>> + /* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid
>> + * pen detect noise.
>> + * The formula is : Pen Detect Debounce Time = (2 ^ pendbc) / ADCClock
>> + */
>> + pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz / 1000, 1);
>> +
>> + while (pendbc >> ++i)
>> + ; /* Empty! Find the shift offset */
>> + if (abs(pendbc - (1 << i)) < abs(pendbc - (1 << (i - 1))))
>> + pendbc = i;
>> + else
>> + pendbc = i - 1;
>> +
>> + if (st->caps->has_tsmr) {
>> + reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average)
>> + & AT91_ADC_TSMR_TSAV;
>> + reg |= AT91_ADC_TSMR_PENDBC_(pendbc) & AT91_ADC_TSMR_PENDBC;
>> + reg |= AT91_ADC_TSMR_NOTSDMA;
>> + reg |= AT91_ADC_TSMR_PENDET_ENA;
>> + reg |= 0x03 << 8; /* TSFREQ, need bigger than TSAV */
>> +
>> + at91_adc_writel(st, AT91_ADC_TSMR, reg);
>> + } else {
>> + /* TODO: for 9g45 which has no TSMR */
>> + }
>> +
>> + /* Change adc internal resistor value for better pen detection,
>> + * default value is 100 kOhm.
>> + * 0 = 200 kOhm, 1 = 150 kOhm, 2 = 100 kOhm, 3 = 50 kOhm
>> + * option only available on ES2 and higher
>> + */
>> + at91_adc_writel(st, AT91_ADC_ACR, st->caps->ts_pen_detect_sensitivity
>> + & AT91_ADC_ACR_PENDETSENS);
>> +
>> + /* Sample Peroid Time = (TRGPER + 1) / ADCClock */
>> + st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US *
>> + adc_clk_khz / 1000) - 1, 1);
>> +
>> + return 0;
>> +}
>> +
>> +static int at91_ts_register(struct at91_adc_state *st,
>> + struct platform_device *pdev)
>> +{
>> + struct input_dev *input;
>> + struct iio_dev *idev = iio_priv_to_dev(st);
>> + int ret;
>> +
>> + input = input_allocate_device();
>> + if (!input) {
>> + dev_err(&idev->dev, "Failed to allocate TS device!\n");
>> + return -ENOMEM;
>> + }
>> +
>> + input->name = DRIVER_NAME;
>> + input->id.bustype = BUS_HOST;
>> + input->dev.parent = &pdev->dev;
>> + input->open = atmel_ts_open;
>> + input->close = atmel_ts_close;
>> +
>> + __set_bit(EV_ABS, input->evbit);
>> + __set_bit(EV_KEY, input->evbit);
>> + __set_bit(BTN_TOUCH, input->keybit);
>> + input_set_abs_params(input, ABS_X, 0, (1 << MAX_POS_BITS) - 1, 0, 0);
>> + input_set_abs_params(input, ABS_Y, 0, (1 << MAX_POS_BITS) - 1, 0, 0);
>> + input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0);
>> +
>> + st->ts_input = input;
>> + input_set_drvdata(input, st);
>> +
>> + ret = input_register_device(input);
>> + if (ret)
>> + input_free_device(st->ts_input);
>> +
>> + return ret;
>> +}
>> +
>> +static void at91_ts_unregister(struct at91_adc_state *st)
>> +{
>> + input_unregister_device(st->ts_input);
>> +}
>> +
>> static int at91_adc_probe(struct platform_device *pdev)
>> {
>> unsigned int prsc, mstrclk, ticks, adc_clk, adc_clk_khz, shtim;
>> @@ -642,7 +947,7 @@ static int at91_adc_probe(struct platform_device *pdev)
>> at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST);
>> at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF);
>> ret = request_irq(st->irq,
>> - at91_adc_eoc_trigger,
>> + at91_adc_interrupt,
>> 0,
>> pdev->dev.driver->name,
>> idev);
>> @@ -687,6 +992,10 @@ static int at91_adc_probe(struct platform_device *pdev)
>> mstrclk = clk_get_rate(st->clk);
>> adc_clk = clk_get_rate(st->adc_clk);
>> adc_clk_khz = adc_clk / 1000;
>> +
>> + dev_dbg(&pdev->dev, "Master clock is set as: %d Hz, adc_clk should set as: %d Hz\n",
>> + mstrclk, adc_clk);
>> +
>> prsc = (mstrclk / (2 * adc_clk)) - 1;
>>
>> if (!st->startup_time) {
>> @@ -723,30 +1032,52 @@ static int at91_adc_probe(struct platform_device *pdev)
>> init_waitqueue_head(&st->wq_data_avail);
>> mutex_init(&st->lock);
>>
>> - ret = at91_adc_buffer_init(idev);
>> - if (ret < 0) {
>> - dev_err(&pdev->dev, "Couldn't initialize the buffer.\n");
>> - goto error_disable_adc_clk;
>> - }
>> + /*
>> + * Since touch screen will set trigger register as period trigger. So
>> + * when touch screen is enabled, then we have to disable hardware
>> + * trigger for classic adc.
>> + */
>> + if (!st->touchscreen_type) {
>> + ret = at91_adc_buffer_init(idev);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "Couldn't initialize the buffer.\n");
>> + goto error_disable_adc_clk;
>> + }
>>
>> - ret = at91_adc_trigger_init(idev);
>> - if (ret < 0) {
>> - dev_err(&pdev->dev, "Couldn't setup the triggers.\n");
>> - goto error_unregister_buffer;
>> + ret = at91_adc_trigger_init(idev);
>> + if (ret < 0) {
>> + dev_err(&pdev->dev, "Couldn't setup the triggers.\n");
>> + at91_adc_buffer_remove(idev);
>> + goto error_disable_adc_clk;
>> + }
>> + } else {
>> + if (!st->caps->has_tsmr) {
>> + dev_err(&pdev->dev, "We don't support non-TSMR adc\n");
>> + goto error_disable_adc_clk;
>> + }
>> +
>> + ret = at91_ts_register(st, pdev);
>> + if (ret)
>> + goto error_disable_adc_clk;
>> +
>> + at91_ts_hw_init(st, adc_clk_khz);
>> }
>>
>> ret = iio_device_register(idev);
>> if (ret < 0) {
>> dev_err(&pdev->dev, "Couldn't register the device.\n");
>> - goto error_remove_triggers;
>> + goto error_iio_device_register;
>> }
>>
>> return 0;
>>
>> -error_remove_triggers:
>> - at91_adc_trigger_remove(idev);
>> -error_unregister_buffer:
>> - at91_adc_buffer_remove(idev);
>> +error_iio_device_register:
>> + if (!st->touchscreen_type) {
>> + at91_adc_trigger_remove(idev);
>> + at91_adc_buffer_remove(idev);
>> + } else {
>> + at91_ts_unregister(st);
>> + }
>> error_disable_adc_clk:
>> clk_disable_unprepare(st->adc_clk);
>> error_disable_clk:
>> @@ -762,8 +1093,12 @@ static int at91_adc_remove(struct platform_device *pdev)
>> struct at91_adc_state *st = iio_priv(idev);
>>
>> iio_device_unregister(idev);
>> - at91_adc_trigger_remove(idev);
>> - at91_adc_buffer_remove(idev);
>> + if (!st->touchscreen_type) {
>> + at91_adc_trigger_remove(idev);
>> + at91_adc_buffer_remove(idev);
>> + } else {
>> + at91_ts_unregister(st);
>> + }
>> clk_disable_unprepare(st->adc_clk);
>> clk_disable_unprepare(st->clk);
>> free_irq(st->irq, idev);
>> @@ -786,6 +1121,7 @@ static struct at91_adc_caps at91sam9260_caps = {
>> };
>>
>> static struct at91_adc_caps at91sam9g45_caps = {
>> + .has_ts = true,
>> .calc_startup_ticks = calc_startup_ticks_9260, /* same as 9260 */
>> .num_channels = 8,
>> .registers = {
>> @@ -799,6 +1135,10 @@ static struct at91_adc_caps at91sam9g45_caps = {
>> };
>>
>> static struct at91_adc_caps at91sam9x5_caps = {
>> + .has_ts = true,
>> + .has_tsmr = true,
>> + .ts_filter_average = 3,
>> + .ts_pen_detect_sensitivity = 2,
>> .calc_startup_ticks = calc_startup_ticks_9x5,
>> .num_channels = 12,
>> .registers = {
>> @@ -825,7 +1165,7 @@ static struct platform_driver at91_adc_driver = {
>> .probe = at91_adc_probe,
>> .remove = at91_adc_remove,
>> .driver = {
>> - .name = "at91_adc",
>> + .name = DRIVER_NAME,
>> .of_match_table = of_match_ptr(at91_adc_dt_ids),
>> },
>> };
>>
^ permalink raw reply
* [PATCH] input: wacom - make sure touch_max is set for touch devices
From: Ping Cheng @ 2013-10-17 0:06 UTC (permalink / raw)
To: linux-input; +Cc: dmitry.torokhov, killertofu, Ping Cheng
Old single touch Tablet PCs do not have touch_max set at
wacom_features. Since touch device at lease supports one
finger, assign touch_max to 1 when touch usage is defined
in its HID Descriptor and touch_max is not pre-defined.
Signed-off-by: Ping Cheng <pingc@wacom.com>
--
This patch is based on last posted (unmerged) patch:
"add support for three new Intuos devices"
---
drivers/input/tablet/wacom_sys.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 81d5910..28066bc 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -304,7 +304,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
struct usb_device *dev = interface_to_usbdev(intf);
char limit = 0;
/* result has to be defined as int for some devices */
- int result = 0;
+ int result = 0, touch_max = 0;
int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
unsigned char *report;
@@ -351,7 +351,8 @@ static int wacom_parse_hid(struct usb_interface *intf,
if (usage == WCM_DESKTOP) {
if (finger) {
features->device_type = BTN_TOOL_FINGER;
-
+ /* touch device at least supports one touch point */
+ touch_max = 1;
switch (features->type) {
case TABLETPC2FG:
features->pktlen = WACOM_PKGLEN_TPC2FG;
@@ -504,6 +505,8 @@ static int wacom_parse_hid(struct usb_interface *intf,
}
out:
+ if (!features->touch_max && touch_max)
+ features->touch_max = touch_max;
result = 0;
kfree(report);
return result;
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH v2] drivers: input: mouse: Remove useless casting in cypress_ps2.c
From: Geyslan Gregório Bem @ 2013-10-16 22:53 UTC (permalink / raw)
To: Joe Perches
Cc: dmitry.torokhov, dudl, kamal, mario_limonciello, git, linux-input,
LKML, kernel-br
In-Reply-To: <1381963198.22110.73.camel@joe-AO722>
2013/10/16 Joe Perches <joe@perches.com>:
> On Wed, 2013-10-16 at 19:31 -0300, Geyslan G. Bem wrote:
>> Get rid of unnecessary (void *) casting in 'cypress_init' function.
> []
>> diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c
> []
>> @@ -680,7 +680,7 @@ int cypress_init(struct psmouse *psmouse)
>> struct cytp_data *cytp;
>>
>> cytp = (struct cytp_data *)kzalloc(sizeof(struct cytp_data), GFP_KERNEL);
>> - psmouse->private = (void *)cytp;
>> + psmouse->private = cytp;
>
> If you are going to remove useless casts, please
> also remove the unnecessary kzalloc cast too.
>
>
Joe, thanks for reply. Actually I did it and receive this reply from Dmitry:
struct cytp_data *cytp;
- cytp = (struct cytp_data *)kzalloc(sizeof(struct cytp_data), GFP_KERNEL);
+ cytp = kzalloc(sizeof(struct cytp_data), GFP_KERNEL);
I already have a patch for this from Jingoo Han in my queue.
psmouse->private = (void *)cytp;
But this cast is also not needed, so if you could send me a patch for it
I'd appreciate that.
^ permalink raw reply
* Re: [PATCH v2] drivers: input: mouse: Remove useless casting in cypress_ps2.c
From: Joe Perches @ 2013-10-16 22:39 UTC (permalink / raw)
To: Geyslan G. Bem
Cc: dmitry.torokhov, dudl, kamal, mario_limonciello, git, linux-input,
linux-kernel, kernel-br
In-Reply-To: <1381962675-26876-1-git-send-email-geyslan@gmail.com>
On Wed, 2013-10-16 at 19:31 -0300, Geyslan G. Bem wrote:
> Get rid of unnecessary (void *) casting in 'cypress_init' function.
[]
> diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c
[]
> @@ -680,7 +680,7 @@ int cypress_init(struct psmouse *psmouse)
> struct cytp_data *cytp;
>
> cytp = (struct cytp_data *)kzalloc(sizeof(struct cytp_data), GFP_KERNEL);
> - psmouse->private = (void *)cytp;
> + psmouse->private = cytp;
If you are going to remove useless casts, please
also remove the unnecessary kzalloc cast too.
^ permalink raw reply
* [PATCH v2] drivers: input: mouse: Remove useless casting in cypress_ps2.c
From: Geyslan G. Bem @ 2013-10-16 22:31 UTC (permalink / raw)
To: dmitry.torokhov
Cc: dudl, kamal, mario_limonciello, git, linux-input, linux-kernel,
kernel-br, Geyslan G. Bem
Get rid of unnecessary (void *) casting in 'cypress_init' function.
Signed-off-by: Geyslan G. Bem <geyslan@gmail.com>
---
drivers/input/mouse/cypress_ps2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c
index f51765f..b87d7ba 100644
--- a/drivers/input/mouse/cypress_ps2.c
+++ b/drivers/input/mouse/cypress_ps2.c
@@ -680,7 +680,7 @@ int cypress_init(struct psmouse *psmouse)
struct cytp_data *cytp;
cytp = (struct cytp_data *)kzalloc(sizeof(struct cytp_data), GFP_KERNEL);
- psmouse->private = (void *)cytp;
+ psmouse->private = cytp;
if (cytp == NULL)
return -ENOMEM;
--
1.8.4
^ permalink raw reply related
* [PATCH v2] Input: usbtouchscreen - separate report and transmit buffer size handling
From: Christian Engelmayer @ 2013-10-16 21:15 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Forest Bond, Daniel Ritz, linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA,
christian.engelmayer-USXAA5bZaHGDvotElmWtJA
In-Reply-To: <20131016062902.GA4282-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org>
This patch supports the separate handling of the USB transfer buffer length
and the length of the buffer used for multi packet support. For devices
supporting multiple report or diagnostic packets, the USB transfer size is now
limited to the USB endpoints wMaxPacketSize - otherwise it defaults to the
configured report packet size as before
This fixes an issue where event reporting can be delayed for an arbitrary
time for multi packet devices. For instance the report size for eGalax devices
is defined to the 16 byte maximum diagnostic packet size as opposed to the 5
byte report packet size. In case the driver requests 16 byte from the USB
interrupt endpoint, the USB host controller driver needs to split up the
request into 2 accesses according to the endpoints wMaxPacketSize of 8 byte.
When the first transfer is answered by the eGalax device with not less than
the full 8 byte requested, the host controller has got no way of knowing
whether the touch controller has got additional data queued and will issue
the second transfer. If per example a liftoff event finishes at such a
wMaxPacketSize boundary, the data will not be available to the usbtouch driver
until a further event is triggered and transfered to the host. From user
perspective the BTN_TOUCH release event in this case is stuck until the next
touch down event.
Signed-off-by: Christian Engelmayer <christian.engelmayer-USXAA5bZaHGDvotElmWtJA@public.gmane.org>
---
v2: Added changes suggested by Dmitry Torokhov:
* Prefer a temporary variable over a multiple conversion of wMaxPaxetSize.
* Avoid further modifiction of the shared device info structure.
The existing violation in the probe function
if (!type->process_pkt)
type->process_pkt = usbtouch_process_pkt;
seems to be conveniance triggered and while at least at the moment applicable
for all devices of a type, could be easily removed. For a complete cleanup and
eg. setting the shared device information 'const', we would have to adapt the
Nexio support first - nexio_read_data:
if (!usbtouch->type->max_xc) {
usbtouch->type->max_xc = 2 * x_len;
input_set_abs_params(usbtouch->input, ABS_X,
0, usbtouch->type->max_xc, 0, 0);
usbtouch->type->max_yc = 2 * y_len;
input_set_abs_params(usbtouch->input, ABS_Y,
0, usbtouch->type->max_yc, 0, 0);
}
---
drivers/input/touchscreen/usbtouchscreen.c | 13 +++++++++----
1 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 721fdb3..d632848 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -106,6 +106,7 @@ struct usbtouch_device_info {
struct usbtouch_usb {
unsigned char *data;
dma_addr_t data_dma;
+ int data_size;
unsigned char *buffer;
int buf_len;
struct urb *irq;
@@ -1523,7 +1524,7 @@ static int usbtouch_reset_resume(struct usb_interface *intf)
static void usbtouch_free_buffers(struct usb_device *udev,
struct usbtouch_usb *usbtouch)
{
- usb_free_coherent(udev, usbtouch->type->rept_size,
+ usb_free_coherent(udev, usbtouch->data_size,
usbtouch->data, usbtouch->data_dma);
kfree(usbtouch->buffer);
}
@@ -1548,6 +1549,7 @@ static int usbtouch_probe(struct usb_interface *intf,
struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = interface_to_usbdev(intf);
struct usbtouch_device_info *type;
+ int wMaxPacketSize;
int err = -ENOMEM;
/* some devices are ignored */
@@ -1557,6 +1559,7 @@ static int usbtouch_probe(struct usb_interface *intf,
endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting);
if (!endpoint)
return -ENXIO;
+ wMaxPacketSize = le16_to_cpu(endpoint->wMaxPacketSize);
usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL);
input_dev = input_allocate_device();
@@ -1568,7 +1571,9 @@ static int usbtouch_probe(struct usb_interface *intf,
if (!type->process_pkt)
type->process_pkt = usbtouch_process_pkt;
- usbtouch->data = usb_alloc_coherent(udev, type->rept_size,
+ usbtouch->data_size = (type->get_pkt_len) ?
+ min(type->rept_size, wMaxPacketSize) : type->rept_size;
+ usbtouch->data = usb_alloc_coherent(udev, usbtouch->data_size,
GFP_KERNEL, &usbtouch->data_dma);
if (!usbtouch->data)
goto out_free;
@@ -1628,12 +1633,12 @@ static int usbtouch_probe(struct usb_interface *intf,
if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT)
usb_fill_int_urb(usbtouch->irq, udev,
usb_rcvintpipe(udev, endpoint->bEndpointAddress),
- usbtouch->data, type->rept_size,
+ usbtouch->data, usbtouch->data_size,
usbtouch_irq, usbtouch, endpoint->bInterval);
else
usb_fill_bulk_urb(usbtouch->irq, udev,
usb_rcvbulkpipe(udev, endpoint->bEndpointAddress),
- usbtouch->data, type->rept_size,
+ usbtouch->data, usbtouch->data_size,
usbtouch_irq, usbtouch);
usbtouch->irq->dev = udev;
--
1.7.2.5
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: Fixing 0eef:0001 (eGalax) driver binding
From: Forest Bond @ 2013-10-16 20:03 UTC (permalink / raw)
To: linux-input
Cc: Sebastian Dalfuß, Jiri Kosina, Daniel Ritz, Max Weninger,
Dmitry Torokhov, Christian Engelmayer
In-Reply-To: <20131015182701.GD14822@alittletooquiet.net>
[-- Attachment #1: Type: text/plain, Size: 2693 bytes --]
Hi,
On Tue, Oct 15, 2013 at 02:27:01PM -0400, Forest Bond wrote:
> 3. Some devices with class HID, protocol None work fine with usbtouchscreen,
> which is where they are currently bound. Okay!
>
> Some of these also work with usbhid (using quirks=0x20000048 to prevent it
> from being ignored). All of the ones I have here are like this. I'm not
> sure if there is a reason to prefer one driver over the other (dual touch?).
>
> Others reportedly do *not* work with usbhid (this is Max):
>
> https://lkml.org/lkml/2009/1/25/127
>
> 4. Some devices with class HID, protocol None do *not* work with usbtouchscreen,
> which is where they are currently bound. No bueno. Here's one (this is
> Sebastian):
>
> http://comments.gmane.org/gmane.linux.kernel.input/31710
>
> I suspect these are all multitouch devices, but I am not sure.
>
> So we need to figure out the device driver mapping that supports the most
> devices (or regresses the fewest, although I think we've messed this up enough
> for that to be a secondary concern).
>
>
> What I'm hoping is that the report in #3 that led to class HID, protocol None
> devices being bound to usbtouchscreen is no longer accurate and these devices
> work fine with current usbhid.
>
> Max, can you test this for us? I.e. does your touch screen work with current
> usbhid using quirks=0x20000048? The following modprobe snippet might be
> helpful:
>
> options usbhid quirks=0x0eef:0x0001:0x40000048
> install usbtouchscreen /bin/false
>
> If Max's touch screen works with current usbhid, I think we can drop the special
> case that binds it to usbtouchscreen and we're done! If not, things will be
> more complicated (e.g. we may have to consider whether a device is multitouch to
> decide if we should bind usbhid or usbtouchscreen).
Max reported to me off-list that he no longer has his touch screen, so this
testing most likely will not be taking place.
Unless someone can identify an EETI/eGalax touch screen with class HID, protocol
None that does not work with current usbhid, I propose we bind these to usbhid
instead of usbtouchscreen and see if anything breaks. This will fix one
regression (Sebastian's) at the risk of re-introducing another one (Max's). But
I think we'll actually end up with both problems fixed.
I think I could also argue that if we're going to break a device, it should be
the one that says it's HID but isn't, not the one that actually is what it says
it is. Hopefully it won't come down to that. ;)
Thoughts?
Thanks,
Forest
--
Forest Bond
http://www.forestbond.com/
http://www.rapidrollout.com/
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox