diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-27 12:24:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-27 12:24:56 -0400 |
commit | 70a3eff5768350c0313a9ae70a15da113171d0ab (patch) | |
tree | 9c2558f92e567bcb35c79f59bc7ebc9cf6fdc9d3 /drivers/input/misc | |
parent | 9ed3689bdceb0064ee6faf0e76f6467122794970 (diff) | |
parent | aa7eb8e78d8ecd6cd0475d86ea8385ff9cb47ece (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (53 commits)
Input: synaptics - fix reporting of min coordinates
Input: tegra-kbc - enable key autorepeat
Input: kxtj9 - fix locking typo in kxtj9_set_poll()
Input: kxtj9 - fix bug in probe()
Input: intel-mid-touch - remove pointless checking for variable 'found'
Input: hp_sdc - staticize hp_sdc_kicker()
Input: pmic8xxx-keypad - fix a leak of the IRQ during init failure
Input: cy8ctmg110_ts - set reset_pin and irq_pin from platform data
Input: cy8ctmg110_ts - constify i2c_device_id table
Input: cy8ctmg110_ts - fix checking return value of i2c_master_send
Input: lifebook - make dmi callback functions return 1
Input: atkbd - make dmi callback functions return 1
Input: gpio_keys - switch to using SIMPLE_DEV_PM_OPS
Input: gpio_keys - add support for device-tree platform data
Input: aiptek - remove double define
Input: synaptics - set minimum coordinates as reported by firmware
Input: synaptics - process button bits in AGM packets
Input: synaptics - rename set_slot to be more descriptive
Input: synaptics - fuzz position for touchpad with reduced filtering
Input: synaptics - set resolution for MT_POSITION_X/Y axes
...
Diffstat (limited to 'drivers/input/misc')
-rw-r--r-- | drivers/input/misc/Kconfig | 38 | ||||
-rw-r--r-- | drivers/input/misc/Makefile | 4 | ||||
-rw-r--r-- | drivers/input/misc/bfin_rotary.c | 1 | ||||
-rw-r--r-- | drivers/input/misc/kxtj9.c | 671 | ||||
-rw-r--r-- | drivers/input/misc/mma8450.c | 256 | ||||
-rw-r--r-- | drivers/input/misc/mpu3050.c | 376 | ||||
-rw-r--r-- | drivers/input/misc/xen-kbdfront.c | 2 |
7 files changed, 1345 insertions, 3 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index d1bf8724b58f..c9104bb4db06 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -100,6 +100,27 @@ config INPUT_MAX8925_ONKEY | |||
100 | To compile this driver as a module, choose M here: the module | 100 | To compile this driver as a module, choose M here: the module |
101 | will be called max8925_onkey. | 101 | will be called max8925_onkey. |
102 | 102 | ||
103 | config INPUT_MMA8450 | ||
104 | tristate "MMA8450 - Freescale's 3-Axis, 8/12-bit Digital Accelerometer" | ||
105 | depends on I2C | ||
106 | select INPUT_POLLDEV | ||
107 | help | ||
108 | Say Y here if you want to support Freescale's MMA8450 Accelerometer | ||
109 | through I2C interface. | ||
110 | |||
111 | To compile this driver as a module, choose M here: the | ||
112 | module will be called mma8450. | ||
113 | |||
114 | config INPUT_MPU3050 | ||
115 | tristate "MPU3050 Triaxial gyroscope sensor" | ||
116 | depends on I2C | ||
117 | help | ||
118 | Say Y here if you want to support InvenSense MPU3050 | ||
119 | connected via an I2C bus. | ||
120 | |||
121 | To compile this driver as a module, choose M here: the | ||
122 | module will be called mpu3050. | ||
123 | |||
103 | config INPUT_APANEL | 124 | config INPUT_APANEL |
104 | tristate "Fujitsu Lifebook Application Panel buttons" | 125 | tristate "Fujitsu Lifebook Application Panel buttons" |
105 | depends on X86 && I2C && LEDS_CLASS | 126 | depends on X86 && I2C && LEDS_CLASS |
@@ -209,6 +230,23 @@ config INPUT_KEYSPAN_REMOTE | |||
209 | To compile this driver as a module, choose M here: the module will | 230 | To compile this driver as a module, choose M here: the module will |
210 | be called keyspan_remote. | 231 | be called keyspan_remote. |
211 | 232 | ||
233 | config INPUT_KXTJ9 | ||
234 | tristate "Kionix KXTJ9 tri-axis digital accelerometer" | ||
235 | depends on I2C | ||
236 | help | ||
237 | Say Y here to enable support for the Kionix KXTJ9 digital tri-axis | ||
238 | accelerometer. | ||
239 | |||
240 | To compile this driver as a module, choose M here: the module will | ||
241 | be called kxtj9. | ||
242 | |||
243 | config INPUT_KXTJ9_POLLED_MODE | ||
244 | bool "Enable polling mode support" | ||
245 | depends on INPUT_KXTJ9 | ||
246 | select INPUT_POLLDEV | ||
247 | help | ||
248 | Say Y here if you need accelerometer to work in polling mode. | ||
249 | |||
212 | config INPUT_POWERMATE | 250 | config INPUT_POWERMATE |
213 | tristate "Griffin PowerMate and Contour Jog support" | 251 | tristate "Griffin PowerMate and Contour Jog support" |
214 | depends on USB_ARCH_HAS_HCD | 252 | depends on USB_ARCH_HAS_HCD |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 4da7c3a60e04..299ad5edba84 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -25,8 +25,11 @@ obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o | |||
25 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 25 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
26 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o | 26 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o |
27 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o | 27 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o |
28 | obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o | ||
28 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o | 29 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o |
29 | obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o | 30 | obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o |
31 | obj-$(CONFIG_INPUT_MMA8450) += mma8450.o | ||
32 | obj-$(CONFIG_INPUT_MPU3050) += mpu3050.o | ||
30 | obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o | 33 | obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o |
31 | obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o | 34 | obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o |
32 | obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o | 35 | obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o |
@@ -46,4 +49,3 @@ obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | |||
46 | obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o | 49 | obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o |
47 | obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o | 50 | obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o |
48 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o | 51 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o |
49 | |||
diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index 4f72bdd69410..d00edc9f39d1 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c | |||
@@ -6,7 +6,6 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/version.h> | ||
10 | #include <linux/init.h> | 9 | #include <linux/init.h> |
11 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
12 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c new file mode 100644 index 000000000000..c456f63b6bae --- /dev/null +++ b/drivers/input/misc/kxtj9.c | |||
@@ -0,0 +1,671 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Kionix, Inc. | ||
3 | * Written by Chris Hudson <chudson@kionix.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
17 | * 02111-1307, USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/input/kxtj9.h> | ||
26 | #include <linux/input-polldev.h> | ||
27 | |||
28 | #define NAME "kxtj9" | ||
29 | #define G_MAX 8000 | ||
30 | /* OUTPUT REGISTERS */ | ||
31 | #define XOUT_L 0x06 | ||
32 | #define WHO_AM_I 0x0F | ||
33 | /* CONTROL REGISTERS */ | ||
34 | #define INT_REL 0x1A | ||
35 | #define CTRL_REG1 0x1B | ||
36 | #define INT_CTRL1 0x1E | ||
37 | #define DATA_CTRL 0x21 | ||
38 | /* CONTROL REGISTER 1 BITS */ | ||
39 | #define PC1_OFF 0x7F | ||
40 | #define PC1_ON (1 << 7) | ||
41 | /* Data ready funtion enable bit: set during probe if using irq mode */ | ||
42 | #define DRDYE (1 << 5) | ||
43 | /* INTERRUPT CONTROL REGISTER 1 BITS */ | ||
44 | /* Set these during probe if using irq mode */ | ||
45 | #define KXTJ9_IEL (1 << 3) | ||
46 | #define KXTJ9_IEA (1 << 4) | ||
47 | #define KXTJ9_IEN (1 << 5) | ||
48 | /* INPUT_ABS CONSTANTS */ | ||
49 | #define FUZZ 3 | ||
50 | #define FLAT 3 | ||
51 | /* RESUME STATE INDICES */ | ||
52 | #define RES_DATA_CTRL 0 | ||
53 | #define RES_CTRL_REG1 1 | ||
54 | #define RES_INT_CTRL1 2 | ||
55 | #define RESUME_ENTRIES 3 | ||
56 | |||
57 | /* | ||
58 | * The following table lists the maximum appropriate poll interval for each | ||
59 | * available output data rate. | ||
60 | */ | ||
61 | static const struct { | ||
62 | unsigned int cutoff; | ||
63 | u8 mask; | ||
64 | } kxtj9_odr_table[] = { | ||
65 | { 3, ODR800F }, | ||
66 | { 5, ODR400F }, | ||
67 | { 10, ODR200F }, | ||
68 | { 20, ODR100F }, | ||
69 | { 40, ODR50F }, | ||
70 | { 80, ODR25F }, | ||
71 | { 0, ODR12_5F}, | ||
72 | }; | ||
73 | |||
74 | struct kxtj9_data { | ||
75 | struct i2c_client *client; | ||
76 | struct kxtj9_platform_data pdata; | ||
77 | struct input_dev *input_dev; | ||
78 | #ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE | ||
79 | struct input_polled_dev *poll_dev; | ||
80 | #endif | ||
81 | unsigned int last_poll_interval; | ||
82 | u8 shift; | ||
83 | u8 ctrl_reg1; | ||
84 | u8 data_ctrl; | ||
85 | u8 int_ctrl; | ||
86 | }; | ||
87 | |||
88 | static int kxtj9_i2c_read(struct kxtj9_data *tj9, u8 addr, u8 *data, int len) | ||
89 | { | ||
90 | struct i2c_msg msgs[] = { | ||
91 | { | ||
92 | .addr = tj9->client->addr, | ||
93 | .flags = tj9->client->flags, | ||
94 | .len = 1, | ||
95 | .buf = &addr, | ||
96 | }, | ||
97 | { | ||
98 | .addr = tj9->client->addr, | ||
99 | .flags = tj9->client->flags | I2C_M_RD, | ||
100 | .len = len, | ||
101 | .buf = data, | ||
102 | }, | ||
103 | }; | ||
104 | |||
105 | return i2c_transfer(tj9->client->adapter, msgs, 2); | ||
106 | } | ||
107 | |||
108 | static void kxtj9_report_acceleration_data(struct kxtj9_data *tj9) | ||
109 | { | ||
110 | s16 acc_data[3]; /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ | ||
111 | s16 x, y, z; | ||
112 | int err; | ||
113 | |||
114 | err = kxtj9_i2c_read(tj9, XOUT_L, (u8 *)acc_data, 6); | ||
115 | if (err < 0) | ||
116 | dev_err(&tj9->client->dev, "accelerometer data read failed\n"); | ||
117 | |||
118 | x = le16_to_cpu(acc_data[tj9->pdata.axis_map_x]) >> tj9->shift; | ||
119 | y = le16_to_cpu(acc_data[tj9->pdata.axis_map_y]) >> tj9->shift; | ||
120 | z = le16_to_cpu(acc_data[tj9->pdata.axis_map_z]) >> tj9->shift; | ||
121 | |||
122 | input_report_abs(tj9->input_dev, ABS_X, tj9->pdata.negate_x ? -x : x); | ||
123 | input_report_abs(tj9->input_dev, ABS_Y, tj9->pdata.negate_y ? -y : y); | ||
124 | input_report_abs(tj9->input_dev, ABS_Z, tj9->pdata.negate_z ? -z : z); | ||
125 | input_sync(tj9->input_dev); | ||
126 | } | ||
127 | |||
128 | static irqreturn_t kxtj9_isr(int irq, void *dev) | ||
129 | { | ||
130 | struct kxtj9_data *tj9 = dev; | ||
131 | int err; | ||
132 | |||
133 | /* data ready is the only possible interrupt type */ | ||
134 | kxtj9_report_acceleration_data(tj9); | ||
135 | |||
136 | err = i2c_smbus_read_byte_data(tj9->client, INT_REL); | ||
137 | if (err < 0) | ||
138 | dev_err(&tj9->client->dev, | ||
139 | "error clearing interrupt status: %d\n", err); | ||
140 | |||
141 | return IRQ_HANDLED; | ||
142 | } | ||
143 | |||
144 | static int kxtj9_update_g_range(struct kxtj9_data *tj9, u8 new_g_range) | ||
145 | { | ||
146 | switch (new_g_range) { | ||
147 | case KXTJ9_G_2G: | ||
148 | tj9->shift = 4; | ||
149 | break; | ||
150 | case KXTJ9_G_4G: | ||
151 | tj9->shift = 3; | ||
152 | break; | ||
153 | case KXTJ9_G_8G: | ||
154 | tj9->shift = 2; | ||
155 | break; | ||
156 | default: | ||
157 | return -EINVAL; | ||
158 | } | ||
159 | |||
160 | tj9->ctrl_reg1 &= 0xe7; | ||
161 | tj9->ctrl_reg1 |= new_g_range; | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static int kxtj9_update_odr(struct kxtj9_data *tj9, unsigned int poll_interval) | ||
167 | { | ||
168 | int err; | ||
169 | int i; | ||
170 | |||
171 | /* Use the lowest ODR that can support the requested poll interval */ | ||
172 | for (i = 0; i < ARRAY_SIZE(kxtj9_odr_table); i++) { | ||
173 | tj9->data_ctrl = kxtj9_odr_table[i].mask; | ||
174 | if (poll_interval < kxtj9_odr_table[i].cutoff) | ||
175 | break; | ||
176 | } | ||
177 | |||
178 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, 0); | ||
179 | if (err < 0) | ||
180 | return err; | ||
181 | |||
182 | err = i2c_smbus_write_byte_data(tj9->client, DATA_CTRL, tj9->data_ctrl); | ||
183 | if (err < 0) | ||
184 | return err; | ||
185 | |||
186 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); | ||
187 | if (err < 0) | ||
188 | return err; | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int kxtj9_device_power_on(struct kxtj9_data *tj9) | ||
194 | { | ||
195 | if (tj9->pdata.power_on) | ||
196 | return tj9->pdata.power_on(); | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static void kxtj9_device_power_off(struct kxtj9_data *tj9) | ||
202 | { | ||
203 | int err; | ||
204 | |||
205 | tj9->ctrl_reg1 &= PC1_OFF; | ||
206 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); | ||
207 | if (err < 0) | ||
208 | dev_err(&tj9->client->dev, "soft power off failed\n"); | ||
209 | |||
210 | if (tj9->pdata.power_off) | ||
211 | tj9->pdata.power_off(); | ||
212 | } | ||
213 | |||
214 | static int kxtj9_enable(struct kxtj9_data *tj9) | ||
215 | { | ||
216 | int err; | ||
217 | |||
218 | err = kxtj9_device_power_on(tj9); | ||
219 | if (err < 0) | ||
220 | return err; | ||
221 | |||
222 | /* ensure that PC1 is cleared before updating control registers */ | ||
223 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, 0); | ||
224 | if (err < 0) | ||
225 | return err; | ||
226 | |||
227 | /* only write INT_CTRL_REG1 if in irq mode */ | ||
228 | if (tj9->client->irq) { | ||
229 | err = i2c_smbus_write_byte_data(tj9->client, | ||
230 | INT_CTRL1, tj9->int_ctrl); | ||
231 | if (err < 0) | ||
232 | return err; | ||
233 | } | ||
234 | |||
235 | err = kxtj9_update_g_range(tj9, tj9->pdata.g_range); | ||
236 | if (err < 0) | ||
237 | return err; | ||
238 | |||
239 | /* turn on outputs */ | ||
240 | tj9->ctrl_reg1 |= PC1_ON; | ||
241 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); | ||
242 | if (err < 0) | ||
243 | return err; | ||
244 | |||
245 | err = kxtj9_update_odr(tj9, tj9->last_poll_interval); | ||
246 | if (err < 0) | ||
247 | return err; | ||
248 | |||
249 | /* clear initial interrupt if in irq mode */ | ||
250 | if (tj9->client->irq) { | ||
251 | err = i2c_smbus_read_byte_data(tj9->client, INT_REL); | ||
252 | if (err < 0) { | ||
253 | dev_err(&tj9->client->dev, | ||
254 | "error clearing interrupt: %d\n", err); | ||
255 | goto fail; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | return 0; | ||
260 | |||
261 | fail: | ||
262 | kxtj9_device_power_off(tj9); | ||
263 | return err; | ||
264 | } | ||
265 | |||
266 | static void kxtj9_disable(struct kxtj9_data *tj9) | ||
267 | { | ||
268 | kxtj9_device_power_off(tj9); | ||
269 | } | ||
270 | |||
271 | static int kxtj9_input_open(struct input_dev *input) | ||
272 | { | ||
273 | struct kxtj9_data *tj9 = input_get_drvdata(input); | ||
274 | |||
275 | return kxtj9_enable(tj9); | ||
276 | } | ||
277 | |||
278 | static void kxtj9_input_close(struct input_dev *dev) | ||
279 | { | ||
280 | struct kxtj9_data *tj9 = input_get_drvdata(dev); | ||
281 | |||
282 | kxtj9_disable(tj9); | ||
283 | } | ||
284 | |||
285 | static void __devinit kxtj9_init_input_device(struct kxtj9_data *tj9, | ||
286 | struct input_dev *input_dev) | ||
287 | { | ||
288 | __set_bit(EV_ABS, input_dev->evbit); | ||
289 | input_set_abs_params(input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT); | ||
290 | input_set_abs_params(input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT); | ||
291 | input_set_abs_params(input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT); | ||
292 | |||
293 | input_dev->name = "kxtj9_accel"; | ||
294 | input_dev->id.bustype = BUS_I2C; | ||
295 | input_dev->dev.parent = &tj9->client->dev; | ||
296 | } | ||
297 | |||
298 | static int __devinit kxtj9_setup_input_device(struct kxtj9_data *tj9) | ||
299 | { | ||
300 | struct input_dev *input_dev; | ||
301 | int err; | ||
302 | |||
303 | input_dev = input_allocate_device(); | ||
304 | if (!input_dev) { | ||
305 | dev_err(&tj9->client->dev, "input device allocate failed\n"); | ||
306 | return -ENOMEM; | ||
307 | } | ||
308 | |||
309 | tj9->input_dev = input_dev; | ||
310 | |||
311 | input_dev->open = kxtj9_input_open; | ||
312 | input_dev->close = kxtj9_input_close; | ||
313 | input_set_drvdata(input_dev, tj9); | ||
314 | |||
315 | kxtj9_init_input_device(tj9, input_dev); | ||
316 | |||
317 | err = input_register_device(tj9->input_dev); | ||
318 | if (err) { | ||
319 | dev_err(&tj9->client->dev, | ||
320 | "unable to register input polled device %s: %d\n", | ||
321 | tj9->input_dev->name, err); | ||
322 | input_free_device(tj9->input_dev); | ||
323 | return err; | ||
324 | } | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * When IRQ mode is selected, we need to provide an interface to allow the user | ||
331 | * to change the output data rate of the part. For consistency, we are using | ||
332 | * the set_poll method, which accepts a poll interval in milliseconds, and then | ||
333 | * calls update_odr() while passing this value as an argument. In IRQ mode, the | ||
334 | * data outputs will not be read AT the requested poll interval, rather, the | ||
335 | * lowest ODR that can support the requested interval. The client application | ||
336 | * will be responsible for retrieving data from the input node at the desired | ||
337 | * interval. | ||
338 | */ | ||
339 | |||
340 | /* Returns currently selected poll interval (in ms) */ | ||
341 | static ssize_t kxtj9_get_poll(struct device *dev, | ||
342 | struct device_attribute *attr, char *buf) | ||
343 | { | ||
344 | struct i2c_client *client = to_i2c_client(dev); | ||
345 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
346 | |||
347 | return sprintf(buf, "%d\n", tj9->last_poll_interval); | ||
348 | } | ||
349 | |||
350 | /* Allow users to select a new poll interval (in ms) */ | ||
351 | static ssize_t kxtj9_set_poll(struct device *dev, struct device_attribute *attr, | ||
352 | const char *buf, size_t count) | ||
353 | { | ||
354 | struct i2c_client *client = to_i2c_client(dev); | ||
355 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
356 | struct input_dev *input_dev = tj9->input_dev; | ||
357 | unsigned int interval; | ||
358 | int error; | ||
359 | |||
360 | error = kstrtouint(buf, 10, &interval); | ||
361 | if (error < 0) | ||
362 | return error; | ||
363 | |||
364 | /* Lock the device to prevent races with open/close (and itself) */ | ||
365 | mutex_lock(&input_dev->mutex); | ||
366 | |||
367 | disable_irq(client->irq); | ||
368 | |||
369 | /* | ||
370 | * Set current interval to the greater of the minimum interval or | ||
371 | * the requested interval | ||
372 | */ | ||
373 | tj9->last_poll_interval = max(interval, tj9->pdata.min_interval); | ||
374 | |||
375 | kxtj9_update_odr(tj9, tj9->last_poll_interval); | ||
376 | |||
377 | enable_irq(client->irq); | ||
378 | mutex_unlock(&input_dev->mutex); | ||
379 | |||
380 | return count; | ||
381 | } | ||
382 | |||
383 | static DEVICE_ATTR(poll, S_IRUGO|S_IWUSR, kxtj9_get_poll, kxtj9_set_poll); | ||
384 | |||
385 | static struct attribute *kxtj9_attributes[] = { | ||
386 | &dev_attr_poll.attr, | ||
387 | NULL | ||
388 | }; | ||
389 | |||
390 | static struct attribute_group kxtj9_attribute_group = { | ||
391 | .attrs = kxtj9_attributes | ||
392 | }; | ||
393 | |||
394 | |||
395 | #ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE | ||
396 | static void kxtj9_poll(struct input_polled_dev *dev) | ||
397 | { | ||
398 | struct kxtj9_data *tj9 = dev->private; | ||
399 | unsigned int poll_interval = dev->poll_interval; | ||
400 | |||
401 | kxtj9_report_acceleration_data(tj9); | ||
402 | |||
403 | if (poll_interval != tj9->last_poll_interval) { | ||
404 | kxtj9_update_odr(tj9, poll_interval); | ||
405 | tj9->last_poll_interval = poll_interval; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | static void kxtj9_polled_input_open(struct input_polled_dev *dev) | ||
410 | { | ||
411 | struct kxtj9_data *tj9 = dev->private; | ||
412 | |||
413 | kxtj9_enable(tj9); | ||
414 | } | ||
415 | |||
416 | static void kxtj9_polled_input_close(struct input_polled_dev *dev) | ||
417 | { | ||
418 | struct kxtj9_data *tj9 = dev->private; | ||
419 | |||
420 | kxtj9_disable(tj9); | ||
421 | } | ||
422 | |||
423 | static int __devinit kxtj9_setup_polled_device(struct kxtj9_data *tj9) | ||
424 | { | ||
425 | int err; | ||
426 | struct input_polled_dev *poll_dev; | ||
427 | poll_dev = input_allocate_polled_device(); | ||
428 | |||
429 | if (!poll_dev) { | ||
430 | dev_err(&tj9->client->dev, | ||
431 | "Failed to allocate polled device\n"); | ||
432 | return -ENOMEM; | ||
433 | } | ||
434 | |||
435 | tj9->poll_dev = poll_dev; | ||
436 | tj9->input_dev = poll_dev->input; | ||
437 | |||
438 | poll_dev->private = tj9; | ||
439 | poll_dev->poll = kxtj9_poll; | ||
440 | poll_dev->open = kxtj9_polled_input_open; | ||
441 | poll_dev->close = kxtj9_polled_input_close; | ||
442 | |||
443 | kxtj9_init_input_device(tj9, poll_dev->input); | ||
444 | |||
445 | err = input_register_polled_device(poll_dev); | ||
446 | if (err) { | ||
447 | dev_err(&tj9->client->dev, | ||
448 | "Unable to register polled device, err=%d\n", err); | ||
449 | input_free_polled_device(poll_dev); | ||
450 | return err; | ||
451 | } | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static void __devexit kxtj9_teardown_polled_device(struct kxtj9_data *tj9) | ||
457 | { | ||
458 | input_unregister_polled_device(tj9->poll_dev); | ||
459 | input_free_polled_device(tj9->poll_dev); | ||
460 | } | ||
461 | |||
462 | #else | ||
463 | |||
464 | static inline int kxtj9_setup_polled_device(struct kxtj9_data *tj9) | ||
465 | { | ||
466 | return -ENOSYS; | ||
467 | } | ||
468 | |||
469 | static inline void kxtj9_teardown_polled_device(struct kxtj9_data *tj9) | ||
470 | { | ||
471 | } | ||
472 | |||
473 | #endif | ||
474 | |||
475 | static int __devinit kxtj9_verify(struct kxtj9_data *tj9) | ||
476 | { | ||
477 | int retval; | ||
478 | |||
479 | retval = kxtj9_device_power_on(tj9); | ||
480 | if (retval < 0) | ||
481 | return retval; | ||
482 | |||
483 | retval = i2c_smbus_read_byte_data(tj9->client, WHO_AM_I); | ||
484 | if (retval < 0) { | ||
485 | dev_err(&tj9->client->dev, "read err int source\n"); | ||
486 | goto out; | ||
487 | } | ||
488 | |||
489 | retval = retval != 0x06 ? -EIO : 0; | ||
490 | |||
491 | out: | ||
492 | kxtj9_device_power_off(tj9); | ||
493 | return retval; | ||
494 | } | ||
495 | |||
496 | static int __devinit kxtj9_probe(struct i2c_client *client, | ||
497 | const struct i2c_device_id *id) | ||
498 | { | ||
499 | const struct kxtj9_platform_data *pdata = client->dev.platform_data; | ||
500 | struct kxtj9_data *tj9; | ||
501 | int err; | ||
502 | |||
503 | if (!i2c_check_functionality(client->adapter, | ||
504 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
505 | dev_err(&client->dev, "client is not i2c capable\n"); | ||
506 | return -ENXIO; | ||
507 | } | ||
508 | |||
509 | if (!pdata) { | ||
510 | dev_err(&client->dev, "platform data is NULL; exiting\n"); | ||
511 | return -EINVAL; | ||
512 | } | ||
513 | |||
514 | tj9 = kzalloc(sizeof(*tj9), GFP_KERNEL); | ||
515 | if (!tj9) { | ||
516 | dev_err(&client->dev, | ||
517 | "failed to allocate memory for module data\n"); | ||
518 | return -ENOMEM; | ||
519 | } | ||
520 | |||
521 | tj9->client = client; | ||
522 | tj9->pdata = *pdata; | ||
523 | |||
524 | if (pdata->init) { | ||
525 | err = pdata->init(); | ||
526 | if (err < 0) | ||
527 | goto err_free_mem; | ||
528 | } | ||
529 | |||
530 | err = kxtj9_verify(tj9); | ||
531 | if (err < 0) { | ||
532 | dev_err(&client->dev, "device not recognized\n"); | ||
533 | goto err_pdata_exit; | ||
534 | } | ||
535 | |||
536 | i2c_set_clientdata(client, tj9); | ||
537 | |||
538 | tj9->ctrl_reg1 = tj9->pdata.res_12bit | tj9->pdata.g_range; | ||
539 | tj9->data_ctrl = tj9->pdata.data_odr_init; | ||
540 | |||
541 | if (client->irq) { | ||
542 | /* If in irq mode, populate INT_CTRL_REG1 and enable DRDY. */ | ||
543 | tj9->int_ctrl |= KXTJ9_IEN | KXTJ9_IEA | KXTJ9_IEL; | ||
544 | tj9->ctrl_reg1 |= DRDYE; | ||
545 | |||
546 | err = kxtj9_setup_input_device(tj9); | ||
547 | if (err) | ||
548 | goto err_pdata_exit; | ||
549 | |||
550 | err = request_threaded_irq(client->irq, NULL, kxtj9_isr, | ||
551 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
552 | "kxtj9-irq", tj9); | ||
553 | if (err) { | ||
554 | dev_err(&client->dev, "request irq failed: %d\n", err); | ||
555 | goto err_destroy_input; | ||
556 | } | ||
557 | |||
558 | err = sysfs_create_group(&client->dev.kobj, &kxtj9_attribute_group); | ||
559 | if (err) { | ||
560 | dev_err(&client->dev, "sysfs create failed: %d\n", err); | ||
561 | goto err_free_irq; | ||
562 | } | ||
563 | |||
564 | } else { | ||
565 | err = kxtj9_setup_polled_device(tj9); | ||
566 | if (err) | ||
567 | goto err_pdata_exit; | ||
568 | } | ||
569 | |||
570 | return 0; | ||
571 | |||
572 | err_free_irq: | ||
573 | free_irq(client->irq, tj9); | ||
574 | err_destroy_input: | ||
575 | input_unregister_device(tj9->input_dev); | ||
576 | err_pdata_exit: | ||
577 | if (tj9->pdata.exit) | ||
578 | tj9->pdata.exit(); | ||
579 | err_free_mem: | ||
580 | kfree(tj9); | ||
581 | return err; | ||
582 | } | ||
583 | |||
584 | static int __devexit kxtj9_remove(struct i2c_client *client) | ||
585 | { | ||
586 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
587 | |||
588 | if (client->irq) { | ||
589 | sysfs_remove_group(&client->dev.kobj, &kxtj9_attribute_group); | ||
590 | free_irq(client->irq, tj9); | ||
591 | input_unregister_device(tj9->input_dev); | ||
592 | } else { | ||
593 | kxtj9_teardown_polled_device(tj9); | ||
594 | } | ||
595 | |||
596 | if (tj9->pdata.exit) | ||
597 | tj9->pdata.exit(); | ||
598 | |||
599 | kfree(tj9); | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | #ifdef CONFIG_PM_SLEEP | ||
605 | static int kxtj9_suspend(struct device *dev) | ||
606 | { | ||
607 | struct i2c_client *client = to_i2c_client(dev); | ||
608 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
609 | struct input_dev *input_dev = tj9->input_dev; | ||
610 | |||
611 | mutex_lock(&input_dev->mutex); | ||
612 | |||
613 | if (input_dev->users) | ||
614 | kxtj9_disable(tj9); | ||
615 | |||
616 | mutex_unlock(&input_dev->mutex); | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static int kxtj9_resume(struct device *dev) | ||
621 | { | ||
622 | struct i2c_client *client = to_i2c_client(dev); | ||
623 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
624 | struct input_dev *input_dev = tj9->input_dev; | ||
625 | int retval = 0; | ||
626 | |||
627 | mutex_lock(&input_dev->mutex); | ||
628 | |||
629 | if (input_dev->users) | ||
630 | kxtj9_enable(tj9); | ||
631 | |||
632 | mutex_unlock(&input_dev->mutex); | ||
633 | return retval; | ||
634 | } | ||
635 | #endif | ||
636 | |||
637 | static SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume); | ||
638 | |||
639 | static const struct i2c_device_id kxtj9_id[] = { | ||
640 | { NAME, 0 }, | ||
641 | { }, | ||
642 | }; | ||
643 | |||
644 | MODULE_DEVICE_TABLE(i2c, kxtj9_id); | ||
645 | |||
646 | static struct i2c_driver kxtj9_driver = { | ||
647 | .driver = { | ||
648 | .name = NAME, | ||
649 | .owner = THIS_MODULE, | ||
650 | .pm = &kxtj9_pm_ops, | ||
651 | }, | ||
652 | .probe = kxtj9_probe, | ||
653 | .remove = __devexit_p(kxtj9_remove), | ||
654 | .id_table = kxtj9_id, | ||
655 | }; | ||
656 | |||
657 | static int __init kxtj9_init(void) | ||
658 | { | ||
659 | return i2c_add_driver(&kxtj9_driver); | ||
660 | } | ||
661 | module_init(kxtj9_init); | ||
662 | |||
663 | static void __exit kxtj9_exit(void) | ||
664 | { | ||
665 | i2c_del_driver(&kxtj9_driver); | ||
666 | } | ||
667 | module_exit(kxtj9_exit); | ||
668 | |||
669 | MODULE_DESCRIPTION("KXTJ9 accelerometer driver"); | ||
670 | MODULE_AUTHOR("Chris Hudson <chudson@kionix.com>"); | ||
671 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c new file mode 100644 index 000000000000..20f8f9284f02 --- /dev/null +++ b/drivers/input/misc/mma8450.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /* | ||
2 | * Driver for Freescale's 3-Axis Accelerometer MMA8450 | ||
3 | * | ||
4 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
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 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/input-polldev.h> | ||
27 | |||
28 | #define MMA8450_DRV_NAME "mma8450" | ||
29 | |||
30 | #define MODE_CHANGE_DELAY_MS 100 | ||
31 | #define POLL_INTERVAL 100 | ||
32 | #define POLL_INTERVAL_MAX 500 | ||
33 | |||
34 | /* register definitions */ | ||
35 | #define MMA8450_STATUS 0x00 | ||
36 | #define MMA8450_STATUS_ZXYDR 0x08 | ||
37 | |||
38 | #define MMA8450_OUT_X8 0x01 | ||
39 | #define MMA8450_OUT_Y8 0x02 | ||
40 | #define MMA8450_OUT_Z8 0x03 | ||
41 | |||
42 | #define MMA8450_OUT_X_LSB 0x05 | ||
43 | #define MMA8450_OUT_X_MSB 0x06 | ||
44 | #define MMA8450_OUT_Y_LSB 0x07 | ||
45 | #define MMA8450_OUT_Y_MSB 0x08 | ||
46 | #define MMA8450_OUT_Z_LSB 0x09 | ||
47 | #define MMA8450_OUT_Z_MSB 0x0a | ||
48 | |||
49 | #define MMA8450_XYZ_DATA_CFG 0x16 | ||
50 | |||
51 | #define MMA8450_CTRL_REG1 0x38 | ||
52 | #define MMA8450_CTRL_REG2 0x39 | ||
53 | |||
54 | /* mma8450 status */ | ||
55 | struct mma8450 { | ||
56 | struct i2c_client *client; | ||
57 | struct input_polled_dev *idev; | ||
58 | }; | ||
59 | |||
60 | static int mma8450_read(struct mma8450 *m, unsigned off) | ||
61 | { | ||
62 | struct i2c_client *c = m->client; | ||
63 | int ret; | ||
64 | |||
65 | ret = i2c_smbus_read_byte_data(c, off); | ||
66 | if (ret < 0) | ||
67 | dev_err(&c->dev, | ||
68 | "failed to read register 0x%02x, error %d\n", | ||
69 | off, ret); | ||
70 | |||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | static int mma8450_write(struct mma8450 *m, unsigned off, u8 v) | ||
75 | { | ||
76 | struct i2c_client *c = m->client; | ||
77 | int error; | ||
78 | |||
79 | error = i2c_smbus_write_byte_data(c, off, v); | ||
80 | if (error < 0) { | ||
81 | dev_err(&c->dev, | ||
82 | "failed to write to register 0x%02x, error %d\n", | ||
83 | off, error); | ||
84 | return error; | ||
85 | } | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static int mma8450_read_xyz(struct mma8450 *m, int *x, int *y, int *z) | ||
91 | { | ||
92 | struct i2c_client *c = m->client; | ||
93 | u8 buff[6]; | ||
94 | int err; | ||
95 | |||
96 | err = i2c_smbus_read_i2c_block_data(c, MMA8450_OUT_X_LSB, 6, buff); | ||
97 | if (err < 0) { | ||
98 | dev_err(&c->dev, | ||
99 | "failed to read block data at 0x%02x, error %d\n", | ||
100 | MMA8450_OUT_X_LSB, err); | ||
101 | return err; | ||
102 | } | ||
103 | |||
104 | *x = ((buff[1] << 4) & 0xff0) | (buff[0] & 0xf); | ||
105 | *y = ((buff[3] << 4) & 0xff0) | (buff[2] & 0xf); | ||
106 | *z = ((buff[5] << 4) & 0xff0) | (buff[4] & 0xf); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static void mma8450_poll(struct input_polled_dev *dev) | ||
112 | { | ||
113 | struct mma8450 *m = dev->private; | ||
114 | int x, y, z; | ||
115 | int ret; | ||
116 | int err; | ||
117 | |||
118 | ret = mma8450_read(m, MMA8450_STATUS); | ||
119 | if (ret < 0) | ||
120 | return; | ||
121 | |||
122 | if (!(ret & MMA8450_STATUS_ZXYDR)) | ||
123 | return; | ||
124 | |||
125 | err = mma8450_read_xyz(m, &x, &y, &z); | ||
126 | if (err) | ||
127 | return; | ||
128 | |||
129 | input_report_abs(dev->input, ABS_X, x); | ||
130 | input_report_abs(dev->input, ABS_Y, y); | ||
131 | input_report_abs(dev->input, ABS_Z, z); | ||
132 | input_sync(dev->input); | ||
133 | } | ||
134 | |||
135 | /* Initialize the MMA8450 chip */ | ||
136 | static void mma8450_open(struct input_polled_dev *dev) | ||
137 | { | ||
138 | struct mma8450 *m = dev->private; | ||
139 | int err; | ||
140 | |||
141 | /* enable all events from X/Y/Z, no FIFO */ | ||
142 | err = mma8450_write(m, MMA8450_XYZ_DATA_CFG, 0x07); | ||
143 | if (err) | ||
144 | return; | ||
145 | |||
146 | /* | ||
147 | * Sleep mode poll rate - 50Hz | ||
148 | * System output data rate - 400Hz | ||
149 | * Full scale selection - Active, +/- 2G | ||
150 | */ | ||
151 | err = mma8450_write(m, MMA8450_CTRL_REG1, 0x01); | ||
152 | if (err < 0) | ||
153 | return; | ||
154 | |||
155 | msleep(MODE_CHANGE_DELAY_MS); | ||
156 | } | ||
157 | |||
158 | static void mma8450_close(struct input_polled_dev *dev) | ||
159 | { | ||
160 | struct mma8450 *m = dev->private; | ||
161 | |||
162 | mma8450_write(m, MMA8450_CTRL_REG1, 0x00); | ||
163 | mma8450_write(m, MMA8450_CTRL_REG2, 0x01); | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * I2C init/probing/exit functions | ||
168 | */ | ||
169 | static int __devinit mma8450_probe(struct i2c_client *c, | ||
170 | const struct i2c_device_id *id) | ||
171 | { | ||
172 | struct input_polled_dev *idev; | ||
173 | struct mma8450 *m; | ||
174 | int err; | ||
175 | |||
176 | m = kzalloc(sizeof(struct mma8450), GFP_KERNEL); | ||
177 | idev = input_allocate_polled_device(); | ||
178 | if (!m || !idev) { | ||
179 | err = -ENOMEM; | ||
180 | goto err_free_mem; | ||
181 | } | ||
182 | |||
183 | m->client = c; | ||
184 | m->idev = idev; | ||
185 | |||
186 | idev->private = m; | ||
187 | idev->input->name = MMA8450_DRV_NAME; | ||
188 | idev->input->id.bustype = BUS_I2C; | ||
189 | idev->poll = mma8450_poll; | ||
190 | idev->poll_interval = POLL_INTERVAL; | ||
191 | idev->poll_interval_max = POLL_INTERVAL_MAX; | ||
192 | idev->open = mma8450_open; | ||
193 | idev->close = mma8450_close; | ||
194 | |||
195 | __set_bit(EV_ABS, idev->input->evbit); | ||
196 | input_set_abs_params(idev->input, ABS_X, -2048, 2047, 32, 32); | ||
197 | input_set_abs_params(idev->input, ABS_Y, -2048, 2047, 32, 32); | ||
198 | input_set_abs_params(idev->input, ABS_Z, -2048, 2047, 32, 32); | ||
199 | |||
200 | err = input_register_polled_device(idev); | ||
201 | if (err) { | ||
202 | dev_err(&c->dev, "failed to register polled input device\n"); | ||
203 | goto err_free_mem; | ||
204 | } | ||
205 | |||
206 | return 0; | ||
207 | |||
208 | err_free_mem: | ||
209 | input_free_polled_device(idev); | ||
210 | kfree(m); | ||
211 | return err; | ||
212 | } | ||
213 | |||
214 | static int __devexit mma8450_remove(struct i2c_client *c) | ||
215 | { | ||
216 | struct mma8450 *m = i2c_get_clientdata(c); | ||
217 | struct input_polled_dev *idev = m->idev; | ||
218 | |||
219 | input_unregister_polled_device(idev); | ||
220 | input_free_polled_device(idev); | ||
221 | kfree(m); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static const struct i2c_device_id mma8450_id[] = { | ||
227 | { MMA8450_DRV_NAME, 0 }, | ||
228 | { }, | ||
229 | }; | ||
230 | MODULE_DEVICE_TABLE(i2c, mma8450_id); | ||
231 | |||
232 | static struct i2c_driver mma8450_driver = { | ||
233 | .driver = { | ||
234 | .name = MMA8450_DRV_NAME, | ||
235 | .owner = THIS_MODULE, | ||
236 | }, | ||
237 | .probe = mma8450_probe, | ||
238 | .remove = __devexit_p(mma8450_remove), | ||
239 | .id_table = mma8450_id, | ||
240 | }; | ||
241 | |||
242 | static int __init mma8450_init(void) | ||
243 | { | ||
244 | return i2c_add_driver(&mma8450_driver); | ||
245 | } | ||
246 | module_init(mma8450_init); | ||
247 | |||
248 | static void __exit mma8450_exit(void) | ||
249 | { | ||
250 | i2c_del_driver(&mma8450_driver); | ||
251 | } | ||
252 | module_exit(mma8450_exit); | ||
253 | |||
254 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
255 | MODULE_DESCRIPTION("MMA8450 3-Axis Accelerometer Driver"); | ||
256 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c new file mode 100644 index 000000000000..b95fac15b2ea --- /dev/null +++ b/drivers/input/misc/mpu3050.c | |||
@@ -0,0 +1,376 @@ | |||
1 | /* | ||
2 | * MPU3050 Tri-axis gyroscope driver | ||
3 | * | ||
4 | * Copyright (C) 2011 Wistron Co.Ltd | ||
5 | * Joseph Lai <joseph_lai@wistron.com> | ||
6 | * | ||
7 | * Trimmed down by Alan Cox <alan@linux.intel.com> to produce this version | ||
8 | * | ||
9 | * This is a 'lite' version of the driver, while we consider the right way | ||
10 | * to present the other features to user space. In particular it requires the | ||
11 | * device has an IRQ, and it only provides an input interface, so is not much | ||
12 | * use for device orientation. A fuller version is available from the Meego | ||
13 | * tree. | ||
14 | * | ||
15 | * This program is based on bma023.c. | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify | ||
18 | * it under the terms of the GNU General Public License as published by | ||
19 | * the Free Software Foundation; version 2 of the License. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, but | ||
22 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
24 | * General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License along | ||
27 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
28 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <linux/module.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/interrupt.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/mutex.h> | ||
37 | #include <linux/err.h> | ||
38 | #include <linux/i2c.h> | ||
39 | #include <linux/input.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/slab.h> | ||
42 | #include <linux/pm_runtime.h> | ||
43 | |||
44 | #define MPU3050_CHIP_ID_REG 0x00 | ||
45 | #define MPU3050_CHIP_ID 0x69 | ||
46 | #define MPU3050_XOUT_H 0x1D | ||
47 | #define MPU3050_PWR_MGM 0x3E | ||
48 | #define MPU3050_PWR_MGM_POS 6 | ||
49 | #define MPU3050_PWR_MGM_MASK 0x40 | ||
50 | |||
51 | #define MPU3050_AUTO_DELAY 1000 | ||
52 | |||
53 | #define MPU3050_MIN_VALUE -32768 | ||
54 | #define MPU3050_MAX_VALUE 32767 | ||
55 | |||
56 | struct axis_data { | ||
57 | s16 x; | ||
58 | s16 y; | ||
59 | s16 z; | ||
60 | }; | ||
61 | |||
62 | struct mpu3050_sensor { | ||
63 | struct i2c_client *client; | ||
64 | struct device *dev; | ||
65 | struct input_dev *idev; | ||
66 | }; | ||
67 | |||
68 | /** | ||
69 | * mpu3050_xyz_read_reg - read the axes values | ||
70 | * @buffer: provide register addr and get register | ||
71 | * @length: length of register | ||
72 | * | ||
73 | * Reads the register values in one transaction or returns a negative | ||
74 | * error code on failure. | ||
75 | */ | ||
76 | static int mpu3050_xyz_read_reg(struct i2c_client *client, | ||
77 | u8 *buffer, int length) | ||
78 | { | ||
79 | /* | ||
80 | * Annoying we can't make this const because the i2c layer doesn't | ||
81 | * declare input buffers const. | ||
82 | */ | ||
83 | char cmd = MPU3050_XOUT_H; | ||
84 | struct i2c_msg msg[] = { | ||
85 | { | ||
86 | .addr = client->addr, | ||
87 | .flags = 0, | ||
88 | .len = 1, | ||
89 | .buf = &cmd, | ||
90 | }, | ||
91 | { | ||
92 | .addr = client->addr, | ||
93 | .flags = I2C_M_RD, | ||
94 | .len = length, | ||
95 | .buf = buffer, | ||
96 | }, | ||
97 | }; | ||
98 | |||
99 | return i2c_transfer(client->adapter, msg, 2); | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * mpu3050_read_xyz - get co-ordinates from device | ||
104 | * @client: i2c address of sensor | ||
105 | * @coords: co-ordinates to update | ||
106 | * | ||
107 | * Return the converted X Y and Z co-ordinates from the sensor device | ||
108 | */ | ||
109 | static void mpu3050_read_xyz(struct i2c_client *client, | ||
110 | struct axis_data *coords) | ||
111 | { | ||
112 | u16 buffer[3]; | ||
113 | |||
114 | mpu3050_xyz_read_reg(client, (u8 *)buffer, 6); | ||
115 | coords->x = be16_to_cpu(buffer[0]); | ||
116 | coords->y = be16_to_cpu(buffer[1]); | ||
117 | coords->z = be16_to_cpu(buffer[2]); | ||
118 | dev_dbg(&client->dev, "%s: x %d, y %d, z %d\n", __func__, | ||
119 | coords->x, coords->y, coords->z); | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * mpu3050_set_power_mode - set the power mode | ||
124 | * @client: i2c client for the sensor | ||
125 | * @val: value to switch on/off of power, 1: normal power, 0: low power | ||
126 | * | ||
127 | * Put device to normal-power mode or low-power mode. | ||
128 | */ | ||
129 | static void mpu3050_set_power_mode(struct i2c_client *client, u8 val) | ||
130 | { | ||
131 | u8 value; | ||
132 | |||
133 | value = i2c_smbus_read_byte_data(client, MPU3050_PWR_MGM); | ||
134 | value = (value & ~MPU3050_PWR_MGM_MASK) | | ||
135 | (((val << MPU3050_PWR_MGM_POS) & MPU3050_PWR_MGM_MASK) ^ | ||
136 | MPU3050_PWR_MGM_MASK); | ||
137 | i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM, value); | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * mpu3050_input_open - called on input event open | ||
142 | * @input: input dev of opened device | ||
143 | * | ||
144 | * The input layer calls this function when input event is opened. The | ||
145 | * function will push the device to resume. Then, the device is ready | ||
146 | * to provide data. | ||
147 | */ | ||
148 | static int mpu3050_input_open(struct input_dev *input) | ||
149 | { | ||
150 | struct mpu3050_sensor *sensor = input_get_drvdata(input); | ||
151 | |||
152 | pm_runtime_get(sensor->dev); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | /** | ||
158 | * mpu3050_input_close - called on input event close | ||
159 | * @input: input dev of closed device | ||
160 | * | ||
161 | * The input layer calls this function when input event is closed. The | ||
162 | * function will push the device to suspend. | ||
163 | */ | ||
164 | static void mpu3050_input_close(struct input_dev *input) | ||
165 | { | ||
166 | struct mpu3050_sensor *sensor = input_get_drvdata(input); | ||
167 | |||
168 | pm_runtime_put(sensor->dev); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * mpu3050_interrupt_thread - handle an IRQ | ||
173 | * @irq: interrupt numner | ||
174 | * @data: the sensor | ||
175 | * | ||
176 | * Called by the kernel single threaded after an interrupt occurs. Read | ||
177 | * the sensor data and generate an input event for it. | ||
178 | */ | ||
179 | static irqreturn_t mpu3050_interrupt_thread(int irq, void *data) | ||
180 | { | ||
181 | struct mpu3050_sensor *sensor = data; | ||
182 | struct axis_data axis; | ||
183 | |||
184 | mpu3050_read_xyz(sensor->client, &axis); | ||
185 | |||
186 | input_report_abs(sensor->idev, ABS_X, axis.x); | ||
187 | input_report_abs(sensor->idev, ABS_Y, axis.y); | ||
188 | input_report_abs(sensor->idev, ABS_Z, axis.z); | ||
189 | input_sync(sensor->idev); | ||
190 | |||
191 | return IRQ_HANDLED; | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * mpu3050_probe - device detection callback | ||
196 | * @client: i2c client of found device | ||
197 | * @id: id match information | ||
198 | * | ||
199 | * The I2C layer calls us when it believes a sensor is present at this | ||
200 | * address. Probe to see if this is correct and to validate the device. | ||
201 | * | ||
202 | * If present install the relevant sysfs interfaces and input device. | ||
203 | */ | ||
204 | static int __devinit mpu3050_probe(struct i2c_client *client, | ||
205 | const struct i2c_device_id *id) | ||
206 | { | ||
207 | struct mpu3050_sensor *sensor; | ||
208 | struct input_dev *idev; | ||
209 | int ret; | ||
210 | int error; | ||
211 | |||
212 | sensor = kzalloc(sizeof(struct mpu3050_sensor), GFP_KERNEL); | ||
213 | idev = input_allocate_device(); | ||
214 | if (!sensor || !idev) { | ||
215 | dev_err(&client->dev, "failed to allocate driver data\n"); | ||
216 | error = -ENOMEM; | ||
217 | goto err_free_mem; | ||
218 | } | ||
219 | |||
220 | sensor->client = client; | ||
221 | sensor->dev = &client->dev; | ||
222 | sensor->idev = idev; | ||
223 | |||
224 | mpu3050_set_power_mode(client, 1); | ||
225 | msleep(10); | ||
226 | |||
227 | ret = i2c_smbus_read_byte_data(client, MPU3050_CHIP_ID_REG); | ||
228 | if (ret < 0) { | ||
229 | dev_err(&client->dev, "failed to detect device\n"); | ||
230 | error = -ENXIO; | ||
231 | goto err_free_mem; | ||
232 | } | ||
233 | |||
234 | if (ret != MPU3050_CHIP_ID) { | ||
235 | dev_err(&client->dev, "unsupported chip id\n"); | ||
236 | error = -ENXIO; | ||
237 | goto err_free_mem; | ||
238 | } | ||
239 | |||
240 | idev->name = "MPU3050"; | ||
241 | idev->id.bustype = BUS_I2C; | ||
242 | idev->dev.parent = &client->dev; | ||
243 | |||
244 | idev->open = mpu3050_input_open; | ||
245 | idev->close = mpu3050_input_close; | ||
246 | |||
247 | __set_bit(EV_ABS, idev->evbit); | ||
248 | input_set_abs_params(idev, ABS_X, | ||
249 | MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0); | ||
250 | input_set_abs_params(idev, ABS_Y, | ||
251 | MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0); | ||
252 | input_set_abs_params(idev, ABS_Z, | ||
253 | MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0); | ||
254 | |||
255 | input_set_drvdata(idev, sensor); | ||
256 | |||
257 | pm_runtime_set_active(&client->dev); | ||
258 | |||
259 | error = request_threaded_irq(client->irq, | ||
260 | NULL, mpu3050_interrupt_thread, | ||
261 | IRQF_TRIGGER_RISING, | ||
262 | "mpu_int", sensor); | ||
263 | if (error) { | ||
264 | dev_err(&client->dev, | ||
265 | "can't get IRQ %d, error %d\n", client->irq, error); | ||
266 | goto err_pm_set_suspended; | ||
267 | } | ||
268 | |||
269 | error = input_register_device(idev); | ||
270 | if (error) { | ||
271 | dev_err(&client->dev, "failed to register input device\n"); | ||
272 | goto err_free_irq; | ||
273 | } | ||
274 | |||
275 | pm_runtime_enable(&client->dev); | ||
276 | pm_runtime_set_autosuspend_delay(&client->dev, MPU3050_AUTO_DELAY); | ||
277 | |||
278 | return 0; | ||
279 | |||
280 | err_free_irq: | ||
281 | free_irq(client->irq, sensor); | ||
282 | err_pm_set_suspended: | ||
283 | pm_runtime_set_suspended(&client->dev); | ||
284 | err_free_mem: | ||
285 | input_unregister_device(idev); | ||
286 | kfree(sensor); | ||
287 | return error; | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * mpu3050_remove - remove a sensor | ||
292 | * @client: i2c client of sensor being removed | ||
293 | * | ||
294 | * Our sensor is going away, clean up the resources. | ||
295 | */ | ||
296 | static int __devexit mpu3050_remove(struct i2c_client *client) | ||
297 | { | ||
298 | struct mpu3050_sensor *sensor = i2c_get_clientdata(client); | ||
299 | |||
300 | pm_runtime_disable(&client->dev); | ||
301 | pm_runtime_set_suspended(&client->dev); | ||
302 | |||
303 | free_irq(client->irq, sensor); | ||
304 | input_unregister_device(sensor->idev); | ||
305 | kfree(sensor); | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | #ifdef CONFIG_PM | ||
311 | /** | ||
312 | * mpu3050_suspend - called on device suspend | ||
313 | * @dev: device being suspended | ||
314 | * | ||
315 | * Put the device into sleep mode before we suspend the machine. | ||
316 | */ | ||
317 | static int mpu3050_suspend(struct device *dev) | ||
318 | { | ||
319 | struct i2c_client *client = to_i2c_client(dev); | ||
320 | |||
321 | mpu3050_set_power_mode(client, 0); | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | /** | ||
327 | * mpu3050_resume - called on device resume | ||
328 | * @dev: device being resumed | ||
329 | * | ||
330 | * Put the device into powered mode on resume. | ||
331 | */ | ||
332 | static int mpu3050_resume(struct device *dev) | ||
333 | { | ||
334 | struct i2c_client *client = to_i2c_client(dev); | ||
335 | |||
336 | mpu3050_set_power_mode(client, 1); | ||
337 | msleep(100); /* wait for gyro chip resume */ | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | #endif | ||
342 | |||
343 | static UNIVERSAL_DEV_PM_OPS(mpu3050_pm, mpu3050_suspend, mpu3050_resume, NULL); | ||
344 | |||
345 | static const struct i2c_device_id mpu3050_ids[] = { | ||
346 | { "mpu3050", 0 }, | ||
347 | { } | ||
348 | }; | ||
349 | MODULE_DEVICE_TABLE(i2c, mpu3050_ids); | ||
350 | |||
351 | static struct i2c_driver mpu3050_i2c_driver = { | ||
352 | .driver = { | ||
353 | .name = "mpu3050", | ||
354 | .owner = THIS_MODULE, | ||
355 | .pm = &mpu3050_pm, | ||
356 | }, | ||
357 | .probe = mpu3050_probe, | ||
358 | .remove = __devexit_p(mpu3050_remove), | ||
359 | .id_table = mpu3050_ids, | ||
360 | }; | ||
361 | |||
362 | static int __init mpu3050_init(void) | ||
363 | { | ||
364 | return i2c_add_driver(&mpu3050_i2c_driver); | ||
365 | } | ||
366 | module_init(mpu3050_init); | ||
367 | |||
368 | static void __exit mpu3050_exit(void) | ||
369 | { | ||
370 | i2c_del_driver(&mpu3050_i2c_driver); | ||
371 | } | ||
372 | module_exit(mpu3050_exit); | ||
373 | |||
374 | MODULE_AUTHOR("Wistron Corp."); | ||
375 | MODULE_DESCRIPTION("MPU3050 Tri-axis gyroscope driver"); | ||
376 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index 62bae99424e6..ad2e51c04db8 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c | |||
@@ -373,7 +373,7 @@ static struct xenbus_driver xenkbd_driver = { | |||
373 | 373 | ||
374 | static int __init xenkbd_init(void) | 374 | static int __init xenkbd_init(void) |
375 | { | 375 | { |
376 | if (!xen_pv_domain()) | 376 | if (!xen_domain()) |
377 | return -ENODEV; | 377 | return -ENODEV; |
378 | 378 | ||
379 | /* Nothing to do if running in dom0. */ | 379 | /* Nothing to do if running in dom0. */ |