| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * 3-axis accelerometer driver for MXC4005XC Memsic sensor |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2014, Intel Corporation. |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 8 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | 6 | */ |
|---|
| 15 | 7 | |
|---|
| 16 | 8 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 64 | 56 | struct mutex mutex; |
|---|
| 65 | 57 | struct regmap *regmap; |
|---|
| 66 | 58 | struct iio_trigger *dready_trig; |
|---|
| 67 | | - __be16 buffer[8]; |
|---|
| 59 | + /* Ensure timestamp is naturally aligned */ |
|---|
| 60 | + struct { |
|---|
| 61 | + __be16 chans[3]; |
|---|
| 62 | + s64 timestamp __aligned(8); |
|---|
| 63 | + } scan; |
|---|
| 68 | 64 | bool trigger_enabled; |
|---|
| 69 | 65 | }; |
|---|
| 70 | 66 | |
|---|
| .. | .. |
|---|
| 143 | 139 | int ret; |
|---|
| 144 | 140 | |
|---|
| 145 | 141 | ret = regmap_bulk_read(data->regmap, MXC4005_REG_XOUT_UPPER, |
|---|
| 146 | | - (u8 *) data->buffer, sizeof(data->buffer)); |
|---|
| 142 | + data->scan.chans, sizeof(data->scan.chans)); |
|---|
| 147 | 143 | if (ret < 0) { |
|---|
| 148 | 144 | dev_err(data->dev, "failed to read axes\n"); |
|---|
| 149 | 145 | return ret; |
|---|
| .. | .. |
|---|
| 158 | 154 | __be16 reg; |
|---|
| 159 | 155 | int ret; |
|---|
| 160 | 156 | |
|---|
| 161 | | - ret = regmap_bulk_read(data->regmap, addr, (u8 *) ®, sizeof(reg)); |
|---|
| 157 | + ret = regmap_bulk_read(data->regmap, addr, ®, sizeof(reg)); |
|---|
| 162 | 158 | if (ret < 0) { |
|---|
| 163 | 159 | dev_err(data->dev, "failed to read reg %02x\n", addr); |
|---|
| 164 | 160 | return ret; |
|---|
| .. | .. |
|---|
| 309 | 305 | if (ret < 0) |
|---|
| 310 | 306 | goto err; |
|---|
| 311 | 307 | |
|---|
| 312 | | - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, |
|---|
| 308 | + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, |
|---|
| 313 | 309 | pf->timestamp); |
|---|
| 314 | 310 | |
|---|
| 315 | 311 | err: |
|---|
| .. | .. |
|---|
| 424 | 420 | |
|---|
| 425 | 421 | mutex_init(&data->mutex); |
|---|
| 426 | 422 | |
|---|
| 427 | | - indio_dev->dev.parent = &client->dev; |
|---|
| 428 | 423 | indio_dev->channels = mxc4005_channels; |
|---|
| 429 | 424 | indio_dev->num_channels = ARRAY_SIZE(mxc4005_channels); |
|---|
| 430 | 425 | indio_dev->available_scan_masks = mxc4005_scan_masks; |
|---|
| .. | .. |
|---|
| 432 | 427 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 433 | 428 | indio_dev->info = &mxc4005_info; |
|---|
| 434 | 429 | |
|---|
| 435 | | - ret = iio_triggered_buffer_setup(indio_dev, |
|---|
| 430 | + ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, |
|---|
| 436 | 431 | iio_pollfunc_store_time, |
|---|
| 437 | 432 | mxc4005_trigger_handler, |
|---|
| 438 | 433 | NULL); |
|---|
| .. | .. |
|---|
| 460 | 455 | if (ret) { |
|---|
| 461 | 456 | dev_err(&client->dev, |
|---|
| 462 | 457 | "failed to init threaded irq\n"); |
|---|
| 463 | | - goto err_buffer_cleanup; |
|---|
| 458 | + return ret; |
|---|
| 464 | 459 | } |
|---|
| 465 | 460 | |
|---|
| 466 | 461 | data->dready_trig->dev.parent = &client->dev; |
|---|
| 467 | 462 | data->dready_trig->ops = &mxc4005_trigger_ops; |
|---|
| 468 | 463 | iio_trigger_set_drvdata(data->dready_trig, indio_dev); |
|---|
| 469 | | - indio_dev->trig = data->dready_trig; |
|---|
| 470 | | - iio_trigger_get(indio_dev->trig); |
|---|
| 471 | | - ret = iio_trigger_register(data->dready_trig); |
|---|
| 464 | + ret = devm_iio_trigger_register(&client->dev, |
|---|
| 465 | + data->dready_trig); |
|---|
| 472 | 466 | if (ret) { |
|---|
| 473 | 467 | dev_err(&client->dev, |
|---|
| 474 | 468 | "failed to register trigger\n"); |
|---|
| 475 | | - goto err_trigger_unregister; |
|---|
| 469 | + return ret; |
|---|
| 476 | 470 | } |
|---|
| 471 | + |
|---|
| 472 | + indio_dev->trig = iio_trigger_get(data->dready_trig); |
|---|
| 477 | 473 | } |
|---|
| 478 | 474 | |
|---|
| 479 | | - ret = iio_device_register(indio_dev); |
|---|
| 480 | | - if (ret < 0) { |
|---|
| 481 | | - dev_err(&client->dev, |
|---|
| 482 | | - "unable to register iio device %d\n", ret); |
|---|
| 483 | | - goto err_buffer_cleanup; |
|---|
| 484 | | - } |
|---|
| 485 | | - |
|---|
| 486 | | - return 0; |
|---|
| 487 | | - |
|---|
| 488 | | -err_trigger_unregister: |
|---|
| 489 | | - iio_trigger_unregister(data->dready_trig); |
|---|
| 490 | | -err_buffer_cleanup: |
|---|
| 491 | | - iio_triggered_buffer_cleanup(indio_dev); |
|---|
| 492 | | - |
|---|
| 493 | | - return ret; |
|---|
| 494 | | -} |
|---|
| 495 | | - |
|---|
| 496 | | -static int mxc4005_remove(struct i2c_client *client) |
|---|
| 497 | | -{ |
|---|
| 498 | | - struct iio_dev *indio_dev = i2c_get_clientdata(client); |
|---|
| 499 | | - struct mxc4005_data *data = iio_priv(indio_dev); |
|---|
| 500 | | - |
|---|
| 501 | | - iio_device_unregister(indio_dev); |
|---|
| 502 | | - |
|---|
| 503 | | - iio_triggered_buffer_cleanup(indio_dev); |
|---|
| 504 | | - if (data->dready_trig) |
|---|
| 505 | | - iio_trigger_unregister(data->dready_trig); |
|---|
| 506 | | - |
|---|
| 507 | | - return 0; |
|---|
| 475 | + return devm_iio_device_register(&client->dev, indio_dev); |
|---|
| 508 | 476 | } |
|---|
| 509 | 477 | |
|---|
| 510 | 478 | static const struct acpi_device_id mxc4005_acpi_match[] = { |
|---|
| 511 | 479 | {"MXC4005", 0}, |
|---|
| 480 | + {"MXC6655", 0}, |
|---|
| 512 | 481 | { }, |
|---|
| 513 | 482 | }; |
|---|
| 514 | 483 | MODULE_DEVICE_TABLE(acpi, mxc4005_acpi_match); |
|---|
| 515 | 484 | |
|---|
| 516 | 485 | static const struct i2c_device_id mxc4005_id[] = { |
|---|
| 517 | 486 | {"mxc4005", 0}, |
|---|
| 487 | + {"mxc6655", 0}, |
|---|
| 518 | 488 | { }, |
|---|
| 519 | 489 | }; |
|---|
| 520 | 490 | MODULE_DEVICE_TABLE(i2c, mxc4005_id); |
|---|
| .. | .. |
|---|
| 525 | 495 | .acpi_match_table = ACPI_PTR(mxc4005_acpi_match), |
|---|
| 526 | 496 | }, |
|---|
| 527 | 497 | .probe = mxc4005_probe, |
|---|
| 528 | | - .remove = mxc4005_remove, |
|---|
| 529 | 498 | .id_table = mxc4005_id, |
|---|
| 530 | 499 | }; |
|---|
| 531 | 500 | |
|---|