diff options
Diffstat (limited to 'drivers/iio/health/max30102.c')
| -rw-r--r-- | drivers/iio/health/max30102.c | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index 74fc260b957e..a48c0881a4c7 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -2,7 +2,7 @@ /* * max30102.c - Support for MAX30102 heart rate and pulse oximeter sensor * - * Copyright (C) 2017 Matt Ranostay <matt@ranostay.consulting> + * Copyright (C) 2017 Matt Ranostay <matt.ranostay@konsulko.com> * * Support for MAX30105 optical particle sensor * Copyright (C) 2017 Peter Meerwald-Stadler <pmeerw@pmeerw.net> @@ -19,13 +19,12 @@ #include <linux/irq.h> #include <linux/i2c.h> #include <linux/mutex.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> #include <linux/iio/kfifo_buf.h> -#define MAX30102_REGMAP_NAME "max30102_regmap" #define MAX30102_DRV_NAME "max30102" #define MAX30102_PART_NUMBER 0x15 @@ -112,7 +111,7 @@ struct max30102_data { }; static const struct regmap_config max30102_regmap_config = { - .name = MAX30102_REGMAP_NAME, + .name = "max30102_regmap", .reg_bits = 8, .val_bits = 8, @@ -273,10 +272,10 @@ static int max30102_read_measurement(struct max30102_data *data, switch (measurements) { case 3: MAX30102_COPY_DATA(2); - /* fall through */ + fallthrough; case 2: MAX30102_COPY_DATA(1); - /* fall through */ + fallthrough; case 1: MAX30102_COPY_DATA(0); break; @@ -293,7 +292,7 @@ static irqreturn_t max30102_interrupt_handler(int irq, void *private) struct iio_dev *indio_dev = private; struct max30102_data *data = iio_priv(indio_dev); unsigned int measurements = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); + iio_get_masklength(indio_dev)); int ret, cnt = 0; mutex_lock(&data->lock); @@ -323,11 +322,10 @@ static int max30102_get_current_idx(unsigned int val, int *reg) static int max30102_led_init(struct max30102_data *data) { struct device *dev = &data->client->dev; - struct device_node *np = dev->of_node; unsigned int val; int reg, ret; - ret = of_property_read_u32(np, "maxim,red-led-current-microamp", &val); + ret = device_property_read_u32(dev, "maxim,red-led-current-microamp", &val); if (ret) { dev_info(dev, "no red-led-current-microamp set\n"); @@ -346,7 +344,7 @@ static int max30102_led_init(struct max30102_data *data) return ret; if (data->chip_id == max30105) { - ret = of_property_read_u32(np, + ret = device_property_read_u32(dev, "maxim,green-led-current-microamp", &val); if (ret) { dev_info(dev, "no green-led-current-microamp set\n"); @@ -368,7 +366,7 @@ static int max30102_led_init(struct max30102_data *data) return ret; } - ret = of_property_read_u32(np, "maxim,ir-led-current-microamp", &val); + ret = device_property_read_u32(dev, "maxim,ir-led-current-microamp", &val); if (ret) { dev_info(dev, "no ir-led-current-microamp set\n"); @@ -449,9 +447,8 @@ static int max30102_get_temp(struct max30102_data *data, int *val, bool en) } /* start acquisition */ - ret = regmap_update_bits(data->regmap, MAX30102_REG_TEMP_CONFIG, - MAX30102_REG_TEMP_CONFIG_TEMP_EN, - MAX30102_REG_TEMP_CONFIG_TEMP_EN); + ret = regmap_set_bits(data->regmap, MAX30102_REG_TEMP_CONFIG, + MAX30102_REG_TEMP_CONFIG_TEMP_EN); if (ret) goto out; @@ -478,12 +475,23 @@ static int max30102_read_raw(struct iio_dev *indio_dev, * Temperature reading can only be acquired when not in * shutdown; leave shutdown briefly when buffer not running */ - mutex_lock(&indio_dev->mlock); - if (!iio_buffer_enabled(indio_dev)) +any_mode_retry: + if (iio_device_claim_buffer_mode(indio_dev)) { + /* + * This one is a *bit* hacky. If we cannot claim buffer + * mode, then try direct mode so that we make sure + * things cannot concurrently change. And we just keep + * trying until we get one of the modes... + */ + if (!iio_device_claim_direct(indio_dev)) + goto any_mode_retry; + ret = max30102_get_temp(data, val, true); - else + iio_device_release_direct(indio_dev); + } else { ret = max30102_get_temp(data, val, false); - mutex_unlock(&indio_dev->mlock); + iio_device_release_buffer_mode(indio_dev); + } if (ret) return ret; @@ -503,11 +511,10 @@ static const struct iio_info max30102_info = { .read_raw = max30102_read_raw, }; -static int max30102_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max30102_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct max30102_data *data; - struct iio_buffer *buffer; struct iio_dev *indio_dev; int ret; unsigned int reg; @@ -516,17 +523,9 @@ static int max30102_probe(struct i2c_client *client, if (!indio_dev) return -ENOMEM; - buffer = devm_iio_kfifo_allocate(&client->dev); - if (!buffer) - return -ENOMEM; - - iio_device_attach_buffer(indio_dev, buffer); - indio_dev->name = MAX30102_DRV_NAME; indio_dev->info = &max30102_info; - indio_dev->modes = (INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE); - indio_dev->setup_ops = &max30102_buffer_setup_ops; - indio_dev->dev.parent = &client->dev; + indio_dev->modes = INDIO_DIRECT_MODE; data = iio_priv(indio_dev); data->indio_dev = indio_dev; @@ -551,6 +550,11 @@ static int max30102_probe(struct i2c_client *client, return -ENODEV; } + ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev, + &max30102_buffer_setup_ops); + if (ret) + return ret; + data->regmap = devm_regmap_init_i2c(client, &max30102_regmap_config); if (IS_ERR(data->regmap)) { dev_err(&client->dev, "regmap initialization failed\n"); @@ -597,25 +601,25 @@ static int max30102_probe(struct i2c_client *client, return iio_device_register(indio_dev); } -static int max30102_remove(struct i2c_client *client) +static void max30102_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); struct max30102_data *data = iio_priv(indio_dev); iio_device_unregister(indio_dev); max30102_set_power(data, false); - - return 0; } static const struct i2c_device_id max30102_id[] = { + { "max30101", max30105 }, { "max30102", max30102 }, { "max30105", max30105 }, - {} + { } }; MODULE_DEVICE_TABLE(i2c, max30102_id); static const struct of_device_id max30102_dt_ids[] = { + { .compatible = "maxim,max30101" }, { .compatible = "maxim,max30102" }, { .compatible = "maxim,max30105" }, { } @@ -625,7 +629,7 @@ MODULE_DEVICE_TABLE(of, max30102_dt_ids); static struct i2c_driver max30102_driver = { .driver = { .name = MAX30102_DRV_NAME, - .of_match_table = of_match_ptr(max30102_dt_ids), + .of_match_table = max30102_dt_ids, }, .probe = max30102_probe, .remove = max30102_remove, @@ -633,6 +637,6 @@ static struct i2c_driver max30102_driver = { }; module_i2c_driver(max30102_driver); -MODULE_AUTHOR("Matt Ranostay <matt@ranostay.consulting>"); +MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); MODULE_DESCRIPTION("MAX30102 heart rate/pulse oximeter and MAX30105 particle sensor driver"); MODULE_LICENSE("GPL"); |
