Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d9f0d96 authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

Merge branch 'next' into for-linus

Prepare first set of updates for 3.9 merge window.
parents 9937c026 005a69d6
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
* Freescale i.MX Keypad Port(KPP) device tree bindings

The KPP is designed to interface with a keypad matrix with 2-point contact
or 3-point contact keys. The KPP is designed to simplify the software task
of scanning a keypad matrix. The KPP is capable of detecting, debouncing,
and decoding one or multiple keys pressed simultaneously on a keypad.

Required SoC Specific Properties:
- compatible: Should be "fsl,<soc>-kpp".

- reg: Physical base address of the KPP and length of memory mapped
  region.

- interrupts: The KPP interrupt number to the CPU(s).

- clocks: The clock provided by the SoC to the KPP. Some SoCs use dummy
clock(The clock for the KPP is provided by the SoCs automatically).

Required Board Specific Properties:
- pinctrl-names: The definition can be found at
pinctrl/pinctrl-bindings.txt.

- pinctrl-0: The definition can be found at
pinctrl/pinctrl-bindings.txt.

- linux,keymap: The definition can be found at
bindings/input/matrix-keymap.txt.

Example:
kpp: kpp@73f94000 {
	compatible = "fsl,imx51-kpp", "fsl,imx21-kpp";
	reg = <0x73f94000 0x4000>;
	interrupts = <60>;
	clocks = <&clks 0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_kpp_1>;
	linux,keymap = <0x00000067	/* KEY_UP */
			0x0001006c	/* KEY_DOWN */
			0x00020072	/* KEY_VOLUMEDOWN */
			0x00030066	/* KEY_HOME */
			0x0100006a	/* KEY_RIGHT */
			0x01010069	/* KEY_LEFT */
			0x0102001c	/* KEY_ENTER */
			0x01030073	/* KEY_VOLUMEUP */
			0x02000040	/* KEY_F6 */
			0x02010042	/* KEY_F8 */
			0x02020043	/* KEY_F9 */
			0x02030044	/* KEY_F10 */
			0x0300003b	/* KEY_F1 */
			0x0301003c	/* KEY_F2 */
			0x0302003d	/* KEY_F3 */
			0x03030074>;	/* KEY_POWER */
};
+22 −0
Original line number Diff line number Diff line
* Tegra keyboard controller
The key controller has maximum 24 pins to make matrix keypad. Any pin
can be configured as row or column. The maximum column pin can be 8
and maximum row pins can be 16 for Tegra20/Tegra30.

Required properties:
- compatible: "nvidia,tegra20-kbc"
- reg: Register base address of KBC.
- interrupts: Interrupt number for the KBC.
- nvidia,kbc-row-pins: The KBC pins which are configured as row. This is an
  array of pin numbers which is used as rows.
- nvidia,kbc-col-pins: The KBC pins which are configured as column. This is an
  array of pin numbers which is used as column.
- linux,keymap: The keymap for keys as described in the binding document
  devicetree/bindings/input/matrix-keymap.txt.

Optional properties, in addition to those specified by the shared
matrix-keyboard bindings:
@@ -19,5 +30,16 @@ Example:
keyboard: keyboard {
	compatible = "nvidia,tegra20-kbc";
	reg = <0x7000e200 0x100>;
	interrupts = <0 85 0x04>;
	nvidia,ghost-filter;
	nvidia,debounce-delay-ms = <640>;
	nvidia,kbc-row-pins = <0 1 2>;    /* pin 0, 1, 2 as rows */
	nvidia,kbc-col-pins = <11 12 13>; /* pin 11, 12, 13 as columns */
	linux,keymap = <0x00000074
			0x00010067
			0x00020066
			0x01010068
			0x02000069
			0x02010070
			0x02020071>;
};
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
#

menu "Input device support"
	depends on !S390 && !UML
	depends on !UML

config INPUT
	tristate "Generic input layer (needed for keyboard, mouse, ...)" if EXPERT
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src)
{
	if (dev->absinfo && test_bit(src, dev->absbit)) {
		dev->absinfo[dst] = dev->absinfo[src];
		dev->absinfo[dst].fuzz = 0;
		dev->absbit[BIT_WORD(dst)] |= BIT_MASK(dst);
	}
}
+46 −36
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@
 * the Free Software Foundation.
*/

