Lines Matching +full:sar +full:- +full:threshold

1 // SPDX-License-Identifier: GPL-2.0
3 * Amlogic Meson Successive Approximation Register (SAR) A/D Converter
10 #include <linux/clk-provider.h>
16 #include <linux/nvmem-consumer.h>
96 (8 + (((_chan) - 2) * 3))
153 * and u-boot source served as reference). These only seem to be relevant on
380 for (i = 0; i < indio_dev->num_channels; i++) in find_channel_by_num()
381 if (indio_dev->channels[i].channel == num) in find_channel_by_num()
382 return &indio_dev->channels[i]; in find_channel_by_num()
391 regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval); in meson_sar_adc_get_fifo_count()
402 tmp = div_s64((s64)val * priv->calibscale, MILLION) + priv->calibbias; in meson_sar_adc_calib_val()
404 return clamp(tmp, 0, (1 << priv->param->resolution) - 1); in meson_sar_adc_calib_val()
418 return regmap_read_poll_timeout_atomic(priv->regmap, MESON_SAR_ADC_REG0, val, in meson_sar_adc_wait_busy_clear()
430 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, in meson_sar_adc_set_chan7_mux()
435 priv->chan7_mux_sel = sel; in meson_sar_adc_set_chan7_mux()
443 struct device *dev = indio_dev->dev.parent; in meson_sar_adc_read_raw_sample()
446 if (!wait_for_completion_timeout(&priv->done, in meson_sar_adc_read_raw_sample()
448 return -ETIMEDOUT; in meson_sar_adc_read_raw_sample()
453 return -EINVAL; in meson_sar_adc_read_raw_sample()
456 regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &regval); in meson_sar_adc_read_raw_sample()
458 if (fifo_chan != chan->address) { in meson_sar_adc_read_raw_sample()
460 fifo_chan, chan->address); in meson_sar_adc_read_raw_sample()
461 return -EINVAL; in meson_sar_adc_read_raw_sample()
465 fifo_val &= GENMASK(priv->param->resolution - 1, 0); in meson_sar_adc_read_raw_sample()
477 int val, address = chan->address; in meson_sar_adc_set_averaging()
480 regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL, in meson_sar_adc_set_averaging()
485 regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL, in meson_sar_adc_set_averaging()
496 * the SAR ADC engine allows sampling multiple channels at the same in meson_sar_adc_enable_channel()
501 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST, in meson_sar_adc_enable_channel()
506 chan->address); in meson_sar_adc_enable_channel()
507 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST, in meson_sar_adc_enable_channel()
511 chan->address); in meson_sar_adc_enable_channel()
512 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW, in meson_sar_adc_enable_channel()
517 chan->address); in meson_sar_adc_enable_channel()
518 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW, in meson_sar_adc_enable_channel()
522 if (chan->address == MESON_SAR_ADC_VOLTAGE_AND_TEMP_CHANNEL) { in meson_sar_adc_enable_channel()
523 if (chan->type == IIO_TEMP) in meson_sar_adc_enable_channel()
528 regmap_update_bits(priv->regmap, in meson_sar_adc_enable_channel()
531 } else if (chan->address == MESON_SAR_ADC_VOLTAGE_AND_MUX_CHANNEL) { in meson_sar_adc_enable_channel()
534 if (chan->channel == NUM_CHAN_7) in meson_sar_adc_enable_channel()
537 sel = chan7_mux_values[chan->channel - NUM_MUX_0_VSS]; in meson_sar_adc_enable_channel()
538 if (sel != priv->chan7_mux_sel) in meson_sar_adc_enable_channel()
547 reinit_completion(&priv->done); in meson_sar_adc_start_sample_engine()
549 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, in meson_sar_adc_start_sample_engine()
553 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, in meson_sar_adc_start_sample_engine()
557 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, in meson_sar_adc_start_sample_engine()
566 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, in meson_sar_adc_stop_sample_engine()
569 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, in meson_sar_adc_stop_sample_engine()
576 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, in meson_sar_adc_stop_sample_engine()
585 mutex_lock(&priv->lock); in meson_sar_adc_lock()
587 if (priv->param->has_bl30_integration) { in meson_sar_adc_lock()
588 /* prevent BL30 from using the SAR ADC while we are using it */ in meson_sar_adc_lock()
589 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, in meson_sar_adc_lock()
596 * wait until BL30 releases it's lock (so we can use the SAR in meson_sar_adc_lock()
599 ret = regmap_read_poll_timeout_atomic(priv->regmap, MESON_SAR_ADC_DELAY, val, in meson_sar_adc_lock()
603 mutex_unlock(&priv->lock); in meson_sar_adc_lock()
615 if (priv->param->has_bl30_integration) in meson_sar_adc_unlock()
616 /* allow BL30 to use the SAR ADC again */ in meson_sar_adc_unlock()
617 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, in meson_sar_adc_unlock()
620 mutex_unlock(&priv->lock); in meson_sar_adc_unlock()
632 regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &tmp); in meson_sar_adc_clear_fifo()
643 struct device *dev = indio_dev->dev.parent; in meson_sar_adc_get_sample()
646 if (chan->type == IIO_TEMP && !priv->temperature_sensor_calibrated) in meson_sar_adc_get_sample()
647 return -ENOTSUPP; in meson_sar_adc_get_sample()
668 chan->address, ret); in meson_sar_adc_get_sample()
680 struct device *dev = indio_dev->dev.parent; in meson_sar_adc_iio_info_read_raw()
694 if (chan->type == IIO_VOLTAGE) { in meson_sar_adc_iio_info_read_raw()
695 ret = regulator_get_voltage(priv->vref); in meson_sar_adc_iio_info_read_raw()
702 *val2 = priv->param->resolution; in meson_sar_adc_iio_info_read_raw()
704 } else if (chan->type == IIO_TEMP) { in meson_sar_adc_iio_info_read_raw()
706 *val = priv->param->temperature_multiplier; in meson_sar_adc_iio_info_read_raw()
707 *val2 = priv->param->temperature_divider; in meson_sar_adc_iio_info_read_raw()
714 return -EINVAL; in meson_sar_adc_iio_info_read_raw()
718 *val = priv->calibbias; in meson_sar_adc_iio_info_read_raw()
722 *val = priv->calibscale / MILLION; in meson_sar_adc_iio_info_read_raw()
723 *val2 = priv->calibscale % MILLION; in meson_sar_adc_iio_info_read_raw()
728 priv->param->temperature_divider, in meson_sar_adc_iio_info_read_raw()
729 priv->param->temperature_multiplier); in meson_sar_adc_iio_info_read_raw()
730 *val -= priv->temperature_sensor_adc_val; in meson_sar_adc_iio_info_read_raw()
734 return -EINVAL; in meson_sar_adc_iio_info_read_raw()
742 struct device *dev = indio_dev->dev.parent; in meson_sar_adc_clk_init()
748 return -ENOMEM; in meson_sar_adc_clk_init()
752 clk_parents[0] = __clk_get_name(priv->clkin); in meson_sar_adc_clk_init()
756 priv->clk_div.reg = base + MESON_SAR_ADC_REG3; in meson_sar_adc_clk_init()
757 priv->clk_div.shift = MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT; in meson_sar_adc_clk_init()
758 priv->clk_div.width = MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH; in meson_sar_adc_clk_init()
759 priv->clk_div.hw.init = &init; in meson_sar_adc_clk_init()
760 priv->clk_div.flags = 0; in meson_sar_adc_clk_init()
762 priv->adc_div_clk = devm_clk_register(dev, &priv->clk_div.hw); in meson_sar_adc_clk_init()
763 if (WARN_ON(IS_ERR(priv->adc_div_clk))) in meson_sar_adc_clk_init()
764 return PTR_ERR(priv->adc_div_clk); in meson_sar_adc_clk_init()
768 return -ENOMEM; in meson_sar_adc_clk_init()
772 clk_parents[0] = __clk_get_name(priv->adc_div_clk); in meson_sar_adc_clk_init()
776 priv->clk_gate.reg = base + MESON_SAR_ADC_REG3; in meson_sar_adc_clk_init()
777 priv->clk_gate.bit_idx = __ffs(MESON_SAR_ADC_REG3_CLK_EN); in meson_sar_adc_clk_init()
778 priv->clk_gate.hw.init = &init; in meson_sar_adc_clk_init()
780 priv->adc_clk = devm_clk_register(dev, &priv->clk_gate.hw); in meson_sar_adc_clk_init()
781 if (WARN_ON(IS_ERR(priv->adc_clk))) in meson_sar_adc_clk_init()
782 return PTR_ERR(priv->adc_clk); in meson_sar_adc_clk_init()
791 struct device *dev = indio_dev->dev.parent; in meson_sar_adc_temp_sensor_init()
802 * was passed via nvmem-cells. in meson_sar_adc_temp_sensor_init()
804 if (ret == -ENODEV) in meson_sar_adc_temp_sensor_init()
810 priv->tsc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "amlogic,hhi-sysctrl"); in meson_sar_adc_temp_sensor_init()
811 if (IS_ERR(priv->tsc_regmap)) in meson_sar_adc_temp_sensor_init()
812 return dev_err_probe(dev, PTR_ERR(priv->tsc_regmap), in meson_sar_adc_temp_sensor_init()
813 "failed to get amlogic,hhi-sysctrl regmap\n"); in meson_sar_adc_temp_sensor_init()
821 return dev_err_probe(dev, -EINVAL, "invalid read size of temperature_calib cell\n"); in meson_sar_adc_temp_sensor_init()
824 trimming_bits = priv->param->temperature_trimming_bits; in meson_sar_adc_temp_sensor_init()
825 trimming_mask = BIT(trimming_bits) - 1; in meson_sar_adc_temp_sensor_init()
827 priv->temperature_sensor_calibrated = in meson_sar_adc_temp_sensor_init()
829 priv->temperature_sensor_coefficient = buf[2] & trimming_mask; in meson_sar_adc_temp_sensor_init()
834 priv->temperature_sensor_adc_val = buf[2]; in meson_sar_adc_temp_sensor_init()
835 priv->temperature_sensor_adc_val |= upper_adc_val << BITS_PER_BYTE; in meson_sar_adc_temp_sensor_init()
836 priv->temperature_sensor_adc_val >>= trimming_bits; in meson_sar_adc_temp_sensor_init()
846 struct device *dev = indio_dev->dev.parent; in meson_sar_adc_init()
855 if (priv->param->has_bl30_integration) { in meson_sar_adc_init()
861 regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval); in meson_sar_adc_init()
872 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, in meson_sar_adc_init()
876 regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0); in meson_sar_adc_init()
878 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, in meson_sar_adc_init()
880 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, in meson_sar_adc_init()
885 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, in meson_sar_adc_init()
889 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, in meson_sar_adc_init()
895 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, in meson_sar_adc_init()
899 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY, in meson_sar_adc_init()
909 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW, in meson_sar_adc_init()
913 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW, in meson_sar_adc_init()
917 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW, in meson_sar_adc_init()
921 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW, in meson_sar_adc_init()
925 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW, in meson_sar_adc_init()
929 regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_10_SW, in meson_sar_adc_init()
944 regmap_write(priv->regmap, MESON_SAR_ADC_AUX_SW, regval); in meson_sar_adc_init()
946 if (priv->temperature_sensor_calibrated) { in meson_sar_adc_init()
947 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, in meson_sar_adc_init()
950 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, in meson_sar_adc_init()
959 priv->temperature_sensor_coefficient); in meson_sar_adc_init()
960 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, in meson_sar_adc_init()
963 if (priv->param->temperature_trimming_bits == 5) { in meson_sar_adc_init()
964 if (priv->temperature_sensor_coefficient & BIT(4)) in meson_sar_adc_init()
973 regmap_update_bits(priv->tsc_regmap, in meson_sar_adc_init()
979 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, in meson_sar_adc_init()
981 regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, in meson_sar_adc_init()
986 priv->param->disable_ring_counter); in meson_sar_adc_init()
987 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, in meson_sar_adc_init()
991 if (priv->param->has_reg11) { in meson_sar_adc_init()
992 regval = FIELD_PREP(MESON_SAR_ADC_REG11_EOC, priv->param->adc_eoc); in meson_sar_adc_init()
993 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, in meson_sar_adc_init()
996 if (priv->param->has_vref_select) { in meson_sar_adc_init()
998 priv->param->vref_select); in meson_sar_adc_init()
999 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, in meson_sar_adc_init()
1004 priv->param->vref_volatge); in meson_sar_adc_init()
1005 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, in meson_sar_adc_init()
1009 priv->param->cmv_select); in meson_sar_adc_init()
1010 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11, in meson_sar_adc_init()
1014 ret = clk_set_parent(priv->adc_sel_clk, priv->clkin); in meson_sar_adc_init()
1018 ret = clk_set_rate(priv->adc_clk, priv->param->clock_rate); in meson_sar_adc_init()
1028 const struct meson_sar_adc_param *param = priv->param; in meson_sar_adc_set_bandgap()
1031 if (param->bandgap_reg == MESON_SAR_ADC_REG11) in meson_sar_adc_set_bandgap()
1036 regmap_update_bits(priv->regmap, param->bandgap_reg, enable_mask, in meson_sar_adc_set_bandgap()
1043 struct device *dev = indio_dev->dev.parent; in meson_sar_adc_hw_enable()
1051 ret = regulator_enable(priv->vref); in meson_sar_adc_hw_enable()
1058 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, in meson_sar_adc_hw_enable()
1063 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, in meson_sar_adc_hw_enable()
1069 ret = clk_prepare_enable(priv->adc_clk); in meson_sar_adc_hw_enable()
1080 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, in meson_sar_adc_hw_enable()
1083 regulator_disable(priv->vref); in meson_sar_adc_hw_enable()
1101 dev_err(indio_dev->dev.parent, "Failed to lock ADC (%pE)\n", ERR_PTR(ret)); in meson_sar_adc_hw_disable()
1103 clk_disable_unprepare(priv->adc_clk); in meson_sar_adc_hw_disable()
1105 regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3, in meson_sar_adc_hw_disable()
1110 regulator_disable(priv->vref); in meson_sar_adc_hw_disable()
1120 unsigned int cnt, threshold; in meson_sar_adc_irq() local
1123 regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval); in meson_sar_adc_irq()
1125 threshold = FIELD_GET(MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK, regval); in meson_sar_adc_irq()
1127 if (cnt < threshold) in meson_sar_adc_irq()
1130 complete(&priv->done); in meson_sar_adc_irq()
1141 nominal0 = (1 << priv->param->resolution) / 4; in meson_sar_adc_calib()
1142 nominal1 = (1 << priv->param->resolution) * 3 / 4; in meson_sar_adc_calib()
1163 ret = -EINVAL; in meson_sar_adc_calib()
1167 priv->calibscale = div_s64((nominal1 - nominal0) * (s64)MILLION, in meson_sar_adc_calib()
1168 value1 - value0); in meson_sar_adc_calib()
1169 priv->calibbias = nominal0 - div_s64((s64)value0 * priv->calibscale, in meson_sar_adc_calib()
1182 if (chan->type == IIO_TEMP) in read_label()
1183 return sprintf(label, "temp-sensor\n"); in read_label()
1184 if (chan->type == IIO_VOLTAGE && chan->channel >= NUM_MUX_0_VSS) in read_label()
1186 chan7_mux_names[chan->channel - NUM_MUX_0_VSS]); in read_label()
1187 if (chan->type == IIO_VOLTAGE) in read_label()
1188 return sprintf(label, "channel-%d\n", chan->channel); in read_label()
1271 .name = "meson-meson8-saradc",
1276 .name = "meson-meson8b-saradc",
1281 .name = "meson-meson8m2-saradc",
1286 .name = "meson-gxbb-saradc",
1291 .name = "meson-gxl-saradc",
1296 .name = "meson-gxm-saradc",
1301 .name = "meson-axg-saradc",
1306 .name = "meson-g12a-saradc",
1311 .compatible = "amlogic,meson8-saradc",
1314 .compatible = "amlogic,meson8b-saradc",
1317 .compatible = "amlogic,meson8m2-saradc",
1320 .compatible = "amlogic,meson-gxbb-saradc",
1323 .compatible = "amlogic,meson-gxl-saradc",
1326 .compatible = "amlogic,meson-gxm-saradc",
1329 .compatible = "amlogic,meson-axg-saradc",
1332 .compatible = "amlogic,meson-g12a-saradc",
1343 struct device *dev = &pdev->dev; in meson_sar_adc_probe()
1350 return dev_err_probe(dev, -ENOMEM, "failed allocating iio device\n"); in meson_sar_adc_probe()
1353 init_completion(&priv->done); in meson_sar_adc_probe()
1357 return dev_err_probe(dev, -ENODEV, "failed to get match data\n"); in meson_sar_adc_probe()
1359 priv->param = match_data->param; in meson_sar_adc_probe()
1361 indio_dev->name = match_data->name; in meson_sar_adc_probe()
1362 indio_dev->modes = INDIO_DIRECT_MODE; in meson_sar_adc_probe()
1363 indio_dev->info = &meson_sar_adc_iio_info; in meson_sar_adc_probe()
1369 priv->regmap = devm_regmap_init_mmio(dev, base, priv->param->regmap_config); in meson_sar_adc_probe()
1370 if (IS_ERR(priv->regmap)) in meson_sar_adc_probe()
1371 return PTR_ERR(priv->regmap); in meson_sar_adc_probe()
1373 irq = irq_of_parse_and_map(dev->of_node, 0); in meson_sar_adc_probe()
1375 return -EINVAL; in meson_sar_adc_probe()
1381 priv->clkin = devm_clk_get(dev, "clkin"); in meson_sar_adc_probe()
1382 if (IS_ERR(priv->clkin)) in meson_sar_adc_probe()
1383 return dev_err_probe(dev, PTR_ERR(priv->clkin), "failed to get clkin\n"); in meson_sar_adc_probe()
1385 priv->core_clk = devm_clk_get_enabled(dev, "core"); in meson_sar_adc_probe()
1386 if (IS_ERR(priv->core_clk)) in meson_sar_adc_probe()
1387 return dev_err_probe(dev, PTR_ERR(priv->core_clk), "failed to get core clk\n"); in meson_sar_adc_probe()
1389 priv->adc_clk = devm_clk_get_optional(dev, "adc_clk"); in meson_sar_adc_probe()
1390 if (IS_ERR(priv->adc_clk)) in meson_sar_adc_probe()
1391 return dev_err_probe(dev, PTR_ERR(priv->adc_clk), "failed to get adc clk\n"); in meson_sar_adc_probe()
1393 priv->adc_sel_clk = devm_clk_get_optional(dev, "adc_sel"); in meson_sar_adc_probe()
1394 if (IS_ERR(priv->adc_sel_clk)) in meson_sar_adc_probe()
1395 return dev_err_probe(dev, PTR_ERR(priv->adc_sel_clk), "failed to get adc_sel clk\n"); in meson_sar_adc_probe()
1397 /* on pre-GXBB SoCs the SAR ADC itself provides the ADC clock: */ in meson_sar_adc_probe()
1398 if (!priv->adc_clk) { in meson_sar_adc_probe()
1404 priv->vref = devm_regulator_get(dev, "vref"); in meson_sar_adc_probe()
1405 if (IS_ERR(priv->vref)) in meson_sar_adc_probe()
1406 return dev_err_probe(dev, PTR_ERR(priv->vref), "failed to get vref regulator\n"); in meson_sar_adc_probe()
1408 priv->calibscale = MILLION; in meson_sar_adc_probe()
1410 if (priv->param->temperature_trimming_bits) { in meson_sar_adc_probe()
1416 if (priv->temperature_sensor_calibrated) { in meson_sar_adc_probe()
1417 indio_dev->channels = meson_sar_adc_and_temp_iio_channels; in meson_sar_adc_probe()
1418 indio_dev->num_channels = in meson_sar_adc_probe()
1421 indio_dev->channels = meson_sar_adc_iio_channels; in meson_sar_adc_probe()
1422 indio_dev->num_channels = in meson_sar_adc_probe()
1430 mutex_init(&priv->lock); in meson_sar_adc_probe()
1472 clk_disable_unprepare(priv->core_clk); in meson_sar_adc_suspend()
1483 ret = clk_prepare_enable(priv->core_clk); in meson_sar_adc_resume()
1499 .name = "meson-saradc",
1508 MODULE_DESCRIPTION("Amlogic Meson SAR ADC driver");