Lines Matching +full:end +full:- +full:of +full:- +full:conversion
1 // SPDX-License-Identifier: GPL-2.0-only
3 * opt3001.c - Texas Instruments OPT3001 Light Sensor
5 * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com
55 /* The end-of-conversion enable is located in the low-limit register */
65 * Time to wait for conversion result to be ready. The device datasheet
67 * This results in worst-case max values of 113ms or 883ms, respectively.
161 * purposes. Use milli lux precision to avoid 32-bit integer in opt3001_find_scale()
165 (scale->val * 1000 + scale->val2 / 1000)) { in opt3001_find_scale()
171 return -EINVAL; in opt3001_find_scale()
181 *val2 = (lux - (*val * 1000)) * 1000; in opt3001_to_iio_ret()
188 opt->mode = mode; in opt3001_set_mode()
237 if (opt->use_irq) { in opt3001_get_lux()
239 * Enable the end-of-conversion interrupt mechanism. Note that in opt3001_get_lux()
240 * doing so will overwrite the low-level limit value however we in opt3001_get_lux()
243 ret = i2c_smbus_write_word_swapped(opt->client, in opt3001_get_lux()
247 dev_err(opt->dev, "failed to write register %02x\n", in opt3001_get_lux()
253 opt->ok_to_ignore_lock = true; in opt3001_get_lux()
256 /* Reset data-ready indicator flag */ in opt3001_get_lux()
257 opt->result_ready = false; in opt3001_get_lux()
259 /* Configure for single-conversion mode and start a new conversion */ in opt3001_get_lux()
260 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION); in opt3001_get_lux()
262 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_get_lux()
270 ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION, in opt3001_get_lux()
273 dev_err(opt->dev, "failed to write register %02x\n", in opt3001_get_lux()
278 if (opt->use_irq) { in opt3001_get_lux()
279 /* Wait for the IRQ to indicate the conversion is complete */ in opt3001_get_lux()
280 ret = wait_event_timeout(opt->result_ready_queue, in opt3001_get_lux()
281 opt->result_ready, in opt3001_get_lux()
284 return -ETIMEDOUT; in opt3001_get_lux()
287 timeout = (opt->int_time == OPT3001_INT_TIME_SHORT) ? in opt3001_get_lux()
292 ret = i2c_smbus_read_word_swapped(opt->client, in opt3001_get_lux()
295 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_get_lux()
301 ret = -ETIMEDOUT; in opt3001_get_lux()
306 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_RESULT); in opt3001_get_lux()
308 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_get_lux()
312 opt->result = ret; in opt3001_get_lux()
313 opt->result_ready = true; in opt3001_get_lux()
317 if (opt->use_irq) in opt3001_get_lux()
319 opt->ok_to_ignore_lock = false; in opt3001_get_lux()
324 if (opt->use_irq) { in opt3001_get_lux()
326 * Disable the end-of-conversion interrupt mechanism by in opt3001_get_lux()
327 * restoring the low-level limit value (clearing in opt3001_get_lux()
330 * bit-overlap and therefore can't be done. in opt3001_get_lux()
332 value = (opt->low_thresh_exp << 12) | opt->low_thresh_mantissa; in opt3001_get_lux()
333 ret = i2c_smbus_write_word_swapped(opt->client, in opt3001_get_lux()
337 dev_err(opt->dev, "failed to write register %02x\n", in opt3001_get_lux()
343 exponent = OPT3001_REG_EXPONENT(opt->result); in opt3001_get_lux()
344 mantissa = OPT3001_REG_MANTISSA(opt->result); in opt3001_get_lux()
354 *val2 = opt->int_time; in opt3001_get_int_time()
364 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION); in opt3001_set_int_time()
366 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_set_int_time()
376 opt->int_time = OPT3001_INT_TIME_SHORT; in opt3001_set_int_time()
380 opt->int_time = OPT3001_INT_TIME_LONG; in opt3001_set_int_time()
383 return -EINVAL; in opt3001_set_int_time()
386 return i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION, in opt3001_set_int_time()
397 if (opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS) in opt3001_read_raw()
398 return -EBUSY; in opt3001_read_raw()
400 if (chan->type != IIO_LIGHT) in opt3001_read_raw()
401 return -EINVAL; in opt3001_read_raw()
403 mutex_lock(&opt->lock); in opt3001_read_raw()
413 ret = -EINVAL; in opt3001_read_raw()
416 mutex_unlock(&opt->lock); in opt3001_read_raw()
428 if (opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS) in opt3001_write_raw()
429 return -EBUSY; in opt3001_write_raw()
431 if (chan->type != IIO_LIGHT) in opt3001_write_raw()
432 return -EINVAL; in opt3001_write_raw()
435 return -EINVAL; in opt3001_write_raw()
438 return -EINVAL; in opt3001_write_raw()
440 mutex_lock(&opt->lock); in opt3001_write_raw()
442 mutex_unlock(&opt->lock); in opt3001_write_raw()
455 mutex_lock(&opt->lock); in opt3001_read_event_value()
459 opt3001_to_iio_ret(opt, opt->high_thresh_exp, in opt3001_read_event_value()
460 opt->high_thresh_mantissa, val, val2); in opt3001_read_event_value()
463 opt3001_to_iio_ret(opt, opt->low_thresh_exp, in opt3001_read_event_value()
464 opt->low_thresh_mantissa, val, val2); in opt3001_read_event_value()
467 ret = -EINVAL; in opt3001_read_event_value()
470 mutex_unlock(&opt->lock); in opt3001_read_event_value()
490 return -EINVAL; in opt3001_write_event_value()
492 mutex_lock(&opt->lock); in opt3001_write_event_value()
496 dev_err(opt->dev, "can't find scale for %d.%06u\n", val, val2); in opt3001_write_event_value()
506 opt->high_thresh_mantissa = mantissa; in opt3001_write_event_value()
507 opt->high_thresh_exp = exponent; in opt3001_write_event_value()
511 opt->low_thresh_mantissa = mantissa; in opt3001_write_event_value()
512 opt->low_thresh_exp = exponent; in opt3001_write_event_value()
515 ret = -EINVAL; in opt3001_write_event_value()
519 ret = i2c_smbus_write_word_swapped(opt->client, reg, value); in opt3001_write_event_value()
521 dev_err(opt->dev, "failed to write register %02x\n", reg); in opt3001_write_event_value()
526 mutex_unlock(&opt->lock); in opt3001_write_event_value()
537 return opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS; in opt3001_read_event_config()
549 if (state && opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS) in opt3001_write_event_config()
552 if (!state && opt->mode == OPT3001_CONFIGURATION_M_SHUTDOWN) in opt3001_write_event_config()
555 mutex_lock(&opt->lock); in opt3001_write_event_config()
560 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION); in opt3001_write_event_config()
562 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_write_event_config()
570 ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION, in opt3001_write_event_config()
573 dev_err(opt->dev, "failed to write register %02x\n", in opt3001_write_event_config()
579 mutex_unlock(&opt->lock); in opt3001_write_event_config()
600 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_MANUFACTURER_ID); in opt3001_read_id()
602 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_read_id()
610 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_DEVICE_ID); in opt3001_read_id()
612 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_read_id()
619 dev_info(opt->dev, "Found %c%c OPT%04x\n", manufacturer[0], in opt3001_read_id()
630 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION); in opt3001_configure()
632 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_configure()
639 /* Enable automatic full-scale setting mode */ in opt3001_configure()
643 /* Reflect status of the device's integration time setting */ in opt3001_configure()
645 opt->int_time = OPT3001_INT_TIME_LONG; in opt3001_configure()
647 opt->int_time = OPT3001_INT_TIME_SHORT; in opt3001_configure()
652 /* Configure for latched window-style comparison operation */ in opt3001_configure()
658 ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION, in opt3001_configure()
661 dev_err(opt->dev, "failed to write register %02x\n", in opt3001_configure()
666 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_LOW_LIMIT); in opt3001_configure()
668 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_configure()
673 opt->low_thresh_mantissa = OPT3001_REG_MANTISSA(ret); in opt3001_configure()
674 opt->low_thresh_exp = OPT3001_REG_EXPONENT(ret); in opt3001_configure()
676 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_HIGH_LIMIT); in opt3001_configure()
678 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_configure()
683 opt->high_thresh_mantissa = OPT3001_REG_MANTISSA(ret); in opt3001_configure()
684 opt->high_thresh_exp = OPT3001_REG_EXPONENT(ret); in opt3001_configure()
696 if (!opt->ok_to_ignore_lock) in opt3001_irq()
697 mutex_lock(&opt->lock); in opt3001_irq()
699 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION); in opt3001_irq()
701 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_irq()
721 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_RESULT); in opt3001_irq()
723 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_irq()
727 opt->result = ret; in opt3001_irq()
728 opt->result_ready = true; in opt3001_irq()
733 if (!opt->ok_to_ignore_lock) in opt3001_irq()
734 mutex_unlock(&opt->lock); in opt3001_irq()
737 wake_up(&opt->result_ready_queue); in opt3001_irq()
744 struct device *dev = &client->dev; in opt3001_probe()
748 int irq = client->irq; in opt3001_probe()
753 return -ENOMEM; in opt3001_probe()
756 opt->client = client; in opt3001_probe()
757 opt->dev = dev; in opt3001_probe()
759 mutex_init(&opt->lock); in opt3001_probe()
760 init_waitqueue_head(&opt->result_ready_queue); in opt3001_probe()
771 iio->name = client->name; in opt3001_probe()
772 iio->channels = opt3001_channels; in opt3001_probe()
773 iio->num_channels = ARRAY_SIZE(opt3001_channels); in opt3001_probe()
774 iio->modes = INDIO_DIRECT_MODE; in opt3001_probe()
775 iio->info = &opt3001_info; in opt3001_probe()
783 /* Make use of INT pin only if valid IRQ no. is given */ in opt3001_probe()
792 opt->use_irq = true; in opt3001_probe()
794 dev_dbg(opt->dev, "enabling interrupt-less operation\n"); in opt3001_probe()
807 if (opt->use_irq) in opt3001_remove()
808 free_irq(client->irq, iio); in opt3001_remove()
810 ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION); in opt3001_remove()
812 dev_err(opt->dev, "failed to read register %02x\n", in opt3001_remove()
820 ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION, in opt3001_remove()
823 dev_err(opt->dev, "failed to write register %02x\n", in opt3001_remove()
838 MODULE_DEVICE_TABLE(of, opt3001_of_match);