* Re: [PATCH 0/7] Remove HAVE_PWM config option
From: Jingoo Han @ 2014-02-11 3:02 UTC (permalink / raw)
To: 'Arnd Bergmann', 'Ralf Baechle',
'Dmitry Torokhov', 'Thierry Reding'
Cc: 'Linus Walleij', 'Russell King - ARM Linux',
'Eric Miao', linux-kernel, linux-arm-kernel, linux-mips,
linux-input, linux-pwm, 'Jingoo Han',
'Sascha Hauer', 'Roland Stigge'
In-Reply-To: <003901cf25fc$73002790$590076b0$%han@samsung.com>
On Monday, February 10, 2014 10:07 AM, Jingoo Han wrote:
>
> The HAVE_PWM symbol is only for legacy platforms that provide
> the PWM API without using the generic framework, while PWM symbol
> is used for PWM drivers using the generic PWM framework.
>
> I looked at all HAVE_PWMs in the latest mainline kernel 3.14-rc1.
> Three platforms are still using HAVE_PWM as below:
>
> 1. ARM - PXA
> ./arch/arm/mach-pxa/Kconfig
>
> 2. ARM - NXP LPC32XX
> ./arch/arm/Kconfig
> config ARCH_LPC32XX
> select HAVE_PWM
>
> 3. MIPS - Ingenic JZ4740 based machines
> ./arch/mips/Kconfig
> config MACH_JZ4740
> select HAVE_PWM
>
> However, the legacy PWM drivers for PXA, LPC32XX, and JZ474 were
> already moved to the generic PWM framework.
> ./drivers/pwm/pwm-pxa.c
> ./drivers/pwm/pwm-lpc32xx.c
> ./drivers/pwm/pwm-jz4740.c
>
> In conclusion, HAVE_PWM should be removed, because HAVE_PWM is
> NOT required anymore.
>
> Jingoo Han (7):
> ARM: pxa: don't select HAVE_PWM
> ARM: lpc32xx: don't select HAVE_PWM
> ARM: remove HAVE_PWM config option
> MIPS: jz4740: don't select HAVE_PWM
> Input: max8997_haptic: remove HAVE_PWM dependencies
> Input: pwm-beepe: remove HAVE_PWM dependencies
> pwm: don't use IS_ENABLED(CONFIG_HAVE_PWM)
>
> arch/arm/Kconfig | 4 ----
> arch/arm/mach-pxa/Kconfig | 15 ---------------
> arch/mips/Kconfig | 1 -
> drivers/input/misc/Kconfig | 4 ++--
> include/linux/pwm.h | 2 +-
> 5 files changed, 3 insertions(+), 23 deletions(-)
(+cc Sascha Hauer, Roland Stigge)
The same patch was already submitted by Sascha Hauer. [1]
So, please ignore this patch. Thank you.
[1] https://lkml.org/lkml/2014/1/16/262
Best regards,
Jingoo Han
>
> I would like to merge these patches as below:
>
> 1. Through arm-soc tree
> [PATCH 1/7] ARM: pxa: don't select HAVE_PWM
> [PATCH 2/7] ARM: lpc32xx: don't select HAVE_PWM
> [PATCH 3/7] ARM: remove HAVE_PWM config option
>
> 2. Through MIPS tree
> [PATCH 4/7] MIPS: jz4740: don't select HAVE_PWM
>
> 3. Through Input tree
> [PATCH 5/7] Input: max8997_haptic: remove HAVE_PWM dependencies
> [PATCH 6/7] Input: pwm-beepe: remove HAVE_PWM dependencies
>
> 4. Through PWM tree
> [PATCH 7/7] pwm: don't use IS_ENABLED(CONFIG_HAVE_PWM)
>
> After merging these patches, all HAVE_PWM will be removed from
> the mainline kernel. Thank you. :-)
>
> Best regards,
> Jingoo Han
^ permalink raw reply
* RE: [PATCH 2/2] gpio: adp5588 - add support for gpio names
From: Hennerich, Michael @ 2014-02-10 20:17 UTC (permalink / raw)
To: Jean-Francois Dagenais, dmitry.torokhov@gmail.com, dtor@mail.ru,
linus.walleij@linaro.org, gnurou@gmail.com
Cc: linux-gpio@vger.kernel.org, linux-input@vger.kernel.org
In-Reply-To: <1392053045-12121-2-git-send-email-jeff.dagenais@gmail.com>
-----Original Message-----
From: Jean-Francois Dagenais [mailto:jeff.dagenais@gmail.com]
Sent: Montag, 10. Februar 2014 18:24
To: Hennerich, Michael; dmitry.torokhov@gmail.com; dtor@mail.ru; linus.walleij@linaro.org; gnurou@gmail.com
Cc: linux-gpio@vger.kernel.org; linux-input@vger.kernel.org; Jean-Francois Dagenais
Subject: [PATCH 2/2] gpio: adp5588 - add support for gpio names
which is already found in the common header for adp5588
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
---
drivers/gpio/gpio-adp5588.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c index 7d3c8d9..d974020 100644
--- a/drivers/gpio/gpio-adp5588.c
+++ b/drivers/gpio/gpio-adp5588.c
@@ -397,6 +397,7 @@ static int adp5588_gpio_probe(struct i2c_client *client,
gc->ngpio = ADP5588_MAXGPIO;
gc->label = client->name;
gc->owner = THIS_MODULE;
+ gc->names = pdata->names;
mutex_init(&dev->lock);
--
1.8.5.3
^ permalink raw reply
* RE: [PATCH 1/2] gpio: adp5588 - use "unsigned" for the setup and teardown callbacks
From: Hennerich, Michael @ 2014-02-10 20:16 UTC (permalink / raw)
To: Jean-Francois Dagenais, dmitry.torokhov@gmail.com, dtor@mail.ru,
linus.walleij@linaro.org, gnurou@gmail.com
Cc: linux-gpio@vger.kernel.org, linux-input@vger.kernel.org
In-Reply-To: <1392053045-12121-1-git-send-email-jeff.dagenais@gmail.com>
-----Original Message-----
From: Jean-Francois Dagenais [mailto:jeff.dagenais@gmail.com]
Sent: Montag, 10. Februar 2014 18:24
To: Hennerich, Michael; dmitry.torokhov@gmail.com; dtor@mail.ru; linus.walleij@linaro.org; gnurou@gmail.com
Cc: linux-gpio@vger.kernel.org; linux-input@vger.kernel.org; Jean-Francois Dagenais
Subject: [PATCH 1/2] gpio: adp5588 - use "unsigned" for the setup and teardown callbacks
to comply with the rest of the GPIO drivers.
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
---
include/linux/i2c/adp5588.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h index d8341cb..c215304 100644
--- a/include/linux/i2c/adp5588.h
+++ b/include/linux/i2c/adp5588.h
@@ -161,10 +161,10 @@ struct adp5588_gpio_platform_data {
unsigned irq_base; /* interrupt base # */
unsigned pullup_dis_mask; /* Pull-Up Disable Mask */
int (*setup)(struct i2c_client *client,
- int gpio, unsigned ngpio,
+ unsigned gpio, unsigned ngpio,
void *context);
int (*teardown)(struct i2c_client *client,
- int gpio, unsigned ngpio,
+ unsigned gpio, unsigned ngpio,
void *context);
void *context;
};
--
1.8.5.3
^ permalink raw reply
* RE: [PATCH 1/2] gpio: adp5588: get value from data out when dir is out
From: Hennerich, Michael @ 2014-02-10 20:16 UTC (permalink / raw)
To: Jean-Francois Dagenais, dmitry.torokhov@gmail.com, dtor@mail.ru,
linus.walleij@linaro.org, gnurou@gmail.com
Cc: linux-gpio@vger.kernel.org, linux-input@vger.kernel.org
In-Reply-To: <1392051929-32290-1-git-send-email-jeff.dagenais@gmail.com>
-----Original Message-----
From: Jean-Francois Dagenais [mailto:jeff.dagenais@gmail.com]
Sent: Montag, 10. Februar 2014 18:05
To: Hennerich, Michael; dmitry.torokhov@gmail.com; dtor@mail.ru; linus.walleij@linaro.org; gnurou@gmail.com
Cc: linux-gpio@vger.kernel.org; linux-input@vger.kernel.org; Jean-Francois Dagenais
Subject: [PATCH 1/2] gpio: adp5588: get value from data out when dir is out
As discussed here: http://ez.analog.com/message/35852,
the 5587 revC and 5588 revB spec sheets contain a mistake in the GPIO_DAT_STATx register description.
According to R.Shnell at ADI, as well as my own observations, it should read:
"GPIO data status (shows GPIO state when read for inputs)".
This commit changes the get value function accordingly.
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
---
drivers/gpio/gpio-adp5588.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c index 3f190e6..7d3c8d9 100644
--- a/drivers/gpio/gpio-adp5588.c
+++ b/drivers/gpio/gpio-adp5588.c
@@ -67,9 +67,20 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) {
struct adp5588_gpio *dev =
container_of(chip, struct adp5588_gpio, gpio_chip);
+ unsigned bank = ADP5588_BANK(off);
+ unsigned bit = ADP5588_BIT(off);
+ int val;
- return !!(adp5588_gpio_read(dev->client,
- GPIO_DAT_STAT1 + ADP5588_BANK(off)) & ADP5588_BIT(off));
+ mutex_lock(&dev->lock);
+
+ if (dev->dir[bank] & bit)
+ val = dev->dat_out[bank];
+ else
+ val = adp5588_gpio_read(dev->client, GPIO_DAT_STAT1 + bank);
+
+ mutex_unlock(&dev->lock);
+
+ return !!(val & bit);
}
static void adp5588_gpio_set_value(struct gpio_chip *chip,
--
1.8.5.3
^ permalink raw reply
* [PATCH 08/14] HID: logitech-dj: remove hid_output_raw_report call
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
hid-input do not use anymore hid_output_raw_report() to set the LEDs.
Use the correct implementation now and make them working again.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-logitech-dj.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 980ede5..486dbde 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -193,9 +193,6 @@ static const u8 hid_reportid_size_map[NUMBER_OF_HID_REPORTS] = {
static struct hid_ll_driver logi_dj_ll_driver;
-static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
- size_t count,
- unsigned char report_type);
static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
@@ -262,7 +259,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
}
dj_hiddev->ll_driver = &logi_dj_ll_driver;
- dj_hiddev->hid_output_raw_report = logi_dj_output_hidraw_report;
dj_hiddev->dev.parent = &djrcv_hdev->dev;
dj_hiddev->bus = BUS_USB;
@@ -544,9 +540,10 @@ static void logi_dj_ll_close(struct hid_device *hid)
dbg_hid("%s:%s\n", __func__, hid->phys);
}
-static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
- size_t count,
- unsigned char report_type)
+static int logi_dj_ll_raw_request(struct hid_device *hid,
+ unsigned char reportnum, __u8 *buf,
+ size_t count, unsigned char report_type,
+ int reqtype)
{
struct dj_device *djdev = hid->driver_data;
struct dj_receiver_dev *djrcv_dev = djdev->dj_receiver_dev;
@@ -567,15 +564,8 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
out_buf[1] = djdev->device_index;
memcpy(out_buf + 2, buf, count);
- /*
- * hid-generic calls us with hid_output_raw_report(), but the LEDs
- * are set through a SET_REPORT command. It works for USB-HID devices
- * because usbhid either calls a SET_REPORT or directly send the output
- * report depending if the device presents an urbout.
- * Let be simple, send a SET_REPORT request.
- */
ret = hid_hw_raw_request(djrcv_dev->hdev, out_buf[0], out_buf,
- DJREPORT_SHORT_LENGTH, report_type, HID_REQ_SET_REPORT);
+ DJREPORT_SHORT_LENGTH, report_type, reqtype);
kfree(out_buf);
return ret;
@@ -662,6 +652,7 @@ static struct hid_ll_driver logi_dj_ll_driver = {
.stop = logi_dj_ll_stop,
.open = logi_dj_ll_open,
.close = logi_dj_ll_close,
+ .raw_request = logi_dj_ll_raw_request,
};
--
1.8.3.1
^ permalink raw reply related
* [PATCH 07/14] HID: input: hid-input remove hid_output_raw_report call
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
hid_output_raw_report() is not a ll_driver callback and should not be used.
To keep the same code path than before, we are forced to play with the
different hid_hw_* calls: if the usb or i2c device does not support
direct output reports, then we will rely on the SET_REPORT HID call.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-input.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index eb00a5b..6b7bdca 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1153,7 +1153,7 @@ static void hidinput_led_worker(struct work_struct *work)
led_work);
struct hid_field *field;
struct hid_report *report;
- int len;
+ int len, ret;
__u8 *buf;
field = hidinput_get_led_field(hid);
@@ -1187,7 +1187,10 @@ static void hidinput_led_worker(struct work_struct *work)
hid_output_report(report, buf);
/* synchronous output report */
- hid_output_raw_report(hid, buf, len, HID_OUTPUT_REPORT);
+ ret = hid_hw_output_report(hid, buf, len);
+ if (ret == -ENOSYS)
+ hid_hw_raw_request(hid, buf[0], buf, len, HID_OUTPUT_REPORT,
+ HID_REQ_SET_REPORT);
kfree(buf);
}
@@ -1266,7 +1269,8 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
}
input_set_drvdata(input_dev, hid);
- if (hid->ll_driver->request || hid->hid_output_raw_report)
+ if (hid->ll_driver->request || hid->ll_driver->output_report ||
+ hid->ll_driver->raw_request)
input_dev->event = hidinput_input_event;
input_dev->open = hidinput_open;
input_dev->close = hidinput_close;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 14/14] HID: core: check parameters when sending/receiving data from the device
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
It is better to check them soon enough before triggering any kernel panic.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/i2c-hid/i2c-hid.c | 2 +-
include/linux/hid.h | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index d3b8d7a..b50860d 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -277,7 +277,7 @@ static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType,
u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister);
u16 maxOutputLength = le16_to_cpu(ihid->hdesc.wMaxOutputLength);
- /* hidraw already checked that data_len < HID_MAX_BUFFER_SIZE */
+ /* hid_hw_* already checked that data_len < HID_MAX_BUFFER_SIZE */
u16 size = 2 /* size */ +
(reportID ? 1 : 0) /* reportID */ +
data_len /* buf */;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index fa07639..f801506 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -986,6 +986,9 @@ static inline int hid_hw_raw_request(struct hid_device *hdev,
unsigned char reportnum, __u8 *buf,
size_t len, unsigned char rtype, int reqtype)
{
+ if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
+ return -EINVAL;
+
if (hdev->ll_driver->raw_request)
return hdev->ll_driver->raw_request(hdev, reportnum, buf, len,
rtype, reqtype);
@@ -1005,6 +1008,9 @@ static inline int hid_hw_raw_request(struct hid_device *hdev,
static inline int hid_hw_output_report(struct hid_device *hdev, __u8 *buf,
size_t len)
{
+ if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
+ return -EINVAL;
+
if (hdev->ll_driver->output_report)
return hdev->ll_driver->output_report(hdev, buf, len);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 13/14] HID: remove hid_output_raw_report
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
hid_output_raw_report() is not used anymore, delete it.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/i2c-hid/i2c-hid.c | 14 --------------
drivers/hid/uhid.c | 1 -
drivers/hid/usbhid/hid-core.c | 12 ------------
include/linux/hid.h | 19 -------------------
net/bluetooth/hidp/core.c | 14 --------------
5 files changed, 60 deletions(-)
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 925fb8d..d3b8d7a 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -596,19 +596,6 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
return ret;
}
-static int __i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
- size_t count, unsigned char report_type)
-{
- struct i2c_client *client = hid->driver_data;
- struct i2c_hid *ihid = i2c_get_clientdata(client);
- bool data = true; /* SET_REPORT */
-
- if (report_type == HID_OUTPUT_REPORT)
- data = le16_to_cpu(ihid->hdesc.wMaxOutputLength) == 0;
-
- return i2c_hid_output_raw_report(hid, buf, count, report_type, data);
-}
-
static int i2c_hid_output_report(struct hid_device *hid, __u8 *buf,
size_t count)
{
@@ -1023,7 +1010,6 @@ static int i2c_hid_probe(struct i2c_client *client,
hid->driver_data = client;
hid->ll_driver = &i2c_hid_ll_driver;
- hid->hid_output_raw_report = __i2c_hid_output_raw_report;
hid->dev.parent = &client->dev;
ACPI_COMPANION_SET(&hid->dev, ACPI_COMPANION(&client->dev));
hid->bus = BUS_I2C;
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index 60acee4..7ed79be 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -400,7 +400,6 @@ static int uhid_dev_create(struct uhid_device *uhid,
hid->uniq[63] = 0;
hid->ll_driver = &uhid_hid_driver;
- hid->hid_output_raw_report = uhid_hid_output_raw;
hid->bus = ev->u.create.bus;
hid->vendor = ev->u.create.vendor;
hid->product = ev->u.create.product;
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 0d1d875..02b3256 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -945,17 +945,6 @@ static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count)
return ret;
}
-static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf,
- size_t count, unsigned char report_type)
-{
- struct usbhid_device *usbhid = hid->driver_data;
-
- if (usbhid->urbout && report_type != HID_FEATURE_REPORT)
- return usbhid_output_report(hid, buf, count);
-
- return usbhid_set_raw_report(hid, buf[0], buf, count, report_type);
-}
-
static void usbhid_restart_queues(struct usbhid_device *usbhid)
{
if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
@@ -1289,7 +1278,6 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
usb_set_intfdata(intf, hid);
hid->ll_driver = &usb_hid_driver;
- hid->hid_output_raw_report = usbhid_output_raw_report;
hid->ff_init = hid_pidff_init;
#ifdef CONFIG_USB_HIDDEV
hid->hiddev_connect = hiddev_connect;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 09fbbd7..fa07639 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -508,9 +508,6 @@ struct hid_device { /* device report descriptor */
struct hid_usage *, __s32);
void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
- /* handler for raw output data, used by hidraw */
- int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char);
-
/* debugging support via debugfs */
unsigned short debug;
struct dentry *debug_dir;
@@ -1015,22 +1012,6 @@ static inline int hid_hw_output_report(struct hid_device *hdev, __u8 *buf,
}
/**
- * hid_output_raw_report - send an output or a feature report to the device
- *
- * @hdev: hid device
- * @buf: raw data to transfer
- * @len: length of buf
- * @report_type: HID_FEATURE_REPORT or HID_OUTPUT_REPORT
- *
- * @return: count of data transfered, negative if error
- */
-static inline int hid_output_raw_report(struct hid_device *hdev, __u8 *buf,
- size_t len, unsigned char report_type)
-{
- return hdev->hid_output_raw_report(hdev, buf, len, report_type);
-}
-
-/**
* hid_hw_idle - send idle request to device
*
* @hdev: hid device
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 77c4bad..89da18d 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -382,18 +382,6 @@ static int hidp_output_report(struct hid_device *hid, __u8 *data, size_t count)
data, count);
}
-static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data,
- size_t count, unsigned char report_type)
-{
- if (report_type == HID_OUTPUT_REPORT) {
- return hidp_output_report(hid, data, count);
- } else if (report_type != HID_FEATURE_REPORT) {
- return -EINVAL;
- }
-
- return hidp_set_raw_report(hid, data[0], data, count, report_type);
-}
-
static int hidp_raw_request(struct hid_device *hid, unsigned char reportnum,
__u8 *buf, size_t len, unsigned char rtype,
int reqtype)
@@ -773,8 +761,6 @@ static int hidp_setup_hid(struct hidp_session *session,
hid->dev.parent = &session->conn->hcon->dev;
hid->ll_driver = &hidp_hid_driver;
- hid->hid_output_raw_report = hidp_output_raw_report;
-
/* True if device is blacklisted in drivers/hid/hid-core.c */
if (hid_ignore(hid)) {
hid_destroy_device(session->hid);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 12/14] HID: hidraw: replace hid_output_raw_report() calls by appropriates ones
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
Remove hid_output_raw_report() call as it is not a ll_driver callbacj,
and switch to the hid_hw_* implementation. USB-HID used to fallback
into SET_REPORT when there were no output interrupt endpoint,
so emulating this if hid_hw_output_report() returns -ENOSYS.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hidraw.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index f8708c9..704718b 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -123,10 +123,8 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
dev = hidraw_table[minor]->hid;
- if (!dev->hid_output_raw_report) {
- ret = -ENODEV;
- goto out;
- }
+ if (!dev->ll_driver->raw_request || !dev->ll_driver->output_report)
+ return -ENODEV;
if (count > HID_MAX_BUFFER_SIZE) {
hid_warn(dev, "pid %d passed too large report\n",
@@ -153,7 +151,21 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
goto out_free;
}
- ret = hid_output_raw_report(dev, buf, count, report_type);
+ if (report_type == HID_OUTPUT_REPORT) {
+ ret = hid_hw_output_report(dev, buf, count);
+ /*
+ * compatibility with old implementation of USB-HID and I2C-HID:
+ * if the device does not support receiving output reports,
+ * on an interrupt endpoint, then fallback to the SET_REPORT
+ * HID command.
+ */
+ if (ret != -ENOSYS)
+ goto out_free;
+ }
+
+ ret = hid_hw_raw_request(dev, buf[0], buf, count, report_type,
+ HID_REQ_SET_REPORT);
+
out_free:
kfree(buf);
out:
--
1.8.3.1
^ permalink raw reply related
* [PATCH 11/14] HID: sony: remove hid_output_raw_report calls
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
We can not directly change the underlying struct hid_ll_driver here
as we did for hdev->hid_output_raw_report.
So allocate a struct ll_driver, and replace the old one when removing
the device.
To get a fully functional driver, we must also split the function
sixaxis_usb_output_raw_report() in 2, one regarding output_report, and
the other for raw_request.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-sony.c | 75 ++++++++++++++++++++++++++++++++++----------------
1 file changed, 52 insertions(+), 23 deletions(-)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index d980943..dbbcd0c8 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -507,6 +507,8 @@ struct sony_sc {
struct work_struct state_worker;
struct power_supply battery;
+ struct hid_ll_driver *prev_ll_driver;
+
#ifdef CONFIG_SONY_FF
__u8 left;
__u8 right;
@@ -760,38 +762,52 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
/*
* The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
- * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
+ * like it should according to usbhid/hid-core.c::usbhid_output_report()
* so we need to override that forcing HID Output Reports on the Control EP.
- *
- * There is also another issue about HID Output Reports via USB, the Sixaxis
- * does not want the report_id as part of the data packet, so we have to
- * discard buf[0] when sending the actual control message, even for numbered
- * reports, humpf!
*/
-static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
- size_t count, unsigned char report_type)
+static int sixaxis_usb_output_report(struct hid_device *hid, __u8 *buf,
+ size_t count)
+{
+ return hid_hw_raw_request(hid, buf[0], buf, count, HID_OUTPUT_REPORT,
+ HID_REQ_SET_REPORT);
+}
+
+/*
+ * There is also another issue about the SET_REPORT command via USB,
+ * the Sixaxis does not want the report_id as part of the data packet, so
+ * we have to discard buf[0] when sending the actual control message, even
+ * for numbered reports, humpf!
+ */
+static int sixaxis_usb_raw_request(struct hid_device *hid,
+ unsigned char reportnum, __u8 *buf,
+ size_t len, unsigned char rtype, int reqtype)
{
struct usb_interface *intf = to_usb_interface(hid->dev.parent);
struct usb_device *dev = interface_to_usbdev(intf);
struct usb_host_interface *interface = intf->cur_altsetting;
- int report_id = buf[0];
int ret;
+ u8 usb_dir;
+ unsigned int usb_pipe;
- if (report_type == HID_OUTPUT_REPORT) {
+ if (reqtype == HID_REQ_SET_REPORT) {
/* Don't send the Report ID */
buf++;
- count--;
+ len--;
+ usb_dir = USB_DIR_OUT;
+ usb_pipe = usb_sndctrlpipe(dev, 0);
+ } else {
+ usb_dir = USB_DIR_IN;
+ usb_pipe = usb_rcvctrlpipe(dev, 0);
}
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- HID_REQ_SET_REPORT,
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- ((report_type + 1) << 8) | report_id,
- interface->desc.bInterfaceNumber, buf, count,
+ ret = usb_control_msg(dev, usb_pipe, reqtype,
+ usb_dir | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ ((rtype + 1) << 8) | reportnum,
+ interface->desc.bInterfaceNumber, buf, len,
USB_CTRL_SET_TIMEOUT);
- /* Count also the Report ID, in case of an Output report. */
- if (ret > 0 && report_type == HID_OUTPUT_REPORT)
+ /* Count also the Report ID. */
+ if (ret > 0 && reqtype == HID_REQ_SET_REPORT)
ret++;
return ret;
@@ -1047,7 +1063,7 @@ static void sixaxis_state_worker(struct work_struct *work)
buf[10] |= sc->led_state[2] << 3;
buf[10] |= sc->led_state[3] << 4;
- hid_output_raw_report(sc->hdev, buf, sizeof(buf), HID_OUTPUT_REPORT);
+ hid_hw_output_report(sc->hdev, buf, sizeof(buf));
}
static void dualshock4_state_worker(struct work_struct *work)
@@ -1254,6 +1270,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
unsigned long quirks = id->driver_data;
struct sony_sc *sc;
unsigned int connect_mask = HID_CONNECT_DEFAULT;
+ struct hid_ll_driver *ll_driver;
sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
if (sc == NULL) {
@@ -1285,13 +1302,20 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
}
if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
- hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;
+ ll_driver = devm_kzalloc(&hdev->dev, sizeof(*ll_driver),
+ GFP_KERNEL);
+ if (ll_driver == NULL)
+ return -ENOMEM;
+ sc->prev_ll_driver = hdev->ll_driver;
+ *ll_driver = *hdev->ll_driver;
+ hdev->ll_driver = ll_driver;
+ ll_driver->output_report = sixaxis_usb_output_report;
+ ll_driver->raw_request = sixaxis_usb_raw_request;
ret = sixaxis_set_operational_usb(hdev);
INIT_WORK(&sc->state_worker, sixaxis_state_worker);
- }
- else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
+ } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
ret = sixaxis_set_operational_bt(hdev);
- else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
+ } else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
/* Report 5 (31 bytes) is used to send data to the controller via USB */
ret = sony_set_output_report(sc, 0x05, 248);
if (ret < 0)
@@ -1339,6 +1363,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
err_close:
hid_hw_close(hdev);
err_stop:
+ if (sc->prev_ll_driver)
+ hdev->ll_driver = sc->prev_ll_driver;
if (sc->quirks & SONY_LED_SUPPORT)
sony_leds_remove(hdev);
if (sc->quirks & SONY_BATTERY_SUPPORT)
@@ -1351,6 +1377,9 @@ static void sony_remove(struct hid_device *hdev)
{
struct sony_sc *sc = hid_get_drvdata(hdev);
+ if (sc->prev_ll_driver)
+ hdev->ll_driver = sc->prev_ll_driver;
+
if (sc->quirks & SONY_LED_SUPPORT)
sony_leds_remove(hdev);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 10/14] HID: wiimote: replace hid_output_raw_report with hid_hw_output_report for output requests
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
For BT transport layer,
ret = hid_output_raw_report(A, B, C, HID_OUTPUT_REPORT);
is equivalent to
ret = hid_hw_output_report(A, B, C);
So use the new API where available
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-wiimote-core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index d7dc6c5b..d003914 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -28,14 +28,14 @@ static int wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
__u8 *buf;
int ret;
- if (!hdev->hid_output_raw_report)
+ if (!hdev->ll_driver->output_report)
return -ENODEV;
buf = kmemdup(buffer, count, GFP_KERNEL);
if (!buf)
return -ENOMEM;
- ret = hid_output_raw_report(hdev, buf, count, HID_OUTPUT_REPORT);
+ ret = hid_hw_output_report(hdev, buf, count);
kfree(buf);
return ret;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 09/14] HID: replace hid_output_raw_report with hid_hw_raw_request for feature requests
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
ret = hid_output_raw_report(A, B, C, HID_FEATURE_REPORT);
is equivalent to
ret = hid_hw_raw_request(A, B[0], B, C, HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
whatever the transport layer is.
So use the new API where available
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-lg.c | 8 ++++----
drivers/hid/hid-magicmouse.c | 4 ++--
drivers/hid/hid-sony.c | 4 ++--
drivers/hid/hid-thingm.c | 4 ++--
drivers/hid/hid-wacom.c | 26 +++++++++++++++-----------
5 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 76ed7e5..a976f48 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -692,8 +692,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) {
unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- ret = hid_output_raw_report(hdev, buf, sizeof(buf),
- HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
if (ret >= 0) {
/* insert a little delay of 10 jiffies ~ 40ms */
@@ -705,8 +705,8 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
buf[1] = 0xB2;
get_random_bytes(&buf[2], 2);
- ret = hid_output_raw_report(hdev, buf, sizeof(buf),
- HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
}
}
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index cb5db3a..ecc2cbf 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -538,8 +538,8 @@ static int magicmouse_probe(struct hid_device *hdev,
* but there seems to be no other way of switching the mode.
* Thus the super-ugly hacky success check below.
*/
- ret = hid_output_raw_report(hdev, feature, sizeof(feature),
- HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(hdev, feature[0], feature, sizeof(feature),
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
if (ret != -EIO && ret != sizeof(feature)) {
hid_err(hdev, "unable to request touch data (%d)\n", ret);
goto err_stop_hw;
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index d275c0d..d980943 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -824,8 +824,8 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev)
static int sixaxis_set_operational_bt(struct hid_device *hdev)
{
unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
- return hid_output_raw_report(hdev, buf, sizeof(buf),
- HID_FEATURE_REPORT);
+ return hid_hw_raw_request(hdev, buf[0], buf, sizeof(buf),
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
}
static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c
index 7dd3197..a97c788 100644
--- a/drivers/hid/hid-thingm.c
+++ b/drivers/hid/hid-thingm.c
@@ -48,8 +48,8 @@ static int blink1_send_command(struct blink1_data *data,
buf[0], buf[1], buf[2], buf[3], buf[4],
buf[5], buf[6], buf[7], buf[8]);
- ret = hid_output_raw_report(data->hdev, buf, BLINK1_CMD_SIZE,
- HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(data->hdev, buf[0], buf, BLINK1_CMD_SIZE,
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
return ret < 0 ? ret : 0;
}
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index c720db9..902013e 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -128,7 +128,8 @@ static void wacom_set_image(struct hid_device *hdev, const char *image,
rep_data[0] = WAC_CMD_ICON_START_STOP;
rep_data[1] = 0;
- ret = hid_output_raw_report(hdev, rep_data, 2, HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2,
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
if (ret < 0)
goto err;
@@ -142,14 +143,15 @@ static void wacom_set_image(struct hid_device *hdev, const char *image,
rep_data[j + 3] = p[(i << 6) + j];
rep_data[2] = i;
- ret = hid_output_raw_report(hdev, rep_data, 67,
- HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 67,
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
}
rep_data[0] = WAC_CMD_ICON_START_STOP;
rep_data[1] = 0;
- ret = hid_output_raw_report(hdev, rep_data, 2, HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2,
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
err:
return;
@@ -181,7 +183,8 @@ static void wacom_leds_set_brightness(struct led_classdev *led_dev,
buf[3] = value;
/* use fixed brightness for OLEDs */
buf[4] = 0x08;
- hid_output_raw_report(hdev, buf, 9, HID_FEATURE_REPORT);
+ hid_hw_raw_request(hdev, buf[0], buf, 9, HID_FEATURE_REPORT,
+ HID_REQ_SET_REPORT);
kfree(buf);
}
@@ -337,8 +340,8 @@ static void wacom_set_features(struct hid_device *hdev, u8 speed)
rep_data[0] = 0x03 ; rep_data[1] = 0x00;
limit = 3;
do {
- ret = hid_output_raw_report(hdev, rep_data, 2,
- HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2,
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
} while (ret < 0 && limit-- > 0);
if (ret >= 0) {
@@ -350,8 +353,9 @@ static void wacom_set_features(struct hid_device *hdev, u8 speed)
rep_data[1] = 0x00;
limit = 3;
do {
- ret = hid_output_raw_report(hdev,
- rep_data, 2, HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(hdev, rep_data[0],
+ rep_data, 2, HID_FEATURE_REPORT,
+ HID_REQ_SET_REPORT);
} while (ret < 0 && limit-- > 0);
if (ret >= 0) {
@@ -376,8 +380,8 @@ static void wacom_set_features(struct hid_device *hdev, u8 speed)
rep_data[0] = 0x03;
rep_data[1] = wdata->features;
- ret = hid_output_raw_report(hdev, rep_data, 2,
- HID_FEATURE_REPORT);
+ ret = hid_hw_raw_request(hdev, rep_data[0], rep_data, 2,
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
if (ret >= 0)
wdata->high_speed = speed;
break;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 06/14] HID: usbhid: change return error of usbhid_output_report
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
If there is no urbout when sending a output report, ENOSYS (Function
not implemented) is a better error than EIO (I/O error).
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/usbhid/hid-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index b9a770f..0d1d875 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -922,7 +922,7 @@ static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count)
int actual_length, skipped_report_id = 0, ret;
if (!usbhid->urbout)
- return -EIO;
+ return -ENOSYS;
if (buf[0] == 0x0) {
/* Don't send the Report ID */
--
1.8.3.1
^ permalink raw reply related
* [PATCH 05/14] HID: i2c-hid: use generic .request() implementation
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
Having our own .request() implementation does not give anything,
so use the generic binding.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/i2c-hid/i2c-hid.c | 31 -------------------------------
1 file changed, 31 deletions(-)
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 07a054a..925fb8d 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -632,36 +632,6 @@ static int i2c_hid_raw_request(struct hid_device *hid, unsigned char reportnum,
}
}
-static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep,
- int reqtype)
-{
- struct i2c_client *client = hid->driver_data;
- char *buf;
- int ret;
- int len = i2c_hid_get_report_length(rep) - 2;
-
- buf = kzalloc(len, GFP_KERNEL);
- if (!buf)
- return;
-
- switch (reqtype) {
- case HID_REQ_GET_REPORT:
- ret = i2c_hid_get_raw_report(hid, rep->id, buf, len, rep->type);
- if (ret < 0)
- dev_err(&client->dev, "%s: unable to get report: %d\n",
- __func__, ret);
- else
- hid_input_report(hid, rep->type, buf, ret, 0);
- break;
- case HID_REQ_SET_REPORT:
- hid_output_report(rep, buf);
- i2c_hid_output_raw_report(hid, buf, len, rep->type, true);
- break;
- }
-
- kfree(buf);
-}
-
static int i2c_hid_parse(struct hid_device *hid)
{
struct i2c_client *client = hid->driver_data;
@@ -817,7 +787,6 @@ static struct hid_ll_driver i2c_hid_ll_driver = {
.open = i2c_hid_open,
.close = i2c_hid_close,
.power = i2c_hid_power,
- .request = i2c_hid_request,
.output_report = i2c_hid_output_report,
.raw_request = i2c_hid_raw_request,
};
--
1.8.3.1
^ permalink raw reply related
* [PATCH 04/14] HID: i2c-hid: implement ll_driver transport-layer callbacks
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
Add output_report and raw_request to i2c-hid.
The current implementation of i2c_hid_output_raw_report decides
by itself if it should use a direct send of the output report
or use the data register (SET_REPORT). Split that by reimplement
the logic in __i2c_hid_output_raw_report() which will be dropped
soon.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/i2c-hid/i2c-hid.c | 69 +++++++++++++++++++++++++++++++++++++------
1 file changed, 60 insertions(+), 9 deletions(-)
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index f57de7f..07a054a 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -257,12 +257,21 @@ static int i2c_hid_get_report(struct i2c_client *client, u8 reportType,
return 0;
}
-static int i2c_hid_set_report(struct i2c_client *client, u8 reportType,
- u8 reportID, unsigned char *buf, size_t data_len)
+/**
+ * i2c_hid_set_or_send_report: forward an incoming report to the device
+ * @client: the i2c_client of the device
+ * @reportType: 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT
+ * @reportID: the report ID
+ * @buf: the actual data to transfer, without the report ID
+ * @len: size of buf
+ * @use_data: true: use SET_REPORT HID command, false: send plain OUTPUT report
+ */
+static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType,
+ u8 reportID, unsigned char *buf, size_t data_len, bool use_data)
{
struct i2c_hid *ihid = i2c_get_clientdata(client);
u8 *args = ihid->argsbuf;
- const struct i2c_hid_cmd * hidcmd = &hid_set_report_cmd;
+ const struct i2c_hid_cmd *hidcmd;
int ret;
u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister);
u16 outputRegister = le16_to_cpu(ihid->hdesc.wOutputRegister);
@@ -279,6 +288,9 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType,
i2c_hid_dbg(ihid, "%s\n", __func__);
+ if (!use_data && maxOutputLength == 0)
+ return -ENOSYS;
+
if (reportID >= 0x0F) {
args[index++] = reportID;
reportID = 0x0F;
@@ -288,9 +300,10 @@ static int i2c_hid_set_report(struct i2c_client *client, u8 reportType,
* use the data register for feature reports or if the device does not
* support the output register
*/
- if (reportType == 0x03 || maxOutputLength == 0) {
+ if (use_data) {
args[index++] = dataRegister & 0xFF;
args[index++] = dataRegister >> 8;
+ hidcmd = &hid_set_report_cmd;
} else {
args[index++] = outputRegister & 0xFF;
args[index++] = outputRegister >> 8;
@@ -559,7 +572,7 @@ static int i2c_hid_get_raw_report(struct hid_device *hid,
}
static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
- size_t count, unsigned char report_type)
+ size_t count, unsigned char report_type, bool use_data)
{
struct i2c_client *client = hid->driver_data;
int report_id = buf[0];
@@ -573,9 +586,9 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
count--;
}
- ret = i2c_hid_set_report(client,
+ ret = i2c_hid_set_or_send_report(client,
report_type == HID_FEATURE_REPORT ? 0x03 : 0x02,
- report_id, buf, count);
+ report_id, buf, count, use_data);
if (report_id && ret >= 0)
ret++; /* add report_id to the number of transfered bytes */
@@ -583,6 +596,42 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
return ret;
}
+static int __i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
+ size_t count, unsigned char report_type)
+{
+ struct i2c_client *client = hid->driver_data;
+ struct i2c_hid *ihid = i2c_get_clientdata(client);
+ bool data = true; /* SET_REPORT */
+
+ if (report_type == HID_OUTPUT_REPORT)
+ data = le16_to_cpu(ihid->hdesc.wMaxOutputLength) == 0;
+
+ return i2c_hid_output_raw_report(hid, buf, count, report_type, data);
+}
+
+static int i2c_hid_output_report(struct hid_device *hid, __u8 *buf,
+ size_t count)
+{
+ return i2c_hid_output_raw_report(hid, buf, count, HID_OUTPUT_REPORT,
+ false);
+}
+
+static int i2c_hid_raw_request(struct hid_device *hid, unsigned char reportnum,
+ __u8 *buf, size_t len, unsigned char rtype,
+ int reqtype)
+{
+ switch (reqtype) {
+ case HID_REQ_GET_REPORT:
+ return i2c_hid_get_raw_report(hid, reportnum, buf, len, rtype);
+ case HID_REQ_SET_REPORT:
+ if (buf[0] != reportnum)
+ return -EINVAL;
+ return i2c_hid_output_raw_report(hid, buf, len, rtype, true);
+ default:
+ return -EIO;
+ }
+}
+
static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep,
int reqtype)
{
@@ -606,7 +655,7 @@ static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep,
break;
case HID_REQ_SET_REPORT:
hid_output_report(rep, buf);
- i2c_hid_output_raw_report(hid, buf, len, rep->type);
+ i2c_hid_output_raw_report(hid, buf, len, rep->type, true);
break;
}
@@ -769,6 +818,8 @@ static struct hid_ll_driver i2c_hid_ll_driver = {
.close = i2c_hid_close,
.power = i2c_hid_power,
.request = i2c_hid_request,
+ .output_report = i2c_hid_output_report,
+ .raw_request = i2c_hid_raw_request,
};
static int i2c_hid_init_irq(struct i2c_client *client)
@@ -1003,7 +1054,7 @@ static int i2c_hid_probe(struct i2c_client *client,
hid->driver_data = client;
hid->ll_driver = &i2c_hid_ll_driver;
- hid->hid_output_raw_report = i2c_hid_output_raw_report;
+ hid->hid_output_raw_report = __i2c_hid_output_raw_report;
hid->dev.parent = &client->dev;
ACPI_COMPANION_SET(&hid->dev, ACPI_COMPANION(&client->dev));
hid->bus = BUS_I2C;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 03/14] HID: core: implement generic .request()
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
.request() can be emulated through .raw_request()
we can implement this emulation in hid-core, and make .request
not mandatory for transport layer drivers.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-core.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
include/linux/hid.h | 5 ++++-
2 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 18fe49b..f36778a 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1248,6 +1248,11 @@ void hid_output_report(struct hid_report *report, __u8 *data)
}
EXPORT_SYMBOL_GPL(hid_output_report);
+static int hid_report_len(struct hid_report *report)
+{
+ return ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7;
+}
+
/*
* Allocator for buffer that is going to be passed to hid_output_report()
*/
@@ -1258,7 +1263,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
* of implement() working on 8 byte chunks
*/
- int len = ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7;
+ int len = hid_report_len(report);
return kmalloc(len, flags);
}
@@ -1314,6 +1319,44 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
return report;
}
+/*
+ * Implement a generic .request() callback, using .raw_request()
+ * DO NOT USE in hid drivers directly, but through hid_hw_request instead.
+ */
+void __hid_request(struct hid_device *hid, struct hid_report *report,
+ int reqtype)
+{
+ char *buf;
+ int ret;
+ int len;
+
+ if (!hid->ll_driver->raw_request)
+ return;
+
+ buf = hid_alloc_report_buf(report, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ len = hid_report_len(report);
+
+ if (reqtype == HID_REQ_SET_REPORT)
+ hid_output_report(report, buf);
+
+ ret = hid->ll_driver->raw_request(hid, report->id, buf, len,
+ report->type, reqtype);
+ if (ret < 0) {
+ dbg_hid("unable to complete request: %d\n", ret);
+ goto out;
+ }
+
+ if (reqtype == HID_REQ_GET_REPORT)
+ hid_input_report(hid, report->type, buf, ret, 0);
+
+out:
+ kfree(buf);
+}
+EXPORT_SYMBOL_GPL(__hid_request);
+
int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
int interrupt)
{
diff --git a/include/linux/hid.h b/include/linux/hid.h
index a837ede..09fbbd7 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -753,6 +753,7 @@ struct hid_field *hidinput_get_led_field(struct hid_device *hid);
unsigned int hidinput_count_leds(struct hid_device *hid);
__s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code);
void hid_output_report(struct hid_report *report, __u8 *data);
+void __hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype);
u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags);
struct hid_device *hid_allocate_device(void);
struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
@@ -965,7 +966,9 @@ static inline void hid_hw_request(struct hid_device *hdev,
struct hid_report *report, int reqtype)
{
if (hdev->ll_driver->request)
- hdev->ll_driver->request(hdev, report, reqtype);
+ return hdev->ll_driver->request(hdev, report, reqtype);
+
+ __hid_request(hdev, report, reqtype);
}
/**
--
1.8.3.1
^ permalink raw reply related
* [PATCH 02/14] HID: uHID: implement .raw_request
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
uHID is missing a SET_REPORT protocol implementation, but as
.hid_get_raw_report() as been removed from struct hid_device,
there were no means to access GET_REPORT in uhid.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/uhid.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index b6de903..60acee4 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -250,6 +250,21 @@ static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf,
return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT);
}
+static int uhid_raw_request(struct hid_device *hid, unsigned char reportnum,
+ __u8 *buf, size_t len, unsigned char rtype,
+ int reqtype)
+{
+ switch (reqtype) {
+ case HID_REQ_GET_REPORT:
+ return uhid_hid_get_raw(hid, reportnum, buf, len, rtype);
+ case HID_REQ_SET_REPORT:
+ /* TODO: implement proper SET_REPORT functionality */
+ return -ENOSYS;
+ default:
+ return -EIO;
+ }
+}
+
static struct hid_ll_driver uhid_hid_driver = {
.start = uhid_hid_start,
.stop = uhid_hid_stop,
@@ -257,6 +272,7 @@ static struct hid_ll_driver uhid_hid_driver = {
.close = uhid_hid_close,
.parse = uhid_hid_parse,
.output_report = uhid_hid_output_report,
+ .raw_request = uhid_raw_request,
};
#ifdef CONFIG_COMPAT
--
1.8.3.1
^ permalink raw reply related
* [PATCH 01/14] HID: uHID: remove duplicated code
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
In-Reply-To: <1392055139-19631-1-git-send-email-benjamin.tissoires@redhat.com>
uhid_hid_output_report() can be implemented through a simple call
to uhid_hid_output_raw().
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/uhid.c | 22 +---------------------
1 file changed, 1 insertion(+), 21 deletions(-)
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index 12439e1..b6de903 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -247,27 +247,7 @@ static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count,
static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf,
size_t count)
{
- struct uhid_device *uhid = hid->driver_data;
- unsigned long flags;
- struct uhid_event *ev;
-
- if (count < 1 || count > UHID_DATA_MAX)
- return -EINVAL;
-
- ev = kzalloc(sizeof(*ev), GFP_KERNEL);
- if (!ev)
- return -ENOMEM;
-
- ev->type = UHID_OUTPUT;
- ev->u.output.size = count;
- ev->u.output.rtype = UHID_OUTPUT_REPORT;
- memcpy(ev->u.output.data, buf, count);
-
- spin_lock_irqsave(&uhid->qlock, flags);
- uhid_queue(uhid, ev);
- spin_unlock_irqrestore(&uhid->qlock, flags);
-
- return count;
+ return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT);
}
static struct hid_ll_driver uhid_hid_driver = {
--
1.8.3.1
^ permalink raw reply related
* [PATCH 00/14] HID: low-level transport cleanup, round 2
From: Benjamin Tissoires @ 2014-02-10 17:58 UTC (permalink / raw)
To: Benjamin Tissoires, Jiri Kosina, David Herrmann, linux-input,
linux-kernel
Hi guys,
this is the second part of the low-level HID transport cleanup.
The series goes on top of the previous one I sent last week.
Some highlights:
- remove hid_output_raw_report from struct hid_device
- uniformization of all transport driver by having only 2 mandatory
communication functions to implement: .raw_request and .output_report
Cheers,
Benjamin
Benjamin Tissoires (14):
HID: uHID: remove duplicated code
HID: uHID: implement .raw_request
HID: core: implement generic .request()
HID: i2c-hid: implement ll_driver transport-layer callbacks
HID: i2c-hid: use generic .request() implementation
HID: usbhid: change return error of usbhid_output_report
HID: input: hid-input remove hid_output_raw_report call
HID: logitech-dj: remove hid_output_raw_report call
HID: replace hid_output_raw_report with hid_hw_raw_request for feature
requests
HID: wiimote: replace hid_output_raw_report with hid_hw_output_report
for output requests
HID: sony: remove hid_output_raw_report calls
HID: hidraw: replace hid_output_raw_report() calls by appropriates
ones
HID: remove hid_output_raw_report
HID: core: check parameters when sending/receiving data from the
device
drivers/hid/hid-core.c | 45 +++++++++++++++++++++++-
drivers/hid/hid-input.c | 10 ++++--
drivers/hid/hid-lg.c | 8 ++---
drivers/hid/hid-logitech-dj.c | 21 ++++-------
drivers/hid/hid-magicmouse.c | 4 +--
drivers/hid/hid-sony.c | 79 +++++++++++++++++++++++++++++-------------
drivers/hid/hid-thingm.c | 4 +--
drivers/hid/hid-wacom.c | 26 ++++++++------
drivers/hid/hid-wiimote-core.c | 4 +--
drivers/hid/hidraw.c | 22 +++++++++---
drivers/hid/i2c-hid/i2c-hid.c | 70 ++++++++++++++++++++-----------------
drivers/hid/uhid.c | 37 +++++++++-----------
drivers/hid/usbhid/hid-core.c | 14 +-------
include/linux/hid.h | 30 ++++++----------
net/bluetooth/hidp/core.c | 14 --------
15 files changed, 218 insertions(+), 170 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH 1/2] gpio: adp5588 - use "unsigned" for the setup and teardown callbacks
From: Jean-Francois Dagenais @ 2014-02-10 17:24 UTC (permalink / raw)
To: michael.hennerich, dmitry.torokhov, dtor, linus.walleij, gnurou
Cc: linux-gpio, linux-input, Jean-Francois Dagenais
to comply with the rest of the GPIO drivers.
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
---
include/linux/i2c/adp5588.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h
index d8341cb..c215304 100644
--- a/include/linux/i2c/adp5588.h
+++ b/include/linux/i2c/adp5588.h
@@ -161,10 +161,10 @@ struct adp5588_gpio_platform_data {
unsigned irq_base; /* interrupt base # */
unsigned pullup_dis_mask; /* Pull-Up Disable Mask */
int (*setup)(struct i2c_client *client,
- int gpio, unsigned ngpio,
+ unsigned gpio, unsigned ngpio,
void *context);
int (*teardown)(struct i2c_client *client,
- int gpio, unsigned ngpio,
+ unsigned gpio, unsigned ngpio,
void *context);
void *context;
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH 2/2] gpio: adp5588 - add support for gpio names
From: Jean-Francois Dagenais @ 2014-02-10 17:24 UTC (permalink / raw)
To: michael.hennerich, dmitry.torokhov, dtor, linus.walleij, gnurou
Cc: linux-gpio, linux-input, Jean-Francois Dagenais
In-Reply-To: <1392053045-12121-1-git-send-email-jeff.dagenais@gmail.com>
which is already found in the common header for adp5588
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
---
drivers/gpio/gpio-adp5588.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c
index 7d3c8d9..d974020 100644
--- a/drivers/gpio/gpio-adp5588.c
+++ b/drivers/gpio/gpio-adp5588.c
@@ -397,6 +397,7 @@ static int adp5588_gpio_probe(struct i2c_client *client,
gc->ngpio = ADP5588_MAXGPIO;
gc->label = client->name;
gc->owner = THIS_MODULE;
+ gc->names = pdata->names;
mutex_init(&dev->lock);
--
1.8.5.3
^ permalink raw reply related
* [PATCH 2/2] input: adp5588-keys: get value from data out when dir is out
From: Jean-Francois Dagenais @ 2014-02-10 17:05 UTC (permalink / raw)
To: michael.hennerich, dmitry.torokhov, dtor, linus.walleij, gnurou
Cc: linux-gpio, linux-input, Jean-Francois Dagenais
In-Reply-To: <1392051929-32290-1-git-send-email-jeff.dagenais@gmail.com>
As discussed here: http://ez.analog.com/message/35852,
the 5587 revC and 5588 revB spec sheets contain a mistake
in the GPIO_DAT_STATx register description.
According to R.Shnell at ADI, as well as my own
observations, it should read:
"GPIO data status (shows GPIO state when read for inputs)".
This commit changes the get value function accordingly.
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
---
drivers/input/keyboard/adp5588-keys.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c
index bb3b57b..5ef7fcf 100644
--- a/drivers/input/keyboard/adp5588-keys.c
+++ b/drivers/input/keyboard/adp5588-keys.c
@@ -76,8 +76,18 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
+ int val;
- return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit);
+ mutex_lock(&kpad->gpio_lock);
+
+ if (kpad->dir[bank] & bit)
+ val = kpad->dat_out[bank];
+ else
+ val = adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank);
+
+ mutex_unlock(&kpad->gpio_lock);
+
+ return !!(val & bit);
}
static void adp5588_gpio_set_value(struct gpio_chip *chip,
--
1.8.5.3
^ permalink raw reply related
* [PATCH 1/2] gpio: adp5588: get value from data out when dir is out
From: Jean-Francois Dagenais @ 2014-02-10 17:05 UTC (permalink / raw)
To: michael.hennerich, dmitry.torokhov, dtor, linus.walleij, gnurou
Cc: linux-gpio, linux-input, Jean-Francois Dagenais
As discussed here: http://ez.analog.com/message/35852,
the 5587 revC and 5588 revB spec sheets contain a mistake
in the GPIO_DAT_STATx register description.
According to R.Shnell at ADI, as well as my own
observations, it should read:
"GPIO data status (shows GPIO state when read for inputs)".
This commit changes the get value function accordingly.
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
---
drivers/gpio/gpio-adp5588.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c
index 3f190e6..7d3c8d9 100644
--- a/drivers/gpio/gpio-adp5588.c
+++ b/drivers/gpio/gpio-adp5588.c
@@ -67,9 +67,20 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
{
struct adp5588_gpio *dev =
container_of(chip, struct adp5588_gpio, gpio_chip);
+ unsigned bank = ADP5588_BANK(off);
+ unsigned bit = ADP5588_BIT(off);
+ int val;
- return !!(adp5588_gpio_read(dev->client,
- GPIO_DAT_STAT1 + ADP5588_BANK(off)) & ADP5588_BIT(off));
+ mutex_lock(&dev->lock);
+
+ if (dev->dir[bank] & bit)
+ val = dev->dat_out[bank];
+ else
+ val = adp5588_gpio_read(dev->client, GPIO_DAT_STAT1 + bank);
+
+ mutex_unlock(&dev->lock);
+
+ return !!(val & bit);
}
static void adp5588_gpio_set_value(struct gpio_chip *chip,
--
1.8.5.3
^ permalink raw reply related
* Re: Re: [PATCH] Introduce Naming Convention in Input Subsystem
From: Aniroop Mathur @ 2014-02-10 15:54 UTC (permalink / raw)
To: Dmitry Torokhov, Benjamin Tissoires
Cc: linux-input@vger.kernel.org, cpgs ., Aniroop Mathur
In-Reply-To: <20140120214933.GA4270@core.coreip.homeip.net>
Dear Mr. Torokhov, Mr. Benjamin,
Greetings!
I sent a mail on January 25th, but still waiting for the reply.
Therefore, sending it again.
I hope to hear soon ~
On Tue, Jan 21, 2014 at 3:19 AM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> Hi Aniroop,
>
> On Tue, Jan 21, 2014 at 01:34:07AM +0530, Aniroop Mathur wrote:
>> Hello Mr Tissoires
>> Greetings !!
>>
>> On Jan 20, 2014 11:54 PM, "Benjamin Tissoires" <benjamin.tissoires@gmail.com>
>> wrote:
>> >
>> > Hi Aniroop,
>> >
>> > [sorry for top posting, but I really don't know where to put this
>> regarding your answers].
>> >
>> No problem at all.
>> In fact I am quite happy to hear from
>> Linux community again
>> Its my pleasure.
>>
>> > I _think_ I get one of the reasons you don't understand Dmitry, and why
>> Dmitry does not understand you. From the different mails, I would say that
>> you are referring to an Android platform.
>> > If it's not the case, then sorry for the noise.
>> >
>> No I am not specifically referring to
>> Android platform
>> But yes, I am from android background
>> and through android only I came up with
>> this idea.
>>
>> > So, the last time I checked with android, this system does _not_ have an
>> udev user-space daemon, which means that what you seem to be doing is
>> parsing manually the sysfs tree to retrieve the inputs and their properties.
>> > This, IMO, is a very bad idea. Parsing the entire sysfs tree is indeed
>> costly and you will have to build everything by hand.
>> >
>> No, Android also have a daemon but it is not udev daemon. There is a
>> separate daemon in android different from generic
>> udev daemon. It is different but basic is
>> still same.
>> Just like udev daemon, android daemon
>> also receives uevents from kernel
>> and creates devfs nodes for us,
>> that is /Dev/input/event1/2/3... based
>> on uevent env variables.
>> Android daemon is different from generic
>> daemon in a sense it does not see any file
>> like udev rules before creating nodes. Instead it directly create nodes as
>> per uevent env variables in the structure.
>> So without opening any extra udev rule
>> file, it create nodes.
>> So I understand it has also a limitation that it only has to be dependent
>> only on default uevents and cannot read any sysfs attribute to identify the
>> device if default uevents are not sufficient.
>
> Why can it not?
>
It cannot because currently in android code, it does not read any
sysfs attribute.
It only reads default kernel uevents. I think functionality may be added to read
sysfs attribute also but this functionality is currently not added in
android code.
I think it is not added because in embedded system mostly there are only single
and unique devices and this manipulation might add extra time during android
initialization.
>>
>> But the problem I am referring is for both in case of generic kernel and
>> android kernel.
>
> So far I really do not see it as generic kernel problem since we do have
> existing infrastructure in userspace that is quite efficient.
>
The existing way is also there but there is always a scope of improvement.
Tell me which is more efficient ?
1. existing method in which udev opens and read udev files for setting name
or
2. Directly set name without doing extra calculations
Its correct existing method will also do the same task but why not to use
more efficient way.
I just want to improve efficiency.
>>
>> > On regular distros, we use udev. This daemon builds its device database
>> from the events generated by the kernels directly (the uevents). Once the
>> events are emitted, we never (except for some user-space drivers) use them
>> in the kernel drivers (at least, I never saw that).
>> >
>> > So if you want to create symlinks, then indeed, you just add 2 or 3 rules
>> in /etc/udev/rules.d, and then the user space (and the system integrator)
>> can see the different devices with the "correct" symlink.
>> > However, the kernel developer will never see them (and especially in the
>> ->probe callback). However, the user-space tools which receives the udev
>> events (emitted from udev, not the kernel this time) can easily retrieve
>> many information from the event. Just run "udevadm info --export-db" on a
>> regular Linux, and you will see that the device which presents the event
>> node (/dev/input/eventX) has all the requirements to identify itself (VID,
>> PID, path, etc...)
>> >
>> Yes udev gives so many uevents but as I checked through logs specifically
>> in case of /Dev/input/event1/2/3/4....it does not give sufficient uevents
>> to identify the device.
>> As I found in logs it gives only 7 env variable like action, subsystem, Dev
>> name, Dev path, major, minor and seq number.
>> It does not give vendor Id or pid.
>> Now with these uevent we cannot identify the input device whether its
>> accelerometer or touchscreen. Can we ??
>
> While information sent in uevent emitted for creation of event device
> might not be enough to identify and classify input device you can:
>
> 1. Capture udevent sent a few moments earlier for the input device
> itself, or
>
> 2. Read /sys/class/$DEVNAME/device/uevent to retrieve input device's
> uevent data:
>
> [dtor@dtor-d630 work]$ cat /sys/class/input/event6/uevent
> MAJOR=13
> MINOR=70
> DEVNAME=input/event6
> [dtor@dtor-d630 work]$ cat /sys/class/input/event6/device/uevent
> PRODUCT=11/2/8/300
> NAME="AlpsPS/2 ALPS DualPoint TouchPad"
> PHYS="isa0060/serio1/input0"
> PROP=8
> EV=b
> KEY=e420 70000 0 0 0 0
> ABS=260800001000003
> MODALIAS=input:b0011v0002p0008e0300-e0,1,3,k110,111,112,145,14A,14D,14E,14F,ra0,1,18,2F,35,36,39,mlsfw
> [dtor@dtor-d630 work]$
>
> That should give you plenty data to work with. Yes, the 2nd option
> involves additional filesystem operations, but this is sysfs (so you are
> not hitting real media) and you only need a few (open, read, and close)
> per device.
Yes this method can surely solve the task , but not the purpose.
My query is why not to use more efficient way when we can ?
( Already discussed this way is backward compatible and is optional to use)
Apart from above, Could you please tell me the role/use of init_name variable,
which is defined in "struct device" ?
(I think, it is also used to set name of device node)
Thanks,
Aniroop Mathur
>
> Thanks.
>
> --
> Dmitry
^ permalink raw reply
* Re: [PATCH 1/4] input: mc13783: Make mc13xxx_buttons_platform_data more flexible
From: Lee Jones @ 2014-02-10 11:29 UTC (permalink / raw)
To: Alexander Shiyan
Cc: linux-input, Dmitry Torokhov, Shawn Guo, Sascha Hauer,
Samuel Ortiz
In-Reply-To: <1392006129-10227-1-git-send-email-shc_work@mail.ru>
> Instead of define each button in separate variable, make an array
> for storing all buttons. This change will help to add support for
> other types of PMIC and add support for probing with devicetree
> in the future.
>
> Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
> ---
> arch/arm/mach-imx/mach-mx31moboard.c | 9 ++++--
> drivers/input/misc/mc13783-pwrbutton.c | 56 +++++++++++++++++-----------------
> include/linux/mfd/mc13xxx.h | 28 +++++++++--------
Are all the changes in these files entangled? If there is any way to
make them orthogonal, then all the better.
<snip>
> --- a/include/linux/mfd/mc13xxx.h
> +++ b/include/linux/mfd/mc13xxx.h
> @@ -172,20 +172,22 @@ struct mc13xxx_leds_platform_data {
> u32 led_control[MAX_LED_CONTROL_REGS];
> };
>
> +#define MAX13XXX_NUM_BUTTONS 3
> +
> +struct mc13xxx_button {
> + u16 keycode;
> + unsigned int flags;
> +#define MC13XXX_BUTTON_DBNC_0MS 0
> +#define MC13XXX_BUTTON_DBNC_30MS 1
> +#define MC13XXX_BUTTON_DBNC_150MS 2
> +#define MC13XXX_BUTTON_DBNC_750MS 3
> +#define MC13XXX_BUTTON_ENABLE (1 << 2)
> +#define MC13XXX_BUTTON_POL_INVERT (1 << 3)
> +#define MC13XXX_BUTTON_RESET_EN (1 << 4)
> +};
> +
Please take the opportunity to remove this slab list of #defines from
the centre of the struct definition. Just above will be fine.
> struct mc13xxx_buttons_platform_data {
> -#define MC13783_BUTTON_DBNC_0MS 0
> -#define MC13783_BUTTON_DBNC_30MS 1
> -#define MC13783_BUTTON_DBNC_150MS 2
> -#define MC13783_BUTTON_DBNC_750MS 3
> -#define MC13783_BUTTON_ENABLE (1 << 2)
> -#define MC13783_BUTTON_POL_INVERT (1 << 3)
> -#define MC13783_BUTTON_RESET_EN (1 << 4)
> - int b1on_flags;
> - unsigned short b1on_key;
> - int b2on_flags;
> - unsigned short b2on_key;
> - int b3on_flags;
> - unsigned short b3on_key;
> + struct mc13xxx_button buttons[MAX13XXX_NUM_BUTTONS];
> };
>
> struct mc13xxx_ts_platform_data {
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
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
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