* [git pull] Input updates for 3.13-rc6
From: Dmitry Torokhov @ 2013-12-31 19:06 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-kernel, linux-input
[-- Attachment #1: Type: text/plain, Size: 928 bytes --]
Hi Linus,
Happy New Year!
Please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
or
master.kernel.org:/pub/scm/linux/kernel/git/dtor/input.git for-linus
to receive updates for the input subsystem. You will get a fix for panic
in gpio-keys driver when set up with absolute events, a fixup to the new
zforce driver and a new keycode definition.
Changelog:
---------
Dmitry Torokhov (1):
Input: allocate absinfo data when setting ABS capability
Heiko Stübner (1):
Input: zforce - fix possible driver hang during suspend
Rafał Miłecki (1):
Input: define KEY_WWAN for Wireless WAN
Diffstat:
--------
drivers/input/input.c | 4 ++++
drivers/input/touchscreen/zforce_ts.c | 21 +++++++++++++++------
include/uapi/linux/input.h | 3 ++-
3 files changed, 21 insertions(+), 7 deletions(-)
--
Dmitry
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH] Input: cros_ec_keyb - switch from using uint8_t to u8
From: Dmitry Torokhov @ 2013-12-31 19:34 UTC (permalink / raw)
To: linux-input
Cc: Simon Glass, Vincent Palatin, Luigi Semenzato, Doug Anderson,
linux-kernel
u8 is proper in-kernel type for unsigned byte data.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/keyboard/cros_ec_keyb.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index 4083796..d44c5d4 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -50,7 +50,7 @@ struct cros_ec_keyb {
int row_shift;
const struct matrix_keymap_data *keymap_data;
bool ghost_filter;
- uint8_t *old_kb_state;
+ u8 *old_kb_state;
struct device *dev;
struct input_dev *idev;
@@ -60,7 +60,7 @@ struct cros_ec_keyb {
static bool cros_ec_keyb_row_has_ghosting(struct cros_ec_keyb *ckdev,
- uint8_t *buf, int row)
+ u8 *buf, int row)
{
int pressed_in_row = 0;
int row_has_teeth = 0;
@@ -89,7 +89,7 @@ static bool cros_ec_keyb_row_has_ghosting(struct cros_ec_keyb *ckdev,
* Returns true when there is at least one combination of pressed keys that
* results in ghosting.
*/
-static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf)
+static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, u8 *buf)
{
int row;
@@ -132,7 +132,7 @@ static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf)
* per column)
*/
static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
- uint8_t *kb_state, int len)
+ u8 *kb_state, int len)
{
struct input_dev *idev = ckdev->idev;
int col, row;
@@ -189,19 +189,19 @@ static void cros_ec_keyb_close(struct input_dev *dev)
&ckdev->notifier);
}
-static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
+static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, u8 *kb_state)
{
return ckdev->ec->command_recv(ckdev->ec, EC_CMD_MKBP_STATE,
kb_state, ckdev->cols);
}
static int cros_ec_keyb_work(struct notifier_block *nb,
- unsigned long state, void *_notify)
+ unsigned long state, void *_notify)
{
int ret;
struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb,
notifier);
- uint8_t kb_state[ckdev->cols];
+ u8 kb_state[ckdev->cols];
ret = cros_ec_keyb_get_state(ckdev, kb_state);
if (ret >= 0)
@@ -282,8 +282,8 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
/* Clear any keys in the buffer */
static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
{
- uint8_t old_state[ckdev->cols];
- uint8_t new_state[ckdev->cols];
+ u8 old_state[ckdev->cols];
+ u8 new_state[ckdev->cols];
unsigned long duration;
int i, ret;
--
1.8.3.1
--
Dmitry
^ permalink raw reply related
* [PATCH] Input: cros_ec_keyb - avoid variable-length arrays on stack
From: Dmitry Torokhov @ 2013-12-31 19:35 UTC (permalink / raw)
To: linux-input
Cc: Simon Glass, Vincent Palatin, Luigi Semenzato, Doug Anderson,
linux-kernel
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
drivers/input/keyboard/cros_ec_keyb.c | 80 ++++++++++++++++++++---------------
1 file changed, 45 insertions(+), 35 deletions(-)
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index d44c5d4..03cb960 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -39,6 +39,7 @@
* @keymap_data: Matrix keymap data used to convert to keyscan values
* @ghost_filter: true to enable the matrix key-ghosting filter
* @old_kb_state: bitmap of keys pressed last scan
+ * @kb_state: bitmap of keys currently pressed
* @dev: Device pointer
* @idev: Input device
* @ec: Top level ChromeOS device to use to talk to EC
@@ -50,17 +51,17 @@ struct cros_ec_keyb {
int row_shift;
const struct matrix_keymap_data *keymap_data;
bool ghost_filter;
- u8 *old_kb_state;
-
struct device *dev;
struct input_dev *idev;
struct cros_ec_device *ec;
struct notifier_block notifier;
+
+ u8 *old_kb_state;
+ u8 kb_state[];
};
-static bool cros_ec_keyb_row_has_ghosting(struct cros_ec_keyb *ckdev,
- u8 *buf, int row)
+static bool cros_ec_keyb_row_has_ghosting(struct cros_ec_keyb *ckdev, int row)
{
int pressed_in_row = 0;
int row_has_teeth = 0;
@@ -68,9 +69,9 @@ static bool cros_ec_keyb_row_has_ghosting(struct cros_ec_keyb *ckdev,
mask = 1 << row;
for (col = 0; col < ckdev->cols; col++) {
- if (buf[col] & mask) {
+ if (ckdev->kb_state[col] & mask) {
pressed_in_row++;
- row_has_teeth |= buf[col] & ~mask;
+ row_has_teeth |= ckdev->kb_state[col] & ~mask;
if (pressed_in_row > 1 && row_has_teeth) {
/* ghosting */
dev_dbg(ckdev->dev,
@@ -89,7 +90,7 @@ static bool cros_ec_keyb_row_has_ghosting(struct cros_ec_keyb *ckdev,
* Returns true when there is at least one combination of pressed keys that
* results in ghosting.
*/
-static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, u8 *buf)
+static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev)
{
int row;
@@ -120,7 +121,7 @@ static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, u8 *buf)
* cheat because the number of rows is small.
*/
for (row = 0; row < ckdev->rows; row++)
- if (cros_ec_keyb_row_has_ghosting(ckdev, buf, row))
+ if (cros_ec_keyb_row_has_ghosting(ckdev, row))
return true;
return false;
@@ -131,8 +132,7 @@ static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, u8 *buf)
* press/release events accordingly. The keyboard state is 13 bytes (one byte
* per column)
*/
-static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
- u8 *kb_state, int len)
+static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, int len)
{
struct input_dev *idev = ckdev->idev;
int col, row;
@@ -142,7 +142,7 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
num_cols = len;
- if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) {
+ if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev)) {
/*
* Simple-minded solution: ignore this state. The obvious
* improvement is to only ignore changes to keys involved in
@@ -157,7 +157,7 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
const unsigned short *keycodes = idev->keycode;
- new_state = kb_state[col] & (1 << row);
+ new_state = ckdev->kb_state[col] & (1 << row);
old_state = ckdev->old_kb_state[col] & (1 << row);
if (new_state != old_state) {
dev_dbg(ckdev->dev,
@@ -168,9 +168,12 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
new_state);
}
}
- ckdev->old_kb_state[col] = kb_state[col];
}
+
input_sync(ckdev->idev);
+
+ memcpy(ckdev->old_kb_state, ckdev->kb_state,
+ ckdev->cols * sizeof(*ckdev->kb_state));
}
static int cros_ec_keyb_open(struct input_dev *dev)
@@ -189,10 +192,10 @@ static void cros_ec_keyb_close(struct input_dev *dev)
&ckdev->notifier);
}
-static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, u8 *kb_state)
+static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev)
{
return ckdev->ec->command_recv(ckdev->ec, EC_CMD_MKBP_STATE,
- kb_state, ckdev->cols);
+ ckdev->kb_state, ckdev->cols);
}
static int cros_ec_keyb_work(struct notifier_block *nb,
@@ -201,11 +204,10 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
int ret;
struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb,
notifier);
- u8 kb_state[ckdev->cols];
- ret = cros_ec_keyb_get_state(ckdev, kb_state);
+ ret = cros_ec_keyb_get_state(ckdev);
if (ret >= 0)
- cros_ec_keyb_process(ckdev, kb_state, ret);
+ cros_ec_keyb_process(ckdev, ret);
return NOTIFY_DONE;
}
@@ -217,32 +219,40 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
struct cros_ec_keyb *ckdev;
struct input_dev *idev;
struct device_node *np;
+ unsigned int rows, cols;
+ size_t size;
int err;
np = pdev->dev.of_node;
if (!np)
return -ENODEV;
- ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL);
- if (!ckdev)
- return -ENOMEM;
- err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows,
- &ckdev->cols);
+ err = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols);
if (err)
return err;
- ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL);
- if (!ckdev->old_kb_state)
- return -ENOMEM;
- idev = devm_input_allocate_device(&pdev->dev);
- if (!idev)
+ /*
+ * Double memory for keyboard state so we have space for storing
+ * current and previous state.
+ */
+ size = sizeof(*ckdev) + 2 * cols * sizeof(*ckdev->kb_state);
+ ckdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+ if (!ckdev)
return -ENOMEM;
+ ckdev->rows = rows;
+ ckdev->cols = cols;
+ ckdev->old_kb_state = &ckdev->kb_state[cols];
+
ckdev->ec = ec;
- ckdev->notifier.notifier_call = cros_ec_keyb_work;
ckdev->dev = dev;
+ ckdev->notifier.notifier_call = cros_ec_keyb_work;
dev_set_drvdata(&pdev->dev, ckdev);
+ idev = devm_input_allocate_device(&pdev->dev);
+ if (!idev)
+ return -ENOMEM;
+
idev->name = ec->ec_name;
idev->phys = ec->phys_name;
__set_bit(EV_REP, idev->evbit);
@@ -282,8 +292,6 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
/* Clear any keys in the buffer */
static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
{
- u8 old_state[ckdev->cols];
- u8 new_state[ckdev->cols];
unsigned long duration;
int i, ret;
@@ -294,11 +302,13 @@ static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
* Assume that the EC keyscan buffer is at most 32 deep.
*/
duration = jiffies;
- ret = cros_ec_keyb_get_state(ckdev, new_state);
+ ret = cros_ec_keyb_get_state(ckdev);
for (i = 1; !ret && i < 32; i++) {
- memcpy(old_state, new_state, sizeof(old_state));
- ret = cros_ec_keyb_get_state(ckdev, new_state);
- if (0 == memcmp(old_state, new_state, sizeof(old_state)))
+ memcpy(ckdev->old_kb_state, ckdev->kb_state,
+ ckdev->cols * sizeof(*ckdev->kb_state));
+ ret = cros_ec_keyb_get_state(ckdev);
+ if (!memcmp(ckdev->old_kb_state, ckdev->kb_state,
+ ckdev->cols * sizeof(*ckdev->kb_state)))
break;
}
duration = jiffies - duration;
--
1.8.3.1
--
Dmitry
^ permalink raw reply related
* Re: [PATCH 0/2] input: mt: Add helper function to send end events
From: Henrik Rydberg @ 2014-01-01 16:19 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Felipe F. Tonello, linux-input, linux-kernel
In-Reply-To: <20131231185035.GD6897@core.coreip.homeip.net>
Hi Dmitry,
>> What problematic scenario is this supposed to solve?
>>
>> The 'release on suspend' is only an approximation to the 'close
>> laptop' scenario, it is certainly not correct in the coffee table
>> case,
>
> Why would it not be correct for coffee table? Do we expect the touches
> to remain valid while the device is asleep?
In some scenarios with placed objects (like a cup or a marker), that would be
the case, yes.
>> for instance. Instead of
>> hardcoding this in the kernel, userland can easily detect long intervals
>> directly using the event time.
>
> But with slots it is not only problem with old events being sent out
> later, it is that we have mix of old (pre-sleep) and new state.
The new state is not really a problem, it will look exactly the same regardless
of how 'old' releases are handled.
> We do that for keys (release them when we transition to system sleep)
> and I think it might be worthwhile to do the same for touch data.
I agree that keyboard applications seldom look at time intervals and hence are
well helped by such a strategy, even though it is not strictly 'correct'.
However, touch interfaces are quite dependent on time intervals, and it
therefore makes a lot of sense to resolve touch timeouts directly in the
application. It also puts less restrictions on what can be done.
Regarding notifications in general, perhaps it would be interesting to be able
to send a notification event via the input interface when a device comes back
from sleep. It could help resolve other complex issues, if there were any.
Thanks,
Henrik
^ permalink raw reply
* Re: [PATCH 0/2] input: mt: Add helper function to send end events
From: Dmitry Torokhov @ 2014-01-01 19:18 UTC (permalink / raw)
To: Henrik Rydberg; +Cc: Felipe F. Tonello, linux-input, linux-kernel
In-Reply-To: <52C43FFE.3010005@euromail.se>
On Wed, Jan 01, 2014 at 05:19:10PM +0100, Henrik Rydberg wrote:
> Hi Dmitry,
>
> >> What problematic scenario is this supposed to solve?
> >>
> >> The 'release on suspend' is only an approximation to the 'close
> >> laptop' scenario, it is certainly not correct in the coffee table
> >> case,
> >
> > Why would it not be correct for coffee table? Do we expect the touches
> > to remain valid while the device is asleep?
>
> In some scenarios with placed objects (like a cup or a marker), that would be
> the case, yes.
>
> >> for instance. Instead of
> >> hardcoding this in the kernel, userland can easily detect long intervals
> >> directly using the event time.
> >
> > But with slots it is not only problem with old events being sent out
> > later, it is that we have mix of old (pre-sleep) and new state.
>
> The new state is not really a problem, it will look exactly the same regardless
> of how 'old' releases are handled.
>
> > We do that for keys (release them when we transition to system sleep)
> > and I think it might be worthwhile to do the same for touch data.
>
> I agree that keyboard applications seldom look at time intervals and hence are
> well helped by such a strategy, even though it is not strictly 'correct'.
> However, touch interfaces are quite dependent on time intervals, and it
> therefore makes a lot of sense to resolve touch timeouts directly in the
> application. It also puts less restrictions on what can be done.
>
> Regarding notifications in general, perhaps it would be interesting to be able
> to send a notification event via the input interface when a device comes back
> from sleep. It could help resolve other complex issues, if there were any.
>
OK, fair enough. If there is a demand we could send SYN_SYSTEM_RESUME
event though the interfaces to allow clients "flush" the state or
otherwise decide if new touch data is actually old touches that were
there pre-suspend.
Felipe, will that help in your case?
Thanks.
--
Dmitry
^ permalink raw reply
* Re: Changes on xpad.c
From: Dmitry Torokhov @ 2014-01-01 19:24 UTC (permalink / raw)
To: Thomaz de Oliveira dos Reis, Mag, Ilia Katsnelson; +Cc: Linux Input
In-Reply-To: <CAAXmX-ma_xX-AVbBJ-DeOQL09T6ZkE9wsN1R1MTuu=rHxwm58Q@mail.gmail.com>
Hi Thomaz, Nol, Ilia,
Happy New Year!
On Thu, Dec 26, 2013 at 10:07:58PM -0200, Thomaz de Oliveira dos Reis wrote:
> Hi!
>
> Hope it is correct.
You forgot to add "Signed-off-by: ..." to your change.
Ilia, Nol, you have added the initial mappings for Razer devices and
chose to map directional pad to buttons instead of HAT0X/Y axis. Could
you remind me why?
Thanks!
> 2013/12/26 Dmitry Torokhov <dmitry.torokhov@gmail.com>
>
> > Hi Tomaz,
> >
> > On Sat, Dec 21, 2013 at 09:48:12PM -0200, Thomaz de Oliveira dos Reis
> > wrote:
> > > Hi!
> > >
> > > I noticed that Razer Onza controller, different from tradional xbox
> > > gamepad, the dpad doesn't works in most games. (Some games is possibile
> > to
> > > configure changing a config file or with interface options but many games
> > > it doesn't works at all)
> > >
> > > Looking at module source code, I saw that it uses the
> > MAP_DPAD_TO_BUTTONS
> > > that was created to use with dance pad (with this controller is not), as
> > > written on this comment:
> > >
> > > Line 69: * - dance pads will map D-PAD to buttons, not axes
> > >
> > > Change this to 0 improve overal compatibility of the controller in most
> > > games, without losing any meaningful functionality.
> > >
> > > Also, if someone REALLY need this strange configuration, the user can set
> > > the "dpad_to_buttons" module param as described here:
> > >
> > > Line 103: MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather
> > > than axes for unknown pads");
> > >
> > > Attached the modified xpad.c module, downloaded from linux-next git file
> > > from today.
> >
> > Please generate a unified diff for your change. See
> > Documentation/SubmittngPatches for explanation how to do this.
> >
> > Thanks.
> >
> >
> > --
> > Dmitry
> >
> --- drivers/input/joystick/xpad.c.orig 2013-12-26 22:02:44.239687200 -0200
> +++ drivers/input/joystick/xpad.c 2013-12-26 22:03:13.199687196 -0200
> @@ -166,8 +166,8 @@ static const struct xpad_device {
> { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 },
> { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
> { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
> - { 0x1689, 0xfd00, "Razer Onza Tournament Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
> - { 0x1689, 0xfd01, "Razer Onza Classic Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
> + { 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 },
> + { 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 },
> { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 },
> { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
> { 0x1bad, 0xf016, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 },
--
Dmitry
^ permalink raw reply
* [PATCH 0/4] input: Add new sun4i-lradc-keys driver
From: Hans de Goede @ 2014-01-01 19:30 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Hi Dimitri,
Here is another input driver for Allwinner sunxi SoCs. As with the touchscreen
driver the dts files are posted here for completeness and will be merged
through Maxime's tree.
Please review and if everything is ok, add this to your tree for Linus.
Thanks & Regards,
Hans
^ permalink raw reply
* [PATCH 1/4] input: Add new sun4i-lradc-keys drivers
From: Hans de Goede @ 2014-01-01 19:30 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
In-Reply-To: <1388604610-20380-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Allwinnner sunxi SoCs have a low resolution adc (called lradc) which is
specifically designed to have various (tablet) keys (ie home, back, search,
etc). attached to it using a resistor network. This adds a driver for this.
There are 2 channels, currently this driver only supports chan0 since there
are no boards known to use chan1. The devicetree properties are already
prefixed with chan0 as preparation for chan1 support in the future.
This has been tested on an olimex a10s-olinuxino-micro, a13-olinuxino, and
a20-olinuxino-micro.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
.../devicetree/bindings/input/sun4i-lradc-keys.txt | 20 ++
drivers/input/keyboard/Kconfig | 10 +
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/sun4i-lradc-keys.c | 243 +++++++++++++++++++++
4 files changed, 274 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
create mode 100644 drivers/input/keyboard/sun4i-lradc-keys.c
diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
new file mode 100644
index 0000000..94960da
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
@@ -0,0 +1,20 @@
+Allwinner sun4i low res adc attached tablet keys
+------------------------------------------------
+
+Required properties:
+ - compatible: "allwinner,sun4i-lradc-keys"
+ - reg: mmio address range of the chip
+ - interrupts: interrupt to which the chip is connected
+ - allwinner,chan0-step: step in mV between keys must be 150 or 200
+ - allwinner,chan0-keycodes: array of include/uapi/linux/input.h KEY_ codes
+
+Example:
+
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ allwinner,chan0-step = <200>;
+ /* KEY_VOLUMEUP VOLUMEDOWN MENU ENTER HOME */
+ allwinner,chan0-keycodes = <115 114 139 28 102>;
+ };
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index bb174c1..d95e6e4 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -544,6 +544,16 @@ config KEYBOARD_STMPE
To compile this driver as a module, choose M here: the module will be
called stmpe-keypad.
+config KEYBOARD_SUN4I_LRADC
+ tristate "Allwinner sun4i low res adc attached tablet keys support"
+ depends on ARCH_SUNXI
+ help
+ This selects support for the Allwinner low res adc attached tablet
+ keys found on Allwinner sunxi SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sun4i-lradc-keys.
+
config KEYBOARD_DAVINCI
tristate "TI DaVinci Key Scan"
depends on ARCH_DAVINCI_DM365
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index a699b61..f3265bd 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
+obj-$(CONFIG_KEYBOARD_SUN4I_LRADC) += sun4i-lradc-keys.o
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o
obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o
diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c
new file mode 100644
index 0000000..9ef4d10
--- /dev/null
+++ b/drivers/input/keyboard/sun4i-lradc-keys.c
@@ -0,0 +1,243 @@
+/*
+ * Allwinner sun4i low res adc attached tablet keys driver
+ *
+ * Copyright (C) 2014 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Allwinnner sunxi SoCs have a lradc which is specifically designed to have
+ * various (tablet) keys (ie home, back, search, etc). attached to it using
+ * a resistor network. This driver is for the keys on such boards.
+ *
+ * There are 2 channels, currently this driver only supports chan0 since there
+ * are no boards known to use chan1. The devicetree properties are already
+ * prefixed with chan0 as preparation for chan1 support in the future.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define LRADC_CTRL 0x00
+#define LRADC_INTC 0x04
+#define LRADC_INTS 0x08
+#define LRADC_DATA0 0x0c
+#define LRADC_DATA1 0x10
+
+/* LRADC_CTRL bits */
+#define FIRST_CONVERT_DLY(x) ((x) << 24) /* 8 bits */
+#define CHAN_SELECT(x) ((x) << 22) /* 2 bits */
+#define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */
+#define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */
+#define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */
+#define HOLD_EN(x) ((x) << 6)
+#define LEVELB_VOL(x) ((x) << 4) /* 2 bits */
+#define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */
+#define ENABLE(x) ((x) << 0)
+
+/* LRADC_INTC and LRADC_INTS bits */
+#define CHAN1_KEYUP_IRQ BIT(12)
+#define CHAN1_ALRDY_HOLD_IRQ BIT(11)
+#define CHAN1_HOLD_IRQ BIT(10)
+#define CHAN1_KEYDOWN_IRQ BIT(9)
+#define CHAN1_DATA_IRQ BIT(8)
+#define CHAN0_KEYUP_IRQ BIT(4)
+#define CHAN0_ALRDY_HOLD_IRQ BIT(3)
+#define CHAN0_HOLD_IRQ BIT(2)
+#define CHAN0_KEYDOWN_IRQ BIT(1)
+#define CHAN0_DATA_IRQ BIT(0)
+
+#define MAX_KEYS 13
+
+/* Lookup table to map the adc val to a keycode index for 150 mv step size */
+static const u8 adc_val_to_key_index_step150[64] = {
+ 0, 0, 0,
+ 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2,
+ 3, 3, 3, 3,
+ 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6,
+ 7, 7, 7, 7,
+ 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9,
+ 10, 10, 10, 10,
+ 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
+};
+
+/* Lookup table to map the adc val to a keycode index for 200 mv step size */
+static const u8 adc_val_to_key_index_step200[64] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+};
+
+struct sun4i_lradc_data {
+ struct device *dev;
+ struct input_dev *input;
+ void __iomem *base;
+ u32 chan0_step;
+ u32 chan0_keycode;
+ u32 chan0_keycodes[MAX_KEYS];
+};
+
+static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)
+{
+ struct sun4i_lradc_data *lradc = dev_id;
+ u32 ints, val;
+
+ ints = readl(lradc->base + LRADC_INTS);
+
+ /*
+ * lradc supports only one keypress at a time, release does not give
+ * any info as to which key was released, so we cache the keycode.
+ */
+ if ((ints & CHAN0_KEYDOWN_IRQ) && lradc->chan0_keycode == 0) {
+ val = readl(lradc->base + LRADC_DATA0);
+ if (lradc->chan0_step == 150)
+ val = adc_val_to_key_index_step150[val];
+ else
+ val = adc_val_to_key_index_step200[val];
+
+ lradc->chan0_keycode = lradc->chan0_keycodes[val];
+ input_report_key(lradc->input, lradc->chan0_keycode, 1);
+ }
+
+ if (ints & CHAN0_KEYUP_IRQ) {
+ input_report_key(lradc->input, lradc->chan0_keycode, 0);
+ lradc->chan0_keycode = 0;
+ }
+
+ input_sync(lradc->input);
+
+ writel(ints, lradc->base + LRADC_INTS);
+
+ return IRQ_HANDLED;
+}
+
+static int sun4i_lradc_open(struct input_dev *dev)
+{
+ struct sun4i_lradc_data *lradc = input_get_drvdata(dev);
+
+ /*
+ * Set sample time to 16 ms / 62.5 Hz. Wait 2 * 16 ms for key to
+ * stabilize on press, wait (1 + 1) * 16 ms for key release
+ */
+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
+ SAMPLE_RATE(2) | ENABLE(1), lradc->base + LRADC_CTRL);
+
+ writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC);
+
+ return 0;
+}
+
+static void sun4i_lradc_close(struct input_dev *dev)
+{
+ struct sun4i_lradc_data *lradc = input_get_drvdata(dev);
+
+ /* Disable lradc, leave other settings unchanged */
+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
+ SAMPLE_RATE(2), lradc->base + LRADC_CTRL);
+ writel(0, lradc->base + LRADC_INTC);
+}
+
+static int sun4i_lradc_probe(struct platform_device *pdev)
+{
+ struct sun4i_lradc_data *lradc;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ int i, ret;
+
+ lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL);
+ if (!lradc)
+ return -ENOMEM;
+
+ ret = of_property_read_u32(np, "allwinner,chan0-step",
+ &lradc->chan0_step);
+ if (ret || (lradc->chan0_step != 150 && lradc->chan0_step != 200)) {
+ dev_err(dev, "Invalid allwinner,chan0-step dt-property\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < MAX_KEYS; i++)
+ of_property_read_u32_index(np, "allwinner,chan0-keycodes",
+ i, &lradc->chan0_keycodes[i]);
+
+ lradc->dev = dev;
+ lradc->input = devm_input_allocate_device(dev);
+ if (!lradc->input)
+ return -ENOMEM;
+
+ lradc->input->name = pdev->name;
+ lradc->input->phys = "sun4i_lradc/input0";
+ lradc->input->open = sun4i_lradc_open;
+ lradc->input->close = sun4i_lradc_close;
+ lradc->input->id.bustype = BUS_HOST;
+ lradc->input->id.vendor = 0x0001;
+ lradc->input->id.product = 0x0001;
+ lradc->input->id.version = 0x0100;
+ lradc->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY);
+ for (i = 0; i < MAX_KEYS; i++)
+ set_bit(lradc->chan0_keycodes[i], lradc->input->keybit);
+ input_set_drvdata(lradc->input, lradc);
+
+ lradc->base = devm_ioremap_resource(dev,
+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
+ if (IS_ERR(lradc->base))
+ return PTR_ERR(lradc->base);
+
+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), sun4i_lradc_irq,
+ 0, "sun4i-lradc-keys", lradc);
+ if (ret)
+ return ret;
+
+ ret = input_register_device(lradc->input);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, lradc);
+ return 0;
+}
+
+static const struct of_device_id sun4i_lradc_of_match[] = {
+ { .compatible = "allwinner,sun4i-lradc-keys", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match);
+
+static struct platform_driver sun4i_lradc_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "sun4i-lradc-keys",
+ .of_match_table = of_match_ptr(sun4i_lradc_of_match),
+ },
+ .probe = sun4i_lradc_probe,
+};
+
+module_platform_driver(sun4i_lradc_driver);
+
+MODULE_DESCRIPTION("Allwinner sun4i low res adc attached tablet keys driver");
+MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
+MODULE_LICENSE("GPL");
--
1.8.4.2
^ permalink raw reply related
* [PATCH 2/4] ARM: dts: sun4i: Add lradc node
From: Hans de Goede @ 2014-01-01 19:30 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
In-Reply-To: <1388604610-20380-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 502f3e2..88f119a 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -447,6 +447,13 @@
interrupts = <24>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-sid";
reg = <0x01c23800 0x10>;
--
1.8.4.2
^ permalink raw reply related
* [PATCH 3/4] ARM: dts: sun5i: Add lradc node
From: Hans de Goede @ 2014-01-01 19:30 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
In-Reply-To: <1388604610-20380-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 7 +++++++
arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 7 +++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 7 +++++++
4 files changed, 28 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index e53fb12..c32162e 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -75,6 +75,13 @@
};
};
+ lradc: lradc@01c22800 {
+ allwinner,chan0-step = <200>;
+ /* KEY_VOLUMEUP VOLUMEDOWN MENU ENTER HOME */
+ allwinner,chan0-keycodes = <115 114 139 28 102>;
+ status = "okay";
+ };
+
uart0: serial@01c28000 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 34dd303..8775bad 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -404,6 +404,13 @@
reg = <0x01c20c90 0x10>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-sid";
reg = <0x01c23800 0x10>;
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index ab566f7..ce31361 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -55,6 +55,13 @@
};
};
+ lradc: lradc@01c22800 {
+ allwinner,chan0-step = <200>;
+ /* KEY_VOLUMEUP VOLUMEDOWN MENU ENTER HOME */
+ allwinner,chan0-keycodes = <115 114 139 28 102>;
+ status = "okay";
+ };
+
uart1: serial@01c28400 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins_b>;
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 264cfa4..90c1ed3 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -362,6 +362,13 @@
reg = <0x01c20c90 0x10>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-sid";
reg = <0x01c23800 0x10>;
--
1.8.4.2
^ permalink raw reply related
* [PATCH 4/4] ARM: dts: sun7i: Add lradc node
From: Hans de Goede @ 2014-01-01 19:30 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
In-Reply-To: <1388604610-20380-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 7 +++++++
arch/arm/boot/dts/sun7i-a20.dtsi | 7 +++++++
2 files changed, 14 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index 0ee2641..dcf9db7 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -86,6 +86,13 @@
};
};
+ lradc: lradc@01c22800 {
+ allwinner,chan0-step = <200>;
+ /* VOLUMEUP VOLUMEDOWN MENU SEARCH HOME ESC ENTER */
+ allwinner,chan0-keycodes = <115 114 139 217 102 1 28>;
+ status = "okay";
+ };
+
uart0: serial@01c28000 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 68e825a..3484275 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -531,6 +531,13 @@
interrupts = <0 24 1>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <0 31 4>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun7i-a20-sid";
reg = <0x01c23800 0x200>;
--
1.8.4.2
^ permalink raw reply related
* Re: [PATCH 3/4] ARM: dts: sun5i: Add lradc node
From: Andrew Lunn @ 2014-01-01 19:45 UTC (permalink / raw)
To: Hans de Goede
Cc: Dmitry Torokhov, Maxime Ripard,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-input-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1388604610-20380-4-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Wed, Jan 01, 2014 at 08:30:09PM +0100, Hans de Goede wrote:
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 7 +++++++
> arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
> arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 7 +++++++
> arch/arm/boot/dts/sun5i-a13.dtsi | 7 +++++++
> 4 files changed, 28 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
> index e53fb12..c32162e 100644
> --- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
> +++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
> @@ -75,6 +75,13 @@
> };
> };
>
> + lradc: lradc@01c22800 {
> + allwinner,chan0-step = <200>;
> + /* KEY_VOLUMEUP VOLUMEDOWN MENU ENTER HOME */
> + allwinner,chan0-keycodes = <115 114 139 28 102>;
Hi Hans
You might want to consider using arch/arm/boot/dts/include/dt-bindings/input/input.h
and then you could have the node:
> + lradc: lradc@01c22800 {
> + allwinner,chan0-step = <200>;
> + allwinner,chan0-keycodes = <KEY_VOLUMEUP VOLUMEDOWN MENU ENTER HOME>;
which is much more readable.
Andrew
^ permalink raw reply
* Re: [PATCH 1/4] input: Add new sun4i-lradc-keys drivers
From: Dmitry Torokhov @ 2014-01-01 20:56 UTC (permalink / raw)
To: Hans de Goede
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <1388604610-20380-2-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Hi Hans,
On Wed, Jan 01, 2014 at 08:30:07PM +0100, Hans de Goede wrote:
> +Required properties:
> + - compatible: "allwinner,sun4i-lradc-keys"
> + - reg: mmio address range of the chip
> + - interrupts: interrupt to which the chip is connected
> + - allwinner,chan0-step: step in mV between keys must be 150 or 200
> + - allwinner,chan0-keycodes: array of include/uapi/linux/input.h KEY_ codes
I think this should be "linux,chan0-keycodes".
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v3 3/5] ARM: dts: sun4i: Add rtp controller node
From: Maxime Ripard @ 2014-01-01 22:51 UTC (permalink / raw)
To: Hans de Goede
Cc: Dmitry Torokhov, linux-input-u79uwXL29TY76Z2rM5mHXA, LM Sensors,
Corentin LABBE, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <1388506852-3548-4-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 361 bytes --]
On Tue, Dec 31, 2013 at 05:20:50PM +0100, Hans de Goede wrote:
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Applied, together with the patch 4/5 and 5/5, in my sunxi/dt-for-3.14
branch.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH v2] ims-pcu: Add commands supported by the new version of the FW
From: Andrey Smirnov @ 2014-01-02 0:47 UTC (permalink / raw)
To: linux-input; +Cc: andrew.smirnov, dmitry.torokhov, linux-kernel
New version of the PCU firmware supports two new commands:
- IMS_PCU_CMD_OFN_SET_CONFIG which allows to write data to the
registers of one finger navigation(OFN) chip present on the device
- IMS_PCU_CMD_OFN_GET_CONFIG which allows to read data form the
registers of said chip.
This commit adds two helper functions to use those commands and sysfs
attributes to use them. It also exposes some OFN configuration
parameters via sysfs.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/input/misc/ims-pcu.c | 269 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 262 insertions(+), 7 deletions(-)
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index e204f26..4244f47 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -68,6 +68,9 @@ struct ims_pcu {
char bl_version[IMS_PCU_BL_VERSION_LEN];
char reset_reason[IMS_PCU_BL_RESET_REASON_LEN];
int update_firmware_status;
+ u8 device_id;
+
+ u8 ofn_reg_addr;
struct usb_interface *ctrl_intf;
@@ -371,6 +374,8 @@ static void ims_pcu_destroy_gamepad(struct ims_pcu *pcu)
#define IMS_PCU_CMD_GET_DEVICE_ID 0xae
#define IMS_PCU_CMD_SPECIAL_INFO 0xb0
#define IMS_PCU_CMD_BOOTLOADER 0xb1 /* Pass data to bootloader */
+#define IMS_PCU_CMD_OFN_SET_CONFIG 0xb3
+#define IMS_PCU_CMD_OFN_GET_CONFIG 0xb4
/* PCU responses */
#define IMS_PCU_RSP_STATUS 0xc0
@@ -389,6 +394,9 @@ static void ims_pcu_destroy_gamepad(struct ims_pcu *pcu)
#define IMS_PCU_RSP_GET_DEVICE_ID 0xce
#define IMS_PCU_RSP_SPECIAL_INFO 0xd0
#define IMS_PCU_RSP_BOOTLOADER 0xd1 /* Bootloader response */
+#define IMS_PCU_RSP_OFN_SET_CONFIG 0xd2
+#define IMS_PCU_RSP_OFN_GET_CONFIG 0xd3
+
#define IMS_PCU_RSP_EVNT_BUTTONS 0xe0 /* Unsolicited, button state */
#define IMS_PCU_GAMEPAD_MASK 0x0001ff80UL /* Bits 7 through 16 */
@@ -1216,6 +1224,227 @@ ims_pcu_update_firmware_status_show(struct device *dev,
static DEVICE_ATTR(update_firmware_status, S_IRUGO,
ims_pcu_update_firmware_status_show, NULL);
+enum pcu_ofn_offsets {
+ OFN_REG_RESULT_LSB_OFFSET = 2,
+ OFN_REG_RESULT_MSB_OFFSET = 3,
+};
+
+static ssize_t ims_pcu_ofn_reg_data_show(struct device *dev,
+ struct device_attribute *dattr,
+ char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct ims_pcu *pcu = usb_get_intfdata(intf);
+ int error;
+
+ mutex_lock(&pcu->cmd_mutex);
+
+ error = ims_pcu_execute_command(pcu, OFN_GET_CONFIG,
+ &pcu->ofn_reg_addr,
+ sizeof(pcu->ofn_reg_addr));
+ if (error >= 0) {
+ const s16 result = pcu->cmd_buf[OFN_REG_RESULT_MSB_OFFSET] << 8 |
+ pcu->cmd_buf[OFN_REG_RESULT_LSB_OFFSET];
+ if (result < 0)
+ error = result;
+ else
+ error = scnprintf(buf, PAGE_SIZE, "%x\n", result);
+ }
+
+ mutex_unlock(&pcu->cmd_mutex);
+
+ return error;
+}
+
+static ssize_t ims_pcu_ofn_reg_data_store(struct device *dev,
+ struct device_attribute *dattr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct ims_pcu *pcu = usb_get_intfdata(intf);
+ int error;
+ u8 value;
+ u8 buffer[2];
+ s16 result;
+
+ error = kstrtou8(buf, 0, &value);
+ if (error)
+ return error;
+
+ buffer[0] = pcu->ofn_reg_addr;
+ buffer[1] = value;
+
+ mutex_lock(&pcu->cmd_mutex);
+
+ error = ims_pcu_execute_command(pcu, OFN_SET_CONFIG,
+ &buffer, sizeof(buffer));
+
+ result = pcu->cmd_buf[OFN_REG_RESULT_MSB_OFFSET] << 8 |
+ pcu->cmd_buf[OFN_REG_RESULT_LSB_OFFSET];
+
+ mutex_unlock(&pcu->cmd_mutex);
+
+ if (!error && result < 0)
+ error = -ENOENT;
+
+ return error ?: count;
+}
+
+static DEVICE_ATTR(ofn_reg_data, S_IRUGO | S_IWUSR,
+ ims_pcu_ofn_reg_data_show, ims_pcu_ofn_reg_data_store);
+
+static ssize_t ims_pcu_ofn_reg_addr_show(struct device *dev,
+ struct device_attribute *dattr,
+ char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct ims_pcu *pcu = usb_get_intfdata(intf);
+ int error;
+
+ mutex_lock(&pcu->cmd_mutex);
+ error = scnprintf(buf, PAGE_SIZE, "%x\n", pcu->ofn_reg_addr);
+ mutex_unlock(&pcu->cmd_mutex);
+
+ return error;
+}
+
+static ssize_t ims_pcu_ofn_reg_addr_store(struct device *dev,
+ struct device_attribute *dattr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct ims_pcu *pcu = usb_get_intfdata(intf);
+ int error;
+ u8 value;
+
+ error = kstrtou8(buf, 0, &value);
+ if (error)
+ return error;
+
+ mutex_lock(&pcu->cmd_mutex);
+ pcu->ofn_reg_addr = value;
+ mutex_unlock(&pcu->cmd_mutex);
+
+ return error ?: count;
+}
+
+static DEVICE_ATTR(ofn_reg_addr, S_IRUGO | S_IWUSR,
+ ims_pcu_ofn_reg_addr_show, ims_pcu_ofn_reg_addr_store);
+
+static ssize_t ims_pcu_ofn_bit_show(u8 addr, u8 nr,
+ struct device *dev,
+ struct device_attribute *dattr,
+ char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct ims_pcu *pcu = usb_get_intfdata(intf);
+ int error;
+
+ mutex_lock(&pcu->cmd_mutex);
+
+ error = ims_pcu_execute_command(pcu, OFN_GET_CONFIG,
+ &addr, sizeof(addr));
+ if (error >= 0) {
+ const s16 result = pcu->cmd_buf[OFN_REG_RESULT_MSB_OFFSET] << 8 |
+ pcu->cmd_buf[OFN_REG_RESULT_LSB_OFFSET];
+ if (result < 0)
+ error = result;
+ else
+ error = scnprintf(buf, PAGE_SIZE, "%d\n",
+ !!(result & (1 << nr)));
+ }
+
+ mutex_unlock(&pcu->cmd_mutex);
+ return error;
+}
+
+static ssize_t ims_pcu_ofn_bit_store(u8 addr, u8 nr,
+ struct device *dev,
+ struct device_attribute *dattr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct ims_pcu *pcu = usb_get_intfdata(intf);
+ int error;
+ int value;
+ u8 contents;
+
+
+ error = kstrtoint(buf, 0, &value);
+ if (error)
+ return error;
+
+ if (value > 1)
+ return -EINVAL;
+
+ mutex_lock(&pcu->cmd_mutex);
+
+ error = ims_pcu_execute_command(pcu, OFN_GET_CONFIG,
+ &addr, sizeof(addr));
+ if (error < 0)
+ goto exit;
+
+ {
+ const s16 result = pcu->cmd_buf[OFN_REG_RESULT_MSB_OFFSET] << 8 |
+ pcu->cmd_buf[OFN_REG_RESULT_LSB_OFFSET];
+ if (result < 0) {
+ error = result;
+ goto exit;
+ }
+ contents = (u8) result;
+ }
+
+ if (value)
+ contents |= 1 << nr;
+ else
+ contents &= ~(1 << nr);
+
+ {
+ const u8 buffer[] = { addr, contents };
+ error = ims_pcu_execute_command(pcu, OFN_SET_CONFIG,
+ &buffer, sizeof(buffer));
+ }
+
+exit:
+ mutex_unlock(&pcu->cmd_mutex);
+
+ if (!error) {
+ const s16 result = pcu->cmd_buf[OFN_REG_RESULT_MSB_OFFSET] << 8 |
+ pcu->cmd_buf[OFN_REG_RESULT_LSB_OFFSET];
+ error = result;
+ }
+
+ return error ?: count;
+}
+
+
+#define IMS_PCU_BIT_ATTR(name, addr, nr) \
+ static ssize_t ims_pcu_##name##_show(struct device *dev, \
+ struct device_attribute *dattr, \
+ char *buf) \
+ { \
+ return ims_pcu_ofn_bit_show(addr, nr, dev, dattr, buf); \
+ } \
+ \
+ static ssize_t ims_pcu_##name##_store(struct device *dev, \
+ struct device_attribute *dattr, \
+ const char *buf, size_t count) \
+ { \
+ return ims_pcu_ofn_bit_store(addr, nr, dev, dattr, buf, count); \
+ } \
+ \
+ static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, \
+ ims_pcu_##name##_show, ims_pcu_##name##_store)
+
+IMS_PCU_BIT_ATTR(ofn_engine_enable, 0x60, 7);
+IMS_PCU_BIT_ATTR(ofn_speed_enable, 0x60, 6);
+IMS_PCU_BIT_ATTR(ofn_assert_enable, 0x60, 5);
+IMS_PCU_BIT_ATTR(ofn_xyquant_enable, 0x60, 4);
+IMS_PCU_BIT_ATTR(ofn_xyscale_enable, 0x60, 1);
+
+IMS_PCU_BIT_ATTR(ofn_scale_x2, 0x63, 6);
+IMS_PCU_BIT_ATTR(ofn_scale_y2, 0x63, 7);
+
static struct attribute *ims_pcu_attrs[] = {
&ims_pcu_attr_part_number.dattr.attr,
&ims_pcu_attr_serial_number.dattr.attr,
@@ -1226,6 +1455,18 @@ static struct attribute *ims_pcu_attrs[] = {
&dev_attr_reset_device.attr,
&dev_attr_update_firmware.attr,
&dev_attr_update_firmware_status.attr,
+
+#define IMS_PCU_ATTRS_OFN_START_OFFSET (9)
+
+ &dev_attr_ofn_reg_data.attr,
+ &dev_attr_ofn_reg_addr.attr,
+ &dev_attr_ofn_engine_enable.attr,
+ &dev_attr_ofn_speed_enable.attr,
+ &dev_attr_ofn_assert_enable.attr,
+ &dev_attr_ofn_xyquant_enable.attr,
+ &dev_attr_ofn_xyscale_enable.attr,
+ &dev_attr_ofn_scale_x2.attr,
+ &dev_attr_ofn_scale_y2.attr,
NULL
};
@@ -1244,8 +1485,21 @@ static umode_t ims_pcu_is_attr_visible(struct kobject *kobj,
mode = 0;
}
} else {
- if (attr == &dev_attr_update_firmware_status.attr)
+ if (attr == &dev_attr_update_firmware_status.attr) {
mode = 0;
+ } else if (pcu->setup_complete && pcu->device_id == 5) {
+ /*
+ PCU-B devices, both GEN_1 and GEN_2(device_id == 5),
+ have no OFN sensor so exposing those attributes
+ for them does not make any sense
+ */
+ int i;
+ for (i = IMS_PCU_ATTRS_OFN_START_OFFSET; ims_pcu_attrs[i]; i++)
+ if (attr == ims_pcu_attrs[i]) {
+ mode = 0;
+ break;
+ }
+ }
}
return mode;
@@ -1624,7 +1878,6 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
static atomic_t device_no = ATOMIC_INIT(0);
const struct ims_pcu_device_info *info;
- u8 device_id;
int error;
error = ims_pcu_get_device_info(pcu);
@@ -1633,7 +1886,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
return error;
}
- error = ims_pcu_identify_type(pcu, &device_id);
+ error = ims_pcu_identify_type(pcu, &pcu->device_id);
if (error) {
dev_err(pcu->dev,
"Failed to identify device, error: %d\n", error);
@@ -1645,9 +1898,9 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
return 0;
}
- if (device_id >= ARRAY_SIZE(ims_pcu_device_info) ||
- !ims_pcu_device_info[device_id].keymap) {
- dev_err(pcu->dev, "Device ID %d is not valid\n", device_id);
+ if (pcu->device_id >= ARRAY_SIZE(ims_pcu_device_info) ||
+ !ims_pcu_device_info[pcu->device_id].keymap) {
+ dev_err(pcu->dev, "Device ID %d is not valid\n", pcu->device_id);
/* Same as above, punt to userspace */
return 0;
}
@@ -1659,7 +1912,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
if (error)
return error;
- info = &ims_pcu_device_info[device_id];
+ info = &ims_pcu_device_info[pcu->device_id];
error = ims_pcu_setup_buttons(pcu, info->keymap, info->keymap_len);
if (error)
goto err_destroy_backlight;
@@ -1672,6 +1925,8 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
pcu->setup_complete = true;
+ sysfs_update_group(&pcu->dev->kobj, &ims_pcu_attr_group);
+
return 0;
err_destroy_backlight:
--
1.8.3.2
^ permalink raw reply related
* Re: Re: [PATCH 3/4] ARM: dts: sun5i: Add lradc node
From: Hans de Goede @ 2014-01-02 9:37 UTC (permalink / raw)
To: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: Dmitry Torokhov, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-input-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20140101194532.GQ32537-g2DYL2Zd6BY@public.gmane.org>
Hi,
On 01/01/2014 08:45 PM, Andrew Lunn wrote:
> On Wed, Jan 01, 2014 at 08:30:09PM +0100, Hans de Goede wrote:
>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> ---
>> arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 7 +++++++
>> arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
>> arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 7 +++++++
>> arch/arm/boot/dts/sun5i-a13.dtsi | 7 +++++++
>> 4 files changed, 28 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
>> index e53fb12..c32162e 100644
>> --- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
>> +++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
>> @@ -75,6 +75,13 @@
>> };
>> };
>>
>> + lradc: lradc@01c22800 {
>> + allwinner,chan0-step = <200>;
>> + /* KEY_VOLUMEUP VOLUMEDOWN MENU ENTER HOME */
>> + allwinner,chan0-keycodes = <115 114 139 28 102>;
>
> Hi Hans
>
> You might want to consider using arch/arm/boot/dts/include/dt-bindings/input/input.h
>
> and then you could have the node:
>
>> + lradc: lradc@01c22800 {
>> + allwinner,chan0-step = <200>;
>> + allwinner,chan0-keycodes = <KEY_VOLUMEUP VOLUMEDOWN MENU ENTER HOME>;
>
> which is much more readable.
Ah, I did not know about that include. Good tip, will fix this in v2.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH 1/4] input: Add new sun4i-lradc-keys drivers
From: Hans de Goede @ 2014-01-02 9:37 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20140101205603.GA1141-WlK9ik9hQGAhIp7JRqBPierSzoNAToWh@public.gmane.org>
Hi,
On 01/01/2014 09:56 PM, Dmitry Torokhov wrote:
> Hi Hans,
>
> On Wed, Jan 01, 2014 at 08:30:07PM +0100, Hans de Goede wrote:
>> +Required properties:
>> + - compatible: "allwinner,sun4i-lradc-keys"
>> + - reg: mmio address range of the chip
>> + - interrupts: interrupt to which the chip is connected
>> + - allwinner,chan0-step: step in mV between keys must be 150 or 200
>> + - allwinner,chan0-keycodes: array of include/uapi/linux/input.h KEY_ codes
>
> I think this should be "linux,chan0-keycodes".
Right, because the codes are Linux specific, will fix in v2.
Regards,
Hans
^ permalink raw reply
* [PATCH v2 0/4] input: Add new sun4i-lradc-keys driver
From: Hans de Goede @ 2014-01-02 9:58 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Hi Dimitri et al,
Here is v2 of the sun4i-lradc-keys driver, changes since v1:
- Use include/dt-bindings/input/input.h
- Rename the keycodes property to linux,chan0-keycodes
Regards,
Hans
^ permalink raw reply
* [PATCH v2 1/4] input: Add new sun4i-lradc-keys driver
From: Hans de Goede @ 2014-01-02 9:58 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
In-Reply-To: <1388656707-16181-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Allwinnner sunxi SoCs have a low resolution adc (called lradc) which is
specifically designed to have various (tablet) keys (ie home, back, search,
etc). attached to it using a resistor network. This adds a driver for this.
There are 2 channels, currently this driver only supports chan0 since there
are no boards known to use chan1. The devicetree properties are already
prefixed with chan0 as preparation for chan1 support in the future.
This has been tested on an olimex a10s-olinuxino-micro, a13-olinuxino, and
a20-olinuxino-micro.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
.../devicetree/bindings/input/sun4i-lradc-keys.txt | 22 ++
drivers/input/keyboard/Kconfig | 10 +
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/sun4i-lradc-keys.c | 243 +++++++++++++++++++++
4 files changed, 276 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
create mode 100644 drivers/input/keyboard/sun4i-lradc-keys.c
diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
new file mode 100644
index 0000000..7801264
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
@@ -0,0 +1,22 @@
+Allwinner sun4i low res adc attached tablet keys
+------------------------------------------------
+
+Required properties:
+ - compatible: "allwinner,sun4i-lradc-keys"
+ - reg: mmio address range of the chip
+ - interrupts: interrupt to which the chip is connected
+ - allwinner,chan0-step: step in mV between keys must be 150 or 200
+ - linux,chan0-keycodes: array of dt-bindings/input/input.h KEY_ codes
+
+Example:
+
+#include <dt-bindings/input/input.h>
+
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ allwinner,chan0-step = <200>;
+ linux,chan0-keycodes = <KEY_VOLUMEUP KEY_VOLUMEDOWN
+ KEY_MENU KEY_ENTER KEY_HOME>;
+ };
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index bb174c1..d95e6e4 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -544,6 +544,16 @@ config KEYBOARD_STMPE
To compile this driver as a module, choose M here: the module will be
called stmpe-keypad.
+config KEYBOARD_SUN4I_LRADC
+ tristate "Allwinner sun4i low res adc attached tablet keys support"
+ depends on ARCH_SUNXI
+ help
+ This selects support for the Allwinner low res adc attached tablet
+ keys found on Allwinner sunxi SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sun4i-lradc-keys.
+
config KEYBOARD_DAVINCI
tristate "TI DaVinci Key Scan"
depends on ARCH_DAVINCI_DM365
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index a699b61..f3265bd 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
+obj-$(CONFIG_KEYBOARD_SUN4I_LRADC) += sun4i-lradc-keys.o
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o
obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o
diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c
new file mode 100644
index 0000000..5c55e17
--- /dev/null
+++ b/drivers/input/keyboard/sun4i-lradc-keys.c
@@ -0,0 +1,243 @@
+/*
+ * Allwinner sun4i low res adc attached tablet keys driver
+ *
+ * Copyright (C) 2014 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Allwinnner sunxi SoCs have a lradc which is specifically designed to have
+ * various (tablet) keys (ie home, back, search, etc). attached to it using
+ * a resistor network. This driver is for the keys on such boards.
+ *
+ * There are 2 channels, currently this driver only supports chan0 since there
+ * are no boards known to use chan1. The devicetree properties are already
+ * prefixed with chan0 as preparation for chan1 support in the future.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define LRADC_CTRL 0x00
+#define LRADC_INTC 0x04
+#define LRADC_INTS 0x08
+#define LRADC_DATA0 0x0c
+#define LRADC_DATA1 0x10
+
+/* LRADC_CTRL bits */
+#define FIRST_CONVERT_DLY(x) ((x) << 24) /* 8 bits */
+#define CHAN_SELECT(x) ((x) << 22) /* 2 bits */
+#define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */
+#define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */
+#define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */
+#define HOLD_EN(x) ((x) << 6)
+#define LEVELB_VOL(x) ((x) << 4) /* 2 bits */
+#define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */
+#define ENABLE(x) ((x) << 0)
+
+/* LRADC_INTC and LRADC_INTS bits */
+#define CHAN1_KEYUP_IRQ BIT(12)
+#define CHAN1_ALRDY_HOLD_IRQ BIT(11)
+#define CHAN1_HOLD_IRQ BIT(10)
+#define CHAN1_KEYDOWN_IRQ BIT(9)
+#define CHAN1_DATA_IRQ BIT(8)
+#define CHAN0_KEYUP_IRQ BIT(4)
+#define CHAN0_ALRDY_HOLD_IRQ BIT(3)
+#define CHAN0_HOLD_IRQ BIT(2)
+#define CHAN0_KEYDOWN_IRQ BIT(1)
+#define CHAN0_DATA_IRQ BIT(0)
+
+#define MAX_KEYS 13
+
+/* Lookup table to map the adc val to a keycode index for 150 mv step size */
+static const u8 adc_val_to_key_index_step150[64] = {
+ 0, 0, 0,
+ 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2,
+ 3, 3, 3, 3,
+ 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6,
+ 7, 7, 7, 7,
+ 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9,
+ 10, 10, 10, 10,
+ 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
+};
+
+/* Lookup table to map the adc val to a keycode index for 200 mv step size */
+static const u8 adc_val_to_key_index_step200[64] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+};
+
+struct sun4i_lradc_data {
+ struct device *dev;
+ struct input_dev *input;
+ void __iomem *base;
+ u32 chan0_step;
+ u32 chan0_keycode;
+ u32 chan0_keycodes[MAX_KEYS];
+};
+
+static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)
+{
+ struct sun4i_lradc_data *lradc = dev_id;
+ u32 ints, val;
+
+ ints = readl(lradc->base + LRADC_INTS);
+
+ /*
+ * lradc supports only one keypress at a time, release does not give
+ * any info as to which key was released, so we cache the keycode.
+ */
+ if ((ints & CHAN0_KEYDOWN_IRQ) && lradc->chan0_keycode == 0) {
+ val = readl(lradc->base + LRADC_DATA0);
+ if (lradc->chan0_step == 150)
+ val = adc_val_to_key_index_step150[val];
+ else
+ val = adc_val_to_key_index_step200[val];
+
+ lradc->chan0_keycode = lradc->chan0_keycodes[val];
+ input_report_key(lradc->input, lradc->chan0_keycode, 1);
+ }
+
+ if (ints & CHAN0_KEYUP_IRQ) {
+ input_report_key(lradc->input, lradc->chan0_keycode, 0);
+ lradc->chan0_keycode = 0;
+ }
+
+ input_sync(lradc->input);
+
+ writel(ints, lradc->base + LRADC_INTS);
+
+ return IRQ_HANDLED;
+}
+
+static int sun4i_lradc_open(struct input_dev *dev)
+{
+ struct sun4i_lradc_data *lradc = input_get_drvdata(dev);
+
+ /*
+ * Set sample time to 16 ms / 62.5 Hz. Wait 2 * 16 ms for key to
+ * stabilize on press, wait (1 + 1) * 16 ms for key release
+ */
+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
+ SAMPLE_RATE(2) | ENABLE(1), lradc->base + LRADC_CTRL);
+
+ writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC);
+
+ return 0;
+}
+
+static void sun4i_lradc_close(struct input_dev *dev)
+{
+ struct sun4i_lradc_data *lradc = input_get_drvdata(dev);
+
+ /* Disable lradc, leave other settings unchanged */
+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
+ SAMPLE_RATE(2), lradc->base + LRADC_CTRL);
+ writel(0, lradc->base + LRADC_INTC);
+}
+
+static int sun4i_lradc_probe(struct platform_device *pdev)
+{
+ struct sun4i_lradc_data *lradc;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ int i, ret;
+
+ lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL);
+ if (!lradc)
+ return -ENOMEM;
+
+ ret = of_property_read_u32(np, "allwinner,chan0-step",
+ &lradc->chan0_step);
+ if (ret || (lradc->chan0_step != 150 && lradc->chan0_step != 200)) {
+ dev_err(dev, "Invalid allwinner,chan0-step dt-property\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < MAX_KEYS; i++)
+ of_property_read_u32_index(np, "linux,chan0-keycodes",
+ i, &lradc->chan0_keycodes[i]);
+
+ lradc->dev = dev;
+ lradc->input = devm_input_allocate_device(dev);
+ if (!lradc->input)
+ return -ENOMEM;
+
+ lradc->input->name = pdev->name;
+ lradc->input->phys = "sun4i_lradc/input0";
+ lradc->input->open = sun4i_lradc_open;
+ lradc->input->close = sun4i_lradc_close;
+ lradc->input->id.bustype = BUS_HOST;
+ lradc->input->id.vendor = 0x0001;
+ lradc->input->id.product = 0x0001;
+ lradc->input->id.version = 0x0100;
+ lradc->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY);
+ for (i = 0; i < MAX_KEYS; i++)
+ set_bit(lradc->chan0_keycodes[i], lradc->input->keybit);
+ input_set_drvdata(lradc->input, lradc);
+
+ lradc->base = devm_ioremap_resource(dev,
+ platform_get_resource(pdev, IORESOURCE_MEM, 0));
+ if (IS_ERR(lradc->base))
+ return PTR_ERR(lradc->base);
+
+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0), sun4i_lradc_irq,
+ 0, "sun4i-lradc-keys", lradc);
+ if (ret)
+ return ret;
+
+ ret = input_register_device(lradc->input);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, lradc);
+ return 0;
+}
+
+static const struct of_device_id sun4i_lradc_of_match[] = {
+ { .compatible = "allwinner,sun4i-lradc-keys", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match);
+
+static struct platform_driver sun4i_lradc_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "sun4i-lradc-keys",
+ .of_match_table = of_match_ptr(sun4i_lradc_of_match),
+ },
+ .probe = sun4i_lradc_probe,
+};
+
+module_platform_driver(sun4i_lradc_driver);
+
+MODULE_DESCRIPTION("Allwinner sun4i low res adc attached tablet keys driver");
+MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
+MODULE_LICENSE("GPL");
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 2/4] ARM: dts: sun4i: Add lradc node
From: Hans de Goede @ 2014-01-02 9:58 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
In-Reply-To: <1388656707-16181-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 502f3e2..88f119a 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -447,6 +447,13 @@
interrupts = <24>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-sid";
reg = <0x01c23800 0x10>;
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 3/4] ARM: dts: sun5i: Add lradc node
From: Hans de Goede @ 2014-01-02 9:58 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
In-Reply-To: <1388656707-16181-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 8 ++++++++
arch/arm/boot/dts/sun5i-a10s.dtsi | 7 +++++++
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 8 ++++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 7 +++++++
4 files changed, 30 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index e53fb12..d93318a 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "sun5i-a10s.dtsi"
+#include <dt-bindings/input/input.h>
/ {
model = "Olimex A10s-Olinuxino Micro";
@@ -75,6 +76,13 @@
};
};
+ lradc: lradc@01c22800 {
+ allwinner,chan0-step = <200>;
+ linux,chan0-keycodes = <KEY_VOLUMEUP KEY_VOLUMEDOWN
+ KEY_MENU KEY_ENTER KEY_HOME>;
+ status = "okay";
+ };
+
uart0: serial@01c28000 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 34dd303..8775bad 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -404,6 +404,13 @@
reg = <0x01c20c90 0x10>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-sid";
reg = <0x01c23800 0x10>;
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index ab566f7..4e99f43 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "sun5i-a13.dtsi"
+#include <dt-bindings/input/input.h>
/ {
model = "Olimex A13-Olinuxino";
@@ -55,6 +56,13 @@
};
};
+ lradc: lradc@01c22800 {
+ allwinner,chan0-step = <200>;
+ linux,chan0-keycodes = <KEY_VOLUMEUP KEY_VOLUMEDOWN
+ KEY_MENU KEY_ENTER KEY_HOME>;
+ status = "okay";
+ };
+
uart1: serial@01c28400 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins_b>;
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 264cfa4..90c1ed3 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -362,6 +362,13 @@
reg = <0x01c20c90 0x10>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun4i-sid";
reg = <0x01c23800 0x10>;
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 4/4] ARM: dts: sun7i: Add lradc node
From: Hans de Goede @ 2014-01-02 9:58 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: linux-input-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede
In-Reply-To: <1388656707-16181-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 9 +++++++++
arch/arm/boot/dts/sun7i-a20.dtsi | 7 +++++++
2 files changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index 0ee2641..2c9a38f 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/include/ "sun7i-a20.dtsi"
+#include <dt-bindings/input/input.h>
/ {
model = "Olimex A20-Olinuxino Micro";
@@ -86,6 +87,14 @@
};
};
+ lradc: lradc@01c22800 {
+ allwinner,chan0-step = <200>;
+ linux,chan0-keycodes = <KEY_VOLUMEUP KEY_VOLUMEDOWN
+ KEY_MENU KEY_SEARCH KEY_HOME
+ KEY_ESC KEY_ENTER>;
+ status = "okay";
+ };
+
uart0: serial@01c28000 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 68e825a..3484275 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -531,6 +531,13 @@
interrupts = <0 24 1>;
};
+ lradc: lradc@01c22800 {
+ compatible = "allwinner,sun4i-lradc-keys";
+ reg = <0x01c22800 0x100>;
+ interrupts = <0 31 4>;
+ status = "disabled";
+ };
+
sid: eeprom@01c23800 {
compatible = "allwinner,sun7i-a20-sid";
reg = <0x01c23800 0x200>;
--
1.8.4.2
^ permalink raw reply related
* Re: [PATCH 1/4] input: Add new sun4i-lradc-keys drivers
From: Heiko Stübner @ 2014-01-02 11:59 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Hans de Goede, Dmitry Torokhov, Maxime Ripard, linux-sunxi,
linux-input, devicetree, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell
In-Reply-To: <52C5336B.9010903@redhat.com>
Hi Hans, Dmitry,
Am Donnerstag, 2. Januar 2014, 10:37:47 schrieb Hans de Goede:
> Hi,
>
> On 01/01/2014 09:56 PM, Dmitry Torokhov wrote:
> > Hi Hans,
> >
> > On Wed, Jan 01, 2014 at 08:30:07PM +0100, Hans de Goede wrote:
> >> +Required properties:
> >> + - compatible: "allwinner,sun4i-lradc-keys"
> >> + - reg: mmio address range of the chip
> >> + - interrupts: interrupt to which the chip is connected
> >> + - allwinner,chan0-step: step in mV between keys must be 150 or 200
> >> + - allwinner,chan0-keycodes: array of include/uapi/linux/input.h KEY_
> >> codes>
> > I think this should be "linux,chan0-keycodes".
>
> Right, because the codes are Linux specific, will fix in v2.
but the property with its "chan0-" thingy would be allwinner-specific if I'm
not mistaken.
Also, instead of inventing yet another vendor-specific property, why not re-use
a button binding similar to gpio-keys like:
lradc: lradc@01c22800 {
compatible = "allwinner,sun4i-lradc-keys";
reg = <0x01c22800 0x100>;
interrupts = <31>;
allwinner,chan0-step = <200>;
#address-cells = <1>;
#size-cells = <0>;
button@0 {
reg = <0>; /* your channel index from above */
linux,code = <115>; /* already used as dt-property */
};
button@1 {
reg = <1>;
linux,code = <114>;
};
...
};
But I may be on the wrong track here, so I've included the devicetree-people
for help, which I guess should've been included from the beginning.
Heiko
^ permalink raw reply
* Re: [PATCH 12/25] HID: sony: fix error return code
From: Jiri Kosina @ 2014-01-02 12:51 UTC (permalink / raw)
To: Julia Lawall; +Cc: kernel-janitors, linux-input, linux-kernel
In-Reply-To: <1388357260-4843-13-git-send-email-Julia.Lawall@lip6.fr>
On Sun, 29 Dec 2013, Julia Lawall wrote:
> From: Julia Lawall <Julia.Lawall@lip6.fr>
>
> Currently the return variable ret is always 0. Set it to other values in
> error cases, as used in the direct return.
>
> A simplified version of the semantic match that finds this problem is as
> follows: (http://coccinelle.lip6.fr/)
>
> // <smpl>
> (
> if@p1 (\(ret < 0\|ret != 0\))
> { ... return ret; }
> |
> ret@p1 = 0
> )
> ... when != ret = e1
> when != &ret
> *if(...)
> {
> ... when != ret = e2
> when forall
> return ret;
> }
>
> // </smpl>
>
> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 1/4] input: Add new sun4i-lradc-keys drivers
From: Hans de Goede @ 2014-01-02 13:45 UTC (permalink / raw)
To: Heiko Stübner,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Dmitry Torokhov, Maxime Ripard,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-input-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Pawel Moll,
Mark Rutland, Stephen Warren, Ian Campbell
In-Reply-To: <1700375.GaI3zFl6RI@phil>
Hi,
On 01/02/2014 12:59 PM, Heiko Stübner wrote:
> Hi Hans, Dmitry,
>
> Am Donnerstag, 2. Januar 2014, 10:37:47 schrieb Hans de Goede:
>> Hi,
>>
>> On 01/01/2014 09:56 PM, Dmitry Torokhov wrote:
>>> Hi Hans,
>>>
>>> On Wed, Jan 01, 2014 at 08:30:07PM +0100, Hans de Goede wrote:
>>>> +Required properties:
>>>> + - compatible: "allwinner,sun4i-lradc-keys"
>>>> + - reg: mmio address range of the chip
>>>> + - interrupts: interrupt to which the chip is connected
>>>> + - allwinner,chan0-step: step in mV between keys must be 150 or 200
>>>> + - allwinner,chan0-keycodes: array of include/uapi/linux/input.h KEY_
>>>> codes>
>>> I think this should be "linux,chan0-keycodes".
>>
>> Right, because the codes are Linux specific, will fix in v2.
>
> but the property with its "chan0-" thingy would be allwinner-specific if I'm
> not mistaken.
Correct, but denoting that this is linux only is more important, so as to
avoid namespace collisions.
>
> Also, instead of inventing yet another vendor-specific property, why not re-use
> a button binding similar to gpio-keys like:
>
> lradc: lradc@01c22800 {
> compatible = "allwinner,sun4i-lradc-keys";
> reg = <0x01c22800 0x100>;
> interrupts = <31>;
> allwinner,chan0-step = <200>;
>
> #address-cells = <1>;
> #size-cells = <0>;
>
> button@0 {
> reg = <0>; /* your channel index from above */
> linux,code = <115>; /* already used as dt-property */
> };
>
> button@1 {
> reg = <1>;
> linux,code = <114>;
> };
Ugh no. Having a vendor specific property which is KISS certainly beats this,
both wrt ease of writing dts files as well as wrt the dts parsing code in the driver.
Regards,
Hans
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
^ 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