18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * mpl3115.c - Support for Freescale MPL3115A2 pressure/temperature sensor 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * (7-bit I2C slave address 0x60) 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * TODO: FIFO buffer, altimeter mode, oversampling, continuous mode, 108c2ecf20Sopenharmony_ci * interrupts, user offset correction, raw mode 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/i2c.h> 158c2ecf20Sopenharmony_ci#include <linux/iio/iio.h> 168c2ecf20Sopenharmony_ci#include <linux/iio/sysfs.h> 178c2ecf20Sopenharmony_ci#include <linux/iio/trigger_consumer.h> 188c2ecf20Sopenharmony_ci#include <linux/iio/buffer.h> 198c2ecf20Sopenharmony_ci#include <linux/iio/triggered_buffer.h> 208c2ecf20Sopenharmony_ci#include <linux/delay.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define MPL3115_STATUS 0x00 238c2ecf20Sopenharmony_ci#define MPL3115_OUT_PRESS 0x01 /* MSB first, 20 bit */ 248c2ecf20Sopenharmony_ci#define MPL3115_OUT_TEMP 0x04 /* MSB first, 12 bit */ 258c2ecf20Sopenharmony_ci#define MPL3115_WHO_AM_I 0x0c 268c2ecf20Sopenharmony_ci#define MPL3115_CTRL_REG1 0x26 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define MPL3115_DEVICE_ID 0xc4 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define MPL3115_STATUS_PRESS_RDY BIT(2) 318c2ecf20Sopenharmony_ci#define MPL3115_STATUS_TEMP_RDY BIT(1) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define MPL3115_CTRL_RESET BIT(2) /* software reset */ 348c2ecf20Sopenharmony_ci#define MPL3115_CTRL_OST BIT(1) /* initiate measurement */ 358c2ecf20Sopenharmony_ci#define MPL3115_CTRL_ACTIVE BIT(0) /* continuous measurement */ 368c2ecf20Sopenharmony_ci#define MPL3115_CTRL_OS_258MS (BIT(5) | BIT(4)) /* 64x oversampling */ 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistruct mpl3115_data { 398c2ecf20Sopenharmony_ci struct i2c_client *client; 408c2ecf20Sopenharmony_ci struct mutex lock; 418c2ecf20Sopenharmony_ci u8 ctrl_reg1; 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_cistatic int mpl3115_request(struct mpl3115_data *data) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci int ret, tries = 15; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci /* trigger measurement */ 498c2ecf20Sopenharmony_ci ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, 508c2ecf20Sopenharmony_ci data->ctrl_reg1 | MPL3115_CTRL_OST); 518c2ecf20Sopenharmony_ci if (ret < 0) 528c2ecf20Sopenharmony_ci return ret; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci while (tries-- > 0) { 558c2ecf20Sopenharmony_ci ret = i2c_smbus_read_byte_data(data->client, MPL3115_CTRL_REG1); 568c2ecf20Sopenharmony_ci if (ret < 0) 578c2ecf20Sopenharmony_ci return ret; 588c2ecf20Sopenharmony_ci /* wait for data ready, i.e. OST cleared */ 598c2ecf20Sopenharmony_ci if (!(ret & MPL3115_CTRL_OST)) 608c2ecf20Sopenharmony_ci break; 618c2ecf20Sopenharmony_ci msleep(20); 628c2ecf20Sopenharmony_ci } 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci if (tries < 0) { 658c2ecf20Sopenharmony_ci dev_err(&data->client->dev, "data not ready\n"); 668c2ecf20Sopenharmony_ci return -EIO; 678c2ecf20Sopenharmony_ci } 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci return 0; 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic int mpl3115_read_raw(struct iio_dev *indio_dev, 738c2ecf20Sopenharmony_ci struct iio_chan_spec const *chan, 748c2ecf20Sopenharmony_ci int *val, int *val2, long mask) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci struct mpl3115_data *data = iio_priv(indio_dev); 778c2ecf20Sopenharmony_ci __be32 tmp = 0; 788c2ecf20Sopenharmony_ci int ret; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci switch (mask) { 818c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_RAW: 828c2ecf20Sopenharmony_ci ret = iio_device_claim_direct_mode(indio_dev); 838c2ecf20Sopenharmony_ci if (ret) 848c2ecf20Sopenharmony_ci return ret; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci switch (chan->type) { 878c2ecf20Sopenharmony_ci case IIO_PRESSURE: /* in 0.25 pascal / LSB */ 888c2ecf20Sopenharmony_ci mutex_lock(&data->lock); 898c2ecf20Sopenharmony_ci ret = mpl3115_request(data); 908c2ecf20Sopenharmony_ci if (ret < 0) { 918c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 928c2ecf20Sopenharmony_ci break; 938c2ecf20Sopenharmony_ci } 948c2ecf20Sopenharmony_ci ret = i2c_smbus_read_i2c_block_data(data->client, 958c2ecf20Sopenharmony_ci MPL3115_OUT_PRESS, 3, (u8 *) &tmp); 968c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 978c2ecf20Sopenharmony_ci if (ret < 0) 988c2ecf20Sopenharmony_ci break; 998c2ecf20Sopenharmony_ci *val = be32_to_cpu(tmp) >> 12; 1008c2ecf20Sopenharmony_ci ret = IIO_VAL_INT; 1018c2ecf20Sopenharmony_ci break; 1028c2ecf20Sopenharmony_ci case IIO_TEMP: /* in 0.0625 celsius / LSB */ 1038c2ecf20Sopenharmony_ci mutex_lock(&data->lock); 1048c2ecf20Sopenharmony_ci ret = mpl3115_request(data); 1058c2ecf20Sopenharmony_ci if (ret < 0) { 1068c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1078c2ecf20Sopenharmony_ci break; 1088c2ecf20Sopenharmony_ci } 1098c2ecf20Sopenharmony_ci ret = i2c_smbus_read_i2c_block_data(data->client, 1108c2ecf20Sopenharmony_ci MPL3115_OUT_TEMP, 2, (u8 *) &tmp); 1118c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1128c2ecf20Sopenharmony_ci if (ret < 0) 1138c2ecf20Sopenharmony_ci break; 1148c2ecf20Sopenharmony_ci *val = sign_extend32(be32_to_cpu(tmp) >> 20, 11); 1158c2ecf20Sopenharmony_ci ret = IIO_VAL_INT; 1168c2ecf20Sopenharmony_ci break; 1178c2ecf20Sopenharmony_ci default: 1188c2ecf20Sopenharmony_ci ret = -EINVAL; 1198c2ecf20Sopenharmony_ci break; 1208c2ecf20Sopenharmony_ci } 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci iio_device_release_direct_mode(indio_dev); 1238c2ecf20Sopenharmony_ci return ret; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_SCALE: 1268c2ecf20Sopenharmony_ci switch (chan->type) { 1278c2ecf20Sopenharmony_ci case IIO_PRESSURE: 1288c2ecf20Sopenharmony_ci *val = 0; 1298c2ecf20Sopenharmony_ci *val2 = 250; /* want kilopascal */ 1308c2ecf20Sopenharmony_ci return IIO_VAL_INT_PLUS_MICRO; 1318c2ecf20Sopenharmony_ci case IIO_TEMP: 1328c2ecf20Sopenharmony_ci *val = 0; 1338c2ecf20Sopenharmony_ci *val2 = 62500; 1348c2ecf20Sopenharmony_ci return IIO_VAL_INT_PLUS_MICRO; 1358c2ecf20Sopenharmony_ci default: 1368c2ecf20Sopenharmony_ci return -EINVAL; 1378c2ecf20Sopenharmony_ci } 1388c2ecf20Sopenharmony_ci } 1398c2ecf20Sopenharmony_ci return -EINVAL; 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic irqreturn_t mpl3115_trigger_handler(int irq, void *p) 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci struct iio_poll_func *pf = p; 1458c2ecf20Sopenharmony_ci struct iio_dev *indio_dev = pf->indio_dev; 1468c2ecf20Sopenharmony_ci struct mpl3115_data *data = iio_priv(indio_dev); 1478c2ecf20Sopenharmony_ci /* 1488c2ecf20Sopenharmony_ci * 32-bit channel + 16-bit channel + padding + ts 1498c2ecf20Sopenharmony_ci * Note that it is possible for only one of the first 2 1508c2ecf20Sopenharmony_ci * channels to be enabled. If that happens, the first element 1518c2ecf20Sopenharmony_ci * of the buffer may be either 16 or 32-bits. As such we cannot 1528c2ecf20Sopenharmony_ci * use a simple structure definition to express this data layout. 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_ci u8 buffer[16] __aligned(8); 1558c2ecf20Sopenharmony_ci int ret, pos = 0; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci mutex_lock(&data->lock); 1588c2ecf20Sopenharmony_ci ret = mpl3115_request(data); 1598c2ecf20Sopenharmony_ci if (ret < 0) { 1608c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1618c2ecf20Sopenharmony_ci goto done; 1628c2ecf20Sopenharmony_ci } 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci memset(buffer, 0, sizeof(buffer)); 1658c2ecf20Sopenharmony_ci if (test_bit(0, indio_dev->active_scan_mask)) { 1668c2ecf20Sopenharmony_ci ret = i2c_smbus_read_i2c_block_data(data->client, 1678c2ecf20Sopenharmony_ci MPL3115_OUT_PRESS, 3, &buffer[pos]); 1688c2ecf20Sopenharmony_ci if (ret < 0) { 1698c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1708c2ecf20Sopenharmony_ci goto done; 1718c2ecf20Sopenharmony_ci } 1728c2ecf20Sopenharmony_ci pos += 4; 1738c2ecf20Sopenharmony_ci } 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci if (test_bit(1, indio_dev->active_scan_mask)) { 1768c2ecf20Sopenharmony_ci ret = i2c_smbus_read_i2c_block_data(data->client, 1778c2ecf20Sopenharmony_ci MPL3115_OUT_TEMP, 2, &buffer[pos]); 1788c2ecf20Sopenharmony_ci if (ret < 0) { 1798c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1808c2ecf20Sopenharmony_ci goto done; 1818c2ecf20Sopenharmony_ci } 1828c2ecf20Sopenharmony_ci } 1838c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci iio_push_to_buffers_with_timestamp(indio_dev, buffer, 1868c2ecf20Sopenharmony_ci iio_get_time_ns(indio_dev)); 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_cidone: 1898c2ecf20Sopenharmony_ci iio_trigger_notify_done(indio_dev->trig); 1908c2ecf20Sopenharmony_ci return IRQ_HANDLED; 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic const struct iio_chan_spec mpl3115_channels[] = { 1948c2ecf20Sopenharmony_ci { 1958c2ecf20Sopenharmony_ci .type = IIO_PRESSURE, 1968c2ecf20Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 1978c2ecf20Sopenharmony_ci .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), 1988c2ecf20Sopenharmony_ci .scan_index = 0, 1998c2ecf20Sopenharmony_ci .scan_type = { 2008c2ecf20Sopenharmony_ci .sign = 'u', 2018c2ecf20Sopenharmony_ci .realbits = 20, 2028c2ecf20Sopenharmony_ci .storagebits = 32, 2038c2ecf20Sopenharmony_ci .shift = 12, 2048c2ecf20Sopenharmony_ci .endianness = IIO_BE, 2058c2ecf20Sopenharmony_ci } 2068c2ecf20Sopenharmony_ci }, 2078c2ecf20Sopenharmony_ci { 2088c2ecf20Sopenharmony_ci .type = IIO_TEMP, 2098c2ecf20Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 2108c2ecf20Sopenharmony_ci .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), 2118c2ecf20Sopenharmony_ci .scan_index = 1, 2128c2ecf20Sopenharmony_ci .scan_type = { 2138c2ecf20Sopenharmony_ci .sign = 's', 2148c2ecf20Sopenharmony_ci .realbits = 12, 2158c2ecf20Sopenharmony_ci .storagebits = 16, 2168c2ecf20Sopenharmony_ci .shift = 4, 2178c2ecf20Sopenharmony_ci .endianness = IIO_BE, 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci }, 2208c2ecf20Sopenharmony_ci IIO_CHAN_SOFT_TIMESTAMP(2), 2218c2ecf20Sopenharmony_ci}; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_cistatic const struct iio_info mpl3115_info = { 2248c2ecf20Sopenharmony_ci .read_raw = &mpl3115_read_raw, 2258c2ecf20Sopenharmony_ci}; 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic int mpl3115_probe(struct i2c_client *client, 2288c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci struct mpl3115_data *data; 2318c2ecf20Sopenharmony_ci struct iio_dev *indio_dev; 2328c2ecf20Sopenharmony_ci int ret; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci ret = i2c_smbus_read_byte_data(client, MPL3115_WHO_AM_I); 2358c2ecf20Sopenharmony_ci if (ret < 0) 2368c2ecf20Sopenharmony_ci return ret; 2378c2ecf20Sopenharmony_ci if (ret != MPL3115_DEVICE_ID) 2388c2ecf20Sopenharmony_ci return -ENODEV; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 2418c2ecf20Sopenharmony_ci if (!indio_dev) 2428c2ecf20Sopenharmony_ci return -ENOMEM; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci data = iio_priv(indio_dev); 2458c2ecf20Sopenharmony_ci data->client = client; 2468c2ecf20Sopenharmony_ci mutex_init(&data->lock); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci i2c_set_clientdata(client, indio_dev); 2498c2ecf20Sopenharmony_ci indio_dev->info = &mpl3115_info; 2508c2ecf20Sopenharmony_ci indio_dev->name = id->name; 2518c2ecf20Sopenharmony_ci indio_dev->modes = INDIO_DIRECT_MODE; 2528c2ecf20Sopenharmony_ci indio_dev->channels = mpl3115_channels; 2538c2ecf20Sopenharmony_ci indio_dev->num_channels = ARRAY_SIZE(mpl3115_channels); 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci /* software reset, I2C transfer is aborted (fails) */ 2568c2ecf20Sopenharmony_ci i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1, 2578c2ecf20Sopenharmony_ci MPL3115_CTRL_RESET); 2588c2ecf20Sopenharmony_ci msleep(50); 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci data->ctrl_reg1 = MPL3115_CTRL_OS_258MS; 2618c2ecf20Sopenharmony_ci ret = i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1, 2628c2ecf20Sopenharmony_ci data->ctrl_reg1); 2638c2ecf20Sopenharmony_ci if (ret < 0) 2648c2ecf20Sopenharmony_ci return ret; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci ret = iio_triggered_buffer_setup(indio_dev, NULL, 2678c2ecf20Sopenharmony_ci mpl3115_trigger_handler, NULL); 2688c2ecf20Sopenharmony_ci if (ret < 0) 2698c2ecf20Sopenharmony_ci return ret; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci ret = iio_device_register(indio_dev); 2728c2ecf20Sopenharmony_ci if (ret < 0) 2738c2ecf20Sopenharmony_ci goto buffer_cleanup; 2748c2ecf20Sopenharmony_ci return 0; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_cibuffer_cleanup: 2778c2ecf20Sopenharmony_ci iio_triggered_buffer_cleanup(indio_dev); 2788c2ecf20Sopenharmony_ci return ret; 2798c2ecf20Sopenharmony_ci} 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_cistatic int mpl3115_standby(struct mpl3115_data *data) 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, 2848c2ecf20Sopenharmony_ci data->ctrl_reg1 & ~MPL3115_CTRL_ACTIVE); 2858c2ecf20Sopenharmony_ci} 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_cistatic int mpl3115_remove(struct i2c_client *client) 2888c2ecf20Sopenharmony_ci{ 2898c2ecf20Sopenharmony_ci struct iio_dev *indio_dev = i2c_get_clientdata(client); 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci iio_device_unregister(indio_dev); 2928c2ecf20Sopenharmony_ci iio_triggered_buffer_cleanup(indio_dev); 2938c2ecf20Sopenharmony_ci mpl3115_standby(iio_priv(indio_dev)); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci return 0; 2968c2ecf20Sopenharmony_ci} 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 2998c2ecf20Sopenharmony_cistatic int mpl3115_suspend(struct device *dev) 3008c2ecf20Sopenharmony_ci{ 3018c2ecf20Sopenharmony_ci return mpl3115_standby(iio_priv(i2c_get_clientdata( 3028c2ecf20Sopenharmony_ci to_i2c_client(dev)))); 3038c2ecf20Sopenharmony_ci} 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_cistatic int mpl3115_resume(struct device *dev) 3068c2ecf20Sopenharmony_ci{ 3078c2ecf20Sopenharmony_ci struct mpl3115_data *data = iio_priv(i2c_get_clientdata( 3088c2ecf20Sopenharmony_ci to_i2c_client(dev))); 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, 3118c2ecf20Sopenharmony_ci data->ctrl_reg1); 3128c2ecf20Sopenharmony_ci} 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(mpl3115_pm_ops, mpl3115_suspend, mpl3115_resume); 3158c2ecf20Sopenharmony_ci#define MPL3115_PM_OPS (&mpl3115_pm_ops) 3168c2ecf20Sopenharmony_ci#else 3178c2ecf20Sopenharmony_ci#define MPL3115_PM_OPS NULL 3188c2ecf20Sopenharmony_ci#endif 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_cistatic const struct i2c_device_id mpl3115_id[] = { 3218c2ecf20Sopenharmony_ci { "mpl3115", 0 }, 3228c2ecf20Sopenharmony_ci { } 3238c2ecf20Sopenharmony_ci}; 3248c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, mpl3115_id); 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_cistatic const struct of_device_id mpl3115_of_match[] = { 3278c2ecf20Sopenharmony_ci { .compatible = "fsl,mpl3115" }, 3288c2ecf20Sopenharmony_ci { } 3298c2ecf20Sopenharmony_ci}; 3308c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, mpl3115_of_match); 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_cistatic struct i2c_driver mpl3115_driver = { 3338c2ecf20Sopenharmony_ci .driver = { 3348c2ecf20Sopenharmony_ci .name = "mpl3115", 3358c2ecf20Sopenharmony_ci .of_match_table = mpl3115_of_match, 3368c2ecf20Sopenharmony_ci .pm = MPL3115_PM_OPS, 3378c2ecf20Sopenharmony_ci }, 3388c2ecf20Sopenharmony_ci .probe = mpl3115_probe, 3398c2ecf20Sopenharmony_ci .remove = mpl3115_remove, 3408c2ecf20Sopenharmony_ci .id_table = mpl3115_id, 3418c2ecf20Sopenharmony_ci}; 3428c2ecf20Sopenharmony_cimodule_i2c_driver(mpl3115_driver); 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ciMODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 3458c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Freescale MPL3115 pressure/temperature driver"); 3468c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 347