/* #define WK0701_DEBUG */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#define RESERVE 20000
#define SYNC_PULSE 1306000
@@ -67,6 +67,7 @@ static inline void walkera0701_parse_frame(struct walkera_dev *w)
{
	int i;
	int val1, val2, val3, val4, val5, val6, val7, val8;
	int magic, magic_bit;
	int crc1, crc2;

	for (crc1 = crc2 = i = 0; i < 10; i++) {
@@ -102,17 +103,12 @@ static inline void walkera0701_parse_frame(struct walkera_dev *w)
	val8 = (w->buf[18] & 1) << 8 | (w->buf[19] << 4) | w->buf[20];
	val8 *= (w->buf[18] & 2) - 1;	/*sign */

#ifdef WK0701_DEBUG
	{
		int magic, magic_bit;
	magic = (w->buf[21] << 4) | w->buf[22];
	magic_bit = (w->buf[24] & 8) >> 3;
		printk(KERN_DEBUG
		       "walkera0701: %4d %4d %4d %4d  %4d %4d %4d %4d (magic %2x %d)\n",
		       val1, val2, val3, val4, val5, val6, val7, val8, magic,
		       magic_bit);
	}
#endif
	pr_debug("%4d %4d %4d %4d  %4d %4d %4d %4d (magic %2x %d)\n",
		 val1, val2, val3, val4, val5, val6, val7, val8,
		 magic, magic_bit);

	input_report_abs(w->input_dev, ABS_X, val2);
	input_report_abs(w->input_dev, ABS_Y, val1);
	input_report_abs(w->input_dev, ABS_Z, val6);
@@ -187,6 +183,9 @@ static int walkera0701_open(struct input_dev *dev)
{
	struct walkera_dev *w = input_get_drvdata(dev);

	if (parport_claim(w->pardevice))
		return -EBUSY;

	parport_enable_irq(w->parport);
	return 0;
}
@@ -197,40 +196,51 @@ static void walkera0701_close(struct input_dev *dev)

	parport_disable_irq(w->parport);
	hrtimer_cancel(&w->timer);

	parport_release(w->pardevice);
}

static int walkera0701_connect(struct walkera_dev *w, int parport)
{
	int err = -ENODEV;
	int error;

	w->parport = parport_find_number(parport);
	if (w->parport == NULL)
	if (!w->parport) {
		pr_err("parport %d does not exist\n", parport);
		return -ENODEV;
	}

	if (w->parport->irq == -1) {
		printk(KERN_ERR "walkera0701: parport without interrupt\n");
		goto init_err;
		pr_err("parport %d does not have interrupt assigned\n",
			parport);
		error = -EINVAL;
		goto err_put_parport;
	}

	err = -EBUSY;
	w->pardevice = parport_register_device(w->parport, "walkera0701",
				    NULL, NULL, walkera0701_irq_handler,
				    PARPORT_DEV_EXCL, w);
	if (!w->pardevice)
		goto init_err;

	if (parport_negotiate(w->pardevice->port, IEEE1284_MODE_COMPAT))
		goto init_err1;
	if (!w->pardevice) {
		pr_err("failed to register parport device\n");
		error = -EIO;
		goto err_put_parport;
	}

	if (parport_claim(w->pardevice))
		goto init_err1;
	if (parport_negotiate(w->pardevice->port, IEEE1284_MODE_COMPAT)) {
		pr_err("failed to negotiate parport mode\n");
		error = -EIO;
		goto err_unregister_device;
	}

	hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	w->timer.function = timer_handler;

	w->input_dev = input_allocate_device();
	if (!w->input_dev)
		goto init_err2;
	if (!w->input_dev) {
		pr_err("failed to allocate input device\n");
		error = -ENOMEM;
		goto err_unregister_device;
	}

	input_set_drvdata(w->input_dev, w);
	w->input_dev->name = "Walkera WK-0701 TX";
@@ -241,6 +251,7 @@ static int walkera0701_connect(struct walkera_dev *w, int parport)
	w->input_dev->id.vendor = 0x0001;
	w->input_dev->id.product = 0x0001;
	w->input_dev->id.version = 0x0100;
	w->input_dev->dev.parent = w->parport->dev;
	w->input_dev->open = walkera0701_open;
	w->input_dev->close = walkera0701_close;

@@ -254,27 +265,26 @@ static int walkera0701_connect(struct walkera_dev *w, int parport)
	input_set_abs_params(w->input_dev, ABS_RUDDER, -512, 512, 0, 0);
	input_set_abs_params(w->input_dev, ABS_MISC, -512, 512, 0, 0);

	err = input_register_device(w->input_dev);
	if (err)
		goto init_err3;
	error = input_register_device(w->input_dev);
	if (error) {
		pr_err("failed to register input device\n");
		goto err_free_input_dev;
	}

	return 0;

 init_err3:
err_free_input_dev:
	input_free_device(w->input_dev);
 init_err2:
	parport_release(w->pardevice);
 init_err1:
err_unregister_device:
	parport_unregister_device(w->pardevice);
 init_err:
err_put_parport:
	parport_put_port(w->parport);
	return err;
	return error;
}

static void walkera0701_disconnect(struct walkera_dev *w)
{
	input_unregister_device(w->input_dev);
	parport_release(w->pardevice);
	parport_unregister_device(w->pardevice);
	parport_put_port(w->parport);
}
Loading