History

Input: add CMA3000 accelerometer driver

Add support for CMA3000 Tri-axis accelerometer, which supports Motion detect, Measurement and Free fall modes. CMA3000 supports both I2C/SPI bus for communication, currently the driver supports I2C based communication.

Hemanth V committed 15 years ago

Commit b029ffa1 parent 33e808c7 files · +781 −0Browse files

Unified · Split

7 files
  1. Documentation/input/cma3000_d0x.txt +115 −0
  2. drivers/input/misc/Kconfig +24 −0
  3. drivers/input/misc/Makefile +2 −0
  4. drivers/input/misc/cma3000_d0x.c +398 −0
  5. drivers/input/misc/cma3000_d0x.h +42 −0
  6. drivers/input/misc/cma3000_d0x_i2c.c +141 −0
  7. include/linux/input/cma3000.h +59 −0
Documentation/input/cma3000_d0x.txt+115−0
@@ -0,0 +1,115 @@
1+Kernel driver for CMA3000-D0x
2+============================
3+
4+Supported chips:
5+* VTI CMA3000-D0x
6+Datasheet:
7+ CMA3000-D0X Product Family Specification 8281000A.02.pdf
8+ <http://www.vti.fi/en/>
9+
10+Author: Hemanth V <hemanthv@ti.com>
11+
12+
13+Description
14+-----------
15+CMA3000 Tri-axis accelerometer supports Motion detect, Measurement and
16+Free fall modes.
17+
18+Motion Detect Mode: Its the low power mode where interrupts are generated only
19+when motion exceeds the defined thresholds.
20+
21+Measurement Mode: This mode is used to read the acceleration data on X,Y,Z
22+axis and supports 400, 100, 40 Hz sample frequency.
23+
24+Free fall Mode: This mode is intended to save system resources.
25+
26+Threshold values: Chip supports defining threshold values for above modes
27+which includes time and g value. Refer product specifications for more details.
28+
29+CMA3000 chip supports mutually exclusive I2C and SPI interfaces for
30+communication, currently the driver supports I2C based communication only.
31+Initial configuration for bus mode is set in non volatile memory and can later
32+be modified through bus interface command.
33+
34+Driver reports acceleration data through input subsystem. It generates ABS_MISC
35+event with value 1 when free fall is detected.
36+
37+Platform data need to be configured for initial default values.
38+
39+Platform Data
40+-------------
41+fuzz_x: Noise on X Axis
42+
43+fuzz_y: Noise on Y Axis
44+
45+fuzz_z: Noise on Z Axis
46+
47+g_range: G range in milli g i.e 2000 or 8000
48+
49+mode: Default Operating mode
50+
51+mdthr: Motion detect g range threshold value
52+
53+mdfftmr: Motion detect and free fall time threshold value
54+
55+ffthr: Free fall g range threshold value
56+
57+Input Interface
58+--------------
59+Input driver version is 1.0.0
60+Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0
61+Input device name: "cma3000-accelerometer"
62+Supported events:
63+ Event type 0 (Sync)
64+ Event type 3 (Absolute)
65+ Event code 0 (X)
66+ Value 47
67+ Min -8000
68+ Max 8000
69+ Fuzz 200
70+ Event code 1 (Y)
71+ Value -28
72+ Min -8000
73+ Max 8000
74+ Fuzz 200
75+ Event code 2 (Z)
76+ Value 905
77+ Min -8000
78+ Max 8000
79+ Fuzz 200
80+ Event code 40 (Misc)
81+ Value 0
82+ Min 0
83+ Max 1
84+ Event type 4 (Misc)
85+
86+
87+Register/Platform parameters Description
88+----------------------------------------
89+
90+mode:
91+ 0: power down mode
92+ 1: 100 Hz Measurement mode
93+ 2: 400 Hz Measurement mode
94+ 3: 40 Hz Measurement mode
95+ 4: Motion Detect mode (default)
96+ 5: 100 Hz Free fall mode
97+ 6: 40 Hz Free fall mode
98+ 7: Power off mode
99+
100+grange:
101+ 2000: 2000 mg or 2G Range
102+ 8000: 8000 mg or 8G Range
103+
104+mdthr:
105+ X: X * 71mg (8G Range)
106+ X: X * 18mg (2G Range)
107+
108+mdfftmr:
109+ X: (X & 0x70) * 100 ms (MDTMR)
110+ (X & 0x0F) * 2.5 ms (FFTMR 400 Hz)
111+ (X & 0x0F) * 10 ms (FFTMR 100 Hz)
112+
113+ffthr:
114+ X: (X >> 2) * 18mg (2G Range)
115+ X: (X & 0x0F) * 71 mg (8G Range)
drivers/input/misc/Kconfig+24−0
@@ -448,4 +448,28 @@ config INPUT_ADXL34X_SPI · 447 unmodified lines
448448 To compile this driver as a module, choose M here: the
449449 module will be called adxl34x-spi.
450450
451+config INPUT_CMA3000
452+ tristate "VTI CMA3000 Tri-axis accelerometer"
453+ help
454+ Say Y here if you want to use VTI CMA3000_D0x Accelerometer
455+ driver
456+
457+ This driver currently only supports I2C interface to the
458+ controller. Also select the I2C method.
459+
460+ If unsure, say N
461+
462+ To compile this driver as a module, choose M here: the
463+ module will be called cma3000_d0x.
464+
465+config INPUT_CMA3000_I2C
466+ tristate "Support I2C bus connection"
467+ depends on INPUT_CMA3000 && I2C
468+ help
469+ Say Y here if you want to use VTI CMA3000_D0x Accelerometer
470+ through I2C interface.
471+
472+ To compile this driver as a module, choose M here: the
473+ module will be called cma3000_d0x_i2c.
474+
451475 endif
drivers/input/misc/Makefile+2−0
@@ -18,6 +18,8 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o · 17 unmodified lines
1818 obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
1919 obj-$(CONFIG_INPUT_BFIN_ROTARY) += bfin_rotary.o
2020 obj-$(CONFIG_INPUT_CM109) += cm109.o
21+obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o
22+obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o
2123 obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
2224 obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o
2325 obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
drivers/input/misc/cma3000_d0x.c+398−0
@@ -0,0 +1,398 @@
1+/*
2+ * VTI CMA3000_D0x Accelerometer driver
3+ *
4+ * Copyright (C) 2010 Texas Instruments
5+ * Author: Hemanth V <hemanthv@ti.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify it
8+ * under the terms of the GNU General Public License version 2 as published by
9+ * the Free Software Foundation.
10+ *
11+ * This program is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14+ * more details.
15+ *
16+ * You should have received a copy of the GNU General Public License along with
17+ * this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include <linux/types.h>
21+#include <linux/interrupt.h>
22+#include <linux/delay.h>
23+#include <linux/slab.h>
24+#include <linux/input.h>
25+#include <linux/input/cma3000.h>
26+
27+#include "cma3000_d0x.h"
28+
29+#define CMA3000_WHOAMI 0x00
30+#define CMA3000_REVID 0x01
31+#define CMA3000_CTRL 0x02
32+#define CMA3000_STATUS 0x03
33+#define CMA3000_RSTR 0x04
34+#define CMA3000_INTSTATUS 0x05
35+#define CMA3000_DOUTX 0x06
36+#define CMA3000_DOUTY 0x07
37+#define CMA3000_DOUTZ 0x08
38+#define CMA3000_MDTHR 0x09
39+#define CMA3000_MDFFTMR 0x0A
40+#define CMA3000_FFTHR 0x0B
41+
42+#define CMA3000_RANGE2G (1 << 7)
43+#define CMA3000_RANGE8G (0 << 7)
44+#define CMA3000_BUSI2C (0 << 4)
45+#define CMA3000_MODEMASK (7 << 1)
46+#define CMA3000_GRANGEMASK (1 << 7)
47+
48+#define CMA3000_STATUS_PERR 1
49+#define CMA3000_INTSTATUS_FFDET (1 << 2)
50+
51+/* Settling time delay in ms */
52+#define CMA3000_SETDELAY 30
53+
54+/* Delay for clearing interrupt in us */
55+#define CMA3000_INTDELAY 44
56+
57+
58+/*
59+ * Bit weights in mg for bit 0, other bits need
60+ * multipy factor 2^n. Eight bit is the sign bit.
61+ */
62+#define BIT_TO_2G 18
63+#define BIT_TO_8G 71
64+
65+struct cma3000_accl_data {
66+ const struct cma3000_bus_ops *bus_ops;
67+ const struct cma3000_platform_data *pdata;
68+
69+ struct device *dev;
70+ struct input_dev *input_dev;
71+
72+ int bit_to_mg;
73+ int irq;
74+
75+ int g_range;
76+ u8 mode;
77+
78+ struct mutex mutex;
79+ bool opened;
80+ bool suspended;
81+};
82+
83+#define CMA3000_READ(data, reg, msg) \
84+ (data->bus_ops->read(data->dev, reg, msg))
85+#define CMA3000_SET(data, reg, val, msg) \
86+ ((data)->bus_ops->write(data->dev, reg, val, msg))
87+
88+/*
89+ * Conversion for each of the eight modes to g, depending
90+ * on G range i.e 2G or 8G. Some modes always operate in
91+ * 8G.
92+ */
93+
94+static int mode_to_mg[8][2] = {
95+ { 0, 0 },
96+ { BIT_TO_8G, BIT_TO_2G },
97+ { BIT_TO_8G, BIT_TO_2G },
98+ { BIT_TO_8G, BIT_TO_8G },
99+ { BIT_TO_8G, BIT_TO_8G },
100+ { BIT_TO_8G, BIT_TO_2G },
101+ { BIT_TO_8G, BIT_TO_2G },
102+ { 0, 0},
103+};
104+
105+static void decode_mg(struct cma3000_accl_data *data, int *datax,
106+ int *datay, int *dataz)
107+{
108+ /* Data in 2's complement, convert to mg */
109+ *datax = ((s8)*datax) * data->bit_to_mg;
110+ *datay = ((s8)*datay) * data->bit_to_mg;
111+ *dataz = ((s8)*dataz) * data->bit_to_mg;
112+}
113+
114+static irqreturn_t cma3000_thread_irq(int irq, void *dev_id)
115+{
116+ struct cma3000_accl_data *data = dev_id;
117+ int datax, datay, dataz;
118+ u8 ctrl, mode, range, intr_status;
119+
120+ intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status");
121+ if (intr_status < 0)
122+ return IRQ_NONE;
123+
124+ /* Check if free fall is detected, report immediately */
125+ if (intr_status & CMA3000_INTSTATUS_FFDET) {
126+ input_report_abs(data->input_dev, ABS_MISC, 1);
127+ input_sync(data->input_dev);
128+ } else {
129+ input_report_abs(data->input_dev, ABS_MISC, 0);
130+ }
131+
132+ datax = CMA3000_READ(data, CMA3000_DOUTX, "X");
133+ datay = CMA3000_READ(data, CMA3000_DOUTY, "Y");
134+ dataz = CMA3000_READ(data, CMA3000_DOUTZ, "Z");
135+
136+ ctrl = CMA3000_READ(data, CMA3000_CTRL, "ctrl");
137+ mode = (ctrl & CMA3000_MODEMASK) >> 1;
138+ range = (ctrl & CMA3000_GRANGEMASK) >> 7;
139+
140+ data->bit_to_mg = mode_to_mg[mode][range];
141+
142+ /* Interrupt not for this device */
143+ if (data->bit_to_mg == 0)
144+ return IRQ_NONE;
145+
146+ /* Decode register values to milli g */
147+ decode_mg(data, &datax, &datay, &dataz);
148+
149+ input_report_abs(data->input_dev, ABS_X, datax);
150+ input_report_abs(data->input_dev, ABS_Y, datay);
151+ input_report_abs(data->input_dev, ABS_Z, dataz);
152+ input_sync(data->input_dev);
153+
154+ return IRQ_HANDLED;
155+}
156+
157+static int cma3000_reset(struct cma3000_accl_data *data)
158+{
159+ int val;
160+
161+ /* Reset sequence */
162+ CMA3000_SET(data, CMA3000_RSTR, 0x02, "Reset");
163+ CMA3000_SET(data, CMA3000_RSTR, 0x0A, "Reset");
164+ CMA3000_SET(data, CMA3000_RSTR, 0x04, "Reset");
165+
166+ /* Settling time delay */
167+ mdelay(10);
168+
169+ val = CMA3000_READ(data, CMA3000_STATUS, "Status");
170+ if (val < 0) {
171+ dev_err(data->dev, "Reset failed\n");
172+ return val;
173+ }
174+
175+ if (val & CMA3000_STATUS_PERR) {
176+ dev_err(data->dev, "Parity Error\n");
177+ return -EIO;
178+ }
179+
180+ return 0;
181+}
182+
183+static int cma3000_poweron(struct cma3000_accl_data *data)
184+{
185+ const struct cma3000_platform_data *pdata = data->pdata;
186+ u8 ctrl = 0;
187+ int ret;
188+
189+ if (data->g_range == CMARANGE_2G) {
190+ ctrl = (data->mode << 1) | CMA3000_RANGE2G;
191+ } else if (data->g_range == CMARANGE_8G) {
192+ ctrl = (data->mode << 1) | CMA3000_RANGE8G;
193+ } else {
194+ dev_info(data->dev,
195+ "Invalid G range specified, assuming 8G\n");
196+ ctrl = (data->mode << 1) | CMA3000_RANGE8G;
197+ }
198+
199+ ctrl |= data->bus_ops->ctrl_mod;
200+
201+ CMA3000_SET(data, CMA3000_MDTHR, pdata->mdthr,
202+ "Motion Detect Threshold");
203+ CMA3000_SET(data, CMA3000_MDFFTMR, pdata->mdfftmr,
204+ "Time register");
205+ CMA3000_SET(data, CMA3000_FFTHR, pdata->ffthr,
206+ "Free fall threshold");
207+ ret = CMA3000_SET(data, CMA3000_CTRL, ctrl, "Mode setting");
208+ if (ret < 0)
209+ return -EIO;
210+
211+ msleep(CMA3000_SETDELAY);
212+
213+ return 0;
214+}
215+
216+static int cma3000_poweroff(struct cma3000_accl_data *data)
217+{
218+ int ret;
219+
220+ ret = CMA3000_SET(data, CMA3000_CTRL, CMAMODE_POFF, "Mode setting");
221+ msleep(CMA3000_SETDELAY);
222+
223+ return ret;
224+}
225+
226+static int cma3000_open(struct input_dev *input_dev)
227+{
228+ struct cma3000_accl_data *data = input_get_drvdata(input_dev);
229+
230+ mutex_lock(&data->mutex);
231+
232+ if (!data->suspended)
233+ cma3000_poweron(data);
234+
235+ data->opened = true;
236+
237+ mutex_unlock(&data->mutex);
238+
239+ return 0;
240+}
241+
242+static void cma3000_close(struct input_dev *input_dev)
243+{
244+ struct cma3000_accl_data *data = input_get_drvdata(input_dev);
245+
246+ mutex_lock(&data->mutex);
247+
248+ if (!data->suspended)
249+ cma3000_poweroff(data);
250+
251+ data->opened = false;
252+
253+ mutex_unlock(&data->mutex);
254+}
255+
256+void cma3000_suspend(struct cma3000_accl_data *data)
257+{
258+ mutex_lock(&data->mutex);
259+
260+ if (!data->suspended && data->opened)
261+ cma3000_poweroff(data);
262+
263+ data->suspended = true;
264+
265+ mutex_unlock(&data->mutex);
266+}
267+EXPORT_SYMBOL(cma3000_suspend);
268+
269+
270+void cma3000_resume(struct cma3000_accl_data *data)
271+{
272+ mutex_lock(&data->mutex);
273+
274+ if (data->suspended && data->opened)
275+ cma3000_poweron(data);
276+
277+ data->suspended = false;
278+
279+ mutex_unlock(&data->mutex);
280+}
281+EXPORT_SYMBOL(cma3000_resume);
282+
283+struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
284+ const struct cma3000_bus_ops *bops)
285+{
286+ const struct cma3000_platform_data *pdata = dev->platform_data;
287+ struct cma3000_accl_data *data;
288+ struct input_dev *input_dev;
289+ int rev;
290+ int error;
291+
292+ if (!pdata) {
293+ dev_err(dev, "platform data not found\n");
294+ error = -EINVAL;
295+ goto err_out;
296+ }
297+
298+
299+ /* if no IRQ return error */
300+ if (irq == 0) {
301+ error = -EINVAL;
302+ goto err_out;
303+ }
304+
305+ data = kzalloc(sizeof(struct cma3000_accl_data), GFP_KERNEL);
306+ input_dev = input_allocate_device();
307+ if (!data || !input_dev) {
308+ error = -ENOMEM;
309+ goto err_free_mem;
310+ }
311+
312+ data->dev = dev;
313+ data->input_dev = input_dev;
314+ data->bus_ops = bops;
315+ data->pdata = pdata;
316+ data->irq = irq;
317+ mutex_init(&data->mutex);
318+
319+ data->mode = pdata->mode;
320+ if (data->mode < CMAMODE_DEFAULT || data->mode > CMAMODE_POFF) {
321+ data->mode = CMAMODE_MOTDET;
322+ dev_warn(dev,
323+ "Invalid mode specified, assuming Motion Detect\n");
324+ }
325+
326+ data->g_range = pdata->g_range;
327+ if (data->g_range != CMARANGE_2G && data->g_range != CMARANGE_8G) {
328+ dev_info(dev,
329+ "Invalid G range specified, assuming 8G\n");
330+ data->g_range = CMARANGE_8G;
331+ }
332+
333+ input_dev->name = "cma3000-accelerometer";
334+ input_dev->id.bustype = bops->bustype;
335+ input_dev->open = cma3000_open;
336+ input_dev->close = cma3000_close;
337+
338+ __set_bit(EV_ABS, input_dev->evbit);
339+
340+ input_set_abs_params(input_dev, ABS_X,
341+ -data->g_range, data->g_range, pdata->fuzz_x, 0);
342+ input_set_abs_params(input_dev, ABS_Y,
343+ -data->g_range, data->g_range, pdata->fuzz_y, 0);
344+ input_set_abs_params(input_dev, ABS_Z,
345+ -data->g_range, data->g_range, pdata->fuzz_z, 0);
346+ input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);
347+
348+ input_set_drvdata(input_dev, data);
349+
350+ error = cma3000_reset(data);
351+ if (error)
352+ goto err_free_mem;
353+
354+ rev = CMA3000_READ(data, CMA3000_REVID, "Revid");
355+ if (rev < 0) {
356+ error = rev;
357+ goto err_free_mem;
358+ }
359+
360+ pr_info("CMA3000 Accelerometer: Revision %x\n", rev);
361+
362+ error = request_threaded_irq(irq, NULL, cma3000_thread_irq,
363+ pdata->irqflags | IRQF_ONESHOT,
364+ "cma3000_d0x", data);
365+ if (error) {
366+ dev_err(dev, "request_threaded_irq failed\n");
367+ goto err_free_mem;
368+ }
369+
370+ error = input_register_device(data->input_dev);
371+ if (error) {
372+ dev_err(dev, "Unable to register input device\n");
373+ goto err_free_irq;
374+ }
375+
376+ return data;
377+
378+err_free_irq:
379+ free_irq(irq, data);
380+err_free_mem:
381+ input_free_device(input_dev);
382+ kfree(data);
383+err_out:
384+ return ERR_PTR(error);
385+}
386+EXPORT_SYMBOL(cma3000_init);
387+
388+void cma3000_exit(struct cma3000_accl_data *data)
389+{
390+ free_irq(data->irq, data);
391+ input_unregister_device(data->input_dev);
392+ kfree(data);
393+}
394+EXPORT_SYMBOL(cma3000_exit);
395+
396+MODULE_DESCRIPTION("CMA3000-D0x Accelerometer Driver");
397+MODULE_LICENSE("GPL");
398+MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");
drivers/input/misc/cma3000_d0x.h+42−0
@@ -0,0 +1,42 @@
1+/*
2+ * VTI CMA3000_D0x Accelerometer driver
3+ *
4+ * Copyright (C) 2010 Texas Instruments
5+ * Author: Hemanth V <hemanthv@ti.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify it
8+ * under the terms of the GNU General Public License version 2 as published by
9+ * the Free Software Foundation.
10+ *
11+ * This program is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14+ * more details.
15+ *
16+ * You should have received a copy of the GNU General Public License along with
17+ * this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef _INPUT_CMA3000_H
21+#define _INPUT_CMA3000_H
22+
23+#include <linux/types.h>
24+#include <linux/input.h>
25+
26+struct device;
27+struct cma3000_accl_data;
28+
29+struct cma3000_bus_ops {
30+ u16 bustype;
31+ u8 ctrl_mod;
32+ int (*read)(struct device *, u8, char *);
33+ int (*write)(struct device *, u8, u8, char *);
34+};
35+
36+struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
37+ const struct cma3000_bus_ops *bops);
38+void cma3000_exit(struct cma3000_accl_data *);
39+void cma3000_suspend(struct cma3000_accl_data *);
40+void cma3000_resume(struct cma3000_accl_data *);
41+
42+#endif
drivers/input/misc/cma3000_d0x_i2c.c+141−0
@@ -0,0 +1,141 @@
1+/*
2+ * Implements I2C interface for VTI CMA300_D0x Accelerometer driver
3+ *
4+ * Copyright (C) 2010 Texas Instruments
5+ * Author: Hemanth V <hemanthv@ti.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify it
8+ * under the terms of the GNU General Public License version 2 as published by
9+ * the Free Software Foundation.
10+ *
11+ * This program is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14+ * more details.
15+ *
16+ * You should have received a copy of the GNU General Public License along with
17+ * this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#include <linux/module.h>
21+#include <linux/i2c.h>
22+#include <linux/input/cma3000.h>
23+#include "cma3000_d0x.h"
24+
25+static int cma3000_i2c_set(struct device *dev,
26+ u8 reg, u8 val, char *msg)
27+{
28+ struct i2c_client *client = to_i2c_client(dev);
29+ int ret;
30+
31+ ret = i2c_smbus_write_byte_data(client, reg, val);
32+ if (ret < 0)
33+ dev_err(&client->dev,
34+ "%s failed (%s, %d)\n", __func__, msg, ret);
35+ return ret;
36+}
37+
38+static int cma3000_i2c_read(struct device *dev, u8 reg, char *msg)
39+{
40+ struct i2c_client *client = to_i2c_client(dev);
41+ int ret;
42+
43+ ret = i2c_smbus_read_byte_data(client, reg);
44+ if (ret < 0)
45+ dev_err(&client->dev,
46+ "%s failed (%s, %d)\n", __func__, msg, ret);
47+ return ret;
48+}
49+
50+static const struct cma3000_bus_ops cma3000_i2c_bops = {
51+ .bustype = BUS_I2C,
52+#define CMA3000_BUSI2C (0 << 4)
53+ .ctrl_mod = CMA3000_BUSI2C,
54+ .read = cma3000_i2c_read,
55+ .write = cma3000_i2c_set,
56+};
57+
58+static int __devinit cma3000_i2c_probe(struct i2c_client *client,
59+ const struct i2c_device_id *id)
60+{
61+ struct cma3000_accl_data *data;
62+
63+ data = cma3000_init(&client->dev, client->irq, &cma3000_i2c_bops);
64+ if (IS_ERR(data))
65+ return PTR_ERR(data);
66+
67+ i2c_set_clientdata(client, data);
68+
69+ return 0;
70+}
71+
72+static int __devexit cma3000_i2c_remove(struct i2c_client *client)
73+{
74+ struct cma3000_accl_data *data = i2c_get_clientdata(client);
75+
76+ cma3000_exit(data);
77+
78+ return 0;
79+}
80+
81+#ifdef CONFIG_PM
82+static int cma3000_i2c_suspend(struct device *dev)
83+{
84+ struct i2c_client *client = to_i2c_client(dev);
85+ struct cma3000_accl_data *data = i2c_get_clientdata(client);
86+
87+ cma3000_suspend(data);
88+
89+ return 0;
90+}
91+
92+static int cma3000_i2c_resume(struct device *dev)
93+{
94+ struct i2c_client *client = to_i2c_client(dev);
95+ struct cma3000_accl_data *data = i2c_get_clientdata(client);
96+
97+ cma3000_resume(data);
98+
99+ return 0;
100+}
101+
102+static const struct dev_pm_ops cma3000_i2c_pm_ops = {
103+ .suspend = cma3000_i2c_suspend,
104+ .resume = cma3000_i2c_resume,
105+};
106+#endif
107+
108+static const struct i2c_device_id cma3000_i2c_id[] = {
109+ { "cma3000_d01", 0 },
110+ { },
111+};
112+
113+static struct i2c_driver cma3000_i2c_driver = {
114+ .probe = cma3000_i2c_probe,
115+ .remove = __devexit_p(cma3000_i2c_remove),
116+ .id_table = cma3000_i2c_id,
117+ .driver = {
118+ .name = "cma3000_i2c_accl",
119+ .owner = THIS_MODULE,
120+#ifdef CONFIG_PM
121+ .pm = &cma3000_i2c_pm_ops,
122+#endif
123+ },
124+};
125+
126+static int __init cma3000_i2c_init(void)
127+{
128+ return i2c_add_driver(&cma3000_i2c_driver);
129+}
130+
131+static void __exit cma3000_i2c_exit(void)
132+{
133+ i2c_del_driver(&cma3000_i2c_driver);
134+}
135+
136+module_init(cma3000_i2c_init);
137+module_exit(cma3000_i2c_exit);
138+
139+MODULE_DESCRIPTION("CMA3000-D0x Accelerometer I2C Driver");
140+MODULE_LICENSE("GPL");
141+MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");
include/linux/input/cma3000.h+59−0
@@ -0,0 +1,59 @@
1+/*
2+ * VTI CMA3000_Dxx Accelerometer driver
3+ *
4+ * Copyright (C) 2010 Texas Instruments
5+ * Author: Hemanth V <hemanthv@ti.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify it
8+ * under the terms of the GNU General Public License version 2 as published by
9+ * the Free Software Foundation.
10+ *
11+ * This program is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14+ * more details.
15+ *
16+ * You should have received a copy of the GNU General Public License along with
17+ * this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+#ifndef _LINUX_CMA3000_H
21+#define _LINUX_CMA3000_H
22+
23+#define CMAMODE_DEFAULT 0
24+#define CMAMODE_MEAS100 1
25+#define CMAMODE_MEAS400 2
26+#define CMAMODE_MEAS40 3
27+#define CMAMODE_MOTDET 4
28+#define CMAMODE_FF100 5
29+#define CMAMODE_FF400 6
30+#define CMAMODE_POFF 7
31+
32+#define CMARANGE_2G 2000
33+#define CMARANGE_8G 8000
34+
35+/**
36+ * struct cma3000_i2c_platform_data - CMA3000 Platform data
37+ * @fuzz_x: Noise on X Axis
38+ * @fuzz_y: Noise on Y Axis
39+ * @fuzz_z: Noise on Z Axis
40+ * @g_range: G range in milli g i.e 2000 or 8000
41+ * @mode: Operating mode
42+ * @mdthr: Motion detect threshold value
43+ * @mdfftmr: Motion detect and free fall time value
44+ * @ffthr: Free fall threshold value
45+ */
46+
47+struct cma3000_platform_data {
48+ int fuzz_x;
49+ int fuzz_y;
50+ int fuzz_z;
51+ int g_range;
52+ uint8_t mode;
53+ uint8_t mdthr;
54+ uint8_t mdfftmr;
55+ uint8_t ffthr;
56+ unsigned long irqflags;
57+};
58+
59+#endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t