Lines Matching +full:ch0 +full:- +full:2
1 // SPDX-License-Identifier: GPL-2.0-only
20 #include <linux/iio/iio-gts-helper.h>
28 #define BU27034_MASK_MEAS_MODE GENMASK(2, 0)
37 #define BU27034_NUM_HW_DATA_CHANS 2
52 * inevitable even if the sensor clock would be perfectly phase-locked to CPU
53 * clock - which we can't say is the case.
56 * risk of losing a sample because things can in a rainy-day scenario be
65 * Other option that was pointed to me would be always sleeping 1/2 of the
69 * Downside is that the time-stamps would be very inaccurate as the wake-up
71 * result 'jumps' in the time-stamps when the delay drifted so that wake-up was
72 * performed during the consecutive wake-ups (Or, when sensor and CPU clocks
73 * were very different and scheduling the wake-ups was very close to given
74 * timeout - and when the time-outs were very close to the actual sensor
75 * sampling, Eg. once in a blue moon, two consecutive time-outs would occur
97 * Available scales with gain 1x - 1024x, timings 55, 100, 200, 400 mS
98 * Time impacts to gain: 1x, 2x, 4x, 8x.
101 * if 1x gain is scale 1, scale for 2x gain is 0.5, 4x => 0.25,
128 * Measurement modes are 55, 100, 200 and 400 mS modes - which do have direct
131 * This means that if meas-mode is changed for example from 400 => 200,
136 #define BU27034_MEAS_MODE_200MS 2
142 GAIN_SCALE_ITIME_US(100000, BU27034_MEAS_MODE_100MS, 2),
186 * sub-optiomal candidates for R/G/B standardization. Hence the
268 ret = regmap_read(data->regmap, reg[chan], &val); in bu27034_get_gain_sel()
285 ret = iio_gts_find_gain_by_sel(&data->gts, sel); in bu27034_get_gain()
287 dev_err(data->dev, "chan %u: unknown gain value 0x%x\n", chan, in bu27034_get_gain()
302 ret = regmap_read(data->regmap, BU27034_REG_MODE_CONTROL1, &sel); in bu27034_get_int_time()
306 return iio_gts_find_int_time_by_sel(&data->gts, in bu27034_get_int_time()
323 return iio_gts_get_scale(&data->gts, gain, ret, val, val2); in _bu27034_get_scale()
337 mutex_lock(&data->mutex); in bu27034_get_scale()
339 mutex_unlock(&data->mutex); in bu27034_get_scale()
358 return regmap_update_bits(data->regmap, reg[chan], mask, val); in bu27034_write_gain_sel()
365 ret = iio_gts_find_sel_by_gain(&data->gts, gain); in bu27034_set_gain()
372 /* Caller should hold the lock to protect data->int_time */
377 ret = iio_gts_find_sel_by_int_time(&data->gts, time); in bu27034_set_int_time()
381 return regmap_update_bits(data->regmap, BU27034_REG_MODE_CONTROL1, in bu27034_set_int_time()
398 mutex_lock(&data->mutex); in bu27034_try_set_int_time()
405 if (!iio_gts_valid_time(&data->gts, time_us)) { in bu27034_try_set_int_time()
406 dev_err(data->dev, "Unsupported integration time %u\n", in bu27034_try_set_int_time()
408 ret = -EINVAL; in bu27034_try_set_int_time()
423 ret = iio_gts_find_new_gain_by_old_gain_time(&data->gts, in bu27034_try_set_int_time()
432 dev_dbg(data->dev, in bu27034_try_set_int_time()
441 * can't support the scale - then the caller should be in bu27034_try_set_int_time()
445 ret = iio_find_closest_gain_low(&data->gts, in bu27034_try_set_int_time()
449 dev_dbg(data->dev, in bu27034_try_set_int_time()
454 dev_dbg(data->dev, in bu27034_try_set_int_time()
456 ret = iio_gts_get_min_gain(&data->gts); in bu27034_try_set_int_time()
460 dev_dbg(data->dev, "chan %u scale changed\n", in bu27034_try_set_int_time()
463 dev_dbg(data->dev, "chan %u new gain %u\n", in bu27034_try_set_int_time()
477 mutex_unlock(&data->mutex); in bu27034_try_set_int_time()
492 return -EINVAL; in bu27034_set_scale()
495 mutex_lock(&data->mutex); in bu27034_set_scale()
496 ret = regmap_read(data->regmap, BU27034_REG_MODE_CONTROL1, &time_sel); in bu27034_set_scale()
500 ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts, time_sel, in bu27034_set_scale()
528 for (i = 0; i < data->gts.num_itime; i++) { in bu27034_set_scale()
529 new_time_sel = data->gts.itime_table[i].sel; in bu27034_set_scale()
536 &data->gts, new_time_sel, val, val2, in bu27034_set_scale()
543 &data->gts, gain.old_gain, time_sel, in bu27034_set_scale()
546 /* Yes - we found suitable time */ in bu27034_set_scale()
552 dev_dbg(data->dev, in bu27034_set_scale()
554 ret = -EINVAL; in bu27034_set_scale()
563 ret = regmap_update_bits(data->regmap, BU27034_REG_MODE_CONTROL1, in bu27034_set_scale()
571 mutex_unlock(&data->mutex); in bu27034_set_scale()
578 * lx = (0.001193 * D0 + (-0.0000747) * D1) * ((D1/D0 – 1.5) * (0.25) + 1)
580 * => -0.000745625 * D0 + 0.0002515625 * D1 + -0.000018675 * D1 * D1 / D0
582 * => (6.44 * ch1 / gain1 + 19.088 * ch0 / gain0 -
583 * 0.47808 * ch1 * ch1 * gain0 / gain1 / gain1 / ch0) /
587 * lx = 0.001193 * D0 - 0.0000747 * D1
589 * => (1.91232 * ch1 / gain1 + 30.5408 * ch0 / gain0 +
590 * [0 * ch1 * ch1 * gain0 / gain1 / gain1 / ch0] ) /
595 * A * ch1 * ch1 * gain0 / (ch0 * gain1 * gain1) +
597 * C * ch0 / gain0
601 * A = -0.47808,
605 * For case 2:
644 static u64 bu27034_fixp_calc_t1_64bit(unsigned int coeff, unsigned int ch0, in bu27034_fixp_calc_t1_64bit() argument
654 if (helper > ch0) { in bu27034_fixp_calc_t1_64bit()
657 return gain_mul_div_helper(helper64, gain0, ch0); in bu27034_fixp_calc_t1_64bit()
660 do_div(helper64, ch0); in bu27034_fixp_calc_t1_64bit()
666 static u64 bu27034_fixp_calc_t1(unsigned int coeff, unsigned int ch0, in bu27034_fixp_calc_t1() argument
674 * multiply with gain0 only after the divisions - even though in bu27034_fixp_calc_t1()
683 return bu27034_fixp_calc_t1_64bit(coeff, ch0, ch1, gain0, gain1); in bu27034_fixp_calc_t1()
686 return bu27034_fixp_calc_t1_64bit(coeff, ch0, ch1, gain0, gain1); in bu27034_fixp_calc_t1()
688 return tmp / (gain1 * gain1) / ch0; in bu27034_fixp_calc_t1()
707 static int bu27034_fixp_calc_lx(unsigned int ch0, unsigned int ch1, in bu27034_fixp_calc_lx() argument
713 .A = 4780800, /* -0.47808 */ in bu27034_fixp_calc_lx()
729 return -EINVAL; in bu27034_fixp_calc_lx()
731 terms[0] = bu27034_fixp_calc_t1(c->A, ch0, ch1, gain0, gain1); in bu27034_fixp_calc_lx()
732 terms[1] = bu27034_fixp_calc_t23(c->B, ch1, gain1); in bu27034_fixp_calc_lx()
733 terms[2] = bu27034_fixp_calc_t23(c->C, ch0, gain0); in bu27034_fixp_calc_lx()
737 if (!c->is_neg[i]) in bu27034_fixp_calc_lx()
746 if (c->is_neg[i]) { in bu27034_fixp_calc_lx()
748 * If the negative term is greater than positive - then in bu27034_fixp_calc_lx()
755 res -= terms[i]; in bu27034_fixp_calc_lx()
768 ret = regmap_read(data->regmap, BU27034_REG_MODE_CONTROL4, &val); in bu27034_has_valid_sample()
770 dev_err(data->dev, "Read failed %d\n", ret); in bu27034_has_valid_sample()
798 ret = regmap_read_poll_timeout(data->regmap, BU27034_REG_MODE_CONTROL4, in bu27034_read_result()
804 ret = regmap_bulk_read(data->regmap, reg[chan], &val, sizeof(val)); in bu27034_read_result()
821 ret = regmap_bulk_read(data->regmap, BU27034_REG_DATA0_LO, in bu27034_get_result_unlocked()
832 dev_err(data->dev, "No data from sensor\n"); in bu27034_get_result_unlocked()
834 return -ETIMEDOUT; in bu27034_get_result_unlocked()
848 return regmap_set_bits(data->regmap, BU27034_REG_MODE_CONTROL4, in bu27034_meas_set()
851 return regmap_clear_bits(data->regmap, BU27034_REG_MODE_CONTROL4, in bu27034_meas_set()
861 return -EINVAL; in bu27034_get_single_result()
886 * lx = (0.001193 * D0 + (-0.0000747) * D1) * ((D1 / D0 – 1.5) * 0.25 + 1)
888 * lx = (0.001193 * D0 + (-0.0000747) * D1)
899 u16 ch0, ch1; in bu27034_calc_mlux() local
905 * easy to spot from the buffers especially if raw-data channels show in bu27034_calc_mlux()
910 ch0 = max_t(u16, 1, le16_to_cpu(res[0])); in bu27034_calc_mlux()
931 unsigned int div = (unsigned int)ch0 * gain1; in bu27034_calc_mlux()
936 d1_d0_ratio_scaled /= ch0 * gain1; in bu27034_calc_mlux()
940 ret = bu27034_fixp_calc_lx(ch0, ch1, gain0, gain1, meastime, 0); in bu27034_calc_mlux()
942 ret = bu27034_fixp_calc_lx(ch0, ch1, gain0, gain1, meastime, 1); in bu27034_calc_mlux()
972 dev_err(data->dev, "failed to disable measurement\n"); in bu27034_get_mlux()
994 ret = bu27034_get_gain(data, chan->channel, val); in bu27034_read_raw()
1001 return bu27034_get_scale(data, chan->channel, val, val2); in bu27034_read_raw()
1007 if (chan->type == IIO_INTENSITY) in bu27034_read_raw()
1009 else if (chan->type == IIO_LIGHT) in bu27034_read_raw()
1012 return -EINVAL; in bu27034_read_raw()
1019 mutex_lock(&data->mutex); in bu27034_read_raw()
1025 ret = result_get(data, chan->channel, val); in bu27034_read_raw()
1027 mutex_unlock(&data->mutex); in bu27034_read_raw()
1036 return -EINVAL; in bu27034_read_raw()
1052 dev_dbg(data->dev, in bu27034_write_raw_get_fmt()
1053 "HARDWAREGAIN is read-only, use scale to set\n"); in bu27034_write_raw_get_fmt()
1054 return -EINVAL; in bu27034_write_raw_get_fmt()
1056 return -EINVAL; in bu27034_write_raw_get_fmt()
1073 ret = bu27034_set_scale(data, chan->channel, val, val2); in bu27034_write_raw()
1079 ret = -EINVAL; in bu27034_write_raw()
1082 ret = -EINVAL; in bu27034_write_raw()
1099 return iio_gts_avail_times(&data->gts, vals, type, length); in bu27034_read_avail()
1101 return iio_gts_all_avail_scales(&data->gts, vals, type, length); in bu27034_read_avail()
1103 return -EINVAL; in bu27034_read_avail()
1119 ret = regmap_write_bits(data->regmap, BU27034_REG_SYSTEM_CONTROL, in bu27034_chip_init()
1122 return dev_err_probe(data->dev, ret, "Sensor reset failed\n"); in bu27034_chip_init()
1126 ret = regmap_reinit_cache(data->regmap, &bu27034_regmap); in bu27034_chip_init()
1128 dev_err(data->dev, "Failed to reinit reg cache\n"); in bu27034_chip_init()
1134 * this to speed-up the int-time acquisition in the start of the buffer in bu27034_chip_init()
1139 ret = regmap_read(data->regmap, BU27034_REG_MODE_CONTROL1, &sel); in bu27034_chip_init()
1141 dev_err(data->dev, "reading integration time failed\n"); in bu27034_chip_init()
1150 ret = regmap_read_poll_timeout(data->regmap, BU27034_REG_MODE_CONTROL4, in bu27034_wait_for_data()
1155 dev_err(data->dev, "data polling %s\n", in bu27034_wait_for_data()
1161 ret = regmap_bulk_read(data->regmap, BU27034_REG_DATA0_LO, in bu27034_wait_for_data()
1162 &data->scan.channels[0], in bu27034_wait_for_data()
1163 sizeof(data->scan.channels)); in bu27034_wait_for_data()
1183 wait_ms -= BU27034_MEAS_WAIT_PREMATURE_MS; in bu27034_buffer_thread()
1196 if (test_bit(BU27034_CHAN_ALS, idev->active_scan_mask)) { in bu27034_buffer_thread()
1199 ret = bu27034_calc_mlux(data, &data->scan.channels[0], in bu27034_buffer_thread()
1202 dev_err(data->dev, "failed to calculate lux\n"); in bu27034_buffer_thread()
1206 * 55mS data ch0 = 0xffff ch1 = 0xffff fits in 26 bits in bu27034_buffer_thread()
1210 data->scan.mlux = (u32)mlux; in bu27034_buffer_thread()
1212 iio_push_to_buffers_with_timestamp(idev, &data->scan, tstamp); in bu27034_buffer_thread()
1224 mutex_lock(&data->mutex); in bu27034_buffer_enable()
1230 "bu27034-buffering-%u", in bu27034_buffer_enable()
1237 data->task = task; in bu27034_buffer_enable()
1240 mutex_unlock(&data->mutex); in bu27034_buffer_enable()
1250 mutex_lock(&data->mutex); in bu27034_buffer_disable()
1251 if (data->task) { in bu27034_buffer_disable()
1252 kthread_stop(data->task); in bu27034_buffer_disable()
1253 data->task = NULL; in bu27034_buffer_disable()
1257 mutex_unlock(&data->mutex); in bu27034_buffer_disable()
1269 struct device *dev = &i2c->dev; in bu27034_probe()
1283 return -ENOMEM; in bu27034_probe()
1302 ARRAY_SIZE(bu27034_itimes), &data->gts); in bu27034_probe()
1306 mutex_init(&data->mutex); in bu27034_probe()
1307 data->regmap = regmap; in bu27034_probe()
1308 data->dev = dev; in bu27034_probe()
1310 idev->channels = bu27034_channels; in bu27034_probe()
1311 idev->num_channels = ARRAY_SIZE(bu27034_channels); in bu27034_probe()
1312 idev->name = "bu27034"; in bu27034_probe()
1313 idev->info = &bu27034_info; in bu27034_probe()
1315 idev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; in bu27034_probe()
1316 idev->available_scan_masks = bu27034_scan_masks; in bu27034_probe()
1342 .name = "bu27034-als",