diff options
Diffstat (limited to 'drivers/misc/mpu3050/mlsl-kernel.c')
-rw-r--r-- | drivers/misc/mpu3050/mlsl-kernel.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/drivers/misc/mpu3050/mlsl-kernel.c b/drivers/misc/mpu3050/mlsl-kernel.c new file mode 100644 index 00000000000..cb1605131cb --- /dev/null +++ b/drivers/misc/mpu3050/mlsl-kernel.c | |||
@@ -0,0 +1,331 @@ | |||
1 | /* | ||
2 | $License: | ||
3 | Copyright (C) 2010 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 | #include "mlsl.h" | ||
21 | #include "mpu-i2c.h" | ||
22 | |||
23 | /* ------------ */ | ||
24 | /* - Defines. - */ | ||
25 | /* ------------ */ | ||
26 | |||
27 | /* ---------------------- */ | ||
28 | /* - Types definitions. - */ | ||
29 | /* ---------------------- */ | ||
30 | |||
31 | /* --------------------- */ | ||
32 | /* - Function p-types. - */ | ||
33 | /* --------------------- */ | ||
34 | |||
35 | /** | ||
36 | * @brief used to open the I2C or SPI serial port. | ||
37 | * This port is used to send and receive data to the MPU device. | ||
38 | * @param portNum | ||
39 | * The COM port number associated with the device in use. | ||
40 | * @return ML_SUCCESS if successful, a non-zero error code otherwise. | ||
41 | */ | ||
42 | tMLError MLSLSerialOpen(char const *port, void **sl_handle) | ||
43 | { | ||
44 | return ML_SUCCESS; | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * @brief used to reset any buffering the driver may be doing | ||
49 | * @return ML_SUCCESS if successful, a non-zero error code otherwise. | ||
50 | */ | ||
51 | tMLError MLSLSerialReset(void *sl_handle) | ||
52 | { | ||
53 | return ML_SUCCESS; | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * @brief used to close the I2C or SPI serial port. | ||
58 | * This port is used to send and receive data to the MPU device. | ||
59 | * @return ML_SUCCESS if successful, a non-zero error code otherwise. | ||
60 | */ | ||
61 | tMLError MLSLSerialClose(void *sl_handle) | ||
62 | { | ||
63 | return ML_SUCCESS; | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * @brief used to read a single byte of data. | ||
68 | * This should be sent by I2C or SPI. | ||
69 | * | ||
70 | * @param slaveAddr I2C slave address of device. | ||
71 | * @param registerAddr Register address to read. | ||
72 | * @param data Single byte of data to read. | ||
73 | * | ||
74 | * @return ML_SUCCESS if the command is successful, an error code otherwise. | ||
75 | */ | ||
76 | tMLError MLSLSerialWriteSingle(void *sl_handle, | ||
77 | unsigned char slaveAddr, | ||
78 | unsigned char registerAddr, | ||
79 | unsigned char data) | ||
80 | { | ||
81 | return sensor_i2c_write_register((struct i2c_adapter *) sl_handle, | ||
82 | slaveAddr, registerAddr, data); | ||
83 | } | ||
84 | |||
85 | |||
86 | /** | ||
87 | * @brief used to write multiple bytes of data from registers. | ||
88 | * This should be sent by I2C. | ||
89 | * | ||
90 | * @param slaveAddr I2C slave address of device. | ||
91 | * @param registerAddr Register address to write. | ||
92 | * @param length Length of burst of data. | ||
93 | * @param data Pointer to block of data. | ||
94 | * | ||
95 | * @return ML_SUCCESS if successful, a non-zero error code otherwise. | ||
96 | */ | ||
97 | tMLError MLSLSerialWrite(void *sl_handle, | ||
98 | unsigned char slaveAddr, | ||
99 | unsigned short length, | ||
100 | unsigned char const *data) | ||
101 | { | ||
102 | tMLError result; | ||
103 | const unsigned short dataLength = length - 1; | ||
104 | const unsigned char startRegAddr = data[0]; | ||
105 | unsigned char i2cWrite[SERIAL_MAX_TRANSFER_SIZE + 1]; | ||
106 | unsigned short bytesWritten = 0; | ||
107 | |||
108 | while (bytesWritten < dataLength) { | ||
109 | unsigned short thisLen = min(SERIAL_MAX_TRANSFER_SIZE, | ||
110 | dataLength - bytesWritten); | ||
111 | if (bytesWritten == 0) { | ||
112 | result = sensor_i2c_write((struct i2c_adapter *) | ||
113 | sl_handle, slaveAddr, | ||
114 | 1 + thisLen, data); | ||
115 | } else { | ||
116 | /* manually increment register addr between chunks */ | ||
117 | i2cWrite[0] = startRegAddr + bytesWritten; | ||
118 | memcpy(&i2cWrite[1], &data[1 + bytesWritten], | ||
119 | thisLen); | ||
120 | result = sensor_i2c_write((struct i2c_adapter *) | ||
121 | sl_handle, slaveAddr, | ||
122 | 1 + thisLen, i2cWrite); | ||
123 | } | ||
124 | if (ML_SUCCESS != result) | ||
125 | return result; | ||
126 | bytesWritten += thisLen; | ||
127 | } | ||
128 | return ML_SUCCESS; | ||
129 | } | ||
130 | |||
131 | |||
132 | /** | ||
133 | * @brief used to read multiple bytes of data from registers. | ||
134 | * This should be sent by I2C. | ||
135 | * | ||
136 | * @param slaveAddr I2C slave address of device. | ||
137 | * @param registerAddr Register address to read. | ||
138 | * @param length Length of burst of data. | ||
139 | * @param data Pointer to block of data. | ||
140 | * | ||
141 | * @return Zero if successful; an error code otherwise | ||
142 | */ | ||
143 | tMLError MLSLSerialRead(void *sl_handle, | ||
144 | unsigned char slaveAddr, | ||
145 | unsigned char registerAddr, | ||
146 | unsigned short length, unsigned char *data) | ||
147 | { | ||
148 | tMLError result; | ||
149 | unsigned short bytesRead = 0; | ||
150 | |||
151 | if (registerAddr == MPUREG_FIFO_R_W | ||
152 | || registerAddr == MPUREG_MEM_R_W) { | ||
153 | return ML_ERROR_INVALID_PARAMETER; | ||
154 | } | ||
155 | while (bytesRead < length) { | ||
156 | unsigned short thisLen = | ||
157 | min(SERIAL_MAX_TRANSFER_SIZE, length - bytesRead); | ||
158 | result = | ||
159 | sensor_i2c_read((struct i2c_adapter *) sl_handle, | ||
160 | slaveAddr, registerAddr + bytesRead, | ||
161 | thisLen, &data[bytesRead]); | ||
162 | if (ML_SUCCESS != result) | ||
163 | return result; | ||
164 | bytesRead += thisLen; | ||
165 | } | ||
166 | return ML_SUCCESS; | ||
167 | } | ||
168 | |||
169 | |||
170 | /** | ||
171 | * @brief used to write multiple bytes of data to the memory. | ||
172 | * This should be sent by I2C. | ||
173 | * | ||
174 | * @param slaveAddr I2C slave address of device. | ||
175 | * @param memAddr The location in the memory to write to. | ||
176 | * @param length Length of burst data. | ||
177 | * @param data Pointer to block of data. | ||
178 | * | ||
179 | * @return Zero if successful; an error code otherwise | ||
180 | */ | ||
181 | tMLError MLSLSerialWriteMem(void *sl_handle, | ||
182 | unsigned char slaveAddr, | ||
183 | unsigned short memAddr, | ||
184 | unsigned short length, | ||
185 | unsigned char const *data) | ||
186 | { | ||
187 | tMLError result; | ||
188 | unsigned short bytesWritten = 0; | ||
189 | |||
190 | if ((memAddr & 0xFF) + length > MPU_MEM_BANK_SIZE) { | ||
191 | pr_err("memory read length (%d B) extends beyond its" | ||
192 | " limits (%d) if started at location %d\n", length, | ||
193 | MPU_MEM_BANK_SIZE, memAddr & 0xFF); | ||
194 | return ML_ERROR_INVALID_PARAMETER; | ||
195 | } | ||
196 | while (bytesWritten < length) { | ||
197 | unsigned short thisLen = | ||
198 | min(SERIAL_MAX_TRANSFER_SIZE, length - bytesWritten); | ||
199 | result = | ||
200 | mpu_memory_write((struct i2c_adapter *) sl_handle, | ||
201 | slaveAddr, memAddr + bytesWritten, | ||
202 | thisLen, &data[bytesWritten]); | ||
203 | if (ML_SUCCESS != result) | ||
204 | return result; | ||
205 | bytesWritten += thisLen; | ||
206 | } | ||
207 | return ML_SUCCESS; | ||
208 | } | ||
209 | |||
210 | |||
211 | /** | ||
212 | * @brief used to read multiple bytes of data from the memory. | ||
213 | * This should be sent by I2C. | ||
214 | * | ||
215 | * @param slaveAddr I2C slave address of device. | ||
216 | * @param memAddr The location in the memory to read from. | ||
217 | * @param length Length of burst data. | ||
218 | * @param data Pointer to block of data. | ||
219 | * | ||
220 | * @return Zero if successful; an error code otherwise | ||
221 | */ | ||
222 | tMLError MLSLSerialReadMem(void *sl_handle, | ||
223 | unsigned char slaveAddr, | ||
224 | unsigned short memAddr, | ||
225 | unsigned short length, unsigned char *data) | ||
226 | { | ||
227 | tMLError result; | ||
228 | unsigned short bytesRead = 0; | ||
229 | |||
230 | if ((memAddr & 0xFF) + length > MPU_MEM_BANK_SIZE) { | ||
231 | printk | ||
232 | ("memory read length (%d B) extends beyond its limits (%d) " | ||
233 | "if started at location %d\n", length, | ||
234 | MPU_MEM_BANK_SIZE, memAddr & 0xFF); | ||
235 | return ML_ERROR_INVALID_PARAMETER; | ||
236 | } | ||
237 | while (bytesRead < length) { | ||
238 | unsigned short thisLen = | ||
239 | min(SERIAL_MAX_TRANSFER_SIZE, length - bytesRead); | ||
240 | result = | ||
241 | mpu_memory_read((struct i2c_adapter *) sl_handle, | ||
242 | slaveAddr, memAddr + bytesRead, | ||
243 | thisLen, &data[bytesRead]); | ||
244 | if (ML_SUCCESS != result) | ||
245 | return result; | ||
246 | bytesRead += thisLen; | ||
247 | } | ||
248 | return ML_SUCCESS; | ||
249 | } | ||
250 | |||
251 | |||
252 | /** | ||
253 | * @brief used to write multiple bytes of data to the fifo. | ||
254 | * This should be sent by I2C. | ||
255 | * | ||
256 | * @param slaveAddr I2C slave address of device. | ||
257 | * @param length Length of burst of data. | ||
258 | * @param data Pointer to block of data. | ||
259 | * | ||
260 | * @return Zero if successful; an error code otherwise | ||
261 | */ | ||
262 | tMLError MLSLSerialWriteFifo(void *sl_handle, | ||
263 | unsigned char slaveAddr, | ||
264 | unsigned short length, | ||
265 | unsigned char const *data) | ||
266 | { | ||
267 | tMLError result; | ||
268 | unsigned char i2cWrite[SERIAL_MAX_TRANSFER_SIZE + 1]; | ||
269 | unsigned short bytesWritten = 0; | ||
270 | |||
271 | if (length > FIFO_HW_SIZE) { | ||
272 | printk(KERN_ERR | ||
273 | "maximum fifo write length is %d\n", FIFO_HW_SIZE); | ||
274 | return ML_ERROR_INVALID_PARAMETER; | ||
275 | } | ||
276 | while (bytesWritten < length) { | ||
277 | unsigned short thisLen = | ||
278 | min(SERIAL_MAX_TRANSFER_SIZE, length - bytesWritten); | ||
279 | i2cWrite[0] = MPUREG_FIFO_R_W; | ||
280 | memcpy(&i2cWrite[1], &data[bytesWritten], thisLen); | ||
281 | result = sensor_i2c_write((struct i2c_adapter *) sl_handle, | ||
282 | slaveAddr, thisLen + 1, | ||
283 | i2cWrite); | ||
284 | if (ML_SUCCESS != result) | ||
285 | return result; | ||
286 | bytesWritten += thisLen; | ||
287 | } | ||
288 | return ML_SUCCESS; | ||
289 | } | ||
290 | |||
291 | |||
292 | /** | ||
293 | * @brief used to read multiple bytes of data from the fifo. | ||
294 | * This should be sent by I2C. | ||
295 | * | ||
296 | * @param slaveAddr I2C slave address of device. | ||
297 | * @param length Length of burst of data. | ||
298 | * @param data Pointer to block of data. | ||
299 | * | ||
300 | * @return Zero if successful; an error code otherwise | ||
301 | */ | ||
302 | tMLError MLSLSerialReadFifo(void *sl_handle, | ||
303 | unsigned char slaveAddr, | ||
304 | unsigned short length, unsigned char *data) | ||
305 | { | ||
306 | tMLError result; | ||
307 | unsigned short bytesRead = 0; | ||
308 | |||
309 | if (length > FIFO_HW_SIZE) { | ||
310 | printk(KERN_ERR | ||
311 | "maximum fifo read length is %d\n", FIFO_HW_SIZE); | ||
312 | return ML_ERROR_INVALID_PARAMETER; | ||
313 | } | ||
314 | while (bytesRead < length) { | ||
315 | unsigned short thisLen = | ||
316 | min(SERIAL_MAX_TRANSFER_SIZE, length - bytesRead); | ||
317 | result = | ||
318 | sensor_i2c_read((struct i2c_adapter *) sl_handle, | ||
319 | slaveAddr, MPUREG_FIFO_R_W, thisLen, | ||
320 | &data[bytesRead]); | ||
321 | if (ML_SUCCESS != result) | ||
322 | return result; | ||
323 | bytesRead += thisLen; | ||
324 | } | ||
325 | |||
326 | return ML_SUCCESS; | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * @} | ||
331 | */ | ||