Lines Matching +full:uv +full:- +full:sensor
1 // SPDX-License-Identifier: GPL-2.0-only
3 * veml6070.c - Support for Vishay VEML6070 UV A light sensor
5 * Copyright 2016 Peter Meerwald-Stadler <[email protected]>
7 * IIO driver for VEML6070 (7-bit I2C slave addresses 0x38 and 0x39)
54 data->rset = 270000; in veml6070_calc_it()
55 device_property_read_u32(dev, "vishay,rset-ohms", &data->rset); in veml6070_calc_it()
57 if (data->rset < 75000 || data->rset > 1200000) in veml6070_calc_it()
58 return dev_err_probe(dev, -EINVAL, "Rset out of range\n"); in veml6070_calc_it()
64 data->rset /= KILO; in veml6070_calc_it()
66 tmp_it = VEML6070_MIN_IT_US * data->rset / VEML6070_MIN_RSET_KOHM; in veml6070_calc_it()
67 for (i = 0; i < ARRAY_SIZE(data->it); i++) { in veml6070_calc_it()
68 data->it[i][0] = (tmp_it << i) / MICRO; in veml6070_calc_it()
69 data->it[i][1] = (tmp_it << i) % MICRO; in veml6070_calc_it()
77 int it_idx = FIELD_GET(VEML6070_COMMAND_IT, data->config); in veml6070_get_it()
79 *val = data->it[it_idx][0]; in veml6070_get_it()
80 *val2 = data->it[it_idx][1]; in veml6070_get_it()
89 for (it_idx = 0; it_idx < ARRAY_SIZE(data->it); it_idx++) { in veml6070_set_it()
90 if (data->it[it_idx][0] == val && data->it[it_idx][1] == val2) in veml6070_set_it()
94 if (it_idx >= ARRAY_SIZE(data->it)) in veml6070_set_it()
95 return -EINVAL; in veml6070_set_it()
97 data->config = (data->config & ~VEML6070_COMMAND_IT) | in veml6070_set_it()
100 return i2c_smbus_write_byte(data->client1, data->config); in veml6070_set_it()
108 guard(mutex)(&data->lock); in veml6070_read()
111 ret = i2c_smbus_write_byte(data->client1, in veml6070_read()
112 data->config & ~VEML6070_COMMAND_SD); in veml6070_read()
120 ret = i2c_smbus_read_byte(data->client2); /* read MSB, address 0x39 */ in veml6070_read()
126 ret = i2c_smbus_read_byte(data->client1); /* read LSB, address 0x38 */ in veml6070_read()
133 ret = i2c_smbus_write_byte(data->client1, data->config); in veml6070_read()
162 * conversion of raw UV intensity values to UV index depends on in veml6070_to_uv_index()
173 it_idx = FIELD_GET(VEML6070_COMMAND_IT, data->config); in veml6070_to_uv_index()
176 val = (val * 270 / data->rset) << 1; in veml6070_to_uv_index()
178 val = (val * 270 / data->rset) >> (it_idx - 1); in veml6070_to_uv_index()
208 return -EINVAL; in veml6070_read_raw()
221 *vals = (int *)data->it; in veml6070_read_avail()
222 *length = 2 * ARRAY_SIZE(data->it); in veml6070_read_avail()
226 return -EINVAL; in veml6070_read_avail()
240 return -EINVAL; in veml6070_write_raw()
254 i2c_unregister_device(data->client2); in veml6070_i2c_unreg()
263 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); in veml6070_probe()
265 return -ENOMEM; in veml6070_probe()
269 data->client1 = client; in veml6070_probe()
270 mutex_init(&data->lock); in veml6070_probe()
272 indio_dev->info = &veml6070_info; in veml6070_probe()
273 indio_dev->channels = veml6070_channels; in veml6070_probe()
274 indio_dev->num_channels = ARRAY_SIZE(veml6070_channels); in veml6070_probe()
275 indio_dev->name = VEML6070_DRV_NAME; in veml6070_probe()
276 indio_dev->modes = INDIO_DIRECT_MODE; in veml6070_probe()
278 ret = veml6070_calc_it(&client->dev, data); in veml6070_probe()
282 ret = devm_regulator_get_enable(&client->dev, "vdd"); in veml6070_probe()
286 data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB); in veml6070_probe()
287 if (IS_ERR(data->client2)) in veml6070_probe()
288 return dev_err_probe(&client->dev, PTR_ERR(data->client2), in veml6070_probe()
291 data->config = FIELD_PREP(VEML6070_COMMAND_IT, VEML6070_IT_10) | in veml6070_probe()
293 ret = i2c_smbus_write_byte(data->client1, data->config); in veml6070_probe()
297 ret = devm_add_action_or_reset(&client->dev, veml6070_i2c_unreg, data); in veml6070_probe()
301 return devm_iio_device_register(&client->dev, indio_dev); in veml6070_probe()
327 MODULE_AUTHOR("Peter Meerwald-Stadler <[email protected]>");
328 MODULE_DESCRIPTION("Vishay VEML6070 UV A light sensor driver");