Lines Matching +full:sensor +full:- +full:gain

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * APDS9160 sensor driver.
4 * Chip is combined proximity and ambient light sensor.
5 * Author: 2024 Mikael Gonella-Bolduc <m.gonella.bolduc@gmail.com>
62 /* Light sensor registers */
198 /* Proximity sensor channel */
211 /* Proximity sensor led current */
242 /* Proximity sensor channel */
253 /* Proximity sensor led current */
337 * struct apds9160_scale - apds9160 scale mapping definition
340 * @gain: Gain multiplier
346 int gain; member
355 .gain = 1,
361 .gain = 3,
367 .gain = 6,
373 .gain = 18,
379 .gain = 54,
385 .gain = 1,
391 .gain = 3,
397 .gain = 6,
403 .gain = 18,
409 .gain = 54,
415 .gain = 1,
421 .gain = 3,
427 .gain = 6,
433 .gain = 18,
439 .gain = 54,
445 .gain = 1,
451 .gain = 3,
457 .gain = 6,
463 .gain = 18,
469 .gain = 54,
587 ret = regmap_field_write(data->reg_ps_rate, in apds9160_set_ps_rate()
591 data->ps_rate = val; in apds9160_set_ps_rate()
596 return -EINVAL; in apds9160_set_ps_rate()
609 ret = regmap_field_write(data->reg_ps_gain, in apds9160_set_ps_gain()
613 data->ps_gain = val; in apds9160_set_ps_gain()
618 return -EINVAL; in apds9160_set_ps_gain()
623 * for an on-chip substraction of the ADC count caused by
633 return -EINVAL; in apds9160_set_ps_cancellation_level()
636 ret = regmap_bulk_write(data->regmap, APDS9160_REG_PS_CAN_LEVEL_DIG_LSB, in apds9160_set_ps_cancellation_level()
641 data->ps_cancellation_level = val; in apds9160_set_ps_cancellation_level()
657 return -EINVAL; in apds9160_set_ps_analog_cancellation()
659 return regmap_write(data->regmap, APDS9160_REG_PS_CAN_LEVEL_ANA_DUR, in apds9160_set_ps_analog_cancellation()
676 return -EINVAL; in apds9160_set_ps_cancellation_current()
679 return -EINVAL; in apds9160_set_ps_cancellation_current()
684 return regmap_write(data->regmap, APDS9160_REG_PS_CAN_LEVEL_ANA_CURRENT, in apds9160_set_ps_cancellation_current()
694 "ps-cancellation-duration", &duration); in apds9160_ps_init_analog_cancellation()
701 "ps-cancellation-current-picoamp", &picoamp); in apds9160_ps_init_analog_cancellation()
706 return dev_err_probe(dev, -EINVAL, in apds9160_ps_init_analog_cancellation()
745 data->reg_ps_current, in apds9160_set_ps_current()
749 data->ps_current = val; in apds9160_set_ps_current()
754 return -EINVAL; in apds9160_set_ps_current()
757 static int apds9160_set_als_gain(struct apds9160_chip *data, int gain) in apds9160_set_als_gain() argument
764 if (gain != apds9160_als_gain_map[idx][0]) in apds9160_set_als_gain()
767 ret = regmap_field_write(data->reg_als_gain, in apds9160_set_als_gain()
771 data->als_hwgain = gain; in apds9160_set_als_gain()
776 return -EINVAL; in apds9160_set_als_gain()
784 if (apds9160_als_scale_map[idx].itime == data->als_itime && in apds9160_set_als_scale()
788 apds9160_als_scale_map[idx].gain); in apds9160_set_als_scale()
791 data->als_scale1 = val; in apds9160_set_als_scale()
792 data->als_scale2 = val2; in apds9160_set_als_scale()
798 return -EINVAL; in apds9160_set_als_scale()
805 return regmap_field_write(data->reg_als_resolution, in apds9160_set_als_resolution()
808 return regmap_field_write(data->reg_als_resolution, in apds9160_set_als_resolution()
811 return regmap_field_write(data->reg_als_resolution, in apds9160_set_als_resolution()
814 return regmap_field_write(data->reg_als_resolution, in apds9160_set_als_resolution()
827 return regmap_field_write(data->reg_als_rate, in apds9160_set_als_rate()
831 return -EINVAL; in apds9160_set_als_rate()
835 * Setting the integration time ajusts resolution, rate, scale and gain
851 data->als_itime = val; in apds9160_set_als_int_time()
853 /* Set the scale minimum gain */ in apds9160_set_als_int_time()
855 if (data->als_itime != apds9160_als_scale_map[idx].itime) in apds9160_set_als_int_time()
863 return -EINVAL; in apds9160_set_als_int_time()
875 switch (chan->type) { in apds9160_read_avail()
889 return -EINVAL; in apds9160_read_avail()
892 switch (chan->type) { in apds9160_read_avail()
901 switch (data->als_itime) { in apds9160_read_avail()
927 return -EINVAL; in apds9160_read_avail()
930 return -EINVAL; in apds9160_read_avail()
933 switch (chan->type) { in apds9160_read_avail()
941 return -EINVAL; in apds9160_read_avail()
945 return -EINVAL; in apds9160_read_avail()
965 return -EINVAL; in apds9160_write_raw_get_fmt()
978 switch (chan->type) { in apds9160_read_raw()
982 ret = regmap_bulk_read(data->regmap, chan->address, in apds9160_read_raw()
996 ret = regmap_bulk_read(data->regmap, chan->address, in apds9160_read_raw()
1005 *val = data->ps_current; in apds9160_read_raw()
1009 return -EINVAL; in apds9160_read_raw()
1012 switch (chan->type) { in apds9160_read_raw()
1014 *val = data->als_hwgain; in apds9160_read_raw()
1018 return -EINVAL; in apds9160_read_raw()
1021 switch (chan->type) { in apds9160_read_raw()
1023 *val = data->ps_rate; in apds9160_read_raw()
1027 *val = data->als_itime; in apds9160_read_raw()
1031 return -EINVAL; in apds9160_read_raw()
1034 switch (chan->type) { in apds9160_read_raw()
1036 *val = data->ps_cancellation_level; in apds9160_read_raw()
1040 return -EINVAL; in apds9160_read_raw()
1043 switch (chan->type) { in apds9160_read_raw()
1045 *val = data->ps_gain; in apds9160_read_raw()
1049 *val = data->als_scale1; in apds9160_read_raw()
1050 *val2 = data->als_scale2; in apds9160_read_raw()
1054 return -EINVAL; in apds9160_read_raw()
1057 return -EINVAL; in apds9160_read_raw()
1067 guard(mutex)(&data->lock); in apds9160_write_raw()
1072 return -EINVAL; in apds9160_write_raw()
1073 switch (chan->type) { in apds9160_write_raw()
1079 return -EINVAL; in apds9160_write_raw()
1082 switch (chan->type) { in apds9160_write_raw()
1088 return -EINVAL; in apds9160_write_raw()
1092 return -EINVAL; in apds9160_write_raw()
1093 switch (chan->type) { in apds9160_write_raw()
1097 return -EINVAL; in apds9160_write_raw()
1101 return -EINVAL; in apds9160_write_raw()
1102 switch (chan->type) { in apds9160_write_raw()
1106 return -EINVAL; in apds9160_write_raw()
1109 return -EINVAL; in apds9160_write_raw()
1118 switch (chan->type) { in apds9160_get_thres_reg()
1126 return -EINVAL; in apds9160_get_thres_reg()
1129 switch (chan->type) { in apds9160_get_thres_reg()
1137 return -EINVAL; in apds9160_get_thres_reg()
1141 return -EINVAL; in apds9160_get_thres_reg()
1158 return -EINVAL; in apds9160_read_event()
1164 switch (chan->type) { in apds9160_read_event()
1168 ret = regmap_bulk_read(data->regmap, reg, &buf, 2); in apds9160_read_event()
1177 ret = regmap_bulk_read(data->regmap, reg, &buf, 3); in apds9160_read_event()
1184 return -EINVAL; in apds9160_read_event()
1199 return -EINVAL; in apds9160_write_event()
1205 switch (chan->type) { in apds9160_write_event()
1210 return -EINVAL; in apds9160_write_event()
1213 return regmap_bulk_write(data->regmap, reg, &buf, 2); in apds9160_write_event()
1219 return -EINVAL; in apds9160_write_event()
1222 return regmap_bulk_write(data->regmap, reg, &buf, 3); in apds9160_write_event()
1225 return -EINVAL; in apds9160_write_event()
1236 switch (chan->type) { in apds9160_read_event_config()
1238 return data->ps_int; in apds9160_read_event_config()
1240 return data->als_int; in apds9160_read_event_config()
1242 return -EINVAL; in apds9160_read_event_config()
1254 switch (chan->type) { in apds9160_write_event_config()
1256 ret = regmap_field_write(data->reg_int_ps, state); in apds9160_write_event_config()
1259 data->ps_int = state; in apds9160_write_event_config()
1263 ret = regmap_field_write(data->reg_int_als, state); in apds9160_write_event_config()
1266 data->als_int = state; in apds9160_write_event_config()
1270 return -EINVAL; in apds9160_write_event_config()
1281 ret = regmap_read(data->regmap, APDS9160_REG_SR, &status); in apds9160_irq_handler()
1283 dev_err_ratelimited(&data->client->dev, in apds9160_irq_handler()
1289 (status & APDS9160_SR_LS_NEW_DATA) && data->als_int) { in apds9160_irq_handler()
1298 (status & APDS9160_SR_PS_NEW_DATA) && data->ps_int) { in apds9160_irq_handler()
1311 struct i2c_client *client = chip->client; in apds9160_detect()
1315 ret = regmap_read(chip->regmap, APDS9160_REG_ID, &val); in apds9160_detect()
1317 dev_err(&client->dev, "ID read failed\n"); in apds9160_detect()
1322 dev_info(&client->dev, "Unknown part id %u\n", val); in apds9160_detect()
1332 ret = regmap_field_write(data->reg_enable_als, 0); in apds9160_disable()
1336 regmap_field_write(data->reg_enable_ps, 0); in apds9160_disable()
1344 ret = regmap_field_write(chip->reg_int_ps, 0); in apds9160_chip_init()
1345 chip->ps_int = 0; in apds9160_chip_init()
1349 ret = regmap_field_write(chip->reg_int_als, 0); in apds9160_chip_init()
1350 chip->als_int = 0; in apds9160_chip_init()
1355 ret = regmap_field_write(chip->reg_enable_als, 1); in apds9160_chip_init()
1359 ret = regmap_field_write(chip->reg_enable_ps, 1); in apds9160_chip_init()
1364 ret = regmap_field_write(chip->reg_ps_resolution, in apds9160_chip_init()
1402 return devm_add_action_or_reset(&chip->client->dev, apds9160_disable, in apds9160_chip_init()
1408 struct device *dev = &data->client->dev; in apds9160_regfield_init()
1409 struct regmap *regmap = data->regmap; in apds9160_regfield_init()
1415 data->reg_int_als = tmp; in apds9160_regfield_init()
1420 data->reg_int_ps = tmp; in apds9160_regfield_init()
1425 data->reg_enable_als = tmp; in apds9160_regfield_init()
1430 data->reg_enable_ps = tmp; in apds9160_regfield_init()
1436 data->reg_ps_overflow = tmp; in apds9160_regfield_init()
1441 data->reg_als_rate = tmp; in apds9160_regfield_init()
1446 data->reg_als_resolution = tmp; in apds9160_regfield_init()
1451 data->reg_ps_rate = tmp; in apds9160_regfield_init()
1456 data->reg_als_gain = tmp; in apds9160_regfield_init()
1462 data->reg_ps_current = tmp; in apds9160_regfield_init()
1467 data->reg_ps_gain = tmp; in apds9160_regfield_init()
1473 data->reg_ps_resolution = tmp; in apds9160_regfield_init()
1498 struct device *dev = &client->dev; in apds9160_probe()
1505 return -ENOMEM; in apds9160_probe()
1511 indio_dev->name = "apds9160"; in apds9160_probe()
1512 indio_dev->modes = INDIO_DIRECT_MODE; in apds9160_probe()
1515 chip->client = client; in apds9160_probe()
1516 chip->regmap = devm_regmap_init_i2c(client, &apds9160_regmap_config); in apds9160_probe()
1517 if (IS_ERR(chip->regmap)) in apds9160_probe()
1518 return dev_err_probe(dev, PTR_ERR(chip->regmap), in apds9160_probe()
1521 chip->client = client; in apds9160_probe()
1522 mutex_init(&chip->lock); in apds9160_probe()
1540 if (client->irq > 0) { in apds9160_probe()
1541 indio_dev->info = &apds9160_info; in apds9160_probe()
1542 indio_dev->channels = apds9160_channels; in apds9160_probe()
1543 indio_dev->num_channels = ARRAY_SIZE(apds9160_channels); in apds9160_probe()
1544 ret = devm_request_threaded_irq(dev, client->irq, NULL, in apds9160_probe()
1551 client->irq); in apds9160_probe()
1554 indio_dev->info = &apds9160_info_no_events; in apds9160_probe()
1555 indio_dev->channels = apds9160_channels_without_events; in apds9160_probe()
1556 indio_dev->num_channels = in apds9160_probe()
1590 MODULE_DESCRIPTION("APDS9160 combined ALS and proximity sensor");
1591 MODULE_AUTHOR("Mikael Gonella-Bolduc <m.gonella.bolduc@gmail.com>");