aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/inv_mpu/accel/cma3000.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/misc/inv_mpu/accel/cma3000.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/misc/inv_mpu/accel/cma3000.c')
-rw-r--r--drivers/misc/inv_mpu/accel/cma3000.c222
1 files changed, 222 insertions, 0 deletions
diff --git a/drivers/misc/inv_mpu/accel/cma3000.c b/drivers/misc/inv_mpu/accel/cma3000.c
new file mode 100644
index 00000000000..496d1f29bdc
--- /dev/null
+++ b/drivers/misc/inv_mpu/accel/cma3000.c
@@ -0,0 +1,222 @@
1/*
2 $License:
3 Copyright (C) 2011 InvenSense Corporation, All Rights Reserved.
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 as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 $
18 */
19
20/*
21 * @addtogroup ACCELDL
22 * @brief Accelerometer setup and handling methods for VTI CMA3000.
23 *
24 * @{
25 * @file cma3000.c
26 * @brief Accelerometer setup and handling methods for VTI CMA3000
27 */
28
29/* -------------------------------------------------------------------------- */
30
31#include <linux/i2c.h>
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/kernel.h>
35#include <linux/errno.h>
36#include <linux/slab.h>
37#include <linux/delay.h>
38#include "mpu-dev.h"
39
40#include <log.h>
41#include <linux/mpu.h>
42#include "mlsl.h"
43#include "mldl_cfg.h"
44#undef MPL_LOG_TAG
45#define MPL_LOG_TAG "MPL-acc"
46
47/* -------------------------------------------------------------------------- */
48
49static int cma3000_suspend(void *mlsl_handle,
50 struct ext_slave_descr *slave,
51 struct ext_slave_platform_data *pdata)
52{
53 int result;
54 /* RAM reset */
55 result =
56 inv_serial_single_write(mlsl_handle, pdata->address, 0x1d, 0xcd);
57 return result;
58}
59
60static int cma3000_resume(void *mlsl_handle,
61 struct ext_slave_descr *slave,
62 struct ext_slave_platform_data *pdata)
63{
64
65 return INV_SUCCESS;
66}
67
68static int cma3000_read(void *mlsl_handle,
69 struct ext_slave_descr *slave,
70 struct ext_slave_platform_data *pdata,
71 unsigned char *data)
72{
73 int result;
74 result = inv_serial_read(mlsl_handle, pdata->address,
75 slave->reg, slave->len, data);
76 return result;
77}
78
79static struct ext_slave_descr cma3000_descr = {
80 .init = NULL,
81 .exit = NULL,
82 .suspend = cma3000_suspend,
83 .resume = cma3000_resume,
84 .read = cma3000_read,
85 .config = NULL,
86 .get_config = NULL,
87 .name = "cma3000",
88 .type = EXT_SLAVE_TYPE_ACCEL,
89 .id = ID_INVALID,
90 .read_reg = 0x06,
91 .read_len = 6,
92 .endian = EXT_SLAVE_LITTLE_ENDIAN,
93 .range = {2, 0},
94 .trigger = NULL,
95
96};
97
98static
99struct ext_slave_descr *cma3000_get_slave_descr(void)
100{
101 return &cma3000_descr;
102}
103
104/* -------------------------------------------------------------------------- */
105
106struct cma3000_mod_private_data {
107 struct i2c_client *client;
108 struct ext_slave_platform_data *pdata;
109};
110
111static unsigned short normal_i2c[] = { I2C_CLIENT_END };
112
113static int cma3000_mod_probe(struct i2c_client *client,
114 const struct i2c_device_id *devid)
115{
116 struct ext_slave_platform_data *pdata;
117 struct cma3000_mod_private_data *private_data;
118 int result = 0;
119
120 dev_info(&client->adapter->dev, "%s: %s\n", __func__, devid->name);
121
122 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
123 result = -ENODEV;
124 goto out_no_free;
125 }
126
127 pdata = client->dev.platform_data;
128 if (!pdata) {
129 dev_err(&client->adapter->dev,
130 "Missing platform data for slave %s\n", devid->name);
131 result = -EFAULT;
132 goto out_no_free;
133 }
134
135 private_data = kzalloc(sizeof(*private_data), GFP_KERNEL);
136 if (!private_data) {
137 result = -ENOMEM;
138 goto out_no_free;
139 }
140
141 i2c_set_clientdata(client, private_data);
142 private_data->client = client;
143 private_data->pdata = pdata;
144
145 result = inv_mpu_register_slave(THIS_MODULE, client, pdata,
146 cma3000_get_slave_descr);
147 if (result) {
148 dev_err(&client->adapter->dev,
149 "Slave registration failed: %s, %d\n",
150 devid->name, result);
151 goto out_free_memory;
152 }
153
154 return result;
155
156out_free_memory:
157 kfree(private_data);
158out_no_free:
159 dev_err(&client->adapter->dev, "%s failed %d\n", __func__, result);
160 return result;
161
162}
163
164static int cma3000_mod_remove(struct i2c_client *client)
165{
166 struct cma3000_mod_private_data *private_data =
167 i2c_get_clientdata(client);
168
169 dev_dbg(&client->adapter->dev, "%s\n", __func__);
170
171 inv_mpu_unregister_slave(client, private_data->pdata,
172 cma3000_get_slave_descr);
173
174 kfree(private_data);
175 return 0;
176}
177
178static const struct i2c_device_id cma3000_mod_id[] = {
179 { "cma3000", ACCEL_ID_CMA3000 },
180 {}
181};
182
183MODULE_DEVICE_TABLE(i2c, cma3000_mod_id);
184
185static struct i2c_driver cma3000_mod_driver = {
186 .class = I2C_CLASS_HWMON,
187 .probe = cma3000_mod_probe,
188 .remove = cma3000_mod_remove,
189 .id_table = cma3000_mod_id,
190 .driver = {
191 .owner = THIS_MODULE,
192 .name = "cma3000_mod",
193 },
194 .address_list = normal_i2c,
195};
196
197static int __init cma3000_mod_init(void)
198{
199 int res = i2c_add_driver(&cma3000_mod_driver);
200 pr_info("%s: Probe name %s\n", __func__, "cma3000_mod");
201 if (res)
202 pr_err("%s failed\n", __func__);
203 return res;
204}
205
206static void __exit cma3000_mod_exit(void)
207{
208 pr_info("%s\n", __func__);
209 i2c_del_driver(&cma3000_mod_driver);
210}
211
212module_init(cma3000_mod_init);
213module_exit(cma3000_mod_exit);
214
215MODULE_AUTHOR("Invensense Corporation");
216MODULE_DESCRIPTION("Driver to integrate CMA3000 sensor with the MPU");
217MODULE_LICENSE("GPL");
218MODULE_ALIAS("cma3000_mod");
219
220/**
221 * @}
222 */