diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-04-03 12:26:49 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-04-03 12:26:49 -0400 |
commit | 692d96552c9a86a919fe6b5b82288a6c77c015a5 (patch) | |
tree | a9e49c040d361ea2293a8966832378def5a06714 /drivers/input/keyboard | |
parent | e4dbedc7eac7da9db363a36f2bd4366962eeefcc (diff) | |
parent | e2c3ecf0ea8e87c5209371af7da107ebc47a5639 (diff) |
Merge branch 'next' into for-linus
First round of input updates for 3.15.
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/Kconfig | 22 | ||||
-rw-r--r-- | drivers/input/keyboard/Makefile | 2 | ||||
-rw-r--r-- | drivers/input/keyboard/clps711x-keypad.c | 207 | ||||
-rw-r--r-- | drivers/input/keyboard/imx_keypad.c | 4 | ||||
-rw-r--r-- | drivers/input/keyboard/pmic8xxx-keypad.c | 348 | ||||
-rw-r--r-- | drivers/input/keyboard/tegra-kbc.c | 13 | ||||
-rw-r--r-- | drivers/input/keyboard/tnetv107x-keypad.c | 329 |
7 files changed, 363 insertions, 562 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a673c9f3a0b9..76842d7dc2e3 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -151,6 +151,18 @@ config KEYBOARD_BFIN | |||
151 | To compile this driver as a module, choose M here: the | 151 | To compile this driver as a module, choose M here: the |
152 | module will be called bf54x-keys. | 152 | module will be called bf54x-keys. |
153 | 153 | ||
154 | config KEYBOARD_CLPS711X | ||
155 | tristate "CLPS711X Keypad support" | ||
156 | depends on OF_GPIO && (ARCH_CLPS711X || COMPILE_TEST) | ||
157 | select INPUT_MATRIXKMAP | ||
158 | select INPUT_POLLDEV | ||
159 | help | ||
160 | Say Y here to enable the matrix keypad on the Cirrus Logic | ||
161 | CLPS711X CPUs. | ||
162 | |||
163 | To compile this driver as a module, choose M here: the | ||
164 | module will be called clps711x-keypad. | ||
165 | |||
154 | config KEYBOARD_LKKBD | 166 | config KEYBOARD_LKKBD |
155 | tristate "DECstation/VAXstation LK201/LK401 keyboard" | 167 | tristate "DECstation/VAXstation LK201/LK401 keyboard" |
156 | select SERIO | 168 | select SERIO |
@@ -595,16 +607,6 @@ config KEYBOARD_TC3589X | |||
595 | To compile this driver as a module, choose M here: the | 607 | To compile this driver as a module, choose M here: the |
596 | module will be called tc3589x-keypad. | 608 | module will be called tc3589x-keypad. |
597 | 609 | ||
598 | config KEYBOARD_TNETV107X | ||
599 | tristate "TI TNETV107X keypad support" | ||
600 | depends on ARCH_DAVINCI_TNETV107X | ||
601 | select INPUT_MATRIXKMAP | ||
602 | help | ||
603 | Say Y here if you want to use the TNETV107X keypad. | ||
604 | |||
605 | To compile this driver as a module, choose M here: the | ||
606 | module will be called tnetv107x-keypad. | ||
607 | |||
608 | config KEYBOARD_TWL4030 | 610 | config KEYBOARD_TWL4030 |
609 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" | 611 | tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" |
610 | depends on TWL4030_CORE | 612 | depends on TWL4030_CORE |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index a699b6172303..11cff7b84b47 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -11,6 +11,7 @@ obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o | |||
11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o | 11 | obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o |
12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o | 12 | obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o |
13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 13 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
14 | obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o | ||
14 | obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o | 15 | obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o |
15 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | 16 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o |
16 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 17 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
@@ -53,7 +54,6 @@ obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o | |||
53 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o | 54 | obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o |
54 | obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o | 55 | obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o |
55 | obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o | 56 | obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o |
56 | obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o | ||
57 | obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o | 57 | obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o |
58 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o | 58 | obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o |
59 | obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o | 59 | obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o |
diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c new file mode 100644 index 000000000000..3955aecee44b --- /dev/null +++ b/drivers/input/keyboard/clps711x-keypad.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * Cirrus Logic CLPS711X Keypad driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/input.h> | ||
13 | #include <linux/input-polldev.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/of_gpio.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/regmap.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/input/matrix_keypad.h> | ||
20 | #include <linux/mfd/syscon.h> | ||
21 | #include <linux/mfd/syscon/clps711x.h> | ||
22 | |||
23 | #define CLPS711X_KEYPAD_COL_COUNT 8 | ||
24 | |||
25 | struct clps711x_gpio_data { | ||
26 | struct gpio_desc *desc; | ||
27 | DECLARE_BITMAP(last_state, CLPS711X_KEYPAD_COL_COUNT); | ||
28 | }; | ||
29 | |||
30 | struct clps711x_keypad_data { | ||
31 | struct regmap *syscon; | ||
32 | int row_count; | ||
33 | unsigned int row_shift; | ||
34 | struct clps711x_gpio_data *gpio_data; | ||
35 | }; | ||
36 | |||
37 | static void clps711x_keypad_poll(struct input_polled_dev *dev) | ||
38 | { | ||
39 | const unsigned short *keycodes = dev->input->keycode; | ||
40 | struct clps711x_keypad_data *priv = dev->private; | ||
41 | bool sync = false; | ||
42 | int col, row; | ||
43 | |||
44 | for (col = 0; col < CLPS711X_KEYPAD_COL_COUNT; col++) { | ||
45 | /* Assert column */ | ||
46 | regmap_update_bits(priv->syscon, SYSCON_OFFSET, | ||
47 | SYSCON1_KBDSCAN_MASK, | ||
48 | SYSCON1_KBDSCAN(8 + col)); | ||
49 | |||
50 | /* Scan rows */ | ||
51 | for (row = 0; row < priv->row_count; row++) { | ||
52 | struct clps711x_gpio_data *data = &priv->gpio_data[row]; | ||
53 | bool state, state1; | ||
54 | |||
55 | /* Read twice for protection against fluctuations */ | ||
56 | do { | ||
57 | state = gpiod_get_value_cansleep(data->desc); | ||
58 | cond_resched(); | ||
59 | state1 = gpiod_get_value_cansleep(data->desc); | ||
60 | } while (state != state1); | ||
61 | |||
62 | if (test_bit(col, data->last_state) != state) { | ||
63 | int code = MATRIX_SCAN_CODE(row, col, | ||
64 | priv->row_shift); | ||
65 | |||
66 | if (state) { | ||
67 | set_bit(col, data->last_state); | ||
68 | input_event(dev->input, EV_MSC, | ||
69 | MSC_SCAN, code); | ||
70 | } else { | ||
71 | clear_bit(col, data->last_state); | ||
72 | } | ||
73 | |||
74 | if (keycodes[code]) | ||
75 | input_report_key(dev->input, | ||
76 | keycodes[code], state); | ||
77 | sync = true; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /* Set all columns to low */ | ||
82 | regmap_update_bits(priv->syscon, SYSCON_OFFSET, | ||
83 | SYSCON1_KBDSCAN_MASK, SYSCON1_KBDSCAN(1)); | ||
84 | } | ||
85 | |||
86 | if (sync) | ||
87 | input_sync(dev->input); | ||
88 | } | ||
89 | |||
90 | static int clps711x_keypad_probe(struct platform_device *pdev) | ||
91 | { | ||
92 | struct clps711x_keypad_data *priv; | ||
93 | struct device *dev = &pdev->dev; | ||
94 | struct device_node *np = dev->of_node; | ||
95 | struct input_polled_dev *poll_dev; | ||
96 | u32 poll_interval; | ||
97 | int i, err; | ||
98 | |||
99 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
100 | if (!priv) | ||
101 | return -ENOMEM; | ||
102 | |||
103 | priv->syscon = | ||
104 | syscon_regmap_lookup_by_compatible("cirrus,clps711x-syscon1"); | ||
105 | if (IS_ERR(priv->syscon)) | ||
106 | return PTR_ERR(priv->syscon); | ||
107 | |||
108 | priv->row_count = of_gpio_named_count(np, "row-gpios"); | ||
109 | if (priv->row_count < 1) | ||
110 | return -EINVAL; | ||
111 | |||
112 | priv->gpio_data = devm_kzalloc(dev, | ||
113 | sizeof(*priv->gpio_data) * priv->row_count, | ||
114 | GFP_KERNEL); | ||
115 | if (!priv->gpio_data) | ||
116 | return -ENOMEM; | ||
117 | |||
118 | priv->row_shift = get_count_order(CLPS711X_KEYPAD_COL_COUNT); | ||
119 | |||
120 | for (i = 0; i < priv->row_count; i++) { | ||
121 | struct clps711x_gpio_data *data = &priv->gpio_data[i]; | ||
122 | |||
123 | data->desc = devm_gpiod_get_index(dev, "row", i); | ||
124 | if (!data->desc) | ||
125 | return -EINVAL; | ||
126 | |||
127 | if (IS_ERR(data->desc)) | ||
128 | return PTR_ERR(data->desc); | ||
129 | |||
130 | gpiod_direction_input(data->desc); | ||
131 | } | ||
132 | |||
133 | err = of_property_read_u32(np, "poll-interval", &poll_interval); | ||
134 | if (err) | ||
135 | return err; | ||
136 | |||
137 | poll_dev = input_allocate_polled_device(); | ||
138 | if (!poll_dev) | ||
139 | return -ENOMEM; | ||
140 | |||
141 | poll_dev->private = priv; | ||
142 | poll_dev->poll = clps711x_keypad_poll; | ||
143 | poll_dev->poll_interval = poll_interval; | ||
144 | poll_dev->input->name = pdev->name; | ||
145 | poll_dev->input->dev.parent = dev; | ||
146 | poll_dev->input->id.bustype = BUS_HOST; | ||
147 | poll_dev->input->id.vendor = 0x0001; | ||
148 | poll_dev->input->id.product = 0x0001; | ||
149 | poll_dev->input->id.version = 0x0100; | ||
150 | |||
151 | err = matrix_keypad_build_keymap(NULL, NULL, priv->row_count, | ||
152 | CLPS711X_KEYPAD_COL_COUNT, | ||
153 | NULL, poll_dev->input); | ||
154 | if (err) | ||
155 | goto out_err; | ||
156 | |||
157 | input_set_capability(poll_dev->input, EV_MSC, MSC_SCAN); | ||
158 | if (of_property_read_bool(np, "autorepeat")) | ||
159 | __set_bit(EV_REP, poll_dev->input->evbit); | ||
160 | |||
161 | platform_set_drvdata(pdev, poll_dev); | ||
162 | |||
163 | /* Set all columns to low */ | ||
164 | regmap_update_bits(priv->syscon, SYSCON_OFFSET, SYSCON1_KBDSCAN_MASK, | ||
165 | SYSCON1_KBDSCAN(1)); | ||
166 | |||
167 | err = input_register_polled_device(poll_dev); | ||
168 | if (err) | ||
169 | goto out_err; | ||
170 | |||
171 | return 0; | ||
172 | |||
173 | out_err: | ||
174 | input_free_polled_device(poll_dev); | ||
175 | return err; | ||
176 | } | ||
177 | |||
178 | static int clps711x_keypad_remove(struct platform_device *pdev) | ||
179 | { | ||
180 | struct input_polled_dev *poll_dev = platform_get_drvdata(pdev); | ||
181 | |||
182 | input_unregister_polled_device(poll_dev); | ||
183 | input_free_polled_device(poll_dev); | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static struct of_device_id clps711x_keypad_of_match[] = { | ||
189 | { .compatible = "cirrus,clps711x-keypad", }, | ||
190 | { } | ||
191 | }; | ||
192 | MODULE_DEVICE_TABLE(of, clps711x_keypad_of_match); | ||
193 | |||
194 | static struct platform_driver clps711x_keypad_driver = { | ||
195 | .driver = { | ||
196 | .name = "clps711x-keypad", | ||
197 | .owner = THIS_MODULE, | ||
198 | .of_match_table = clps711x_keypad_of_match, | ||
199 | }, | ||
200 | .probe = clps711x_keypad_probe, | ||
201 | .remove = clps711x_keypad_remove, | ||
202 | }; | ||
203 | module_platform_driver(clps711x_keypad_driver); | ||
204 | |||
205 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | ||
206 | MODULE_DESCRIPTION("Cirrus Logic CLPS711X Keypad driver"); | ||
207 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index cbf4f8038cba..97ec33572e56 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -439,7 +439,7 @@ static int imx_keypad_probe(struct platform_device *pdev) | |||
439 | irq = platform_get_irq(pdev, 0); | 439 | irq = platform_get_irq(pdev, 0); |
440 | if (irq < 0) { | 440 | if (irq < 0) { |
441 | dev_err(&pdev->dev, "no irq defined in platform data\n"); | 441 | dev_err(&pdev->dev, "no irq defined in platform data\n"); |
442 | return -EINVAL; | 442 | return irq; |
443 | } | 443 | } |
444 | 444 | ||
445 | input_dev = devm_input_allocate_device(&pdev->dev); | 445 | input_dev = devm_input_allocate_device(&pdev->dev); |
@@ -449,7 +449,7 @@ static int imx_keypad_probe(struct platform_device *pdev) | |||
449 | } | 449 | } |
450 | 450 | ||
451 | keypad = devm_kzalloc(&pdev->dev, sizeof(struct imx_keypad), | 451 | keypad = devm_kzalloc(&pdev->dev, sizeof(struct imx_keypad), |
452 | GFP_KERNEL); | 452 | GFP_KERNEL); |
453 | if (!keypad) { | 453 | if (!keypad) { |
454 | dev_err(&pdev->dev, "not enough memory for driver data\n"); | 454 | dev_err(&pdev->dev, "not enough memory for driver data\n"); |
455 | return -ENOMEM; | 455 | return -ENOMEM; |
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 2c9f19ac35ea..80c6b0ef3fc8 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c | |||
@@ -19,10 +19,9 @@ | |||
19 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | 22 | #include <linux/regmap.h> | |
23 | #include <linux/mfd/pm8xxx/core.h> | 23 | #include <linux/of.h> |
24 | #include <linux/mfd/pm8xxx/gpio.h> | 24 | #include <linux/input/matrix_keypad.h> |
25 | #include <linux/input/pmic8xxx-keypad.h> | ||
26 | 25 | ||
27 | #define PM8XXX_MAX_ROWS 18 | 26 | #define PM8XXX_MAX_ROWS 18 |
28 | #define PM8XXX_MAX_COLS 8 | 27 | #define PM8XXX_MAX_COLS 8 |
@@ -85,8 +84,10 @@ | |||
85 | 84 | ||
86 | /** | 85 | /** |
87 | * struct pmic8xxx_kp - internal keypad data structure | 86 | * struct pmic8xxx_kp - internal keypad data structure |
88 | * @pdata - keypad platform data pointer | 87 | * @num_cols - number of columns of keypad |
88 | * @num_rows - number of row of keypad | ||
89 | * @input - input device pointer for keypad | 89 | * @input - input device pointer for keypad |
90 | * @regmap - regmap handle | ||
90 | * @key_sense_irq - key press/release irq number | 91 | * @key_sense_irq - key press/release irq number |
91 | * @key_stuck_irq - key stuck notification irq number | 92 | * @key_stuck_irq - key stuck notification irq number |
92 | * @keycodes - array to hold the key codes | 93 | * @keycodes - array to hold the key codes |
@@ -96,8 +97,10 @@ | |||
96 | * @ctrl_reg - control register value | 97 | * @ctrl_reg - control register value |
97 | */ | 98 | */ |
98 | struct pmic8xxx_kp { | 99 | struct pmic8xxx_kp { |
99 | const struct pm8xxx_keypad_platform_data *pdata; | 100 | unsigned int num_rows; |
101 | unsigned int num_cols; | ||
100 | struct input_dev *input; | 102 | struct input_dev *input; |
103 | struct regmap *regmap; | ||
101 | int key_sense_irq; | 104 | int key_sense_irq; |
102 | int key_stuck_irq; | 105 | int key_stuck_irq; |
103 | 106 | ||
@@ -110,40 +113,13 @@ struct pmic8xxx_kp { | |||
110 | u8 ctrl_reg; | 113 | u8 ctrl_reg; |
111 | }; | 114 | }; |
112 | 115 | ||
113 | static int pmic8xxx_kp_write_u8(struct pmic8xxx_kp *kp, | ||
114 | u8 data, u16 reg) | ||
115 | { | ||
116 | int rc; | ||
117 | |||
118 | rc = pm8xxx_writeb(kp->dev->parent, reg, data); | ||
119 | return rc; | ||
120 | } | ||
121 | |||
122 | static int pmic8xxx_kp_read(struct pmic8xxx_kp *kp, | ||
123 | u8 *data, u16 reg, unsigned num_bytes) | ||
124 | { | ||
125 | int rc; | ||
126 | |||
127 | rc = pm8xxx_read_buf(kp->dev->parent, reg, data, num_bytes); | ||
128 | return rc; | ||
129 | } | ||
130 | |||
131 | static int pmic8xxx_kp_read_u8(struct pmic8xxx_kp *kp, | ||
132 | u8 *data, u16 reg) | ||
133 | { | ||
134 | int rc; | ||
135 | |||
136 | rc = pmic8xxx_kp_read(kp, data, reg, 1); | ||
137 | return rc; | ||
138 | } | ||
139 | |||
140 | static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col) | 116 | static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col) |
141 | { | 117 | { |
142 | /* all keys pressed on that particular row? */ | 118 | /* all keys pressed on that particular row? */ |
143 | if (col == 0x00) | 119 | if (col == 0x00) |
144 | return 1 << kp->pdata->num_cols; | 120 | return 1 << kp->num_cols; |
145 | else | 121 | else |
146 | return col & ((1 << kp->pdata->num_cols) - 1); | 122 | return col & ((1 << kp->num_cols) - 1); |
147 | } | 123 | } |
148 | 124 | ||
149 | /* | 125 | /* |
@@ -161,9 +137,9 @@ static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col) | |||
161 | static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) | 137 | static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) |
162 | { | 138 | { |
163 | int rc; | 139 | int rc; |
164 | u8 scan_val; | 140 | unsigned int scan_val; |
165 | 141 | ||
166 | rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); | 142 | rc = regmap_read(kp->regmap, KEYP_SCAN, &scan_val); |
167 | if (rc < 0) { | 143 | if (rc < 0) { |
168 | dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); | 144 | dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); |
169 | return rc; | 145 | return rc; |
@@ -171,7 +147,7 @@ static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) | |||
171 | 147 | ||
172 | scan_val |= 0x1; | 148 | scan_val |= 0x1; |
173 | 149 | ||
174 | rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); | 150 | rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val); |
175 | if (rc < 0) { | 151 | if (rc < 0) { |
176 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); | 152 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); |
177 | return rc; | 153 | return rc; |
@@ -187,31 +163,29 @@ static int pmic8xxx_kp_read_data(struct pmic8xxx_kp *kp, u16 *state, | |||
187 | u16 data_reg, int read_rows) | 163 | u16 data_reg, int read_rows) |
188 | { | 164 | { |
189 | int rc, row; | 165 | int rc, row; |
190 | u8 new_data[PM8XXX_MAX_ROWS]; | 166 | unsigned int val; |
191 | |||
192 | rc = pmic8xxx_kp_read(kp, new_data, data_reg, read_rows); | ||
193 | if (rc) | ||
194 | return rc; | ||
195 | 167 | ||
196 | for (row = 0; row < kp->pdata->num_rows; row++) { | 168 | for (row = 0; row < read_rows; row++) { |
197 | dev_dbg(kp->dev, "new_data[%d] = %d\n", row, | 169 | rc = regmap_read(kp->regmap, data_reg, &val); |
198 | new_data[row]); | 170 | if (rc) |
199 | state[row] = pmic8xxx_col_state(kp, new_data[row]); | 171 | return rc; |
172 | dev_dbg(kp->dev, "%d = %d\n", row, val); | ||
173 | state[row] = pmic8xxx_col_state(kp, val); | ||
200 | } | 174 | } |
201 | 175 | ||
202 | return rc; | 176 | return 0; |
203 | } | 177 | } |
204 | 178 | ||
205 | static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, | 179 | static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, |
206 | u16 *old_state) | 180 | u16 *old_state) |
207 | { | 181 | { |
208 | int rc, read_rows; | 182 | int rc, read_rows; |
209 | u8 scan_val; | 183 | unsigned int scan_val; |
210 | 184 | ||
211 | if (kp->pdata->num_rows < PM8XXX_MIN_ROWS) | 185 | if (kp->num_rows < PM8XXX_MIN_ROWS) |
212 | read_rows = PM8XXX_MIN_ROWS; | 186 | read_rows = PM8XXX_MIN_ROWS; |
213 | else | 187 | else |
214 | read_rows = kp->pdata->num_rows; | 188 | read_rows = kp->num_rows; |
215 | 189 | ||
216 | pmic8xxx_chk_sync_read(kp); | 190 | pmic8xxx_chk_sync_read(kp); |
217 | 191 | ||
@@ -236,14 +210,14 @@ static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, | |||
236 | /* 4 * 32KHz clocks */ | 210 | /* 4 * 32KHz clocks */ |
237 | udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); | 211 | udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); |
238 | 212 | ||
239 | rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN); | 213 | rc = regmap_read(kp->regmap, KEYP_SCAN, &scan_val); |
240 | if (rc < 0) { | 214 | if (rc < 0) { |
241 | dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); | 215 | dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); |
242 | return rc; | 216 | return rc; |
243 | } | 217 | } |
244 | 218 | ||
245 | scan_val &= 0xFE; | 219 | scan_val &= 0xFE; |
246 | rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); | 220 | rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val); |
247 | if (rc < 0) | 221 | if (rc < 0) |
248 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); | 222 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); |
249 | 223 | ||
@@ -255,13 +229,13 @@ static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, | |||
255 | { | 229 | { |
256 | int row, col, code; | 230 | int row, col, code; |
257 | 231 | ||
258 | for (row = 0; row < kp->pdata->num_rows; row++) { | 232 | for (row = 0; row < kp->num_rows; row++) { |
259 | int bits_changed = new_state[row] ^ old_state[row]; | 233 | int bits_changed = new_state[row] ^ old_state[row]; |
260 | 234 | ||
261 | if (!bits_changed) | 235 | if (!bits_changed) |
262 | continue; | 236 | continue; |
263 | 237 | ||
264 | for (col = 0; col < kp->pdata->num_cols; col++) { | 238 | for (col = 0; col < kp->num_cols; col++) { |
265 | if (!(bits_changed & (1 << col))) | 239 | if (!(bits_changed & (1 << col))) |
266 | continue; | 240 | continue; |
267 | 241 | ||
@@ -287,9 +261,9 @@ static bool pmic8xxx_detect_ghost_keys(struct pmic8xxx_kp *kp, u16 *new_state) | |||
287 | u16 check, row_state; | 261 | u16 check, row_state; |
288 | 262 | ||
289 | check = 0; | 263 | check = 0; |
290 | for (row = 0; row < kp->pdata->num_rows; row++) { | 264 | for (row = 0; row < kp->num_rows; row++) { |
291 | row_state = (~new_state[row]) & | 265 | row_state = (~new_state[row]) & |
292 | ((1 << kp->pdata->num_cols) - 1); | 266 | ((1 << kp->num_cols) - 1); |
293 | 267 | ||
294 | if (hweight16(row_state) > 1) { | 268 | if (hweight16(row_state) > 1) { |
295 | if (found_first == -1) | 269 | if (found_first == -1) |
@@ -379,10 +353,10 @@ static irqreturn_t pmic8xxx_kp_stuck_irq(int irq, void *data) | |||
379 | static irqreturn_t pmic8xxx_kp_irq(int irq, void *data) | 353 | static irqreturn_t pmic8xxx_kp_irq(int irq, void *data) |
380 | { | 354 | { |
381 | struct pmic8xxx_kp *kp = data; | 355 | struct pmic8xxx_kp *kp = data; |
382 | u8 ctrl_val, events; | 356 | unsigned int ctrl_val, events; |
383 | int rc; | 357 | int rc; |
384 | 358 | ||
385 | rc = pmic8xxx_kp_read(kp, &ctrl_val, KEYP_CTRL, 1); | 359 | rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val); |
386 | if (rc < 0) { | 360 | if (rc < 0) { |
387 | dev_err(kp->dev, "failed to read keyp_ctrl register\n"); | 361 | dev_err(kp->dev, "failed to read keyp_ctrl register\n"); |
388 | return IRQ_HANDLED; | 362 | return IRQ_HANDLED; |
@@ -397,8 +371,13 @@ static irqreturn_t pmic8xxx_kp_irq(int irq, void *data) | |||
397 | return IRQ_HANDLED; | 371 | return IRQ_HANDLED; |
398 | } | 372 | } |
399 | 373 | ||
400 | static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) | 374 | static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp, |
375 | struct platform_device *pdev) | ||
401 | { | 376 | { |
377 | const struct device_node *of_node = pdev->dev.of_node; | ||
378 | unsigned int scan_delay_ms; | ||
379 | unsigned int row_hold_ns; | ||
380 | unsigned int debounce_ms; | ||
402 | int bits, rc, cycles; | 381 | int bits, rc, cycles; |
403 | u8 scan_val = 0, ctrl_val = 0; | 382 | u8 scan_val = 0, ctrl_val = 0; |
404 | static const u8 row_bits[] = { | 383 | static const u8 row_bits[] = { |
@@ -406,40 +385,69 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) | |||
406 | }; | 385 | }; |
407 | 386 | ||
408 | /* Find column bits */ | 387 | /* Find column bits */ |
409 | if (kp->pdata->num_cols < KEYP_CTRL_SCAN_COLS_MIN) | 388 | if (kp->num_cols < KEYP_CTRL_SCAN_COLS_MIN) |
410 | bits = 0; | 389 | bits = 0; |
411 | else | 390 | else |
412 | bits = kp->pdata->num_cols - KEYP_CTRL_SCAN_COLS_MIN; | 391 | bits = kp->num_cols - KEYP_CTRL_SCAN_COLS_MIN; |
413 | ctrl_val = (bits & KEYP_CTRL_SCAN_COLS_BITS) << | 392 | ctrl_val = (bits & KEYP_CTRL_SCAN_COLS_BITS) << |
414 | KEYP_CTRL_SCAN_COLS_SHIFT; | 393 | KEYP_CTRL_SCAN_COLS_SHIFT; |
415 | 394 | ||
416 | /* Find row bits */ | 395 | /* Find row bits */ |
417 | if (kp->pdata->num_rows < KEYP_CTRL_SCAN_ROWS_MIN) | 396 | if (kp->num_rows < KEYP_CTRL_SCAN_ROWS_MIN) |
418 | bits = 0; | 397 | bits = 0; |
419 | else | 398 | else |
420 | bits = row_bits[kp->pdata->num_rows - KEYP_CTRL_SCAN_ROWS_MIN]; | 399 | bits = row_bits[kp->num_rows - KEYP_CTRL_SCAN_ROWS_MIN]; |
421 | 400 | ||
422 | ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT); | 401 | ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT); |
423 | 402 | ||
424 | rc = pmic8xxx_kp_write_u8(kp, ctrl_val, KEYP_CTRL); | 403 | rc = regmap_write(kp->regmap, KEYP_CTRL, ctrl_val); |
425 | if (rc < 0) { | 404 | if (rc < 0) { |
426 | dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); | 405 | dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); |
427 | return rc; | 406 | return rc; |
428 | } | 407 | } |
429 | 408 | ||
430 | bits = (kp->pdata->debounce_ms / 5) - 1; | 409 | if (of_property_read_u32(of_node, "scan-delay", &scan_delay_ms)) |
410 | scan_delay_ms = MIN_SCAN_DELAY; | ||
411 | |||
412 | if (scan_delay_ms > MAX_SCAN_DELAY || scan_delay_ms < MIN_SCAN_DELAY || | ||
413 | !is_power_of_2(scan_delay_ms)) { | ||
414 | dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); | ||
415 | return -EINVAL; | ||
416 | } | ||
417 | |||
418 | if (of_property_read_u32(of_node, "row-hold", &row_hold_ns)) | ||
419 | row_hold_ns = MIN_ROW_HOLD_DELAY; | ||
420 | |||
421 | if (row_hold_ns > MAX_ROW_HOLD_DELAY || | ||
422 | row_hold_ns < MIN_ROW_HOLD_DELAY || | ||
423 | ((row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { | ||
424 | dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); | ||
425 | return -EINVAL; | ||
426 | } | ||
427 | |||
428 | if (of_property_read_u32(of_node, "debounce", &debounce_ms)) | ||
429 | debounce_ms = MIN_DEBOUNCE_TIME; | ||
430 | |||
431 | if (((debounce_ms % 5) != 0) || | ||
432 | debounce_ms > MAX_DEBOUNCE_TIME || | ||
433 | debounce_ms < MIN_DEBOUNCE_TIME) { | ||
434 | dev_err(&pdev->dev, "invalid debounce time supplied\n"); | ||
435 | return -EINVAL; | ||
436 | } | ||
437 | |||
438 | bits = (debounce_ms / 5) - 1; | ||
431 | 439 | ||
432 | scan_val |= (bits << KEYP_SCAN_DBOUNCE_SHIFT); | 440 | scan_val |= (bits << KEYP_SCAN_DBOUNCE_SHIFT); |
433 | 441 | ||
434 | bits = fls(kp->pdata->scan_delay_ms) - 1; | 442 | bits = fls(scan_delay_ms) - 1; |
435 | scan_val |= (bits << KEYP_SCAN_PAUSE_SHIFT); | 443 | scan_val |= (bits << KEYP_SCAN_PAUSE_SHIFT); |
436 | 444 | ||
437 | /* Row hold time is a multiple of 32KHz cycles. */ | 445 | /* Row hold time is a multiple of 32KHz cycles. */ |
438 | cycles = (kp->pdata->row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC; | 446 | cycles = (row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC; |
439 | 447 | ||
440 | scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT); | 448 | scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT); |
441 | 449 | ||
442 | rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN); | 450 | rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val); |
443 | if (rc) | 451 | if (rc) |
444 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); | 452 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); |
445 | 453 | ||
@@ -447,34 +455,13 @@ static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) | |||
447 | 455 | ||
448 | } | 456 | } |
449 | 457 | ||
450 | static int pmic8xxx_kp_config_gpio(int gpio_start, int num_gpios, | ||
451 | struct pmic8xxx_kp *kp, struct pm_gpio *gpio_config) | ||
452 | { | ||
453 | int rc, i; | ||
454 | |||
455 | if (gpio_start < 0 || num_gpios < 0) | ||
456 | return -EINVAL; | ||
457 | |||
458 | for (i = 0; i < num_gpios; i++) { | ||
459 | rc = pm8xxx_gpio_config(gpio_start + i, gpio_config); | ||
460 | if (rc) { | ||
461 | dev_err(kp->dev, "%s: FAIL pm8xxx_gpio_config():" | ||
462 | "for PM GPIO [%d] rc=%d.\n", | ||
463 | __func__, gpio_start + i, rc); | ||
464 | return rc; | ||
465 | } | ||
466 | } | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp) | 458 | static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp) |
472 | { | 459 | { |
473 | int rc; | 460 | int rc; |
474 | 461 | ||
475 | kp->ctrl_reg |= KEYP_CTRL_KEYP_EN; | 462 | kp->ctrl_reg |= KEYP_CTRL_KEYP_EN; |
476 | 463 | ||
477 | rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); | 464 | rc = regmap_write(kp->regmap, KEYP_CTRL, kp->ctrl_reg); |
478 | if (rc < 0) | 465 | if (rc < 0) |
479 | dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); | 466 | dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); |
480 | 467 | ||
@@ -487,7 +474,7 @@ static int pmic8xxx_kp_disable(struct pmic8xxx_kp *kp) | |||
487 | 474 | ||
488 | kp->ctrl_reg &= ~KEYP_CTRL_KEYP_EN; | 475 | kp->ctrl_reg &= ~KEYP_CTRL_KEYP_EN; |
489 | 476 | ||
490 | rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL); | 477 | rc = regmap_write(kp->regmap, KEYP_CTRL, kp->ctrl_reg); |
491 | if (rc < 0) | 478 | if (rc < 0) |
492 | return rc; | 479 | return rc; |
493 | 480 | ||
@@ -520,106 +507,62 @@ static void pmic8xxx_kp_close(struct input_dev *dev) | |||
520 | */ | 507 | */ |
521 | static int pmic8xxx_kp_probe(struct platform_device *pdev) | 508 | static int pmic8xxx_kp_probe(struct platform_device *pdev) |
522 | { | 509 | { |
523 | const struct pm8xxx_keypad_platform_data *pdata = | 510 | unsigned int rows, cols; |
524 | dev_get_platdata(&pdev->dev); | 511 | bool repeat; |
525 | const struct matrix_keymap_data *keymap_data; | 512 | bool wakeup; |
526 | struct pmic8xxx_kp *kp; | 513 | struct pmic8xxx_kp *kp; |
527 | int rc; | 514 | int rc; |
528 | u8 ctrl_val; | 515 | unsigned int ctrl_val; |
529 | |||
530 | struct pm_gpio kypd_drv = { | ||
531 | .direction = PM_GPIO_DIR_OUT, | ||
532 | .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, | ||
533 | .output_value = 0, | ||
534 | .pull = PM_GPIO_PULL_NO, | ||
535 | .vin_sel = PM_GPIO_VIN_S3, | ||
536 | .out_strength = PM_GPIO_STRENGTH_LOW, | ||
537 | .function = PM_GPIO_FUNC_1, | ||
538 | .inv_int_pol = 1, | ||
539 | }; | ||
540 | |||
541 | struct pm_gpio kypd_sns = { | ||
542 | .direction = PM_GPIO_DIR_IN, | ||
543 | .pull = PM_GPIO_PULL_UP_31P5, | ||
544 | .vin_sel = PM_GPIO_VIN_S3, | ||
545 | .out_strength = PM_GPIO_STRENGTH_NO, | ||
546 | .function = PM_GPIO_FUNC_NORMAL, | ||
547 | .inv_int_pol = 1, | ||
548 | }; | ||
549 | 516 | ||
517 | rc = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); | ||
518 | if (rc) | ||
519 | return rc; | ||
550 | 520 | ||
551 | if (!pdata || !pdata->num_cols || !pdata->num_rows || | 521 | if (cols > PM8XXX_MAX_COLS || rows > PM8XXX_MAX_ROWS || |
552 | pdata->num_cols > PM8XXX_MAX_COLS || | 522 | cols < PM8XXX_MIN_COLS) { |
553 | pdata->num_rows > PM8XXX_MAX_ROWS || | ||
554 | pdata->num_cols < PM8XXX_MIN_COLS) { | ||
555 | dev_err(&pdev->dev, "invalid platform data\n"); | 523 | dev_err(&pdev->dev, "invalid platform data\n"); |
556 | return -EINVAL; | 524 | return -EINVAL; |
557 | } | 525 | } |
558 | 526 | ||
559 | if (!pdata->scan_delay_ms || | 527 | repeat = !of_property_read_bool(pdev->dev.of_node, |
560 | pdata->scan_delay_ms > MAX_SCAN_DELAY || | 528 | "linux,input-no-autorepeat"); |
561 | pdata->scan_delay_ms < MIN_SCAN_DELAY || | 529 | wakeup = of_property_read_bool(pdev->dev.of_node, |
562 | !is_power_of_2(pdata->scan_delay_ms)) { | 530 | "linux,keypad-wakeup"); |
563 | dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); | ||
564 | return -EINVAL; | ||
565 | } | ||
566 | |||
567 | if (!pdata->row_hold_ns || | ||
568 | pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || | ||
569 | pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || | ||
570 | ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { | ||
571 | dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); | ||
572 | return -EINVAL; | ||
573 | } | ||
574 | |||
575 | if (!pdata->debounce_ms || | ||
576 | ((pdata->debounce_ms % 5) != 0) || | ||
577 | pdata->debounce_ms > MAX_DEBOUNCE_TIME || | ||
578 | pdata->debounce_ms < MIN_DEBOUNCE_TIME) { | ||
579 | dev_err(&pdev->dev, "invalid debounce time supplied\n"); | ||
580 | return -EINVAL; | ||
581 | } | ||
582 | |||
583 | keymap_data = pdata->keymap_data; | ||
584 | if (!keymap_data) { | ||
585 | dev_err(&pdev->dev, "no keymap data supplied\n"); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | 531 | ||
589 | kp = kzalloc(sizeof(*kp), GFP_KERNEL); | 532 | kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); |
590 | if (!kp) | 533 | if (!kp) |
591 | return -ENOMEM; | 534 | return -ENOMEM; |
592 | 535 | ||
536 | kp->regmap = dev_get_regmap(pdev->dev.parent, NULL); | ||
537 | if (!kp->regmap) | ||
538 | return -ENODEV; | ||
539 | |||
593 | platform_set_drvdata(pdev, kp); | 540 | platform_set_drvdata(pdev, kp); |
594 | 541 | ||
595 | kp->pdata = pdata; | 542 | kp->num_rows = rows; |
543 | kp->num_cols = cols; | ||
596 | kp->dev = &pdev->dev; | 544 | kp->dev = &pdev->dev; |
597 | 545 | ||
598 | kp->input = input_allocate_device(); | 546 | kp->input = devm_input_allocate_device(&pdev->dev); |
599 | if (!kp->input) { | 547 | if (!kp->input) { |
600 | dev_err(&pdev->dev, "unable to allocate input device\n"); | 548 | dev_err(&pdev->dev, "unable to allocate input device\n"); |
601 | rc = -ENOMEM; | 549 | return -ENOMEM; |
602 | goto err_alloc_device; | ||
603 | } | 550 | } |
604 | 551 | ||
605 | kp->key_sense_irq = platform_get_irq(pdev, 0); | 552 | kp->key_sense_irq = platform_get_irq(pdev, 0); |
606 | if (kp->key_sense_irq < 0) { | 553 | if (kp->key_sense_irq < 0) { |
607 | dev_err(&pdev->dev, "unable to get keypad sense irq\n"); | 554 | dev_err(&pdev->dev, "unable to get keypad sense irq\n"); |
608 | rc = -ENXIO; | 555 | return kp->key_sense_irq; |
609 | goto err_get_irq; | ||
610 | } | 556 | } |
611 | 557 | ||
612 | kp->key_stuck_irq = platform_get_irq(pdev, 1); | 558 | kp->key_stuck_irq = platform_get_irq(pdev, 1); |
613 | if (kp->key_stuck_irq < 0) { | 559 | if (kp->key_stuck_irq < 0) { |
614 | dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); | 560 | dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); |
615 | rc = -ENXIO; | 561 | return kp->key_stuck_irq; |
616 | goto err_get_irq; | ||
617 | } | 562 | } |
618 | 563 | ||
619 | kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; | 564 | kp->input->name = "PMIC8XXX keypad"; |
620 | kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; | 565 | kp->input->phys = "pmic8xxx_keypad/input0"; |
621 | |||
622 | kp->input->dev.parent = &pdev->dev; | ||
623 | 566 | ||
624 | kp->input->id.bustype = BUS_I2C; | 567 | kp->input->id.bustype = BUS_I2C; |
625 | kp->input->id.version = 0x0001; | 568 | kp->input->id.version = 0x0001; |
@@ -629,15 +572,15 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) | |||
629 | kp->input->open = pmic8xxx_kp_open; | 572 | kp->input->open = pmic8xxx_kp_open; |
630 | kp->input->close = pmic8xxx_kp_close; | 573 | kp->input->close = pmic8xxx_kp_close; |
631 | 574 | ||
632 | rc = matrix_keypad_build_keymap(keymap_data, NULL, | 575 | rc = matrix_keypad_build_keymap(NULL, NULL, |
633 | PM8XXX_MAX_ROWS, PM8XXX_MAX_COLS, | 576 | PM8XXX_MAX_ROWS, PM8XXX_MAX_COLS, |
634 | kp->keycodes, kp->input); | 577 | kp->keycodes, kp->input); |
635 | if (rc) { | 578 | if (rc) { |
636 | dev_err(&pdev->dev, "failed to build keymap\n"); | 579 | dev_err(&pdev->dev, "failed to build keymap\n"); |
637 | goto err_get_irq; | 580 | return rc; |
638 | } | 581 | } |
639 | 582 | ||
640 | if (pdata->rep) | 583 | if (repeat) |
641 | __set_bit(EV_REP, kp->input->evbit); | 584 | __set_bit(EV_REP, kp->input->evbit); |
642 | input_set_capability(kp->input, EV_MSC, MSC_SCAN); | 585 | input_set_capability(kp->input, EV_MSC, MSC_SCAN); |
643 | 586 | ||
@@ -647,44 +590,32 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) | |||
647 | memset(kp->keystate, 0xff, sizeof(kp->keystate)); | 590 | memset(kp->keystate, 0xff, sizeof(kp->keystate)); |
648 | memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); | 591 | memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); |
649 | 592 | ||
650 | rc = pmic8xxx_kpd_init(kp); | 593 | rc = pmic8xxx_kpd_init(kp, pdev); |
651 | if (rc < 0) { | 594 | if (rc < 0) { |
652 | dev_err(&pdev->dev, "unable to initialize keypad controller\n"); | 595 | dev_err(&pdev->dev, "unable to initialize keypad controller\n"); |
653 | goto err_get_irq; | 596 | return rc; |
654 | } | ||
655 | |||
656 | rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, | ||
657 | pdata->num_cols, kp, &kypd_sns); | ||
658 | if (rc < 0) { | ||
659 | dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); | ||
660 | goto err_gpio_config; | ||
661 | } | ||
662 | |||
663 | rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, | ||
664 | pdata->num_rows, kp, &kypd_drv); | ||
665 | if (rc < 0) { | ||
666 | dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); | ||
667 | goto err_gpio_config; | ||
668 | } | 597 | } |
669 | 598 | ||
670 | rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, | 599 | rc = devm_request_any_context_irq(&pdev->dev, kp->key_sense_irq, |
671 | IRQF_TRIGGER_RISING, "pmic-keypad", kp); | 600 | pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", |
601 | kp); | ||
672 | if (rc < 0) { | 602 | if (rc < 0) { |
673 | dev_err(&pdev->dev, "failed to request keypad sense irq\n"); | 603 | dev_err(&pdev->dev, "failed to request keypad sense irq\n"); |
674 | goto err_get_irq; | 604 | return rc; |
675 | } | 605 | } |
676 | 606 | ||
677 | rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, | 607 | rc = devm_request_any_context_irq(&pdev->dev, kp->key_stuck_irq, |
678 | IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); | 608 | pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, |
609 | "pmic-keypad-stuck", kp); | ||
679 | if (rc < 0) { | 610 | if (rc < 0) { |
680 | dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); | 611 | dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); |
681 | goto err_req_stuck_irq; | 612 | return rc; |
682 | } | 613 | } |
683 | 614 | ||
684 | rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); | 615 | rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val); |
685 | if (rc < 0) { | 616 | if (rc < 0) { |
686 | dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); | 617 | dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); |
687 | goto err_pmic_reg_read; | 618 | return rc; |
688 | } | 619 | } |
689 | 620 | ||
690 | kp->ctrl_reg = ctrl_val; | 621 | kp->ctrl_reg = ctrl_val; |
@@ -692,34 +623,10 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) | |||
692 | rc = input_register_device(kp->input); | 623 | rc = input_register_device(kp->input); |
693 | if (rc < 0) { | 624 | if (rc < 0) { |
694 | dev_err(&pdev->dev, "unable to register keypad input device\n"); | 625 | dev_err(&pdev->dev, "unable to register keypad input device\n"); |
695 | goto err_pmic_reg_read; | 626 | return rc; |
696 | } | 627 | } |
697 | 628 | ||
698 | device_init_wakeup(&pdev->dev, pdata->wakeup); | 629 | device_init_wakeup(&pdev->dev, wakeup); |
699 | |||
700 | return 0; | ||
701 | |||
702 | err_pmic_reg_read: | ||
703 | free_irq(kp->key_stuck_irq, kp); | ||
704 | err_req_stuck_irq: | ||
705 | free_irq(kp->key_sense_irq, kp); | ||
706 | err_gpio_config: | ||
707 | err_get_irq: | ||
708 | input_free_device(kp->input); | ||
709 | err_alloc_device: | ||
710 | kfree(kp); | ||
711 | return rc; | ||
712 | } | ||
713 | |||
714 | static int pmic8xxx_kp_remove(struct platform_device *pdev) | ||
715 | { | ||
716 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); | ||
717 | |||
718 | device_init_wakeup(&pdev->dev, 0); | ||
719 | free_irq(kp->key_stuck_irq, kp); | ||
720 | free_irq(kp->key_sense_irq, kp); | ||
721 | input_unregister_device(kp->input); | ||
722 | kfree(kp); | ||
723 | 630 | ||
724 | return 0; | 631 | return 0; |
725 | } | 632 | } |
@@ -769,13 +676,20 @@ static int pmic8xxx_kp_resume(struct device *dev) | |||
769 | static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, | 676 | static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, |
770 | pmic8xxx_kp_suspend, pmic8xxx_kp_resume); | 677 | pmic8xxx_kp_suspend, pmic8xxx_kp_resume); |
771 | 678 | ||
679 | static const struct of_device_id pm8xxx_match_table[] = { | ||
680 | { .compatible = "qcom,pm8058-keypad" }, | ||
681 | { .compatible = "qcom,pm8921-keypad" }, | ||
682 | { } | ||
683 | }; | ||
684 | MODULE_DEVICE_TABLE(of, pm8xxx_match_table); | ||
685 | |||
772 | static struct platform_driver pmic8xxx_kp_driver = { | 686 | static struct platform_driver pmic8xxx_kp_driver = { |
773 | .probe = pmic8xxx_kp_probe, | 687 | .probe = pmic8xxx_kp_probe, |
774 | .remove = pmic8xxx_kp_remove, | ||
775 | .driver = { | 688 | .driver = { |
776 | .name = PM8XXX_KEYPAD_DEV_NAME, | 689 | .name = "pm8xxx-keypad", |
777 | .owner = THIS_MODULE, | 690 | .owner = THIS_MODULE, |
778 | .pm = &pm8xxx_kp_pm_ops, | 691 | .pm = &pm8xxx_kp_pm_ops, |
692 | .of_match_table = pm8xxx_match_table, | ||
779 | }, | 693 | }, |
780 | }; | 694 | }; |
781 | module_platform_driver(pmic8xxx_kp_driver); | 695 | module_platform_driver(pmic8xxx_kp_driver); |
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 8508879f6faf..9757a58bc897 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/input/matrix_keypad.h> | 33 | #include <linux/input/matrix_keypad.h> |
34 | #include <linux/clk/tegra.h> | 34 | #include <linux/reset.h> |
35 | #include <linux/err.h> | 35 | #include <linux/err.h> |
36 | 36 | ||
37 | #define KBC_MAX_KPENT 8 | 37 | #define KBC_MAX_KPENT 8 |
@@ -116,6 +116,7 @@ struct tegra_kbc { | |||
116 | u32 wakeup_key; | 116 | u32 wakeup_key; |
117 | struct timer_list timer; | 117 | struct timer_list timer; |
118 | struct clk *clk; | 118 | struct clk *clk; |
119 | struct reset_control *rst; | ||
119 | const struct tegra_kbc_hw_support *hw_support; | 120 | const struct tegra_kbc_hw_support *hw_support; |
120 | int max_keys; | 121 | int max_keys; |
121 | int num_rows_and_columns; | 122 | int num_rows_and_columns; |
@@ -373,9 +374,9 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) | |||
373 | clk_prepare_enable(kbc->clk); | 374 | clk_prepare_enable(kbc->clk); |
374 | 375 | ||
375 | /* Reset the KBC controller to clear all previous status.*/ | 376 | /* Reset the KBC controller to clear all previous status.*/ |
376 | tegra_periph_reset_assert(kbc->clk); | 377 | reset_control_assert(kbc->rst); |
377 | udelay(100); | 378 | udelay(100); |
378 | tegra_periph_reset_deassert(kbc->clk); | 379 | reset_control_assert(kbc->rst); |
379 | udelay(100); | 380 | udelay(100); |
380 | 381 | ||
381 | tegra_kbc_config_pins(kbc); | 382 | tegra_kbc_config_pins(kbc); |
@@ -663,6 +664,12 @@ static int tegra_kbc_probe(struct platform_device *pdev) | |||
663 | return PTR_ERR(kbc->clk); | 664 | return PTR_ERR(kbc->clk); |
664 | } | 665 | } |
665 | 666 | ||
667 | kbc->rst = devm_reset_control_get(&pdev->dev, "kbc"); | ||
668 | if (IS_ERR(kbc->rst)) { | ||
669 | dev_err(&pdev->dev, "failed to get keyboard reset\n"); | ||
670 | return PTR_ERR(kbc->rst); | ||
671 | } | ||
672 | |||
666 | /* | 673 | /* |
667 | * The time delay between two consecutive reads of the FIFO is | 674 | * The time delay between two consecutive reads of the FIFO is |
668 | * the sum of the repeat time and the time taken for scanning | 675 | * the sum of the repeat time and the time taken for scanning |
diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c deleted file mode 100644 index 086511c2121b..000000000000 --- a/drivers/input/keyboard/tnetv107x-keypad.c +++ /dev/null | |||
@@ -1,329 +0,0 @@ | |||
1 | /* | ||
2 | * Texas Instruments TNETV107X Keypad Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/input/matrix_keypad.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #define BITS(x) (BIT(x) - 1) | ||
30 | |||
31 | #define KEYPAD_ROWS 9 | ||
32 | #define KEYPAD_COLS 9 | ||
33 | |||
34 | #define DEBOUNCE_MIN 0x400ul | ||
35 | #define DEBOUNCE_MAX 0x3ffffffful | ||
36 | |||
37 | struct keypad_regs { | ||
38 | u32 rev; | ||
39 | u32 mode; | ||
40 | u32 mask; | ||
41 | u32 pol; | ||
42 | u32 dclock; | ||
43 | u32 rclock; | ||
44 | u32 stable_cnt; | ||
45 | u32 in_en; | ||
46 | u32 out; | ||
47 | u32 out_en; | ||
48 | u32 in; | ||
49 | u32 lock; | ||
50 | u32 pres[3]; | ||
51 | }; | ||
52 | |||
53 | #define keypad_read(kp, reg) __raw_readl(&(kp)->regs->reg) | ||
54 | #define keypad_write(kp, reg, val) __raw_writel(val, &(kp)->regs->reg) | ||
55 | |||
56 | struct keypad_data { | ||
57 | struct input_dev *input_dev; | ||
58 | struct resource *res; | ||
59 | struct keypad_regs __iomem *regs; | ||
60 | struct clk *clk; | ||
61 | struct device *dev; | ||
62 | spinlock_t lock; | ||
63 | int irq_press; | ||
64 | int irq_release; | ||
65 | int rows, cols, row_shift; | ||
66 | int debounce_ms, active_low; | ||
67 | u32 prev_keys[3]; | ||
68 | unsigned short keycodes[]; | ||
69 | }; | ||
70 | |||
71 | static irqreturn_t keypad_irq(int irq, void *data) | ||
72 | { | ||
73 | struct keypad_data *kp = data; | ||
74 | int i, bit, val, row, col, code; | ||
75 | unsigned long flags; | ||
76 | u32 curr_keys[3]; | ||
77 | u32 change; | ||
78 | |||
79 | spin_lock_irqsave(&kp->lock, flags); | ||
80 | |||
81 | memset(curr_keys, 0, sizeof(curr_keys)); | ||
82 | if (irq == kp->irq_press) | ||
83 | for (i = 0; i < 3; i++) | ||
84 | curr_keys[i] = keypad_read(kp, pres[i]); | ||
85 | |||
86 | for (i = 0; i < 3; i++) { | ||
87 | change = curr_keys[i] ^ kp->prev_keys[i]; | ||
88 | |||
89 | while (change) { | ||
90 | bit = fls(change) - 1; | ||
91 | change ^= BIT(bit); | ||
92 | val = curr_keys[i] & BIT(bit); | ||
93 | bit += i * 32; | ||
94 | row = bit / KEYPAD_COLS; | ||
95 | col = bit % KEYPAD_COLS; | ||
96 | |||
97 | code = MATRIX_SCAN_CODE(row, col, kp->row_shift); | ||
98 | input_event(kp->input_dev, EV_MSC, MSC_SCAN, code); | ||
99 | input_report_key(kp->input_dev, kp->keycodes[code], | ||
100 | val); | ||
101 | } | ||
102 | } | ||
103 | input_sync(kp->input_dev); | ||
104 | memcpy(kp->prev_keys, curr_keys, sizeof(curr_keys)); | ||
105 | |||
106 | if (irq == kp->irq_press) | ||
107 | keypad_write(kp, lock, 0); /* Allow hardware updates */ | ||
108 | |||
109 | spin_unlock_irqrestore(&kp->lock, flags); | ||
110 | |||
111 | return IRQ_HANDLED; | ||
112 | } | ||
113 | |||
114 | static int keypad_start(struct input_dev *dev) | ||
115 | { | ||
116 | struct keypad_data *kp = input_get_drvdata(dev); | ||
117 | unsigned long mask, debounce, clk_rate_khz; | ||
118 | unsigned long flags; | ||
119 | |||
120 | clk_enable(kp->clk); | ||
121 | clk_rate_khz = clk_get_rate(kp->clk) / 1000; | ||
122 | |||
123 | spin_lock_irqsave(&kp->lock, flags); | ||
124 | |||
125 | /* Initialize device registers */ | ||
126 | keypad_write(kp, mode, 0); | ||
127 | |||
128 | mask = BITS(kp->rows) << KEYPAD_COLS; | ||
129 | mask |= BITS(kp->cols); | ||
130 | keypad_write(kp, mask, ~mask); | ||
131 | |||
132 | keypad_write(kp, pol, kp->active_low ? 0 : 0x3ffff); | ||
133 | keypad_write(kp, stable_cnt, 3); | ||
134 | |||
135 | debounce = kp->debounce_ms * clk_rate_khz; | ||
136 | debounce = clamp(debounce, DEBOUNCE_MIN, DEBOUNCE_MAX); | ||
137 | keypad_write(kp, dclock, debounce); | ||
138 | keypad_write(kp, rclock, 4 * debounce); | ||
139 | |||
140 | keypad_write(kp, in_en, 1); | ||
141 | |||
142 | spin_unlock_irqrestore(&kp->lock, flags); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static void keypad_stop(struct input_dev *dev) | ||
148 | { | ||
149 | struct keypad_data *kp = input_get_drvdata(dev); | ||
150 | |||
151 | synchronize_irq(kp->irq_press); | ||
152 | synchronize_irq(kp->irq_release); | ||
153 | clk_disable(kp->clk); | ||
154 | } | ||
155 | |||
156 | static int keypad_probe(struct platform_device *pdev) | ||
157 | { | ||
158 | const struct matrix_keypad_platform_data *pdata; | ||
159 | const struct matrix_keymap_data *keymap_data; | ||
160 | struct device *dev = &pdev->dev; | ||
161 | struct keypad_data *kp; | ||
162 | int error = 0, sz, row_shift; | ||
163 | u32 rev = 0; | ||
164 | |||
165 | pdata = dev_get_platdata(&pdev->dev); | ||
166 | if (!pdata) { | ||
167 | dev_err(dev, "cannot find device data\n"); | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | keymap_data = pdata->keymap_data; | ||
172 | if (!keymap_data) { | ||
173 | dev_err(dev, "cannot find keymap data\n"); | ||
174 | return -EINVAL; | ||
175 | } | ||
176 | |||
177 | row_shift = get_count_order(pdata->num_col_gpios); | ||
178 | sz = offsetof(struct keypad_data, keycodes); | ||
179 | sz += (pdata->num_row_gpios << row_shift) * sizeof(kp->keycodes[0]); | ||
180 | kp = kzalloc(sz, GFP_KERNEL); | ||
181 | if (!kp) { | ||
182 | dev_err(dev, "cannot allocate device info\n"); | ||
183 | return -ENOMEM; | ||
184 | } | ||
185 | |||
186 | kp->dev = dev; | ||
187 | kp->rows = pdata->num_row_gpios; | ||
188 | kp->cols = pdata->num_col_gpios; | ||
189 | kp->row_shift = row_shift; | ||
190 | platform_set_drvdata(pdev, kp); | ||
191 | spin_lock_init(&kp->lock); | ||
192 | |||
193 | kp->irq_press = platform_get_irq_byname(pdev, "press"); | ||
194 | kp->irq_release = platform_get_irq_byname(pdev, "release"); | ||
195 | if (kp->irq_press < 0 || kp->irq_release < 0) { | ||
196 | dev_err(dev, "cannot determine device interrupts\n"); | ||
197 | error = -ENODEV; | ||
198 | goto error_res; | ||
199 | } | ||
200 | |||
201 | kp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
202 | if (!kp->res) { | ||
203 | dev_err(dev, "cannot determine register area\n"); | ||
204 | error = -ENODEV; | ||
205 | goto error_res; | ||
206 | } | ||
207 | |||
208 | if (!request_mem_region(kp->res->start, resource_size(kp->res), | ||
209 | pdev->name)) { | ||
210 | dev_err(dev, "cannot claim register memory\n"); | ||
211 | kp->res = NULL; | ||
212 | error = -EINVAL; | ||
213 | goto error_res; | ||
214 | } | ||
215 | |||
216 | kp->regs = ioremap(kp->res->start, resource_size(kp->res)); | ||
217 | if (!kp->regs) { | ||
218 | dev_err(dev, "cannot map register memory\n"); | ||
219 | error = -ENOMEM; | ||
220 | goto error_map; | ||
221 | } | ||
222 | |||
223 | kp->clk = clk_get(dev, NULL); | ||
224 | if (IS_ERR(kp->clk)) { | ||
225 | dev_err(dev, "cannot claim device clock\n"); | ||
226 | error = PTR_ERR(kp->clk); | ||
227 | goto error_clk; | ||
228 | } | ||
229 | |||
230 | error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, | ||
231 | IRQF_ONESHOT, dev_name(dev), kp); | ||
232 | if (error < 0) { | ||
233 | dev_err(kp->dev, "Could not allocate keypad press key irq\n"); | ||
234 | goto error_irq_press; | ||
235 | } | ||
236 | |||
237 | error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, | ||
238 | IRQF_ONESHOT, dev_name(dev), kp); | ||
239 | if (error < 0) { | ||
240 | dev_err(kp->dev, "Could not allocate keypad release key irq\n"); | ||
241 | goto error_irq_release; | ||
242 | } | ||
243 | |||
244 | kp->input_dev = input_allocate_device(); | ||
245 | if (!kp->input_dev) { | ||
246 | dev_err(dev, "cannot allocate input device\n"); | ||
247 | error = -ENOMEM; | ||
248 | goto error_input; | ||
249 | } | ||
250 | |||
251 | kp->input_dev->name = pdev->name; | ||
252 | kp->input_dev->dev.parent = &pdev->dev; | ||
253 | kp->input_dev->open = keypad_start; | ||
254 | kp->input_dev->close = keypad_stop; | ||
255 | |||
256 | clk_enable(kp->clk); | ||
257 | rev = keypad_read(kp, rev); | ||
258 | kp->input_dev->id.bustype = BUS_HOST; | ||
259 | kp->input_dev->id.product = ((rev >> 8) & 0x07); | ||
260 | kp->input_dev->id.version = ((rev >> 16) & 0xfff); | ||
261 | clk_disable(kp->clk); | ||
262 | |||
263 | error = matrix_keypad_build_keymap(keymap_data, NULL, | ||
264 | kp->rows, kp->cols, | ||
265 | kp->keycodes, kp->input_dev); | ||
266 | if (error) { | ||
267 | dev_err(dev, "Failed to build keymap\n"); | ||
268 | goto error_reg; | ||
269 | } | ||
270 | |||
271 | if (!pdata->no_autorepeat) | ||
272 | kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
273 | input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); | ||
274 | |||
275 | input_set_drvdata(kp->input_dev, kp); | ||
276 | |||
277 | error = input_register_device(kp->input_dev); | ||
278 | if (error < 0) { | ||
279 | dev_err(dev, "Could not register input device\n"); | ||
280 | goto error_reg; | ||
281 | } | ||
282 | |||
283 | return 0; | ||
284 | |||
285 | |||
286 | error_reg: | ||
287 | input_free_device(kp->input_dev); | ||
288 | error_input: | ||
289 | free_irq(kp->irq_release, kp); | ||
290 | error_irq_release: | ||
291 | free_irq(kp->irq_press, kp); | ||
292 | error_irq_press: | ||
293 | clk_put(kp->clk); | ||
294 | error_clk: | ||
295 | iounmap(kp->regs); | ||
296 | error_map: | ||
297 | release_mem_region(kp->res->start, resource_size(kp->res)); | ||
298 | error_res: | ||
299 | kfree(kp); | ||
300 | return error; | ||
301 | } | ||
302 | |||
303 | static int keypad_remove(struct platform_device *pdev) | ||
304 | { | ||
305 | struct keypad_data *kp = platform_get_drvdata(pdev); | ||
306 | |||
307 | free_irq(kp->irq_press, kp); | ||
308 | free_irq(kp->irq_release, kp); | ||
309 | input_unregister_device(kp->input_dev); | ||
310 | clk_put(kp->clk); | ||
311 | iounmap(kp->regs); | ||
312 | release_mem_region(kp->res->start, resource_size(kp->res)); | ||
313 | kfree(kp); | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static struct platform_driver keypad_driver = { | ||
319 | .probe = keypad_probe, | ||
320 | .remove = keypad_remove, | ||
321 | .driver.name = "tnetv107x-keypad", | ||
322 | .driver.owner = THIS_MODULE, | ||
323 | }; | ||
324 | module_platform_driver(keypad_driver); | ||
325 | |||
326 | MODULE_AUTHOR("Cyril Chemparathy"); | ||
327 | MODULE_DESCRIPTION("TNETV107X Keypad Driver"); | ||
328 | MODULE_ALIAS("platform:tnetv107x-keypad"); | ||
329 | MODULE_LICENSE("GPL"); | ||