input: Add new sun4i-lradc-keys driver
Subsystems (5)
PATCH v3 1/1 input: Add new sun4i-lradc-keys driver
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.
This has been tested on an olimex a10s-olinuxino-micro, a13-olinuxino, and a20-olinuxino-micro.
--
Changes in v2:
-Change devicetree bindings to use a per key subnode, like gpio-keys does Changes in v3:
-Handle keyup irq flag before irqdown, in case we get both at once
--- .../devicetree/bindings/input/sun4i-lradc-keys.txt | 62 +++++ MAINTAINERS | 7 + drivers/input/keyboard/Kconfig | 10 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/sun4i-lradc-keys.c | 259 +++++++++++++++++++++ 5 files changed, 339 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt create mode 100644 drivers/input/keyboard/sun4i-lradc-keys.c
Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt new file +62 -0
@@ -0,0 +1,62 @@ +Allwinner sun4i low res adc attached tablet keys +------------------------------------------------ + +Required properties: + - compatible: "allwinner,sun4i-a10-lradc-keys" + - reg: mmio address range of the chip + - interrupts: interrupt to which the chip is connected + - vref-supply: powersupply for the lradc reference voltage + +Each key is represented as a sub-node of "allwinner,sun4i-a10-lradc-keys": + +Required subnode-properties: + - label: Descriptive name of the key. + - linux,code: Keycode to emit. + - channel: Channel this key is attached to, mut be 0 or 1. + - voltage: Voltage in ?V at lradc input when this key is pressed. + +Example: + +#include <dt-bindings/input/input.h> + + lradc: lradc at 01c22800 { + compatible = "allwinner,sun4i-a10-lradc-keys"; + reg = <0x01c22800 0x100>; + interrupts = <31>; + vref-supply = <®_vcc3v0>; + + button at 191 { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + channel = <0>; + voltage = <191274>; + }; + + button at 392 { + label = "Volume Down"; + linux,code = <KEY_VOLUMEDOWN>; + channel = <0>; + voltage = <392644>; + }; + + button at 601 { + label = "Menu"; + linux,code = <KEY_MENU>; + channel = <0>; + voltage = <601151>; + }; + + button at 795 { + label = "Enter"; + linux,code = <KEY_ENTER>; + channel = <0>; + voltage = <795090>; + }; + + button at 987 { + label = "Home"; + linux,code = <KEY_HOMEPAGE>; + channel = <0>; + voltage = <987387>; + }; + };
MAINTAINERS +7 -0
@@ -9209,6 +9209,13 @@ F: arch/m68k/sun3*/ F: arch/m68k/include/asm/sun3* F: drivers/net/ethernet/i825xx/sun3* +SUN4I LOW RES ADC ATTACHED TABLET KEYS DRIVER +M: Hans de Goede <[email protected]> +L: linux-input at vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt +F: drivers/input/keyboard/sun4i-lradc-keys.c + SUNDANCE NETWORK DRIVER M: Denis Kirjanov <[email protected]> L: netdev at vger.kernel.org
drivers/input/keyboard/Kconfig +10 -0
@@ -567,6 +567,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
drivers/input/keyboard/Makefile +1 -0
@@ -53,6 +53,7 @@ obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o obj-$(CONFIG_KEYBOARD_ST_KEYSCAN) += st-keyscan.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
drivers/input/keyboard/sun4i-lradc-keys.c new file +259 -0
259 lines not on this page · raw message
Signature · 1 line
2.1.0
Dmitry Torokhov
maintainerPATCH v3 1/1 input: Add new sun4i-lradc-keys driver
Hi Hans,
Quoted 10 lines · Hans de Goede
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.
This has been tested on an olimex a10s-olinuxino-micro, a13-olinuxino, and a20-olinuxino-micro.
Quoted 6 lines
Signed-off-by Hans de Goede <[email protected]>--
Changes in v2:
-Change devicetree bindings to use a per key subnode, like gpio-keys does Changes in v3:
-Handle keyup irq flag before irqdown, in case we get both at once
Thank you for making changes. Can you please tell me if the driver still works if you drop the patch below on top of it? The changes are:
- split DT parsing into a separate function;
- make sure keymap is not empty;
- change 'ret' variable to 'error';
Thanks!
Signature · 10 lines
Dmitry Input: sun4i-lradc-keys - misc changes From: Dmitry Torokhov <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]> --- drivers/input/keyboard/sun4i-lradc-keys.c | 87 +++++++++++++++++++---------- 1 file changed, 57 insertions(+), 30 deletions(-)
drivers/input/keyboard/sun4i-lradc-keys.c +57 -30
@@ -122,11 +122,11 @@ static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id)static int sun4i_lradc_open (struct input_dev *dev) {struct sun4i_lradc_data *lradc =input_get_drvdata (dev); -int ret; +int error; - ret =regulator_enable (lradc->vref_supply); -if (ret) -return ret; + error =regulator_enable (lradc->vref_supply); +if (error) +return error;/* lradc Vref internally is divided by 2/3 */ lradc->vref =regulator_get_voltage (lradc->vref_supply) *2 /3 ;
@@ -155,42 +155,48 @@ static void sun4i_lradc_close(struct input_dev *dev)regulator_disable (lradc->vref_supply); } -static int sun4i_lradc_probe (struct platform_device *pdev) +static int sun4i_lradc_load_dt_keymap (struct device *dev, +struct sun4i_lradc_data *lradc) { -struct sun4i_lradc_data *lradc; -struct device *dev = &pdev->dev; -struct device_node *pp, *np = dev->of_node; -u32 channel; -int i, ret; +struct device_node *np, *pp; +int i; +int error; - lradc =devm_kzalloc (dev,sizeof (struct sun4i_lradc_data ),GFP_KERNEL ); -if (!lradc) -return -ENOMEM ; + np = dev->of_node; +if (!np) +return -EINVAL ; lradc->chan0_map_count =of_get_child_count (np); - lradc->chan0_map =devm_kmalloc (dev, lradc->chan0_map_count * -sizeof (struct sun4i_lradc_keymap ),GFP_KERNEL ); +if (lradc->chan0_map_count ==0 ) { +dev_err (dev,"keymap is missing in device tree\n" ); +return -EINVAL ; + } + + lradc->chan0_map =devm_kmalloc_array (dev, lradc->chan0_map_count, +sizeof (struct sun4i_lradc_keymap ), +GFP_KERNEL );if (!lradc->chan0_map)return -ENOMEM ; i =0 ;for_each_child_of_node (np, pp) {struct sun4i_lradc_keymap *map = &lradc->chan0_map[i]; +u32 channel; - ret =of_property_read_u32 (pp,"channel" , &channel); -if (ret || channel !=0 ) { + error =of_property_read_u32 (pp,"channel" , &channel); +if (error || channel !=0 ) {dev_err (dev,"%s: Inval channel prop\n" , pp->name);return -EINVAL ; } - ret =of_property_read_u32 (pp,"voltage" , &map->voltage); -if (ret) { + error =of_property_read_u32 (pp,"voltage" , &map->voltage); +if (error) {dev_err (dev,"%s: Inval voltage prop\n" , pp->name);return -EINVAL ; } - ret =of_property_read_u32 (pp,"linux,code" , &map->keycode); -if (ret) { + error =of_property_read_u32 (pp,"linux,code" , &map->keycode); +if (error) {dev_err (dev,"%s: Inval linux,code prop\n" , pp->name);return -EINVAL ; }
@@ -198,6 +204,24 @@ static int sun4i_lradc_probe(struct platform_device *pdev) i++; } +return 0 ; +} + +static int sun4i_lradc_probe (struct platform_device *pdev) +{ +struct sun4i_lradc_data *lradc; +struct device *dev = &pdev->dev; +int i; +int error; + + lradc =devm_kzalloc (dev,sizeof (struct sun4i_lradc_data ),GFP_KERNEL ); +if (!lradc) +return -ENOMEM ; + + error =sun4i_lradc_load_dt_keymap (dev, lradc); +if (error) +return error; + lradc->vref_supply =devm_regulator_get (dev,"vref" );if (IS_ERR (lradc->vref_supply))return PTR_ERR (lradc->vref_supply);
@@ -215,9 +239,11 @@ static int sun4i_lradc_probe(struct platform_device *pdev) 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 ); + +__set_bit (EV_KEY , lradc->input->evbit);for (i =0 ; i < lradc->chan0_map_count; i++) -set_bit (lradc->chan0_map[i].keycode, lradc->input->keybit); +__set_bit (lradc->chan0_map[i].keycode, lradc->input->keybit); +input_set_drvdata (lradc->input, lradc); lradc->base = devm_ioremap_resource(dev,
@@ -225,14 +251,15 @@ static int sun4i_lradc_probe(struct platform_device *pdev)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-a10-lradc-keys" , lradc); -if (ret) -return ret; + error =devm_request_irq (dev,platform_get_irq (pdev,0 ), + sun4i_lradc_irq,0 , +"sun4i-a10-lradc-keys" , lradc); +if (error) +return error; - ret =input_register_device (lradc->input); -if (ret) -return ret; + error =input_register_device (lradc->input); +if (error) +return error;platform_set_drvdata (pdev, lradc);return 0 ;
PATCH v3 1/1 input: Add new sun4i-lradc-keys driver
Hi Dmitry,
Quoted 23 lines · Dmitry Torokhov
Hi Hans,
Quoted 10 lines · Hans de Goede
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.
This has been tested on an olimex a10s-olinuxino-micro, a13-olinuxino, and a20-olinuxino-micro.
Quoted 6 lines
Signed-off-by Hans de Goede <[email protected]>--
Changes in v2:
-Change devicetree bindings to use a per key subnode, like gpio-keys does Changes in v3:
-Handle keyup irq flag before irqdown, in case we get both at onceThank you for making changes. Can you please tell me if the driver still works if you drop the patch below on top of it? The changes are:
Quoted 3 lines
- split DT parsing into a separate function;
- make sure keymap is not empty;
- change 'ret' variable to 'error';
The proposed changes look good, and I've given them a test-spin and everything still works fine.
Thanks & Regards,
Hans
Dmitry Torokhov
maintainerPATCH v3 1/1 input: Add new sun4i-lradc-keys driver
Quoted 26 lines · Hans de Goede
Hi Dmitry,
Quoted 23 lines · Dmitry Torokhov
Hi Hans,
Quoted 10 lines · Hans de Goede
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.
This has been tested on an olimex a10s-olinuxino-micro, a13-olinuxino, and a20-olinuxino-micro.
Quoted 6 lines
Signed-off-by Hans de Goede <[email protected]>--
Changes in v2:
-Change devicetree bindings to use a per key subnode, like gpio-keys does Changes in v3:
-Handle keyup irq flag before irqdown, in case we get both at onceThank you for making changes. Can you please tell me if the driver still works if you drop the patch below on top of it? The changes are:
Quoted 6 lines
Quoted 3 lines
- split DT parsing into a separate function;
- make sure keymap is not empty;
- change 'ret' variable to 'error';The proposed changes look good, and I've given them a test-spin and everything still works fine.
Excellent, folded and applied.
Thanks.
Signature · 1 line
Dmitry