Lines Matching +full:reset +full:- +full:pin +full:- +full:assert +full:- +full:time +full:- +full:ms
1 // SPDX-License-Identifier: GPL-2.0-only
3 * RPR-0521 ROHM Ambient Light and Proximity Sensor
7 * IIO driver for RPR-0521RS (7-bit I2C slave address 0x38).
31 #define RPR0521_REG_PXS_DATA 0x44 /* 16-bit, little endian */
32 #define RPR0521_REG_ALS_DATA0 0x46 /* 16-bit, little endian */
33 #define RPR0521_REG_ALS_DATA1 0x48 /* 16-bit, little endian */
68 #define RPR0521_DEFAULT_MEAS_TIME 0x06 /* ALS - 100ms, PXS - 100ms */
170 {2, 500000, 20, 0}, /* 1000, measurement 100ms, sleep 300ms */
171 {2, 500000, 10, 0}, /* 1001, measurement 100ms, sleep 300ms */
190 /* optimize runtime pm ops - enable/disable device only if needed */
297 ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL, in rpr0521_als_enable()
304 data->als_dev_en = true; in rpr0521_als_enable()
306 data->als_dev_en = false; in rpr0521_als_enable()
315 ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL, in rpr0521_pxs_enable()
322 data->pxs_dev_en = true; in rpr0521_pxs_enable()
324 data->pxs_dev_en = false; in rpr0521_pxs_enable()
330 * rpr0521_set_power_state - handles runtime PM state and sensors enabled status
346 data->als_ps_need_en = on; in rpr0521_set_power_state()
347 data->als_need_dis = !on; in rpr0521_set_power_state()
351 data->pxs_ps_need_en = on; in rpr0521_set_power_state()
352 data->pxs_need_dis = !on; in rpr0521_set_power_state()
359 * Note: If either measurement is re-enabled before _suspend(), in rpr0521_set_power_state()
363 ret = pm_runtime_resume_and_get(&data->client->dev); in rpr0521_set_power_state()
365 pm_runtime_mark_last_busy(&data->client->dev); in rpr0521_set_power_state()
366 ret = pm_runtime_put_autosuspend(&data->client->dev); in rpr0521_set_power_state()
369 dev_err(&data->client->dev, in rpr0521_set_power_state()
377 if (data->als_ps_need_en) { in rpr0521_set_power_state()
381 data->als_ps_need_en = false; in rpr0521_set_power_state()
384 if (data->pxs_ps_need_en) { in rpr0521_set_power_state()
388 data->pxs_ps_need_en = false; in rpr0521_set_power_state()
401 ret = regmap_read(data->regmap, RPR0521_REG_INTERRUPT, ®); in rpr0521_is_triggered()
418 data->irq_timestamp = iio_get_time_ns(indio_dev); in rpr0521_drdy_irq_handler()
434 iio_trigger_poll_nested(data->drdy_trigger0); in rpr0521_drdy_irq_thread()
444 struct iio_dev *indio_dev = pf->indio_dev; in rpr0521_trigger_consumer_handler()
449 if (iio_trigger_using_own(indio_dev) && data->irq_timestamp) { in rpr0521_trigger_consumer_handler()
450 pf->timestamp = data->irq_timestamp; in rpr0521_trigger_consumer_handler()
451 data->irq_timestamp = 0; in rpr0521_trigger_consumer_handler()
454 if (!pf->timestamp) in rpr0521_trigger_consumer_handler()
455 pf->timestamp = iio_get_time_ns(indio_dev); in rpr0521_trigger_consumer_handler()
457 err = regmap_bulk_read(data->regmap, RPR0521_REG_PXS_DATA, in rpr0521_trigger_consumer_handler()
458 data->scan.channels, in rpr0521_trigger_consumer_handler()
459 (3 * 2) + 1); /* 3 * 16-bit + (discarded) int clear reg. */ in rpr0521_trigger_consumer_handler()
462 &data->scan, pf->timestamp); in rpr0521_trigger_consumer_handler()
464 dev_err(&data->client->dev, in rpr0521_trigger_consumer_handler()
466 pf->timestamp = 0; in rpr0521_trigger_consumer_handler()
468 iio_trigger_notify_done(indio_dev->trig); in rpr0521_trigger_consumer_handler()
478 err = regmap_update_bits(data->regmap, RPR0521_REG_PXS_CTRL, in rpr0521_write_int_enable()
482 dev_err(&data->client->dev, "PS control reg write fail.\n"); in rpr0521_write_int_enable()
483 return -EBUSY; in rpr0521_write_int_enable()
487 err = regmap_write(data->regmap, RPR0521_REG_INTERRUPT, in rpr0521_write_int_enable()
493 dev_err(&data->client->dev, "Interrupt setup write fail.\n"); in rpr0521_write_int_enable()
494 return -EBUSY; in rpr0521_write_int_enable()
502 /* Don't care of clearing mode, assert and latch. */ in rpr0521_write_int_disable()
503 return regmap_write(data->regmap, RPR0521_REG_INTERRUPT, in rpr0521_write_int_disable()
525 dev_err(&data->client->dev, "rpr0521_pxs_drdy_set_state failed\n"); in rpr0521_pxs_drdy_set_state()
540 mutex_lock(&data->lock); in rpr0521_buffer_preenable()
543 mutex_unlock(&data->lock); in rpr0521_buffer_preenable()
545 dev_err(&data->client->dev, "_buffer_preenable fail\n"); in rpr0521_buffer_preenable()
555 mutex_lock(&data->lock); in rpr0521_buffer_postdisable()
558 mutex_unlock(&data->lock); in rpr0521_buffer_postdisable()
560 dev_err(&data->client->dev, "_buffer_postdisable fail\n"); in rpr0521_buffer_postdisable()
575 ret = regmap_read(data->regmap, rpr0521_gain[chan].reg, ®); in rpr0521_get_gain()
589 int i, idx = -EINVAL; in rpr0521_set_gain()
602 return regmap_update_bits(data->regmap, rpr0521_gain[chan].reg, in rpr0521_set_gain()
613 ret = regmap_read(data->regmap, RPR0521_REG_MODE_CTRL, ®); in rpr0521_read_samp_freq()
619 return -EINVAL; in rpr0521_read_samp_freq()
633 return -EINVAL; in rpr0521_read_samp_freq()
654 return -EINVAL; in rpr0521_write_samp_freq_common()
664 return -EINVAL; in rpr0521_write_samp_freq_common()
667 return regmap_update_bits(data->regmap, in rpr0521_write_samp_freq_common()
678 ret = regmap_bulk_read(data->regmap, in rpr0521_read_ps_offset()
682 dev_err(&data->client->dev, "Failed to read PS OFFSET register\n"); in rpr0521_read_ps_offset()
696 ret = regmap_raw_write(data->regmap, in rpr0521_write_ps_offset()
700 dev_err(&data->client->dev, "Failed to write PS OFFSET register\n"); in rpr0521_write_ps_offset()
719 if (chan->type != IIO_INTENSITY && chan->type != IIO_PROXIMITY) in rpr0521_read_raw()
720 return -EINVAL; in rpr0521_read_raw()
724 return -EBUSY; in rpr0521_read_raw()
726 device_mask = rpr0521_data_reg[chan->address].device_mask; in rpr0521_read_raw()
728 mutex_lock(&data->lock); in rpr0521_read_raw()
733 ret = regmap_bulk_read(data->regmap, in rpr0521_read_raw()
734 rpr0521_data_reg[chan->address].address, in rpr0521_read_raw()
744 mutex_unlock(&data->lock); in rpr0521_read_raw()
754 mutex_lock(&data->lock); in rpr0521_read_raw()
755 ret = rpr0521_get_gain(data, chan->address, val, val2); in rpr0521_read_raw()
756 mutex_unlock(&data->lock); in rpr0521_read_raw()
763 mutex_lock(&data->lock); in rpr0521_read_raw()
764 ret = rpr0521_read_samp_freq(data, chan->type, val, val2); in rpr0521_read_raw()
765 mutex_unlock(&data->lock); in rpr0521_read_raw()
772 mutex_lock(&data->lock); in rpr0521_read_raw()
774 mutex_unlock(&data->lock); in rpr0521_read_raw()
781 return -EINVAL; in rpr0521_read_raw()
794 mutex_lock(&data->lock); in rpr0521_write_raw()
795 ret = rpr0521_set_gain(data, chan->address, val, val2); in rpr0521_write_raw()
796 mutex_unlock(&data->lock); in rpr0521_write_raw()
801 mutex_lock(&data->lock); in rpr0521_write_raw()
802 ret = rpr0521_write_samp_freq_common(data, chan->type, in rpr0521_write_raw()
804 mutex_unlock(&data->lock); in rpr0521_write_raw()
809 mutex_lock(&data->lock); in rpr0521_write_raw()
811 mutex_unlock(&data->lock); in rpr0521_write_raw()
816 return -EINVAL; in rpr0521_write_raw()
831 ret = regmap_read(data->regmap, RPR0521_REG_ID, &id); in rpr0521_init()
833 dev_err(&data->client->dev, "Failed to read REG_ID register\n"); in rpr0521_init()
838 dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n", in rpr0521_init()
840 return -ENODEV; in rpr0521_init()
843 /* set default measurement time - 100 ms for both ALS and PS */ in rpr0521_init()
844 ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL, in rpr0521_init()
861 data->irq_timestamp = 0; in rpr0521_init()
871 ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL, in rpr0521_poweroff()
879 data->als_dev_en = false; in rpr0521_poweroff()
880 data->pxs_dev_en = false; in rpr0521_poweroff()
883 * Int pin keeps state after power off. Set pin to high impedance in rpr0521_poweroff()
886 ret = regmap_read(data->regmap, RPR0521_REG_INTERRUPT, &tmp); in rpr0521_poweroff()
888 dev_err(&data->client->dev, "Failed to reset int pin.\n"); in rpr0521_poweroff()
925 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); in rpr0521_probe()
927 return -ENOMEM; in rpr0521_probe()
931 dev_err(&client->dev, "regmap_init failed!\n"); in rpr0521_probe()
937 data->client = client; in rpr0521_probe()
938 data->regmap = regmap; in rpr0521_probe()
940 mutex_init(&data->lock); in rpr0521_probe()
942 indio_dev->info = &rpr0521_info; in rpr0521_probe()
943 indio_dev->name = RPR0521_DRV_NAME; in rpr0521_probe()
944 indio_dev->channels = rpr0521_channels; in rpr0521_probe()
945 indio_dev->num_channels = ARRAY_SIZE(rpr0521_channels); in rpr0521_probe()
946 indio_dev->modes = INDIO_DIRECT_MODE; in rpr0521_probe()
950 dev_err(&client->dev, "rpr0521 chip init failed\n"); in rpr0521_probe()
954 ret = pm_runtime_set_active(&client->dev); in rpr0521_probe()
958 pm_runtime_enable(&client->dev); in rpr0521_probe()
959 pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS); in rpr0521_probe()
960 pm_runtime_use_autosuspend(&client->dev); in rpr0521_probe()
968 if (client->irq) { in rpr0521_probe()
970 data->drdy_trigger0 = devm_iio_trigger_alloc( in rpr0521_probe()
971 indio_dev->dev.parent, in rpr0521_probe()
972 "%s-dev%d", indio_dev->name, iio_device_id(indio_dev)); in rpr0521_probe()
973 if (!data->drdy_trigger0) { in rpr0521_probe()
974 ret = -ENOMEM; in rpr0521_probe()
977 data->drdy_trigger0->ops = &rpr0521_trigger_ops; in rpr0521_probe()
978 indio_dev->available_scan_masks = rpr0521_available_scan_masks; in rpr0521_probe()
979 iio_trigger_set_drvdata(data->drdy_trigger0, indio_dev); in rpr0521_probe()
982 ret = devm_request_threaded_irq(&client->dev, client->irq, in rpr0521_probe()
987 dev_err(&client->dev, "request irq %d for trigger0 failed\n", in rpr0521_probe()
988 client->irq); in rpr0521_probe()
992 ret = devm_iio_trigger_register(indio_dev->dev.parent, in rpr0521_probe()
993 data->drdy_trigger0); in rpr0521_probe()
995 dev_err(&client->dev, "iio trigger register failed\n"); in rpr0521_probe()
1005 ret = devm_iio_triggered_buffer_setup(indio_dev->dev.parent, in rpr0521_probe()
1011 dev_err(&client->dev, "iio triggered buffer setup failed\n"); in rpr0521_probe()
1023 pm_runtime_disable(&client->dev); in rpr0521_probe()
1024 pm_runtime_set_suspended(&client->dev); in rpr0521_probe()
1037 pm_runtime_disable(&client->dev); in rpr0521_remove()
1038 pm_runtime_set_suspended(&client->dev); in rpr0521_remove()
1049 mutex_lock(&data->lock); in rpr0521_runtime_suspend()
1051 if (!data->als_need_dis) in rpr0521_runtime_suspend()
1052 data->als_ps_need_en = data->als_dev_en; in rpr0521_runtime_suspend()
1053 if (!data->pxs_need_dis) in rpr0521_runtime_suspend()
1054 data->pxs_ps_need_en = data->pxs_dev_en; in rpr0521_runtime_suspend()
1058 regcache_mark_dirty(data->regmap); in rpr0521_runtime_suspend()
1059 mutex_unlock(&data->lock); in rpr0521_runtime_suspend()
1070 regcache_sync(data->regmap); in rpr0521_runtime_resume()
1071 if (data->als_ps_need_en) { in rpr0521_runtime_resume()
1075 data->als_ps_need_en = false; in rpr0521_runtime_resume()
1078 if (data->pxs_ps_need_en) { in rpr0521_runtime_resume()
1082 data->pxs_ps_need_en = false; in rpr0521_runtime_resume()