summaryrefslogtreecommitdiffstats
path: root/drivers/iio/light/veml6070.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/light/veml6070.c')
-rw-r--r--drivers/iio/light/veml6070.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/drivers/iio/light/veml6070.c b/drivers/iio/light/veml6070.c
index f8321d346d77..898e285322d4 100644
--- a/drivers/iio/light/veml6070.c
+++ b/drivers/iio/light/veml6070.c
@@ -42,36 +42,36 @@ static int veml6070_read(struct veml6070_data *data)
int ret;
u8 msb, lsb;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
/* disable shutdown */
ret = i2c_smbus_write_byte(data->client1,
data->config & ~VEML6070_COMMAND_SD);
if (ret < 0)
- goto out;
+ return ret;
msleep(125 + 10); /* measurement takes up to 125 ms for IT 1x */
ret = i2c_smbus_read_byte(data->client2); /* read MSB, address 0x39 */
if (ret < 0)
- goto out;
+ return ret;
+
msb = ret;
ret = i2c_smbus_read_byte(data->client1); /* read LSB, address 0x38 */
if (ret < 0)
- goto out;
+ return ret;
+
lsb = ret;
/* shutdown again */
ret = i2c_smbus_write_byte(data->client1, data->config);
if (ret < 0)
- goto out;
+ return ret;
ret = (msb << 8) | lsb;
-out:
- mutex_unlock(&data->lock);
- return ret;
+ return 0;
}
static const struct iio_chan_spec veml6070_channels[] = {
@@ -135,6 +135,13 @@ static const struct iio_info veml6070_info = {
.read_raw = veml6070_read_raw,
};
+static void veml6070_i2c_unreg(void *p)
+{
+ struct veml6070_data *data = p;
+
+ i2c_unregister_device(data->client2);
+}
+
static int veml6070_probe(struct i2c_client *client)
{
struct veml6070_data *data;
@@ -156,36 +163,26 @@ static int veml6070_probe(struct i2c_client *client)
indio_dev->name = VEML6070_DRV_NAME;
indio_dev->modes = INDIO_DIRECT_MODE;
+ ret = devm_regulator_get_enable(&client->dev, "vdd");
+ if (ret < 0)
+ return ret;
+
data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB);
- if (IS_ERR(data->client2)) {
- dev_err(&client->dev, "i2c device for second chip address failed\n");
- return PTR_ERR(data->client2);
- }
+ if (IS_ERR(data->client2))
+ return dev_err_probe(&client->dev, PTR_ERR(data->client2),
+ "i2c device for second chip address failed\n");
data->config = VEML6070_IT_10 | VEML6070_COMMAND_RSRVD |
VEML6070_COMMAND_SD;
ret = i2c_smbus_write_byte(data->client1, data->config);
if (ret < 0)
- goto fail;
+ return ret;
- ret = iio_device_register(indio_dev);
+ ret = devm_add_action_or_reset(&client->dev, veml6070_i2c_unreg, data);
if (ret < 0)
- goto fail;
-
- return ret;
+ return ret;
-fail:
- i2c_unregister_device(data->client2);
- return ret;
-}
-
-static void veml6070_remove(struct i2c_client *client)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct veml6070_data *data = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- i2c_unregister_device(data->client2);
+ return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id veml6070_id[] = {
@@ -194,12 +191,18 @@ static const struct i2c_device_id veml6070_id[] = {
};
MODULE_DEVICE_TABLE(i2c, veml6070_id);
+static const struct of_device_id veml6070_of_match[] = {
+ { .compatible = "vishay,veml6070" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, veml6070_of_match);
+
static struct i2c_driver veml6070_driver = {
.driver = {
.name = VEML6070_DRV_NAME,
+ .of_match_table = veml6070_of_match,
},
.probe = veml6070_probe,
- .remove = veml6070_remove,
.id_table = veml6070_id,
};