Commit 2f0172cdbf4c7b818cb7c0441ff42ffd52eab3e2

Authored by larche
1 parent 34a3c0b0a6
Exists in master and in 2 other branches fhd, fhd-demo

= rotary encoder 드라이버 변경 =

	add prime-encoder 드라이버로 새로 추가
kernel/linux-imx6_3.14.28/arch/arm/boot/dts/imx6s-prime-oven.dts
... ... @@ -21,24 +21,14 @@
21 21 model = "Freescale i.MX6 Solo/DualLite Prime Oven Device Board(PFUZE100)";
22 22 compatible = "fsl,imx6dl-prime-oven", "fsl,imx6dl";
23 23  
24   - rotary@0 {
25   - compatible = "rotary-encoder";
26   - gpios = <&gpio6 11 1>, <&gpio6 10 1>;
27   - linux,axis = <1>; /* ABS_Y */
28   - rotary-encoder,steps = <24>;
29   - rotary-encoder,rollover;
30   - };
31   -
32   - gpio_keys {
33   - compatible = "gpio-keys";
34   - #address-cells = <1>;
35   - #size-cells = <0>;
36   - autorepeat;
37   - button@21 {
38   - label = "GPIO Key UP";
39   - linux,code = <KEY_UP>;
40   - gpios = <&gpio6 14 1>;
41   - };
  24 + prime_encoder@0 {
  25 + compatible = "prime-encoder";
  26 + gpios = <&gpio6 11 1>, <&gpio6 10 1>, <&gpio6 14 1>;
  27 + /* add larche@falinux.com - private value */
  28 + prime-encoder,button;
  29 + prime-encoder,left_code = <KEY_F1>;
  30 + prime-encoder,right_code = <KEY_F3>;
  31 + prime-encoder,center_code = <KEY_F2>;
42 32 };
43 33 };
44 34  
... ...
kernel/linux-imx6_3.14.28/arch/arm/configs/imx6s_prime_oven_defconfig
... ... @@ -1388,7 +1388,8 @@ CONFIG_INPUT_MISC=y
1388 1388 # CONFIG_INPUT_CM109 is not set
1389 1389 # CONFIG_INPUT_UINPUT is not set
1390 1390 # CONFIG_INPUT_PCF8574 is not set
1391   -CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
  1391 +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
  1392 +CONFIG_INPUT_GPIO_PRIME_ENCODER=y
1392 1393 # CONFIG_INPUT_ADXL34X is not set
1393 1394 # CONFIG_INPUT_IMS_PCU is not set
1394 1395 # CONFIG_INPUT_CMA3000 is not set
... ...
kernel/linux-imx6_3.14.28/drivers/input/misc/Kconfig
... ... @@ -490,6 +490,17 @@ config INPUT_GPIO_ROTARY_ENCODER
490 490 To compile this driver as a module, choose M here: the
491 491 module will be called rotary_encoder.
492 492  
  493 +config INPUT_GPIO_PRIME_ENCODER
  494 + tristate "Prime encoders connected to GPIO pins"
  495 + depends on GPIOLIB
  496 + help
  497 + Say Y here to add support for rotary encoders connected to GPIO lines.
  498 + Check file:Documentation/input/rotary-encoder.txt for more
  499 + information.
  500 +
  501 + To compile this driver as a module, choose M here: the
  502 + module will be called rotary_encoder.
  503 +
493 504 config INPUT_RB532_BUTTON
494 505 tristate "Mikrotik Routerboard 532 button interface"
495 506 depends on MIKROTIK_RB532
... ...
kernel/linux-imx6_3.14.28/drivers/input/misc/Makefile
... ... @@ -51,6 +51,7 @@ obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o
51 51 obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
52 52 obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o
53 53 obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
  54 +obj-$(CONFIG_INPUT_GPIO_PRIME_ENCODER) += prime_encoder.o
