aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/inv_mpu/accel/bma250.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/bma250.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/misc/inv_mpu/accel/bma250.c')
-rw-r--r--drivers/misc/inv_mpu/accel/bma250.c787
1 files changed, 787 insertions, 0 deletions
diff --git a/drivers/misc/inv_mpu/accel/bma250.c b/drivers/misc/inv_mpu/accel/bma250.c
new file mode 100644
index 00000000000..6a245f4566a
--- /dev/null
+++ b/drivers/misc/inv_mpu/accel/bma250.c
@@ -0,0 +1,787 @@
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 Provides the interface to setup and handle an accelerometer.
23 *
24 * @{
25 * @file bma250.c
26 * @brief Accelerometer setup and handling methods for Bosch BMA250.
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 <linux/mpu.h>
41#include "mlsl.h"
42#include "mldl_cfg.h"
43
44/* -------------------------------------------------------------------------- */
45
46/* registers */
47#define BMA250_STATUS_REG (0x0A)
48#define BMA250_FSR_REG (0x0F)
49#define BMA250_ODR_REG (0x10)
50#define BMA250_PWR_REG (0x11)
51#define BMA250_SOFTRESET_REG (0x14)
52#define BMA250_INT_TYPE_REG (0x17)
53#define BMA250_INT_DST_REG (0x1A)
54#define BMA250_INT_SRC_REG (0x1E)
55
56/* masks */
57#define BMA250_STATUS_RDY_MASK (0x80)
58#define BMA250_FSR_MASK (0x0F)
59#define BMA250_ODR_MASK (0x1F)
60#define BMA250_PWR_SLEEP_MASK (0x80)
61#define BMA250_PWR_AWAKE_MASK (0x00)
62#define BMA250_SOFTRESET_MASK (0xB6)
63#define BMA250_INT_TYPE_MASK (0x10)
64#define BMA250_INT_DST_1_MASK (0x01)
65#define BMA250_INT_DST_2_MASK (0x80)
66#define BMA250_INT_SRC_MASK (0x00)
67
68/* -------------------------------------------------------------------------- */
69
70struct bma250_config {
71 unsigned int odr; /** < output data rate in mHz */
72 unsigned int fsr; /** < full scale range mg */
73 unsigned char irq_type;
74};
75
76struct bma250_private_data {
77 struct bma250_config suspend; /** < suspend configuration */
78 struct bma250_config resume; /** < resume configuration */
79};
80
81/* -------------------------------------------------------------------------- */
82/**
83 * @brief Sets the IRQ to fire when one of the IRQ events occur.
84 * Threshold and duration will not be used unless the type is MOT or
85 * NMOT.
86 *
87 * @param mlsl_handle
88 * the handle to the serial channel the device is connected to.
89 * @param pdata
90 * a pointer to the slave platform data.
91 * @param config
92 * configuration to apply to, suspend or resume
93 * @param apply
94 * whether to apply immediately or save the settings to be applied
95 * at the next resume.
96 * @param irq_type
97 * the type of IRQ. Valid values are
98 * - MPU_SLAVE_IRQ_TYPE_NONE
99 * - MPU_SLAVE_IRQ_TYPE_MOTION
100 * - MPU_SLAVE_IRQ_TYPE_DATA_READY
101 *
102 * @return INV_SUCCESS if successful or a non-zero error code.
103 */
104static int bma250_set_irq(void *mlsl_handle,
105 struct ext_slave_platform_data *pdata,
106 struct bma250_config *config,
107 int apply, long irq_type)
108{
109 int result = INV_SUCCESS;
110 unsigned char irqtype_reg;
111 unsigned char irqdst_reg;
112 unsigned char irqsrc_reg;
113
114 switch (irq_type) {
115 case MPU_SLAVE_IRQ_TYPE_DATA_READY:
116 /* data ready int. */
117 irqtype_reg = BMA250_INT_TYPE_MASK;
118 /* routed to interrupt pin 1 */
119 irqdst_reg = BMA250_INT_DST_1_MASK;
120 /* from filtered data */
121 irqsrc_reg = BMA250_INT_SRC_MASK;
122 break;
123 /* unfinished
124 case MPU_SLAVE_IRQ_TYPE_MOTION:
125 reg1 = 0x00;
126 reg2 = config->mot_int1_cfg;
127 reg3 = ;
128 break;
129 */
130 case MPU_SLAVE_IRQ_TYPE_NONE:
131 irqtype_reg = 0x00;
132 irqdst_reg = 0x00;
133 irqsrc_reg = 0x00;
134 break;
135 default:
136 return INV_ERROR_INVALID_PARAMETER;
137 break;
138 }
139
140 config->irq_type = (unsigned char)irq_type;
141
142 if (apply) {
143 /* select the type of interrupt to use */
144 result = inv_serial_single_write(mlsl_handle, pdata->address,
145 BMA250_INT_TYPE_REG, irqtype_reg);
146 if (result) {
147 LOG_RESULT_LOCATION(result);
148 return result;
149 }
150 /* select to which interrupt pin to route it to */
151 result = inv_serial_single_write(mlsl_handle, pdata->address,
152 BMA250_INT_DST_REG, irqdst_reg);
153 if (result) {
154 LOG_RESULT_LOCATION(result);
155 return result;
156 }
157 /* select whether the interrupt works off filtered or
158 unfiltered data */
159 result = inv_serial_single_write(mlsl_handle, pdata->address,
160 BMA250_INT_SRC_REG, irqsrc_reg);
161 if (result) {
162 LOG_RESULT_LOCATION(result);
163 return result;
164 }
165 }
166 return result;
167}
168
169/**
170 * @brief Set the output data rate for the particular configuration.
171 *
172 * @param mlsl_handle
173 * the handle to the serial channel the device is connected to.
174 * @param pdata
175 * a pointer to the slave platform data.
176 * @param config
177 * Config to modify with new ODR.
178 * @param apply
179 * whether to apply immediately or save the settings to be applied
180 * at the next resume.
181 * @param odr
182 * Output data rate in units of 1/1000Hz (mHz).
183 *
184 * @return INV_SUCCESS if successful or a non-zero error code.
185 */
186static int bma250_set_odr(void *mlsl_handle,
187 struct ext_slave_platform_data *pdata,
188 struct bma250_config *config,
189 int apply,
190 long odr)
191{
192 int result = INV_SUCCESS;
193 unsigned char reg_odr;
194
195 /* Table uses bandwidth which is half the sample rate */
196 odr = odr >> 1;
197 if (odr >= 1000000) {
198 reg_odr = 0x0F;
199 config->odr = 2000000;
200 } else if (odr >= 500000) {
201 reg_odr = 0x0E;
202 config->odr = 1000000;
203 } else if (odr >= 250000) {
204 reg_odr = 0x0D;
205 config->odr = 500000;
206 } else if (odr >= 125000) {
207 reg_odr = 0x0C;
208 config->odr = 250000;
209 } else if (odr >= 62500) {
210 reg_odr = 0x0B;
211 config->odr = 125000;
212 } else if (odr >= 31250) {
213 reg_odr = 0x0A;
214 config->odr = 62500;
215 } else if (odr >= 15630) {
216 reg_odr = 0x09;
217 config->odr = 31250;
218 } else {
219 reg_odr = 0x08;
220 config->odr = 15630;
221 }
222
223 if (apply) {
224 MPL_LOGV("ODR: %d\n", config->odr);
225 result = inv_serial_single_write(mlsl_handle, pdata->address,
226 BMA250_ODR_REG, reg_odr);
227 if (result) {
228 LOG_RESULT_LOCATION(result);
229 return result;
230 }
231 }
232
233 return result;
234}
235
236/**
237 * @brief Set the full scale range of the accels
238 *
239 * @param mlsl_handle
240 * the handle to the serial channel the device is connected to.
241 * @param pdata
242 * a pointer to the slave platform data.
243 * @param config
244 * pointer to configuration.
245 * @param apply
246 * whether to apply immediately or save the settings to be applied
247 * at the next resume.
248 * @param fsr
249 * requested full scale range.
250 *
251 * @return INV_SUCCESS if successful or a non-zero error code.
252 */
253static int bma250_set_fsr(void *mlsl_handle,
254 struct ext_slave_platform_data *pdata,
255 struct bma250_config *config,
256 int apply,
257 long fsr)
258{
259 int result = INV_SUCCESS;
260 unsigned char reg_fsr_mask;
261
262 if (fsr <= 2000) {
263 reg_fsr_mask = 0x03;
264 config->fsr = 2000;
265 } else if (fsr <= 4000) {
266 reg_fsr_mask = 0x05;
267 config->fsr = 4000;
268 } else if (fsr <= 8000) {
269 reg_fsr_mask = 0x08;
270 config->fsr = 8000;
271 } else { /* 8001 -> oo */
272 reg_fsr_mask = 0x0C;
273 config->fsr = 16000;
274 }
275
276 if (apply) {
277 MPL_LOGV("FSR: %d\n", config->fsr);
278 result = inv_serial_single_write(mlsl_handle, pdata->address,
279 BMA250_FSR_REG, reg_fsr_mask);
280 if (result) {
281 LOG_RESULT_LOCATION(result);
282 return result;
283 }
284 }
285 return result;
286}
287
288/**
289 * @brief one-time device driver initialization function.
290 * If the driver is built as a kernel module, this function will be
291 * called when the module is loaded in the kernel.
292 * If the driver is built-in in the kernel, this function will be
293 * called at boot time.
294 *
295 * @param mlsl_handle
296 * the handle to the serial channel the device is connected to.
297 * @param slave
298 * a pointer to the slave descriptor data structure.
299 * @param pdata
300 * a pointer to the slave platform data.
301 *
302 * @return INV_SUCCESS if successful or a non-zero error code.
303 */
304static int bma250_init(void *mlsl_handle,
305 struct ext_slave_descr *slave,
306 struct ext_slave_platform_data *pdata)
307{
308 int result;
309 long range;
310
311 struct bma250_private_data *private_data;
312 private_data = kzalloc(sizeof(struct bma250_private_data), GFP_KERNEL);
313
314 if (!private_data)
315 return INV_ERROR_MEMORY_EXAUSTED;
316
317 pdata->private_data = private_data;
318
319 result = inv_serial_single_write(mlsl_handle, pdata->address,
320 BMA250_SOFTRESET_REG, BMA250_SOFTRESET_MASK);
321 if (result) {
322 LOG_RESULT_LOCATION(result);
323 return result;
324 }
325 msleep(1);
326
327 result = bma250_set_odr(mlsl_handle, pdata, &private_data->suspend,
328 false, 0);
329 if (result) {
330 LOG_RESULT_LOCATION(result);
331 return result;
332 }
333 result = bma250_set_odr(mlsl_handle, pdata, &private_data->resume,
334 false, 200000);
335 if (result) {
336 LOG_RESULT_LOCATION(result);
337 return result;
338 }
339
340 range = range_fixedpoint_to_long_mg(slave->range);
341 result = bma250_set_fsr(mlsl_handle, pdata, &private_data->suspend,
342 false, range);
343 result = bma250_set_fsr(mlsl_handle, pdata, &private_data->resume,
344 false, range);
345 if (result) {
346 LOG_RESULT_LOCATION(result);
347 return result;
348 }
349
350 result = bma250_set_irq(mlsl_handle, pdata, &private_data->suspend,
351 false, MPU_SLAVE_IRQ_TYPE_NONE);
352 if (result) {
353 LOG_RESULT_LOCATION(result);
354 return result;
355 }
356 result = bma250_set_irq(mlsl_handle, pdata, &private_data->resume,
357 false, MPU_SLAVE_IRQ_TYPE_NONE);
358 if (result) {
359 LOG_RESULT_LOCATION(result);
360 return result;
361 }
362
363 result = inv_serial_single_write(mlsl_handle, pdata->address,
364 BMA250_PWR_REG, BMA250_PWR_SLEEP_MASK);
365 if (result) {
366 LOG_RESULT_LOCATION(result);
367 return result;
368 }
369
370 return result;
371}
372
373/**
374 * @brief one-time device driver exit function.
375 * If the driver is built as a kernel module, this function will be
376 * called when the module is removed from the kernel.
377 *
378 * @param mlsl_handle
379 * the handle to the serial channel the device is connected to.
380 * @param slave
381 * a pointer to the slave descriptor data structure.
382 * @param pdata
383 * a pointer to the slave platform data.
384 *
385 * @return INV_SUCCESS if successful or a non-zero error code.
386 */
387static int bma250_exit(void *mlsl_handle,
388 struct ext_slave_descr *slave,
389 struct ext_slave_platform_data *pdata)
390{
391 kfree(pdata->private_data);
392 return INV_SUCCESS;
393}
394
395/**
396 * @brief device configuration facility.
397 *
398 * @param mlsl_handle
399 * the handle to the serial channel the device is connected to.
400 * @param slave
401 * a pointer to the slave descriptor data structure.
402 * @param pdata
403 * a pointer to the slave platform data.
404 * @param data
405 * a pointer to the configuration data structure.
406 *
407 * @return INV_SUCCESS if successful or a non-zero error code.
408 */
409static int bma250_config(void *mlsl_handle,
410 struct ext_slave_descr *slave,
411 struct ext_slave_platform_data *pdata,
412 struct ext_slave_config *data)
413{
414 struct bma250_private_data *private_data =
415 (struct bma250_private_data *)(pdata->private_data);
416
417 if (!data->data)
418 return INV_ERROR_INVALID_PARAMETER;
419
420 switch (data->key) {
421 case MPU_SLAVE_CONFIG_ODR_SUSPEND:
422 return bma250_set_odr(mlsl_handle, pdata,
423 &private_data->suspend,
424 data->apply,
425 *((long *)data->data));
426 case MPU_SLAVE_CONFIG_ODR_RESUME:
427 return bma250_set_odr(mlsl_handle, pdata,
428 &private_data->resume,
429 data->apply,
430 *((long *)data->data));
431 case MPU_SLAVE_CONFIG_FSR_SUSPEND:
432 return bma250_set_fsr(mlsl_handle, pdata,
433 &private_data->suspend,
434 data->apply,
435 *((long *)data->data));
436 case MPU_SLAVE_CONFIG_FSR_RESUME:
437 return bma250_set_fsr(mlsl_handle, pdata,
438 &private_data->resume,
439 data->apply,
440 *((long *)data->data));
441 case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
442 return bma250_set_irq(mlsl_handle, pdata,
443 &private_data->suspend,
444 data->apply,
445 *((long *)data->data));
446 case MPU_SLAVE_CONFIG_IRQ_RESUME:
447 return bma250_set_irq(mlsl_handle, pdata,
448 &private_data->resume,
449 data->apply,
450 *((long *)data->data));
451 default:
452 return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
453 };
454 return INV_SUCCESS;
455}
456
457/**
458 * @brief facility to retrieve the device configuration.
459 *
460 * @param mlsl_handle
461 * the handle to the serial channel the device is connected to.
462 * @param slave
463 * a pointer to the slave descriptor data structure.
464 * @param pdata
465 * a pointer to the slave platform data.
466 * @param data
467 * a pointer to store the returned configuration data structure.
468 *
469 * @return INV_SUCCESS if successful or a non-zero error code.
470 */
471static int bma250_get_config(void *mlsl_handle,
472 struct ext_slave_descr *slave,
473 struct ext_slave_platform_data *pdata,
474 struct ext_slave_config *data)
475{
476 struct bma250_private_data *private_data =
477 (struct bma250_private_data *)(pdata->private_data);
478
479 if (!data->data)
480 return INV_ERROR_INVALID_PARAMETER;
481
482 switch (data->key) {
483 case MPU_SLAVE_CONFIG_ODR_SUSPEND:
484 (*(unsigned long *)data->data) =
485 (unsigned long) private_data->suspend.odr;
486 break;
487 case MPU_SLAVE_CONFIG_ODR_RESUME:
488 (*(unsigned long *)data->data) =
489 (unsigned long) private_data->resume.odr;
490 break;
491 case MPU_SLAVE_CONFIG_FSR_SUSPEND:
492 (*(unsigned long *)data->data) =
493 (unsigned long) private_data->suspend.fsr;
494 break;
495 case MPU_SLAVE_CONFIG_FSR_RESUME:
496 (*(unsigned long *)data->data) =
497 (unsigned long) private_data->resume.fsr;
498 break;
499 case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
500 (*(unsigned long *)data->data) =
501 (unsigned long) private_data->suspend.irq_type;
502 break;
503 case MPU_SLAVE_CONFIG_IRQ_RESUME:
504 (*(unsigned long *)data->data) =
505 (unsigned long) private_data->resume.irq_type;
506 break;
507 default:
508 return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
509 };
510
511 return INV_SUCCESS;
512}
513
514/**
515 * @brief suspends the device to put it in its lowest power mode.
516 *
517 * @param mlsl_handle
518 * the handle to the serial channel the device is connected to.
519 * @param slave
520 * a pointer to the slave descriptor data structure.
521 * @param pdata
522 * a pointer to the slave platform data.
523 *
524 * @return INV_SUCCESS if successful or a non-zero error code.
525 */
526static int bma250_suspend(void *mlsl_handle,
527 struct ext_slave_descr *slave,
528 struct ext_slave_platform_data *pdata)
529{
530 int result;
531 struct bma250_config *suspend_config =
532 &((struct bma250_private_data *)pdata->private_data)->suspend;
533
534 result = bma250_set_odr(mlsl_handle, pdata, suspend_config,
535 true, suspend_config->odr);
536 if (result) {
537 LOG_RESULT_LOCATION(result);
538 return result;
539 }
540 result = bma250_set_fsr(mlsl_handle, pdata, suspend_config,
541 true, suspend_config->fsr);
542 if (result) {
543 LOG_RESULT_LOCATION(result);
544 return result;
545 }
546 result = bma250_set_irq(mlsl_handle, pdata, suspend_config,
547 true, suspend_config->irq_type);
548 if (result) {
549 LOG_RESULT_LOCATION(result);
550 return result;
551 }
552
553 result = inv_serial_single_write(mlsl_handle, pdata->address,
554 BMA250_PWR_REG, BMA250_PWR_SLEEP_MASK);
555 if (result) {
556 LOG_RESULT_LOCATION(result);
557 return result;
558 }
559
560 msleep(3); /* 3 ms powerup time maximum */
561 return result;
562}
563
564/**
565 * @brief resume the device in the proper power state given the configuration
566 * chosen.
567 *
568 * @param mlsl_handle
569 * the handle to the serial channel the device is connected to.
570 * @param slave
571 * a pointer to the slave descriptor data structure.
572 * @param pdata
573 * a pointer to the slave platform data.
574 *
575 * @return INV_SUCCESS if successful or a non-zero error code.
576 */
577static int bma250_resume(void *mlsl_handle,
578 struct ext_slave_descr *slave,
579 struct ext_slave_platform_data *pdata)
580{
581 int result;
582 struct bma250_config *resume_config =
583 &((struct bma250_private_data *)pdata->private_data)->resume;
584
585 result = bma250_set_odr(mlsl_handle, pdata, resume_config,
586 true, resume_config->odr);
587 if (result) {
588 LOG_RESULT_LOCATION(result);
589 return result;
590 }
591 result = bma250_set_fsr(mlsl_handle, pdata, resume_config,
592 true, resume_config->fsr);
593 if (result) {
594 LOG_RESULT_LOCATION(result);
595 return result;
596 }
597 result = bma250_set_irq(mlsl_handle, pdata, resume_config,
598 true, resume_config->irq_type);
599 if (result) {
600 LOG_RESULT_LOCATION(result);
601 return result;
602 }
603
604 result = inv_serial_single_write(mlsl_handle, pdata->address,
605 BMA250_PWR_REG, BMA250_PWR_AWAKE_MASK);
606 if (result) {
607 LOG_RESULT_LOCATION(result);
608 return result;
609 }
610
611 return result;
612}
613
614/**
615 * @brief read the sensor data from the device.
616 *
617 * @param mlsl_handle
618 * the handle to the serial channel the device is connected to.
619 * @param slave
620 * a pointer to the slave descriptor data structure.
621 * @param pdata
622 * a pointer to the slave platform data.
623 * @param data
624 * a buffer to store the data read.
625 *
626 * @return INV_SUCCESS if successful or a non-zero error code.
627 */
628static int bma250_read(void *mlsl_handle,
629 struct ext_slave_descr *slave,
630 struct ext_slave_platform_data *pdata,
631 unsigned char *data)
632{
633 int result = INV_SUCCESS;
634 result = inv_serial_read(mlsl_handle, pdata->address,
635 BMA250_STATUS_REG, 1, data);
636 if (1) { /* KLP - workaroud for small data ready window */
637 result = inv_serial_read(mlsl_handle, pdata->address,
638 slave->read_reg, slave->read_len, data);
639 return result;
640 } else
641 return INV_ERROR_ACCEL_DATA_NOT_READY;
642}
643
644static struct ext_slave_descr bma250_descr = {
645 .init = bma250_init,
646 .exit = bma250_exit,
647 .suspend = bma250_suspend,
648 .resume = bma250_resume,
649 .read = bma250_read,
650 .config = bma250_config,
651 .get_config = bma250_get_config,
652 .name = "bma250",
653 .type = EXT_SLAVE_TYPE_ACCEL,
654 .id = ACCEL_ID_BMA250,
655 .read_reg = 0x02,
656 .read_len = 6,
657 .endian = EXT_SLAVE_LITTLE_ENDIAN,
658 .range = {2, 0},
659 .trigger = NULL,
660};
661
662static
663struct ext_slave_descr *bma250_get_slave_descr(void)
664{
665 return &bma250_descr;
666}
667
668/* -------------------------------------------------------------------------- */
669
670/* Platform data for the MPU */
671struct bma250_mod_private_data {
672 struct i2c_client *client;
673 struct ext_slave_platform_data *pdata;
674};
675
676static unsigned short normal_i2c[] = { I2C_CLIENT_END };
677
678static int bma250_mod_probe(struct i2c_client *client,
679 const struct i2c_device_id *devid)
680{
681 struct ext_slave_platform_data *pdata;
682 struct bma250_mod_private_data *private_data;
683 int result = 0;
684
685 dev_info(&client->adapter->dev, "%s: %s\n", __func__, devid->name);
686
687 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
688 result = -ENODEV;
689 goto out_no_free;
690 }
691
692 pdata = client->dev.platform_data;
693 if (!pdata) {
694 dev_err(&client->adapter->dev,
695 "Missing platform data for slave %s\n", devid->name);
696 result = -EFAULT;
697 goto out_no_free;
698 }
699
700 private_data = kzalloc(sizeof(*private_data), GFP_KERNEL);
701 if (!private_data) {
702 result = -ENOMEM;
703 goto out_no_free;
704 }
705
706 i2c_set_clientdata(client, private_data);
707 private_data->client = client;
708 private_data->pdata = pdata;
709
710 result = inv_mpu_register_slave(THIS_MODULE, client, pdata,
711 bma250_get_slave_descr);
712 if (result) {
713 dev_err(&client->adapter->dev,
714 "Slave registration failed: %s, %d\n",
715 devid->name, result);
716 goto out_free_memory;
717 }
718
719 return result;
720
721out_free_memory:
722 kfree(private_data);
723out_no_free:
724 dev_err(&client->adapter->dev, "%s failed %d\n", __func__, result);
725 return result;
726
727}
728
729static int bma250_mod_remove(struct i2c_client *client)
730{
731 struct bma250_mod_private_data *private_data =
732 i2c_get_clientdata(client);
733
734 dev_dbg(&client->adapter->dev, "%s\n", __func__);
735
736 inv_mpu_unregister_slave(client, private_data->pdata,
737 bma250_get_slave_descr);
738
739 kfree(private_data);
740 return 0;
741}
742
743static const struct i2c_device_id bma250_mod_id[] = {
744 { "bma250", ACCEL_ID_BMA250 },
745 {}
746};
747
748MODULE_DEVICE_TABLE(i2c, bma250_mod_id);
749
750static struct i2c_driver bma250_mod_driver = {
751 .class = I2C_CLASS_HWMON,
752 .probe = bma250_mod_probe,
753 .remove = bma250_mod_remove,
754 .id_table = bma250_mod_id,
755 .driver = {
756 .owner = THIS_MODULE,
757 .name = "bma250_mod",
758 },
759 .address_list = normal_i2c,
760};
761
762static int __init bma250_mod_init(void)
763{
764 int res = i2c_add_driver(&bma250_mod_driver);
765 pr_info("%s: Probe name %s\n", __func__, "bma250_mod");
766 if (res)
767 pr_err("%s failed\n", __func__);
768 return res;
769}
770
771static void __exit bma250_mod_exit(void)
772{
773 pr_info("%s\n", __func__);
774 i2c_del_driver(&bma250_mod_driver);
775}
776
777module_init(bma250_mod_init);
778module_exit(bma250_mod_exit);
779
780MODULE_AUTHOR("Invensense Corporation");
781MODULE_DESCRIPTION("Driver to integrate BMA250 sensor with the MPU");
782MODULE_LICENSE("GPL");
783MODULE_ALIAS("bma250_mod");
784
785/**
786 * @}
787 */