aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcin Niestroj <m.niestroj@grinn-global.com>2016-09-10 13:42:53 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-09-10 13:47:49 -0400
commit722dc54628ca5cffd3b4581b523775aa422b55df (patch)
tree059efc9592fb7a60cb7d50eef06890e10c7482cd
parent3521a0f05d28e75612bbe1ee014bdfedf831b23f (diff)
Input: tps65218-pwrbutton - add support for tps65217 variant
The power button found in tps65217 device is very similar to the tps65218, so let's enhance the driver to support both variants. This driver enables us to use tps65217's power button as KEY_POWER on am335x boards (directly connected button in chiliboard, accessible pin via expansion header in beaglebone). This patch has been tested with chiliboard. Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt17
-rw-r--r--drivers/input/misc/Kconfig4
-rw-r--r--drivers/input/misc/tps65218-pwrbutton.c92
3 files changed, 81 insertions, 32 deletions
diff --git a/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
index e30e0b93f2b3..3e5b9793341f 100644
--- a/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
+++ b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
@@ -1,13 +1,24 @@
1Texas Instruments TPS65218 power button 1Texas Instruments TPS65217 and TPS65218 power button
2
3This module is part of the TPS65217/TPS65218. For more details about the whole
4TPS65217 chip see Documentation/devicetree/bindings/regulator/tps65217.txt.
2 5
3This driver provides a simple power button event via an Interrupt. 6This driver provides a simple power button event via an Interrupt.
4 7
5Required properties: 8Required properties:
6- compatible: should be "ti,tps65218-pwrbutton" 9- compatible: should be "ti,tps65217-pwrbutton" or "ti,tps65218-pwrbutton"
10
11Required properties for TPS65218:
7- interrupts: should be one of the following 12- interrupts: should be one of the following
8 - <3 IRQ_TYPE_EDGE_BOTH>: For controllers compatible with tps65218 13 - <3 IRQ_TYPE_EDGE_BOTH>: For controllers compatible with tps65218
9 14
10Example: 15Examples:
16
17&tps {
18 tps65217-pwrbutton {
19 compatible = "ti,tps65217-pwrbutton";
20 };
21};
11 22
12&tps { 23&tps {
13 power-button { 24 power-button {
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7cdb89397d18..7ffb614ce566 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -466,10 +466,10 @@ config INPUT_RETU_PWRBUTTON
466 466
467config INPUT_TPS65218_PWRBUTTON 467config INPUT_TPS65218_PWRBUTTON
468 tristate "TPS65218 Power button driver" 468 tristate "TPS65218 Power button driver"
469 depends on MFD_TPS65218 469 depends on (MFD_TPS65217 || MFD_TPS65218)
470 help 470 help
471 Say Y here if you want to enable power buttong reporting for 471 Say Y here if you want to enable power buttong reporting for
472 the TPS65218 Power Management IC device. 472 TPS65217 and TPS65218 Power Management IC devices.
473 473
474 To compile this driver as a module, choose M here. The module will 474 To compile this driver as a module, choose M here. The module will
475 be called tps65218-pwrbutton. 475 be called tps65218-pwrbutton.
diff --git a/drivers/input/misc/tps65218-pwrbutton.c b/drivers/input/misc/tps65218-pwrbutton.c
index a39b62651a4b..3273217ce80c 100644
--- a/drivers/input/misc/tps65218-pwrbutton.c
+++ b/drivers/input/misc/tps65218-pwrbutton.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * Texas Instruments' TPS65218 Power Button Input Driver 2 * Texas Instruments' TPS65217 and TPS65218 Power Button Input Driver
3 * 3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
5 * Author: Felipe Balbi <balbi@ti.com> 5 * Author: Felipe Balbi <balbi@ti.com>
6 * Author: Marcin Niestroj <m.niestroj@grinn-global.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -18,31 +19,61 @@
18#include <linux/input.h> 19#include <linux/input.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/mfd/tps65217.h>
21#include <linux/mfd/tps65218.h> 23#include <linux/mfd/tps65218.h>
22#include <linux/module.h> 24#include <linux/module.h>
23#include <linux/of.h> 25#include <linux/of.h>
24#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/regmap.h>
25#include <linux/slab.h> 28#include <linux/slab.h>
26 29
27struct tps65218_pwrbutton { 30struct tps6521x_data {
31 unsigned int reg_status;
32 unsigned int pb_mask;
33 const char *name;
34};
35
36static const struct tps6521x_data tps65217_data = {
37 .reg_status = TPS65217_REG_STATUS,
38 .pb_mask = TPS65217_STATUS_PB,
39 .name = "tps65217_pwrbutton",
40};
41
42static const struct tps6521x_data tps65218_data = {
43 .reg_status = TPS65218_REG_STATUS,
44 .pb_mask = TPS65218_STATUS_PB_STATE,
45 .name = "tps65218_pwrbutton",
46};
47
48struct tps6521x_pwrbutton {
28 struct device *dev; 49 struct device *dev;
29 struct tps65218 *tps; 50 struct regmap *regmap;
30 struct input_dev *idev; 51 struct input_dev *idev;
52 const struct tps6521x_data *data;
53 char phys[32];
54};
55
56static const struct of_device_id of_tps6521x_pb_match[] = {
57 { .compatible = "ti,tps65217-pwrbutton", .data = &tps65217_data },
58 { .compatible = "ti,tps65218-pwrbutton", .data = &tps65218_data },
59 { },
31}; 60};
61MODULE_DEVICE_TABLE(of, of_tps6521x_pb_match);
32 62
33static irqreturn_t tps65218_pwr_irq(int irq, void *_pwr) 63static irqreturn_t tps6521x_pb_irq(int irq, void *_pwr)
34{ 64{
35 struct tps65218_pwrbutton *pwr = _pwr; 65 struct tps6521x_pwrbutton *pwr = _pwr;
66 const struct tps6521x_data *tps_data = pwr->data;
36 unsigned int reg; 67 unsigned int reg;
37 int error; 68 int error;
38 69
39 error = tps65218_reg_read(pwr->tps, TPS65218_REG_STATUS, &reg); 70 error = regmap_read(pwr->regmap, tps_data->reg_status, &reg);
40 if (error) { 71 if (error) {
41 dev_err(pwr->dev, "can't read register: %d\n", error); 72 dev_err(pwr->dev, "can't read register: %d\n", error);
42 goto out; 73 goto out;
43 } 74 }
44 75
45 if (reg & TPS65218_STATUS_PB_STATE) { 76 if (reg & tps_data->pb_mask) {
46 input_report_key(pwr->idev, KEY_POWER, 1); 77 input_report_key(pwr->idev, KEY_POWER, 1);
47 pm_wakeup_event(pwr->dev, 0); 78 pm_wakeup_event(pwr->dev, 0);
48 } else { 79 } else {
@@ -55,42 +86,55 @@ out:
55 return IRQ_HANDLED; 86 return IRQ_HANDLED;
56} 87}
57 88
58static int tps65218_pwron_probe(struct platform_device *pdev) 89static int tps6521x_pb_probe(struct platform_device *pdev)
59{ 90{
60 struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent);
61 struct device *dev = &pdev->dev; 91 struct device *dev = &pdev->dev;
62 struct tps65218_pwrbutton *pwr; 92 struct tps6521x_pwrbutton *pwr;
63 struct input_dev *idev; 93 struct input_dev *idev;
94 const struct of_device_id *match;
64 int error; 95 int error;
65 int irq; 96 int irq;
66 97
98 match = of_match_node(of_tps6521x_pb_match, pdev->dev.of_node);
99 if (!match)
100 return -ENXIO;
101
67 pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL); 102 pwr = devm_kzalloc(dev, sizeof(*pwr), GFP_KERNEL);
68 if (!pwr) 103 if (!pwr)
69 return -ENOMEM; 104 return -ENOMEM;
70 105
106 pwr->data = match->data;
107
71 idev = devm_input_allocate_device(dev); 108 idev = devm_input_allocate_device(dev);
72 if (!idev) 109 if (!idev)
73 return -ENOMEM; 110 return -ENOMEM;
74 111
75 idev->name = "tps65218_pwrbutton"; 112 idev->name = pwr->data->name;
76 idev->phys = "tps65218_pwrbutton/input0"; 113 snprintf(pwr->phys, sizeof(pwr->phys), "%s/input0",
114 pwr->data->name);
115 idev->phys = pwr->phys;
77 idev->dev.parent = dev; 116 idev->dev.parent = dev;
78 idev->id.bustype = BUS_I2C; 117 idev->id.bustype = BUS_I2C;
79 118
80 input_set_capability(idev, EV_KEY, KEY_POWER); 119 input_set_capability(idev, EV_KEY, KEY_POWER);
81 120
82 pwr->tps = tps; 121 pwr->regmap = dev_get_regmap(pdev->dev.parent, NULL);
83 pwr->dev = dev; 122 pwr->dev = dev;
84 pwr->idev = idev; 123 pwr->idev = idev;
85 platform_set_drvdata(pdev, pwr); 124 platform_set_drvdata(pdev, pwr);
86 device_init_wakeup(dev, true); 125 device_init_wakeup(dev, true);
87 126
88 irq = platform_get_irq(pdev, 0); 127 irq = platform_get_irq(pdev, 0);
89 error = devm_request_threaded_irq(dev, irq, NULL, tps65218_pwr_irq, 128 if (irq < 0) {
129 dev_err(dev, "No IRQ resource!\n");
130 return -EINVAL;
131 }
132
133 error = devm_request_threaded_irq(dev, irq, NULL, tps6521x_pb_irq,
90 IRQF_TRIGGER_RISING | 134 IRQF_TRIGGER_RISING |
91 IRQF_TRIGGER_FALLING | 135 IRQF_TRIGGER_FALLING |
92 IRQF_ONESHOT, 136 IRQF_ONESHOT,
93 "tps65218-pwrbutton", pwr); 137 pwr->data->name, pwr);
94 if (error) { 138 if (error) {
95 dev_err(dev, "failed to request IRQ #%d: %d\n", 139 dev_err(dev, "failed to request IRQ #%d: %d\n",
96 irq, error); 140 irq, error);
@@ -106,21 +150,15 @@ static int tps65218_pwron_probe(struct platform_device *pdev)
106 return 0; 150 return 0;
107} 151}
108 152
109static const struct of_device_id of_tps65218_pwr_match[] = { 153static struct platform_driver tps6521x_pb_driver = {
110 { .compatible = "ti,tps65218-pwrbutton" }, 154 .probe = tps6521x_pb_probe,
111 { },
112};
113MODULE_DEVICE_TABLE(of, of_tps65218_pwr_match);
114
115static struct platform_driver tps65218_pwron_driver = {
116 .probe = tps65218_pwron_probe,
117 .driver = { 155 .driver = {
118 .name = "tps65218_pwrbutton", 156 .name = "tps6521x_pwrbutton",
119 .of_match_table = of_tps65218_pwr_match, 157 .of_match_table = of_tps6521x_pb_match,
120 }, 158 },
121}; 159};
122module_platform_driver(tps65218_pwron_driver); 160module_platform_driver(tps6521x_pb_driver);
123 161
124MODULE_DESCRIPTION("TPS65218 Power Button"); 162MODULE_DESCRIPTION("TPS6521X Power Button");
125MODULE_LICENSE("GPL v2"); 163MODULE_LICENSE("GPL v2");
126MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); 164MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");