Skip to content

Commit

Permalink
Merge branch 'next' into for-linus
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Torokhov committed Apr 8, 2009
2 parents 577c9c4 + 59cc1dd commit ba28f22
Show file tree
Hide file tree
Showing 28 changed files with 3,062 additions and 200 deletions.
101 changes: 101 additions & 0 deletions Documentation/input/rotary-encoder.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
rotary-encoder - a generic driver for GPIO connected devices
Daniel Mack <daniel@caiaq.de>, Feb 2009

0. Function
-----------

Rotary encoders are devices which are connected to the CPU or other
peripherals with two wires. The outputs are phase-shifted by 90 degrees
and by triggering on falling and rising edges, the turn direction can
be determined.

The phase diagram of these two outputs look like this:

_____ _____ _____
| | | | | |
Channel A ____| |_____| |_____| |____

: : : : : : : : : : : :
__ _____ _____ _____
| | | | | | |
Channel B |_____| |_____| |_____| |__

: : : : : : : : : : : :
Event a b c d a b c d a b c d

|<-------->|
one step


For more information, please see
http://en.wikipedia.org/wiki/Rotary_encoder


1. Events / state machine
-------------------------

a) Rising edge on channel A, channel B in low state
This state is used to recognize a clockwise turn

b) Rising edge on channel B, channel A in high state
When entering this state, the encoder is put into 'armed' state,
meaning that there it has seen half the way of a one-step transition.

c) Falling edge on channel A, channel B in high state
This state is used to recognize a counter-clockwise turn

d) Falling edge on channel B, channel A in low state
Parking position. If the encoder enters this state, a full transition
should have happend, unless it flipped back on half the way. The
'armed' state tells us about that.

2. Platform requirements
------------------------

As there is no hardware dependent call in this driver, the platform it is
used with must support gpiolib. Another requirement is that IRQs must be
able to fire on both edges.


3. Board integration
--------------------

To use this driver in your system, register a platform_device with the
name 'rotary-encoder' and associate the IRQs and some specific platform
data with it.

struct rotary_encoder_platform_data is declared in
include/linux/rotary-encoder.h and needs to be filled with the number of
steps the encoder has and can carry information about externally inverted
signals (because of used invertig buffer or other reasons).

Because GPIO to IRQ mapping is platform specific, this information must
be given in seperately to the driver. See the example below.

---------<snip>---------

/* board support file example */

#include <linux/input.h>
#include <linux/rotary_encoder.h>

#define GPIO_ROTARY_A 1
#define GPIO_ROTARY_B 2

static struct rotary_encoder_platform_data my_rotary_encoder_info = {
.steps = 24,
.axis = ABS_X,
.gpio_a = GPIO_ROTARY_A,
.gpio_b = GPIO_ROTARY_B,
.inverted_a = 0,
.inverted_b = 0,
};

static struct platform_device rotary_encoder_device = {
.name = "rotary-encoder",
.id = 0,
.dev = {
.platform_data = &my_rotary_encoder_info,
}
};

3 changes: 3 additions & 0 deletions arch/mips/include/asm/mach-rc32434/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ struct rb532_gpio_reg {
/* Compact Flash GPIO pin */
#define CF_GPIO_NUM 13

/* S1 button GPIO (shared with UART0_SIN) */
#define GPIO_BTN_S1 1

extern void rb532_gpio_set_ilevel(int bit, unsigned gpio);
extern void rb532_gpio_set_istat(int bit, unsigned gpio);
extern void rb532_gpio_set_func(unsigned gpio);
Expand Down
19 changes: 1 addition & 18 deletions arch/mips/rb532/devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,26 +200,9 @@ static struct platform_device rb532_led = {
.id = -1,
};

static struct gpio_keys_button rb532_gpio_btn[] = {
{
.gpio = 1,
.code = BTN_0,
.desc = "S1",
.active_low = 1,
}
};

static struct gpio_keys_platform_data rb532_gpio_btn_data = {
.buttons = rb532_gpio_btn,
.nbuttons = ARRAY_SIZE(rb532_gpio_btn),
};

static struct platform_device rb532_button = {
.name = "gpio-keys",
.name = "rb532-button",
.id = -1,
.dev = {
.platform_data = &rb532_gpio_btn_data,
}
};

static struct resource rb532_wdt_res[] = {
Expand Down
13 changes: 10 additions & 3 deletions drivers/input/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ static void input_start_autorepeat(struct input_dev *dev, int code)
}
}

static void input_stop_autorepeat(struct input_dev *dev)
{
del_timer(&dev->timer);
}

#define INPUT_IGNORE_EVENT 0
#define INPUT_PASS_TO_HANDLERS 1
#define INPUT_PASS_TO_DEVICE 2
Expand Down Expand Up @@ -167,6 +172,8 @@ static void input_handle_event(struct input_dev *dev,
__change_bit(code, dev->key);
if (value)
input_start_autorepeat(dev, code);
else
input_stop_autorepeat(dev);
}

disposition = INPUT_PASS_TO_HANDLERS;
Expand Down Expand Up @@ -737,11 +744,11 @@ static inline void input_wakeup_procfs_readers(void)

static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
{
int state = input_devices_state;

poll_wait(file, &input_devices_poll_wait, wait);
if (state != input_devices_state)
if (file->f_version != input_devices_state) {
file->f_version = input_devices_state;
return POLLIN | POLLRDNORM;
}

return 0;
}
Expand Down
Loading

0 comments on commit ba28f22

Please sign in to comment.