54 55 obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
55 56 obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o
56 57 obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
... ...
kernel/linux-imx6_3.14.28/drivers/input/misc/prime_encoder.c
... ... @@ -0,0 +1,378 @@
  1 +/*
  2 + * rotary_encoder.c
  3 + *
  4 + * (c) 2009 Daniel Mack <daniel@caiaq.de>
  5 + * Copyright (C) 2011 Johan Hovold <jhovold@gmail.com>
  6 + *
  7 + * state machine code inspired by code from Tim Ruetz
  8 + *
  9 + * A generic driver for rotary encoders connected to GPIO lines.
  10 + * See file:Documentation/input/rotary-encoder.txt for more information
  11 + *
  12 + * This program is free software; you can redistribute it and/or modify
  13 + * it under the terms of the GNU General Public License version 2 as
  14 + * published by the Free Software Foundation.
  15 + */
  16 +
  17 +#include <linux/kernel.h>
  18 +#include <linux/module.h>
  19 +#include <linux/interrupt.h>
  20 +#include <linux/input.h>
  21 +#include <linux/device.h>
  22 +#include <linux/platform_device.h>
  23 +#include <linux/gpio.h>
  24 +#include <linux/prime_encoder.h>
  25 +#include <linux/slab.h>
  26 +#include <linux/of.h>
  27 +#include <linux/of_platform.h>
  28 +#include <linux/of_gpio.h>
  29 +
  30 +#define DRV_NAME "prime-encoder"
  31 +
  32 +struct rotary_encoder {
  33 + struct input_dev *input;
  34 + const struct rotary_encoder_platform_data *pdata;
  35 +
  36 + unsigned int irq_a;
  37 + unsigned int irq_b;
  38 + // add larche@falinux.com, for button
  39 + unsigned int irq_button;
  40 + char last_value;
  41 + unsigned int l_key_state;
  42 + unsigned int r_key_state;
  43 +};
  44 +
  45 +/***
  46 + * add larche@falinux.com
  47 + *
  48 + * ab
  49 + *
  50 + * 11
  51 + *{R} 10 01 {L}
  52 + * 00
  53 + */
  54 +static int rotary_encoder_get_value(const struct rotary_encoder_platform_data *pdata)
  55 +{
  56 + int a = !!gpio_get_value(pdata->gpio_a);
  57 + int b = !!gpio_get_value(pdata->gpio_b);
  58 + int val = 0;
  59 +
  60 + val&=0x0;
  61 + val|=(a<<1);
  62 + val|=(b<<0);
  63 +
  64 + return val;
  65 +}
  66 +
  67 +static irqreturn_t rotary_encoder_irq_center_button(int irq, void *dev_id)
  68 +{
  69 + struct rotary_encoder *encoder = dev_id;
  70 + const struct rotary_encoder_platform_data *pdata = encoder->pdata;
  71 + int key_state;
  72 +
  73 + key_state = gpio_get_value(pdata->gpio_button) ^ pdata->inverted_button;
  74 + input_event(encoder->input, EV_KEY, pdata->center_code, !!key_state);
  75 + input_sync(encoder->input);
  76 +
  77 + return IRQ_HANDLED;
  78 +}
  79 +
  80 +static irqreturn_t rotary_encoder_irq_single_step(int irq, void *dev_id)
  81 +{
  82 + struct rotary_encoder *encoder = dev_id;
  83 + const struct rotary_encoder_platform_data *pdata = encoder->pdata;
  84 + int state = 0;
  85 + int key_state = 0;
  86 +
  87 + state = rotary_encoder_get_value(pdata);
  88 +
  89 + switch(encoder->last_value)
  90 + {
  91 + case 0x0:
  92 + if(state == 0x2)
  93 + {
  94 + key_state = (encoder->r_key_state ? 0 : 1);
  95 + encoder->r_key_state = key_state;
  96 + input_event(encoder->input, EV_KEY, pdata->right_code, !!key_state);
  97 + }
  98 + else if(state == 0x1)
  99 + {
  100 + key_state = (encoder->l_key_state ? 0 : 1);
  101 + encoder->l_key_state = key_state;
  102 + input_event(encoder->input, EV_KEY, pdata->left_code, !!key_state);
  103 + }
  104 +
  105 + break;
  106 +
  107 + case 0x1:
  108 + if(state == 0x0)
  109 + {
  110 + key_state = (encoder->r_key_state ? 0 : 1);
  111 + encoder->r_key_state = key_state;
  112 + input_event(encoder->input, EV_KEY, pdata->right_code, !!key_state);
  113 + }
  114 + else if(state == 0x3)
  115 + {
  116 + key_state = (encoder->l_key_state ? 0 : 1);
  117 + encoder->l_key_state = key_state;
  118 + input_event(encoder->input, EV_KEY, pdata->left_code, !!key_state);
  119 + }
  120 +
  121 + break;
  122 +
  123 + case 0x2:
  124 + if(state == 0x3)
  125 + {
  126 + key_state = (encoder->r_key_state ? 0 : 1);
  127 + encoder->r_key_state = key_state;
  128 + input_event(encoder->input, EV_KEY, pdata->right_code, !!key_state);
  129 + }
  130 + else if(state == 0x0)
  131 + {
  132 + key_state = (encoder->l_key_state ? 0 : 1);
  133 + encoder->l_key_state = key_state;
  134 + input_event(encoder->input, EV_KEY, pdata->left_code, !!key_state);
  135 + }
  136 +
  137 + break;
  138 +
  139 + case 0x3:
  140 + if(state == 0x1)
  141 + {
  142 + key_state = (encoder->r_key_state ? 0 : 1);
  143 + encoder->r_key_state = key_state;
  144 + input_event(encoder->input, EV_KEY, pdata->right_code, !!key_state);
  145 + }
  146 + else if(state == 0x2)
  147 + {
  148 + key_state = (encoder->l_key_state ? 0 : 1);
  149 + encoder->l_key_state = key_state;
  150 + input_event(encoder->input, EV_KEY, pdata->left_code, !!key_state);
  151 + }
  152 +
  153 + break;
  154 + }
  155 +
  156 + input_sync(encoder->input);
  157 +
  158 + encoder->last_value = state;
  159 +
  160 + return IRQ_HANDLED;
  161 +}
  162 +
  163 +#ifdef CONFIG_OF
  164 +static struct of_device_id rotary_encoder_of_match[] = {
  165 + { .compatible = "prime-encoder", },
  166 + { },
  167 +};
  168 +MODULE_DEVICE_TABLE(of, rotary_encoder_of_match);
  169 +
  170 +static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct device *dev)
  171 +{
  172 + const struct of_device_id *of_id =
  173 + of_match_device(rotary_encoder_of_match, dev);
  174 + struct device_node *np = dev->of_node;
  175 + struct rotary_encoder_platform_data *pdata;
  176 + enum of_gpio_flags flags;
  177 +
  178 + if (!of_id || !np)
  179 + return NULL;
  180 +
  181 + pdata = kzalloc(sizeof(struct rotary_encoder_platform_data),
  182 + GFP_KERNEL);
  183 + if (!pdata)
  184 + return ERR_PTR(-ENOMEM);
  185 +
  186 + pdata->gpio_a = of_get_gpio_flags(np, 0, &flags);
  187 + pdata->inverted_a = flags & OF_GPIO_ACTIVE_LOW;
  188 +
  189 + pdata->gpio_b = of_get_gpio_flags(np, 1, &flags);
  190 + pdata->inverted_b = flags & OF_GPIO_ACTIVE_LOW;
  191 +
  192 + // add larche@falinux.com
  193 + pdata->is_button = !!of_get_property(np,
  194 + "prime-encoder,button", NULL);
  195 + if(pdata->is_button) {
  196 + pdata->gpio_button = of_get_gpio_flags(np, 2, &flags);
  197 + pdata->inverted_button = flags & OF_GPIO_ACTIVE_LOW;
  198 + if( of_property_read_u32( np, "prime-encoder,left_code", &pdata->left_code) )
  199 + pdata->left_code = KEY_F1;
  200 + if( of_property_read_u32( np, "prime-encoder,right_code", &pdata->right_code) )
  201 + pdata->right_code = KEY_F2;
  202 + if( of_property_read_u32( np, "prime-encoder,center_code", &pdata->center_code) )
  203 + pdata->center_code = KEY_F3;
  204 + }
  205 +
  206 + return pdata;
  207 +}
  208 +#else
  209 +static inline struct rotary_encoder_platform_data *
  210 +rotary_encoder_parse_dt(struct device *dev)
  211 +{
  212 + return NULL;
  213 +}
  214 +#endif
  215 +
  216 +static int rotary_encoder_probe(struct platform_device *pdev)
  217 +{
  218 + struct device *dev = &pdev->dev;
  219 + const struct rotary_encoder_platform_data *pdata = dev_get_platdata(dev);
  220 + struct rotary_encoder *encoder;
  221 + struct input_dev *input;
  222 + irq_handler_t handler;
  223 + irq_handler_t handler_button;
  224 + int err;
  225 +
  226 + if (!pdata) {
  227 + pdata = rotary_encoder_parse_dt(dev);
  228 + if (IS_ERR(pdata))
  229 + return PTR_ERR(pdata);
  230 +
  231 + if (!pdata) {
  232 + dev_err(dev, "missing platform data\n");
  233 + return -EINVAL;
  234 + }
  235 + }
  236 +
  237 + encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL);
  238 + input = input_allocate_device();
  239 + if (!encoder || !input) {
  240 + err = -ENOMEM;
  241 + goto exit_free_mem;
  242 + }
  243 +
  244 + encoder->input = input;
  245 + encoder->pdata = pdata;
  246 +
  247 + input->name = pdev->name;
  248 + input->id.bustype = BUS_HOST;
  249 + input->dev.parent = dev;
  250 +
  251 + /* request the GPIOs */
  252 + err = gpio_request_one(pdata->gpio_a, GPIOF_IN, dev_name(dev));
  253 + if (err) {
  254 + dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_a);
  255 + goto exit_free_mem;
  256 + }
  257 +
  258 + err = gpio_request_one(pdata->gpio_b, GPIOF_IN, dev_name(dev));
  259 + if (err) {
  260 + dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_b);
  261 + goto exit_free_gpio_a;
  262 + }
  263 +
  264 + if(pdata->is_button) {
  265 + err = gpio_request_one(pdata->gpio_button, GPIOF_IN, dev_name(dev));
  266 + if (err) {
  267 + dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_button);
  268 + goto exit_free_gpio_b;
  269 + }
  270 + }
  271 +
  272 + encoder->irq_a = gpio_to_irq(pdata->gpio_a);
  273 + encoder->irq_b = gpio_to_irq(pdata->gpio_b);
  274 + encoder->irq_button = gpio_to_irq(pdata->gpio_button);
  275 +
  276 + handler = &rotary_encoder_irq_single_step;
  277 + handler_button = &rotary_encoder_irq_center_button;
  278 + encoder->last_value = rotary_encoder_get_value(pdata);
  279 +
  280 + err = request_irq(encoder->irq_a, handler,
  281 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  282 + DRV_NAME, encoder);
  283 + if (err) {
  284 + dev_err(dev, "unable to request IRQ %d\n", encoder->irq_a);
  285 + goto exit_free_gpio_button;
  286 + }
  287 +
  288 + err = request_irq(encoder->irq_b, handler,
  289 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  290 + DRV_NAME, encoder);
  291 + if (err) {
  292 + dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b);
  293 + goto exit_free_irq_a;
  294 + }
  295 +
  296 + err = request_irq(encoder->irq_button, handler_button,
  297 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  298 + DRV_NAME, encoder);
  299 + if (err) {
  300 + dev_err(dev, "unable to request IRQ %d\n", encoder->irq_b);
  301 + goto exit_free_irq_b;
  302 + }
  303 +
  304 + err = input_register_device(input);
  305 + if (err) {
  306 + dev_err(dev, "failed to register input device\n");
  307 + goto exit_free_irq_button;
  308 + }
  309 +
  310 + input_set_capability(input, EV_KEY, pdata->left_code); // Left
  311 + input_set_capability(input, EV_KEY, pdata->right_code); // Right
  312 + input_set_capability(input, EV_KEY, pdata->center_code); // Center
  313 +
  314 + encoder->l_key_state = 0;
  315 + encoder->r_key_state = 0;
  316 +
  317 + platform_set_drvdata(pdev, encoder);
  318 +
  319 + return 0;
  320 +
  321 +exit_free_irq_button:
  322 + free_irq(encoder->irq_button, encoder);
  323 +exit_free_irq_b:
  324 + free_irq(encoder->irq_b, encoder);
  325 +exit_free_irq_a:
  326 + free_irq(encoder->irq_a, encoder);
  327 +exit_free_gpio_button:
  328 + if(pdata->is_button) {
  329 + gpio_free(pdata->gpio_button);
  330 + }
  331 +exit_free_gpio_b:
  332 + gpio_free(pdata->gpio_b);
  333 +exit_free_gpio_a:
  334 + gpio_free(pdata->gpio_a);
  335 +exit_free_mem:
  336 + input_free_device(input);
  337 + kfree(encoder);
  338 + if (!dev_get_platdata(&pdev->dev))
  339 + kfree(pdata);
  340 +
  341 + return err;
  342 +
  343 +}
  344 +
  345 +static int rotary_encoder_remove(struct platform_device *pdev)
  346 +{
  347 + struct rotary_encoder *encoder = platform_get_drvdata(pdev);
  348 + const struct rotary_encoder_platform_data *pdata = encoder->pdata;
  349 +
  350 + free_irq(encoder->irq_a, encoder);
  351 + free_irq(encoder->irq_b, encoder);
  352 + gpio_free(pdata->gpio_a);
  353 + gpio_free(pdata->gpio_b);
  354 +
  355 + input_unregister_device(encoder->input);
  356 + kfree(encoder);
  357 +
  358 + if (!dev_get_platdata(&pdev->dev))
  359 + kfree(pdata);
  360 +
  361 + return 0;
  362 +}
  363 +
  364 +static struct platform_driver rotary_encoder_driver = {
  365 + .probe = rotary_encoder_probe,
  366 + .remove = rotary_encoder_remove,
  367 + .driver = {
  368 + .name = DRV_NAME,
  369 + .owner = THIS_MODULE,
  370 + .of_match_table = of_match_ptr(rotary_encoder_of_match),
  371 + }
  372 +};
  373 +module_platform_driver(rotary_encoder_driver);
  374 +
  375 +MODULE_ALIAS("platform:" DRV_NAME);
  376 +MODULE_DESCRIPTION("GPIO rotary encoder driver");
  377 +MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>, Johan Hovold");
  378 +MODULE_LICENSE("GPL v2");
... ...
kernel/linux-imx6_3.14.28/include/linux/prime_encoder.h
... ... @@ -0,0 +1,17 @@
  1 +#ifndef __ROTARY_ENCODER_H__
  2 +#define __ROTARY_ENCODER_H__
  3 +
  4 +struct rotary_encoder_platform_data {
  5 + unsigned int gpio_a;
  6 + unsigned int gpio_b;
  7 + unsigned int gpio_button;
  8 + unsigned int inverted_a;
  9 + unsigned int inverted_b;
  10 + unsigned int inverted_button;
  11 + unsigned int left_code;
  12 + unsigned int right_code;
  13 + unsigned int center_code;
  14 + bool is_button;
  15 +};
  16 +
  17 +#endif /* __ROTARY_ENCODER_H__ */
... ...