aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mpu3050/accel/kxtf9.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mpu3050/accel/kxtf9.c')
-rw-r--r--drivers/misc/mpu3050/accel/kxtf9.c669
1 files changed, 669 insertions, 0 deletions
diff --git a/drivers/misc/mpu3050/accel/kxtf9.c b/drivers/misc/mpu3050/accel/kxtf9.c
new file mode 100644
index 00000000000..938cd572a8f
--- /dev/null
+++ b/drivers/misc/mpu3050/accel/kxtf9.c
@@ -0,0 +1,669 @@
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/**
21 * @defgroup ACCELDL (Motion Library - Accelerometer Driver Layer)
22 * @brief Provides the interface to setup and handle an accelerometers
23 * connected to the secondary I2C interface of the gyroscope.
24 *
25 * @{
26 * @file kxtf9.c
27 * @brief Accelerometer setup and handling methods.
28*/
29
30/* ------------------ */
31/* - Include Files. - */
32/* ------------------ */
33
34#undef MPL_LOG_NDEBUG
35#define MPL_LOG_NDEBUG 1
36
37#ifdef __KERNEL__
38#include <linux/module.h>
39#endif
40
41#include "mpu.h"
42#include "mlsl.h"
43#include "mlos.h"
44
45#include <log.h>
46#undef MPL_LOG_TAG
47#define MPL_LOG_TAG "MPL-acc"
48
49#define KXTF9_XOUT_HPF_L (0x00) /* 0000 0000 */
50#define KXTF9_XOUT_HPF_H (0x01) /* 0000 0001 */
51#define KXTF9_YOUT_HPF_L (0x02) /* 0000 0010 */
52#define KXTF9_YOUT_HPF_H (0x03) /* 0000 0011 */
53#define KXTF9_ZOUT_HPF_L (0x04) /* 0001 0100 */
54#define KXTF9_ZOUT_HPF_H (0x05) /* 0001 0101 */
55#define KXTF9_XOUT_L (0x06) /* 0000 0110 */
56#define KXTF9_XOUT_H (0x07) /* 0000 0111 */
57#define KXTF9_YOUT_L (0x08) /* 0000 1000 */
58#define KXTF9_YOUT_H (0x09) /* 0000 1001 */
59#define KXTF9_ZOUT_L (0x0A) /* 0001 1010 */
60#define KXTF9_ZOUT_H (0x0B) /* 0001 1011 */
61#define KXTF9_ST_RESP (0x0C) /* 0000 1100 */
62#define KXTF9_WHO_AM_I (0x0F) /* 0000 1111 */
63#define KXTF9_TILT_POS_CUR (0x10) /* 0001 0000 */
64#define KXTF9_TILT_POS_PRE (0x11) /* 0001 0001 */
65#define KXTF9_INT_SRC_REG1 (0x15) /* 0001 0101 */
66#define KXTF9_INT_SRC_REG2 (0x16) /* 0001 0110 */
67#define KXTF9_STATUS_REG (0x18) /* 0001 1000 */
68#define KXTF9_INT_REL (0x1A) /* 0001 1010 */
69#define KXTF9_CTRL_REG1 (0x1B) /* 0001 1011 */
70#define KXTF9_CTRL_REG2 (0x1C) /* 0001 1100 */
71#define KXTF9_CTRL_REG3 (0x1D) /* 0001 1101 */
72#define KXTF9_INT_CTRL_REG1 (0x1E) /* 0001 1110 */
73#define KXTF9_INT_CTRL_REG2 (0x1F) /* 0001 1111 */
74#define KXTF9_INT_CTRL_REG3 (0x20) /* 0010 0000 */
75#define KXTF9_DATA_CTRL_REG (0x21) /* 0010 0001 */
76#define KXTF9_TILT_TIMER (0x28) /* 0010 1000 */
77#define KXTF9_WUF_TIMER (0x29) /* 0010 1001 */
78#define KXTF9_TDT_TIMER (0x2B) /* 0010 1011 */
79#define KXTF9_TDT_H_THRESH (0x2C) /* 0010 1100 */
80#define KXTF9_TDT_L_THRESH (0x2D) /* 0010 1101 */
81#define KXTF9_TDT_TAP_TIMER (0x2E) /* 0010 1110 */
82#define KXTF9_TDT_TOTAL_TIMER (0x2F) /* 0010 1111 */
83#define KXTF9_TDT_LATENCY_TIMER (0x30) /* 0011 0000 */
84#define KXTF9_TDT_WINDOW_TIMER (0x31) /* 0011 0001 */
85#define KXTF9_WUF_THRESH (0x5A) /* 0101 1010 */
86#define KXTF9_TILT_ANGLE (0x5C) /* 0101 1100 */
87#define KXTF9_HYST_SET (0x5F) /* 0101 1111 */
88
89#define KXTF9_MAX_DUR (0xFF)
90#define KXTF9_MAX_THS (0xFF)
91#define KXTF9_THS_COUNTS_P_G (32)
92
93/* --------------------- */
94/* - Variables. - */
95/* --------------------- */
96
97struct kxtf9_config {
98 unsigned int odr; /* Output data rate mHz */
99 unsigned int fsr; /* full scale range mg */
100 unsigned int ths; /* Motion no-motion thseshold mg */
101 unsigned int dur; /* Motion no-motion duration ms */
102 unsigned int irq_type;
103 unsigned char reg_ths;
104 unsigned char reg_dur;
105 unsigned char reg_odr;
106 unsigned char reg_int_cfg1;
107 unsigned char reg_int_cfg2;
108 unsigned char ctrl_reg1;
109};
110
111struct kxtf9_private_data {
112 struct kxtf9_config suspend;
113 struct kxtf9_config resume;
114};
115
116/*****************************************
117 Accelerometer Initialization Functions
118*****************************************/
119
120static int kxtf9_set_ths(void *mlsl_handle,
121 struct ext_slave_platform_data *pdata,
122 struct kxtf9_config *config,
123 int apply,
124 long ths)
125{
126 int result = ML_SUCCESS;
127 if ((ths * KXTF9_THS_COUNTS_P_G / 1000) > KXTF9_MAX_THS)
128 ths = (KXTF9_MAX_THS * 1000) / KXTF9_THS_COUNTS_P_G;
129
130 if (ths < 0)
131 ths = 0;
132
133 config->ths = ths;
134 config->reg_ths = (unsigned char)
135 ((long)(ths * KXTF9_THS_COUNTS_P_G) / 1000);
136 MPL_LOGV("THS: %d, 0x%02x\n", config->ths, (int)config->reg_ths);
137 if (apply)
138 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
139 KXTF9_WUF_THRESH,
140 config->reg_ths);
141 return result;
142}
143
144static int kxtf9_set_dur(void *mlsl_handle,
145 struct ext_slave_platform_data *pdata,
146 struct kxtf9_config *config,
147 int apply,
148 long dur)
149{
150 int result = ML_SUCCESS;
151 long reg_dur = (dur * config->odr) / 1000000;
152 config->dur = dur;
153
154 if (reg_dur > KXTF9_MAX_DUR)
155 reg_dur = KXTF9_MAX_DUR;
156
157 config->reg_dur = (unsigned char) reg_dur;
158 MPL_LOGV("DUR: %d, 0x%02x\n", config->dur, (int)config->reg_dur);
159 if (apply)
160 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
161 KXTF9_WUF_TIMER,
162 (unsigned char)reg_dur);
163 return result;
164}
165
166/**
167 * Sets the IRQ to fire when one of the IRQ events occur. Threshold and
168 * duration will not be used uless the type is MOT or NMOT.
169 *
170 * @param config configuration to apply to, suspend or resume
171 * @param irq_type The type of IRQ. Valid values are
172 * - MPU_SLAVE_IRQ_TYPE_NONE
173 * - MPU_SLAVE_IRQ_TYPE_MOTION
174 * - MPU_SLAVE_IRQ_TYPE_DATA_READY
175 */
176static int kxtf9_set_irq(void *mlsl_handle,
177 struct ext_slave_platform_data *pdata,
178 struct kxtf9_config *config,
179 int apply,
180 long irq_type)
181{
182 int result = ML_SUCCESS;
183 struct kxtf9_private_data *private_data = pdata->private_data;
184
185 config->irq_type = (unsigned char)irq_type;
186 config->ctrl_reg1 &= ~0x22;
187 if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) {
188 config->ctrl_reg1 |= 0x20;
189 config->reg_int_cfg1 = 0x38;
190 config->reg_int_cfg2 = 0x00;
191 } else if (irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) {
192 config->ctrl_reg1 |= 0x02;
193 if ((unsigned long) config ==
194 (unsigned long) &private_data->suspend)
195 config->reg_int_cfg1 = 0x34;
196 else
197 config->reg_int_cfg1 = 0x24;
198 config->reg_int_cfg2 = 0xE0;
199 } else {
200 config->reg_int_cfg1 = 0x00;
201 config->reg_int_cfg2 = 0x00;
202 }
203
204 if (apply) {
205 /* Must clear bit 7 before writing new configuration */
206 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
207 KXTF9_CTRL_REG1, 0x40);
208 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
209 KXTF9_INT_CTRL_REG1,
210 config->reg_int_cfg1);
211 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
212 KXTF9_INT_CTRL_REG2,
213 config->reg_int_cfg2);
214 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
215 KXTF9_CTRL_REG1,
216 config->ctrl_reg1);
217 }
218 MPL_LOGV("CTRL_REG1: %lx, INT_CFG1: %lx, INT_CFG2: %lx\n",
219 (unsigned long)config->ctrl_reg1,
220 (unsigned long)config->reg_int_cfg1,
221 (unsigned long)config->reg_int_cfg2);
222
223 return result;
224}
225
226/**
227 * Set the Output data rate for the particular configuration
228 *
229 * @param config Config to modify with new ODR
230 * @param odr Output data rate in units of 1/1000Hz
231 */
232static int kxtf9_set_odr(void *mlsl_handle,
233 struct ext_slave_platform_data *pdata,
234 struct kxtf9_config *config,
235 int apply,
236 long odr)
237{
238 unsigned char bits;
239 int result = ML_SUCCESS;
240
241 /* Data sheet says there is 12.5 hz, but that seems to produce a single
242 * correct data value, thus we remove it from the table */
243 if (odr > 400000) {
244 config->odr = 800000;
245 bits = 0x06;
246 } else if (odr > 200000) {
247 config->odr = 400000;
248 bits = 0x05;
249 } else if (odr > 100000) {
250 config->odr = 200000;
251 bits = 0x04;
252 } else if (odr > 50000) {
253 config->odr = 100000;
254 bits = 0x03;
255 } else if (odr > 25000) {
256 config->odr = 50000;
257 bits = 0x02;
258 } else if (odr != 0) {
259 config->odr = 25000;
260 bits = 0x01;
261 } else {
262 config->odr = 0;
263 bits = 0;
264 }
265
266 config->reg_odr = bits;
267 kxtf9_set_dur(mlsl_handle, pdata,
268 config, apply, config->dur);
269 MPL_LOGV("ODR: %d, 0x%02x\n", config->odr, (int)config->ctrl_reg1);
270 if (apply) {
271 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
272 KXTF9_DATA_CTRL_REG,
273 config->reg_odr);
274 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
275 KXTF9_CTRL_REG1,
276 0x40);
277 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
278 KXTF9_CTRL_REG1,
279 config->ctrl_reg1);
280 }
281 return result;
282}
283
284/**
285 * Set the full scale range of the accels
286 *
287 * @param config pointer to configuration
288 * @param fsr requested full scale range
289 */
290static int kxtf9_set_fsr(void *mlsl_handle,
291 struct ext_slave_platform_data *pdata,
292 struct kxtf9_config *config,
293 int apply,
294 long fsr)
295{
296 int result = ML_SUCCESS;
297
298 config->ctrl_reg1 = (config->ctrl_reg1 & 0xE7);
299 if (fsr <= 2000) {
300 config->fsr = 2000;
301 config->ctrl_reg1 |= 0x00;
302 } else if (fsr <= 4000) {
303 config->fsr = 4000;
304 config->ctrl_reg1 |= 0x08;
305 } else {
306 config->fsr = 8000;
307 config->ctrl_reg1 |= 0x10;
308 }
309
310 MPL_LOGV("FSR: %d\n", config->fsr);
311 if (apply) {
312 /* Must clear bit 7 before writing new configuration */
313 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
314 KXTF9_CTRL_REG1, 0x40);
315 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
316 KXTF9_CTRL_REG1, config->ctrl_reg1);
317 }
318 return result;
319}
320
321static int kxtf9_suspend(void *mlsl_handle,
322 struct ext_slave_descr *slave,
323 struct ext_slave_platform_data *pdata)
324{
325 int result;
326 unsigned char data;
327 struct kxtf9_private_data *private_data = pdata->private_data;
328
329 /* Wake up */
330 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
331 KXTF9_CTRL_REG1, 0x40);
332 ERROR_CHECK(result);
333 /* INT_CTRL_REG1: */
334 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
335 KXTF9_INT_CTRL_REG1,
336 private_data->suspend.reg_int_cfg1);
337 ERROR_CHECK(result);
338 /* WUF_THRESH: */
339 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
340 KXTF9_WUF_THRESH,
341 private_data->suspend.reg_ths);
342 ERROR_CHECK(result);
343 /* DATA_CTRL_REG */
344 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
345 KXTF9_DATA_CTRL_REG,
346 private_data->suspend.reg_odr);
347 ERROR_CHECK(result);
348 /* WUF_TIMER */
349 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
350 KXTF9_WUF_TIMER, private_data->suspend.reg_dur);
351 ERROR_CHECK(result);
352
353 /* Normal operation */
354 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
355 KXTF9_CTRL_REG1,
356 private_data->suspend.ctrl_reg1);
357 ERROR_CHECK(result);
358 result = MLSLSerialRead(mlsl_handle, pdata->address,
359 KXTF9_INT_REL, 1, &data);
360 ERROR_CHECK(result);
361
362 return result;
363}
364
365/* full scale setting - register and mask */
366#define ACCEL_KIONIX_CTRL_REG (0x1b)
367#define ACCEL_KIONIX_CTRL_MASK (0x18)
368
369static int kxtf9_resume(void *mlsl_handle,
370 struct ext_slave_descr *slave,
371 struct ext_slave_platform_data *pdata)
372{
373 int result = ML_SUCCESS;
374 unsigned char data;
375 struct kxtf9_private_data *private_data = pdata->private_data;
376
377 /* Wake up */
378 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
379 KXTF9_CTRL_REG1, 0x40);
380 ERROR_CHECK(result);
381 /* INT_CTRL_REG1: */
382 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
383 KXTF9_INT_CTRL_REG1,
384 private_data->resume.reg_int_cfg1);
385 ERROR_CHECK(result);
386 /* WUF_THRESH: */
387 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
388 KXTF9_WUF_THRESH, private_data->resume.reg_ths);
389 ERROR_CHECK(result);
390 /* DATA_CTRL_REG */
391 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
392 KXTF9_DATA_CTRL_REG,
393 private_data->resume.reg_odr);
394 ERROR_CHECK(result);
395 /* WUF_TIMER */
396 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
397 KXTF9_WUF_TIMER, private_data->resume.reg_dur);
398 ERROR_CHECK(result);
399
400 /* Normal operation */
401 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
402 KXTF9_CTRL_REG1,
403 private_data->resume.ctrl_reg1);
404 ERROR_CHECK(result);
405 result = MLSLSerialRead(mlsl_handle, pdata->address,
406 KXTF9_INT_REL, 1, &data);
407 ERROR_CHECK(result);
408
409 return ML_SUCCESS;
410}
411
412static int kxtf9_init(void *mlsl_handle,
413 struct ext_slave_descr *slave,
414 struct ext_slave_platform_data *pdata)
415{
416
417 struct kxtf9_private_data *private_data;
418 int result = ML_SUCCESS;
419
420 private_data = (struct kxtf9_private_data *)
421 MLOSMalloc(sizeof(struct kxtf9_private_data));
422
423 if (!private_data)
424 return ML_ERROR_MEMORY_EXAUSTED;
425
426 /* RAM reset */
427 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
428 KXTF9_CTRL_REG1,
429 0x40); /* Fastest Reset */
430 ERROR_CHECK(result);
431 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
432 KXTF9_DATA_CTRL_REG,
433 0x36); /* Fastest Reset */
434 ERROR_CHECK(result);
435 result = MLSLSerialWriteSingle(mlsl_handle, pdata->address,
436 KXTF9_CTRL_REG3, 0xcd); /* Reset */
437 ERROR_CHECK(result);
438 MLOSSleep(2);
439
440 pdata->private_data = private_data;
441
442 private_data->resume.ctrl_reg1 = 0xC0;
443 private_data->suspend.ctrl_reg1 = 0x40;
444
445 result = kxtf9_set_dur(mlsl_handle, pdata, &private_data->suspend,
446 FALSE, 1000);
447 ERROR_CHECK(result);
448 result = kxtf9_set_dur(mlsl_handle, pdata, &private_data->resume,
449 FALSE, 2540);
450 ERROR_CHECK(result);
451
452 result = kxtf9_set_odr(mlsl_handle, pdata, &private_data->suspend,
453 FALSE, 50000);
454 ERROR_CHECK(result);
455 result = kxtf9_set_odr(mlsl_handle, pdata, &private_data->resume,
456 FALSE, 200000);
457
458 result = kxtf9_set_fsr(mlsl_handle, pdata, &private_data->suspend,
459 FALSE, 2000);
460 ERROR_CHECK(result);
461 result = kxtf9_set_fsr(mlsl_handle, pdata, &private_data->resume,
462 FALSE, 2000);
463 ERROR_CHECK(result);
464
465 result = kxtf9_set_ths(mlsl_handle, pdata, &private_data->suspend,
466 FALSE, 80);
467 ERROR_CHECK(result);
468 result = kxtf9_set_ths(mlsl_handle, pdata, &private_data->resume,
469 FALSE, 40);
470 ERROR_CHECK(result);
471
472 result = kxtf9_set_irq(mlsl_handle, pdata, &private_data->suspend,
473 FALSE,
474 MPU_SLAVE_IRQ_TYPE_NONE);
475 ERROR_CHECK(result);
476 result = kxtf9_set_irq(mlsl_handle, pdata, &private_data->resume,
477 FALSE,
478 MPU_SLAVE_IRQ_TYPE_NONE);
479 ERROR_CHECK(result);
480 return result;
481}
482
483static int kxtf9_exit(void *mlsl_handle,
484 struct ext_slave_descr *slave,
485 struct ext_slave_platform_data *pdata)
486{
487 if (pdata->private_data)
488 return MLOSFree(pdata->private_data);
489 else
490 return ML_SUCCESS;
491}
492
493static int kxtf9_config(void *mlsl_handle,
494 struct ext_slave_descr *slave,
495 struct ext_slave_platform_data *pdata,
496 struct ext_slave_config *data)
497{
498 int retval;
499 long odr;
500 struct kxtf9_private_data *private_data = pdata->private_data;
501 if (!data->data)
502 return ML_ERROR_INVALID_PARAMETER;
503
504 switch (data->key) {
505 case MPU_SLAVE_CONFIG_ODR_SUSPEND:
506 return kxtf9_set_odr(mlsl_handle, pdata,
507 &private_data->suspend,
508 data->apply,
509 *((long *)data->data));
510 case MPU_SLAVE_CONFIG_ODR_RESUME:
511 odr = *((long *)data->data);
512 if (odr != 0)
513 private_data->resume.ctrl_reg1 |= 0x80;
514
515 retval = kxtf9_set_odr(mlsl_handle, pdata,
516 &private_data->resume,
517 data->apply,
518 odr);
519 return retval;
520 case MPU_SLAVE_CONFIG_FSR_SUSPEND:
521 return kxtf9_set_fsr(mlsl_handle, pdata,
522 &private_data->suspend,
523 data->apply,
524 *((long *)data->data));
525 case MPU_SLAVE_CONFIG_FSR_RESUME:
526 return kxtf9_set_fsr(mlsl_handle, pdata,
527 &private_data->resume,
528 data->apply,
529 *((long *)data->data));
530 case MPU_SLAVE_CONFIG_MOT_THS:
531 return kxtf9_set_ths(mlsl_handle, pdata,
532 &private_data->suspend,
533 data->apply,
534 *((long *)data->data));
535 case MPU_SLAVE_CONFIG_NMOT_THS:
536 return kxtf9_set_ths(mlsl_handle, pdata,
537 &private_data->resume,
538 data->apply,
539 *((long *)data->data));
540 case MPU_SLAVE_CONFIG_MOT_DUR:
541 return kxtf9_set_dur(mlsl_handle, pdata,
542 &private_data->suspend,
543 data->apply,
544 *((long *)data->data));
545 case MPU_SLAVE_CONFIG_NMOT_DUR:
546 return kxtf9_set_dur(mlsl_handle, pdata,
547 &private_data->resume,
548 data->apply,
549 *((long *)data->data));
550 case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
551 return kxtf9_set_irq(mlsl_handle, pdata,
552 &private_data->suspend,
553 data->apply,
554 *((long *)data->data));
555 case MPU_SLAVE_CONFIG_IRQ_RESUME:
556 return kxtf9_set_irq(mlsl_handle, pdata,
557 &private_data->resume,
558 data->apply,
559 *((long *)data->data));
560 default:
561 return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
562 };
563
564 return ML_SUCCESS;
565}
566
567static int kxtf9_get_config(void *mlsl_handle,
568 struct ext_slave_descr *slave,
569 struct ext_slave_platform_data *pdata,
570 struct ext_slave_config *data)
571{
572 struct kxtf9_private_data *private_data = pdata->private_data;
573 if (!data->data)
574 return ML_ERROR_INVALID_PARAMETER;
575
576 switch (data->key) {
577 case MPU_SLAVE_CONFIG_ODR_SUSPEND:
578 (*(unsigned long *)data->data) =
579 (unsigned long) private_data->suspend.odr;
580 break;
581 case MPU_SLAVE_CONFIG_ODR_RESUME:
582 (*(unsigned long *)data->data) =
583 (unsigned long) private_data->resume.odr;
584 break;
585 case MPU_SLAVE_CONFIG_FSR_SUSPEND:
586 (*(unsigned long *)data->data) =
587 (unsigned long) private_data->suspend.fsr;
588 break;
589 case MPU_SLAVE_CONFIG_FSR_RESUME:
590 (*(unsigned long *)data->data) =
591 (unsigned long) private_data->resume.fsr;
592 break;
593 case MPU_SLAVE_CONFIG_MOT_THS:
594 (*(unsigned long *)data->data) =
595 (unsigned long) private_data->suspend.ths;
596 break;
597 case MPU_SLAVE_CONFIG_NMOT_THS:
598 (*(unsigned long *)data->data) =
599 (unsigned long) private_data->resume.ths;
600 break;
601 case MPU_SLAVE_CONFIG_MOT_DUR:
602 (*(unsigned long *)data->data) =
603 (unsigned long) private_data->suspend.dur;
604 break;
605 case MPU_SLAVE_CONFIG_NMOT_DUR:
606 (*(unsigned long *)data->data) =
607 (unsigned long) private_data->resume.dur;
608 break;
609 case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
610 (*(unsigned long *)data->data) =
611 (unsigned long) private_data->suspend.irq_type;
612 break;
613 case MPU_SLAVE_CONFIG_IRQ_RESUME:
614 (*(unsigned long *)data->data) =
615 (unsigned long) private_data->resume.irq_type;
616 break;
617 default:
618 return ML_ERROR_FEATURE_NOT_IMPLEMENTED;
619 };
620
621 return ML_SUCCESS;
622}
623
624static int kxtf9_read(void *mlsl_handle,
625 struct ext_slave_descr *slave,
626 struct ext_slave_platform_data *pdata,
627 unsigned char *data)
628{
629 int result;
630 unsigned char reg;
631 result = MLSLSerialRead(mlsl_handle, pdata->address,
632 KXTF9_INT_SRC_REG2, 1, &reg);
633 ERROR_CHECK(result);
634
635 if (!(reg & 0x10))
636 return ML_ERROR_ACCEL_DATA_NOT_READY;
637
638 result = MLSLSerialRead(mlsl_handle, pdata->address,
639 slave->reg, slave->len, data);
640 ERROR_CHECK(result);
641 return result;
642}
643
644static struct ext_slave_descr kxtf9_descr = {
645 /*.init = */ kxtf9_init,
646 /*.exit = */ kxtf9_exit,
647 /*.suspend = */ kxtf9_suspend,
648 /*.resume = */ kxtf9_resume,
649 /*.read = */ kxtf9_read,
650 /*.config = */ kxtf9_config,
651 /*.get_config = */ kxtf9_get_config,
652 /*.name = */ "kxtf9",
653 /*.type = */ EXT_SLAVE_TYPE_ACCELEROMETER,
654 /*.id = */ ACCEL_ID_KXTF9,
655 /*.reg = */ 0x06,
656 /*.len = */ 6,
657 /*.endian = */ EXT_SLAVE_LITTLE_ENDIAN,
658 /*.range = */ {2, 0},
659};
660
661struct ext_slave_descr *kxtf9_get_slave_descr(void)
662{
663 return &kxtf9_descr;
664}
665EXPORT_SYMBOL(kxtf9_get_slave_descr);
666
667/**
668 * @}
669**/