diff options
Diffstat (limited to 'drivers/iio/light/tcs3472.c')
| -rw-r--r-- | drivers/iio/light/tcs3472.c | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index e7923b514d7a..12429a3261b3 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * tcs3472.c - Support for TAOS TCS3472 color light-to-digital converter * * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net> * - * This file is subject to the terms and conditions of version 2 of - * the GNU General Public License. See the file COPYING in the main - * directory of this archive for more details. - * * Color light sensor with 16-bit channels for red, green, blue, clear); * 7-bit I2C slave address 0x39 (TCS34721, TCS34723) or 0x29 (TCS34725, * TCS34727) @@ -67,7 +64,6 @@ struct tcs3472_data { u8 control; u8 atime; u8 apers; - u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */ }; static const struct iio_event_spec tcs3472_events[] = { @@ -147,16 +143,15 @@ static int tcs3472_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - ret = iio_device_claim_direct_mode(indio_dev); - if (ret) - return ret; + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; ret = tcs3472_req_data(data); if (ret < 0) { - iio_device_release_direct_mode(indio_dev); + iio_device_release_direct(indio_dev); return ret; } ret = i2c_smbus_read_word_data(data->client, chan->address); - iio_device_release_direct_mode(indio_dev); + iio_device_release_direct(indio_dev); if (ret < 0) return ret; *val = ret; @@ -326,7 +321,7 @@ static int tcs3472_read_event_config(struct iio_dev *indio_dev, static int tcs3472_write_event_config(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, enum iio_event_type type, - enum iio_event_direction dir, int state) + enum iio_event_direction dir, bool state) { struct tcs3472_data *data = iio_priv(indio_dev); int ret = 0; @@ -377,22 +372,26 @@ static irqreturn_t tcs3472_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct tcs3472_data *data = iio_priv(indio_dev); int i, j = 0; + /* Ensure timestamp is naturally aligned */ + struct { + u16 chans[4]; + aligned_s64 timestamp; + } scan = { }; int ret = tcs3472_req_data(data); if (ret < 0) goto done; - for_each_set_bit(i, indio_dev->active_scan_mask, - indio_dev->masklength) { + iio_for_each_active_channel(indio_dev, i) { ret = i2c_smbus_read_word_data(data->client, TCS3472_CDATA + 2*i); if (ret < 0) goto done; - data->buffer[j++] = ret; + scan.chans[j++] = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan), iio_get_time_ns(indio_dev)); done: @@ -441,8 +440,7 @@ static const struct iio_info tcs3472_info = { .attrs = &tcs3472_attribute_group, }; -static int tcs3472_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tcs3472_probe(struct i2c_client *client) { struct tcs3472_data *data; struct iio_dev *indio_dev; @@ -457,7 +455,6 @@ static int tcs3472_probe(struct i2c_client *client, data->client = client; mutex_init(&data->lock); - indio_dev->dev.parent = &client->dev; indio_dev->info = &tcs3472_info; indio_dev->name = TCS3472_DRV_NAME; indio_dev->channels = tcs3472_channels; @@ -535,7 +532,8 @@ static int tcs3472_probe(struct i2c_client *client, return 0; free_irq: - free_irq(client->irq, indio_dev); + if (client->irq) + free_irq(client->irq, indio_dev); buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); return ret; @@ -558,19 +556,17 @@ static int tcs3472_powerdown(struct tcs3472_data *data) return ret; } -static int tcs3472_remove(struct i2c_client *client) +static void tcs3472_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); - free_irq(client->irq, indio_dev); + if (client->irq) + free_irq(client->irq, indio_dev); iio_triggered_buffer_cleanup(indio_dev); tcs3472_powerdown(iio_priv(indio_dev)); - - return 0; } -#ifdef CONFIG_PM_SLEEP static int tcs3472_suspend(struct device *dev) { struct tcs3472_data *data = iio_priv(i2c_get_clientdata( @@ -596,12 +592,12 @@ static int tcs3472_resume(struct device *dev) return ret; } -#endif -static SIMPLE_DEV_PM_OPS(tcs3472_pm_ops, tcs3472_suspend, tcs3472_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(tcs3472_pm_ops, tcs3472_suspend, + tcs3472_resume); static const struct i2c_device_id tcs3472_id[] = { - { "tcs3472", 0 }, + { "tcs3472" }, { } }; MODULE_DEVICE_TABLE(i2c, tcs3472_id); @@ -609,7 +605,7 @@ MODULE_DEVICE_TABLE(i2c, tcs3472_id); static struct i2c_driver tcs3472_driver = { .driver = { .name = TCS3472_DRV_NAME, - .pm = &tcs3472_pm_ops, + .pm = pm_sleep_ptr(&tcs3472_pm_ops), }, .probe = tcs3472_probe, .remove = tcs3472_remove, |
