aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>2011-12-24 03:09:04 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-12-24 04:06:19 -0500
commitcd314fa6375b4de092a5b1de6aa194117523ecbb (patch)
tree2a9c58830e31ffd686870d52d7d10aad0fbe7867 /drivers/input
parent3b5187248bd07e400af081ad777e9aa1e5519ad7 (diff)
Input: mpu3050 - configure the sampling method
This will improve the output of the sensor. Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/misc/mpu3050.c108
1 files changed, 103 insertions, 5 deletions
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
index ebec0baa1e3..208d1a1cc7f 100644
--- a/drivers/input/misc/mpu3050.c
+++ b/drivers/input/misc/mpu3050.c
@@ -41,18 +41,67 @@
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/pm_runtime.h> 42#include <linux/pm_runtime.h>
43 43
44#define MPU3050_CHIP_ID_REG 0x00
45#define MPU3050_CHIP_ID 0x69 44#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 45
51#define MPU3050_AUTO_DELAY 1000 46#define MPU3050_AUTO_DELAY 1000
52 47
53#define MPU3050_MIN_VALUE -32768 48#define MPU3050_MIN_VALUE -32768
54#define MPU3050_MAX_VALUE 32767 49#define MPU3050_MAX_VALUE 32767
55 50
51#define MPU3050_DEFAULT_POLL_INTERVAL 200
52#define MPU3050_DEFAULT_FS_RANGE 3
53
54/* Register map */
55#define MPU3050_CHIP_ID_REG 0x00
56#define MPU3050_SMPLRT_DIV 0x15
57#define MPU3050_DLPF_FS_SYNC 0x16
58#define MPU3050_INT_CFG 0x17
59#define MPU3050_XOUT_H 0x1D
60#define MPU3050_PWR_MGM 0x3E
61#define MPU3050_PWR_MGM_POS 6
62
63/* Register bits */
64
65/* DLPF_FS_SYNC */
66#define MPU3050_EXT_SYNC_NONE 0x00
67#define MPU3050_EXT_SYNC_TEMP 0x20
68#define MPU3050_EXT_SYNC_GYROX 0x40
69#define MPU3050_EXT_SYNC_GYROY 0x60
70#define MPU3050_EXT_SYNC_GYROZ 0x80
71#define MPU3050_EXT_SYNC_ACCELX 0xA0
72#define MPU3050_EXT_SYNC_ACCELY 0xC0
73#define MPU3050_EXT_SYNC_ACCELZ 0xE0
74#define MPU3050_EXT_SYNC_MASK 0xE0
75#define MPU3050_FS_250DPS 0x00
76#define MPU3050_FS_500DPS 0x08
77#define MPU3050_FS_1000DPS 0x10
78#define MPU3050_FS_2000DPS 0x18
79#define MPU3050_FS_MASK 0x18
80#define MPU3050_DLPF_CFG_256HZ_NOLPF2 0x00
81#define MPU3050_DLPF_CFG_188HZ 0x01
82#define MPU3050_DLPF_CFG_98HZ 0x02
83#define MPU3050_DLPF_CFG_42HZ 0x03
84#define MPU3050_DLPF_CFG_20HZ 0x04
85#define MPU3050_DLPF_CFG_10HZ 0x05
86#define MPU3050_DLPF_CFG_5HZ 0x06
87#define MPU3050_DLPF_CFG_2100HZ_NOLPF 0x07
88#define MPU3050_DLPF_CFG_MASK 0x07
89/* INT_CFG */
90#define MPU3050_RAW_RDY_EN 0x01
91#define MPU3050_MPU_RDY_EN 0x02
92#define MPU3050_LATCH_INT_EN 0x04
93/* PWR_MGM */
94#define MPU3050_PWR_MGM_PLL_X 0x01
95#define MPU3050_PWR_MGM_PLL_Y 0x02
96#define MPU3050_PWR_MGM_PLL_Z 0x03
97#define MPU3050_PWR_MGM_CLKSEL 0x07
98#define MPU3050_PWR_MGM_STBY_ZG 0x08
99#define MPU3050_PWR_MGM_STBY_YG 0x10
100#define MPU3050_PWR_MGM_STBY_XG 0x20
101#define MPU3050_PWR_MGM_SLEEP 0x40
102#define MPU3050_PWR_MGM_RESET 0x80
103#define MPU3050_PWR_MGM_MASK 0x40
104
56struct axis_data { 105struct axis_data {
57 s16 x; 106 s16 x;
58 s16 y; 107 s16 y;
@@ -203,6 +252,51 @@ static irqreturn_t mpu3050_interrupt_thread(int irq, void *data)
203} 252}
204 253
205/** 254/**
255 * mpu3050_hw_init - initialize hardware
256 * @sensor: the sensor
257 *
258 * Called during device probe; configures the sampling method.
259 */
260static int __devinit mpu3050_hw_init(struct mpu3050_sensor *sensor)
261{
262 struct i2c_client *client = sensor->client;
263 int ret;
264 u8 reg;
265
266 /* Reset */
267 ret = i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM,
268 MPU3050_PWR_MGM_RESET);
269 if (ret < 0)
270 return ret;
271
272 ret = i2c_smbus_read_byte_data(client, MPU3050_PWR_MGM);
273 if (ret < 0)
274 return ret;
275
276 ret &= ~MPU3050_PWR_MGM_CLKSEL;
277 ret |= MPU3050_PWR_MGM_PLL_Z;
278 ret = i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM, ret);
279 if (ret < 0)
280 return ret;
281
282 /* Output frequency divider. The poll interval */
283 ret = i2c_smbus_write_byte_data(client, MPU3050_SMPLRT_DIV,
284 MPU3050_DEFAULT_POLL_INTERVAL - 1);
285 if (ret < 0)
286 return ret;
287
288 /* Set low pass filter and full scale */
289 reg = MPU3050_DEFAULT_FS_RANGE;
290 reg |= MPU3050_DLPF_CFG_42HZ << 3;
291 reg |= MPU3050_EXT_SYNC_NONE << 5;
292 ret = i2c_smbus_write_byte_data(client, MPU3050_DLPF_FS_SYNC, reg);
293 if (ret < 0)
294 return ret;
295
296 return 0;
297}
298
299/**
206 * mpu3050_probe - device detection callback 300 * mpu3050_probe - device detection callback
207 * @client: i2c client of found device 301 * @client: i2c client of found device
208 * @id: id match information 302 * @id: id match information
@@ -267,6 +361,10 @@ static int __devinit mpu3050_probe(struct i2c_client *client,
267 361
268 pm_runtime_set_active(&client->dev); 362 pm_runtime_set_active(&client->dev);
269 363
364 error = mpu3050_hw_init(sensor);
365 if (error)
366 goto err_pm_set_suspended;
367
270 error = request_threaded_irq(client->irq, 368 error = request_threaded_irq(client->irq,
271 NULL, mpu3050_interrupt_thread, 369 NULL, mpu3050_interrupt_thread,
272 IRQF_TRIGGER_RISING, 370 IRQF_TRIGGER_RISING,