Lines Matching full:adc
3 * IIO driver for MCP356X/MCP356XR and MCP346X/MCP346XR series ADC chip family
14 …MCP3461-2-4-Two-Four-Eight-Channel-153.6-ksps-Low-Noise-16-Bit-Delta-Sigma-ADC-Data-Sheet-20006180…
64 * ADC Output Data Format 32-bit (25-bit right justified data + Channel ID):
65 * CHID[3:0] + SGN extension (4 bits) + 24-bit ADC data.
70 * ADC Output Data Format 32-bit (25-bit right justified data):
71 * SGN extension (8-bit) + 24-bit ADC data.
76 * ADC Output Data Format 32-bit (24-bit left justified data):
77 * 24-bit ADC data + 0x00 (8-bit).
78 * It does not allow overrange (ADC code locked to 0xFFFFFF or 0x800000).
82 * ADC Output Data Format 24-bit (default ADC coding):
83 * 24-bit ADC data.
84 * It does not allow overrange (ADC code locked to 0xFFFFFF or 0x800000).
97 * One-shot conversion or one-shot cycle in SCAN mode. It sets ADC_MODE[1:0] to ‘0x’ (ADC
286 * BOOST[1:0]: ADC Bias Current Selection
338 * @resolution: ADC resolution
349 * struct mcp3564_state - working data for a ADC device
357 * @oversampling: the index inside oversampling list of the ADC
358 * @hwgain: the index inside hardware gain list of the ADC
362 * @current_boost_mode: the index inside current boost list of the ADC
363 * @burnout_mode: the index inside current bias list of the ADC
364 * @auto_zeroing_mux: set if ADC auto-zeroing algorithm is enabled
365 * @auto_zeroing_ref: set if ADC auto-Zeroing Reference Buffer Setting is enabled
366 * @have_vref: does the ADC have an internal voltage reference?
403 static int mcp3564_read_8bits(struct mcp3564_state *adc, u8 reg, u8 *val) in mcp3564_read_8bits() argument
409 tx_buf = mcp3564_cmd_read(adc->dev_addr, reg); in mcp3564_read_8bits()
411 ret = spi_write_then_read(adc->spi, &tx_buf, sizeof(tx_buf), in mcp3564_read_8bits()
418 static int mcp3564_read_16bits(struct mcp3564_state *adc, u8 reg, u16 *val) in mcp3564_read_16bits() argument
424 tx_buf = mcp3564_cmd_read(adc->dev_addr, reg); in mcp3564_read_16bits()
426 ret = spi_write_then_read(adc->spi, &tx_buf, sizeof(tx_buf), in mcp3564_read_16bits()
433 static int mcp3564_read_32bits(struct mcp3564_state *adc, u8 reg, u32 *val) in mcp3564_read_32bits() argument
439 tx_buf = mcp3564_cmd_read(adc->dev_addr, reg); in mcp3564_read_32bits()
441 ret = spi_write_then_read(adc->spi, &tx_buf, sizeof(tx_buf), in mcp3564_read_32bits()
448 static int mcp3564_write_8bits(struct mcp3564_state *adc, u8 reg, u8 val) in mcp3564_write_8bits() argument
452 tx_buf[0] = mcp3564_cmd_write(adc->dev_addr, reg); in mcp3564_write_8bits()
455 return spi_write_then_read(adc->spi, tx_buf, sizeof(tx_buf), NULL, 0); in mcp3564_write_8bits()
458 static int mcp3564_write_24bits(struct mcp3564_state *adc, u8 reg, u32 val) in mcp3564_write_24bits() argument
462 val |= (mcp3564_cmd_write(adc->dev_addr, reg) << 24); in mcp3564_write_24bits()
465 return spi_write_then_read(adc->spi, &val_be, sizeof(val_be), NULL, 0); in mcp3564_write_24bits()
468 static int mcp3564_fast_cmd(struct mcp3564_state *adc, u8 fast_cmd) in mcp3564_fast_cmd() argument
472 val = FIELD_PREP(MCP3564_CMD_HW_ADDR_MASK, adc->dev_addr) | in mcp3564_fast_cmd()
475 return spi_write_then_read(adc->spi, &val, 1, NULL, 0); in mcp3564_fast_cmd()
478 static int mcp3564_update_8bits(struct mcp3564_state *adc, u8 reg, u32 mask, u8 val) in mcp3564_update_8bits() argument
485 ret = mcp3564_read_8bits(adc, reg, &tmp); in mcp3564_update_8bits()
492 return mcp3564_write_8bits(adc, reg, tmp); in mcp3564_update_8bits()
499 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_set_current_boost_mode() local
504 mutex_lock(&adc->lock); in mcp3564_set_current_boost_mode()
505 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG2_REG, MCP3564_CONFIG2_BOOST_CURRENT_MASK, in mcp3564_set_current_boost_mode()
511 adc->current_boost_mode = mode; in mcp3564_set_current_boost_mode()
513 mutex_unlock(&adc->lock); in mcp3564_set_current_boost_mode()
521 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_get_current_boost_mode() local
523 return adc->current_boost_mode; in mcp3564_get_current_boost_mode()
549 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_auto_zeroing_mux_show() local
551 return sysfs_emit(buf, "%d\n", adc->auto_zeroing_mux); in mcp3564_auto_zeroing_mux_show()
559 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_auto_zeroing_mux_store() local
567 mutex_lock(&adc->lock); in mcp3564_auto_zeroing_mux_store()
568 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG2_REG, MCP3564_CONFIG2_AZ_MUX_MASK, in mcp3564_auto_zeroing_mux_store()
574 adc->auto_zeroing_mux = auto_zero; in mcp3564_auto_zeroing_mux_store()
576 mutex_unlock(&adc->lock); in mcp3564_auto_zeroing_mux_store()
586 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_auto_zeroing_ref_show() local
588 return sysfs_emit(buf, "%d\n", adc->auto_zeroing_ref); in mcp3564_auto_zeroing_ref_show()
596 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_auto_zeroing_ref_store() local
604 mutex_lock(&adc->lock); in mcp3564_auto_zeroing_ref_store()
605 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG2_REG, MCP3564_CONFIG2_AZ_REF_MASK, in mcp3564_auto_zeroing_ref_store()
611 adc->auto_zeroing_ref = auto_zero; in mcp3564_auto_zeroing_ref_store()
613 mutex_unlock(&adc->lock); in mcp3564_auto_zeroing_ref_store()
748 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_read_single_value() local
753 ret = mcp3564_write_8bits(adc, MCP3564_MUX_REG, channel->address); in mcp3564_read_single_value()
757 /* Start ADC Conversion using fast command (overwrites ADC_MODE[1:0] = 11) */ in mcp3564_read_single_value()
758 ret = mcp3564_fast_cmd(adc, MCP3564_FASTCMD_START); in mcp3564_read_single_value()
769 adc, MCP3564_IRQ_REG, &tmp); in mcp3564_read_single_value()
782 return mcp3564_read_32bits(adc, MCP3564_ADCDATA_REG, val); in mcp3564_read_single_value()
790 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_read_avail() local
807 *vals = (int *)adc->scale_tbls; in mcp3564_read_avail()
808 *length = ARRAY_SIZE(adc->scale_tbls) * 2; in mcp3564_read_avail()
828 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_read_raw() local
834 mutex_lock(&adc->lock); in mcp3564_read_raw()
835 *val = mcp3564_burnout_avail[adc->burnout_mode][0]; in mcp3564_read_raw()
836 *val2 = mcp3564_burnout_avail[adc->burnout_mode][1]; in mcp3564_read_raw()
837 mutex_unlock(&adc->lock); in mcp3564_read_raw()
846 mutex_lock(&adc->lock); in mcp3564_read_raw()
847 *val = adc->scale_tbls[adc->hwgain][0]; in mcp3564_read_raw()
848 *val2 = adc->scale_tbls[adc->hwgain][1]; in mcp3564_read_raw()
849 mutex_unlock(&adc->lock); in mcp3564_read_raw()
852 *val = mcp3564_oversampling_avail[adc->oversampling]; in mcp3564_read_raw()
855 *val = adc->calib_bias; in mcp3564_read_raw()
858 *val = adc->calib_scale; in mcp3564_read_raw()
887 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_write_raw() local
906 if (burnout == adc->burnout_mode) in mcp3564_write_raw()
909 mutex_lock(&adc->lock); in mcp3564_write_raw()
910 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG0_REG, in mcp3564_write_raw()
917 adc->burnout_mode = burnout; in mcp3564_write_raw()
918 mutex_unlock(&adc->lock); in mcp3564_write_raw()
924 mutex_lock(&adc->lock); in mcp3564_write_raw()
925 ret = mcp3564_write_24bits(adc, MCP3564_OFFSETCAL_REG, val); in mcp3564_write_raw()
927 adc->calib_bias = val; in mcp3564_write_raw()
928 mutex_unlock(&adc->lock); in mcp3564_write_raw()
934 if (adc->calib_scale == val) in mcp3564_write_raw()
937 mutex_lock(&adc->lock); in mcp3564_write_raw()
938 ret = mcp3564_write_24bits(adc, MCP3564_GAINCAL_REG, val); in mcp3564_write_raw()
940 adc->calib_scale = val; in mcp3564_write_raw()
941 mutex_unlock(&adc->lock); in mcp3564_write_raw()
950 if (adc->oversampling == tmp) in mcp3564_write_raw()
953 mutex_lock(&adc->lock); in mcp3564_write_raw()
954 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG1_REG, in mcp3564_write_raw()
957 adc->oversampling)); in mcp3564_write_raw()
959 adc->oversampling = tmp; in mcp3564_write_raw()
960 mutex_unlock(&adc->lock); in mcp3564_write_raw()
964 if (val == adc->scale_tbls[hwgain][0] && in mcp3564_write_raw()
965 val2 == adc->scale_tbls[hwgain][1]) in mcp3564_write_raw()
971 if (hwgain == adc->hwgain) in mcp3564_write_raw()
974 mutex_lock(&adc->lock); in mcp3564_write_raw()
975 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG2_REG, in mcp3564_write_raw()
979 adc->hwgain = hwgain; in mcp3564_write_raw()
981 mutex_unlock(&adc->lock); in mcp3564_write_raw()
991 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_read_label() local
993 return sprintf(label, "%s\n", adc->labels[chan->scan_index]); in mcp3564_read_label()
998 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_parse_fw_children() local
999 struct device *dev = &adc->spi->dev; in mcp3564_parse_fw_children()
1020 if (num_ch > adc->chip_info->num_channels) in mcp3564_parse_fw_children()
1022 num_ch, adc->chip_info->num_channels); in mcp3564_parse_fw_children()
1064 adc->labels[chan_idx] = label; in mcp3564_parse_fw_children()
1074 adc->labels[chan_idx] = mcp3564_channel_labels[0]; in mcp3564_parse_fw_children()
1081 adc->labels[chan_idx] = mcp3564_channel_labels[1]; in mcp3564_parse_fw_children()
1095 static void mcp3564_fill_scale_tbls(struct mcp3564_state *adc) in mcp3564_fill_scale_tbls() argument
1097 unsigned int pow = adc->chip_info->resolution - 1; in mcp3564_fill_scale_tbls()
1104 ref = adc->vref_mv; in mcp3564_fill_scale_tbls()
1111 adc->scale_tbls[i][1] = tmp0; in mcp3564_fill_scale_tbls()
1117 struct mcp3564_state *adc = iio_priv(indio_dev); in mcp3564_config() local
1118 struct device *dev = &adc->spi->dev; in mcp3564_config()
1143 adc->dev_addr = FIELD_GET(MCP3564_HW_ADDR_MASK, tmp); in mcp3564_config()
1145 dev_dbg(dev, "use HW device address %i\n", adc->dev_addr); in mcp3564_config()
1147 ret = mcp3564_read_8bits(adc, MCP3564_RESERVED_C_REG, &tmp_reg); in mcp3564_config()
1153 adc->have_vref = false; in mcp3564_config()
1156 adc->have_vref = true; in mcp3564_config()
1164 ret = mcp3564_read_16bits(adc, MCP3564_RESERVED_E_REG, &tmp_u16); in mcp3564_config()
1170 if (adc->have_vref) in mcp3564_config()
1176 if (adc->have_vref) in mcp3564_config()
1182 if (adc->have_vref) in mcp3564_config()
1188 if (adc->have_vref) in mcp3564_config()
1194 if (adc->have_vref) in mcp3564_config()
1200 if (adc->have_vref) in mcp3564_config()
1216 adc->chip_info = spi_get_device_match_data(adc->spi); in mcp3564_config()
1217 if (!adc->chip_info) { in mcp3564_config()
1218 dev_id = spi_get_device_id(adc->spi); in mcp3564_config()
1219 adc->chip_info = (const struct mcp3564_chip_info *)dev_id->driver_data; in mcp3564_config()
1222 adc->have_vref = adc->chip_info->have_vref; in mcp3564_config()
1224 adc->chip_info = &mcp3564_chip_infos_tbl[ids]; in mcp3564_config()
1227 dev_dbg(dev, "Found %s chip\n", adc->chip_info->name); in mcp3564_config()
1229 adc->vref = devm_regulator_get_optional(dev, "vref"); in mcp3564_config()
1230 if (IS_ERR(adc->vref)) { in mcp3564_config()
1231 if (PTR_ERR(adc->vref) != -ENODEV) in mcp3564_config()
1232 return dev_err_probe(dev, PTR_ERR(adc->vref), in mcp3564_config()
1236 if (!adc->have_vref) in mcp3564_config()
1237 return dev_err_probe(dev, PTR_ERR(adc->vref), in mcp3564_config()
1239 adc->vref = NULL; in mcp3564_config()
1242 ret = regulator_enable(adc->vref); in mcp3564_config()
1247 adc->vref); in mcp3564_config()
1253 ret = regulator_get_voltage(adc->vref); in mcp3564_config()
1258 adc->vref_mv = ret / MILLI; in mcp3564_config()
1273 ret = mcp3564_write_8bits(adc, MCP3564_LOCK_REG, MCP3564_LOCK_WRITE_ACCESS_PASSWORD); in mcp3564_config()
1277 ret = mcp3564_write_8bits(adc, MCP3564_IRQ_REG, 0x03); in mcp3564_config()
1281 ret = mcp3564_fast_cmd(adc, MCP3564_FASTCMD_RESET); in mcp3564_config()
1294 ret = mcp3564_write_24bits(adc, MCP3564_GAINCAL_REG, MCP3564_DEFAULT_GAINCAL); in mcp3564_config()
1298 adc->calib_scale = MCP3564_DEFAULT_GAINCAL; in mcp3564_config()
1300 ret = mcp3564_write_24bits(adc, MCP3564_OFFSETCAL_REG, MCP3564_DEFAULT_OFFSETCAL); in mcp3564_config()
1304 ret = mcp3564_write_24bits(adc, MCP3564_TIMER_REG, MCP3564_TIMER_DEFAULT_VALUE); in mcp3564_config()
1308 ret = mcp3564_write_24bits(adc, MCP3564_SCAN_REG, in mcp3564_config()
1314 ret = mcp3564_write_8bits(adc, MCP3564_MUX_REG, MCP3564_MUX_SET(MCP3564_CH0, MCP3564_CH1)); in mcp3564_config()
1318 ret = mcp3564_write_8bits(adc, MCP3564_IRQ_REG, in mcp3564_config()
1331 ret = mcp3564_write_8bits(adc, MCP3564_CONFIG3_REG, tmp_reg); in mcp3564_config()
1339 ret = mcp3564_write_8bits(adc, MCP3564_CONFIG2_REG, tmp_reg); in mcp3564_config()
1343 adc->hwgain = 0x01; in mcp3564_config()
1344 adc->auto_zeroing_mux = true; in mcp3564_config()
1345 adc->auto_zeroing_ref = false; in mcp3564_config()
1346 adc->current_boost_mode = MCP3564_BOOST_CURRENT_x1_00; in mcp3564_config()
1350 ret = mcp3564_write_8bits(adc, MCP3564_CONFIG1_REG, tmp_reg); in mcp3564_config()
1354 adc->oversampling = MCP3564_OVERSAMPLING_RATIO_98304; in mcp3564_config()
1361 if (!adc->vref) { in mcp3564_config()
1363 adc->vref_mv = MCP3564R_INT_VREF_MV; in mcp3564_config()
1366 ret = mcp3564_write_8bits(adc, MCP3564_CONFIG0_REG, tmp_reg); in mcp3564_config()
1368 adc->burnout_mode = MCP3564_CONFIG0_CS_SEL_0_0_uA; in mcp3564_config()
1422 struct mcp3564_state *adc; in mcp3564_probe() local
1424 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); in mcp3564_probe()
1428 adc = iio_priv(indio_dev); in mcp3564_probe()
1429 adc->spi = spi; in mcp3564_probe()
1444 dev_dbg(&spi->dev, "%s: Vref (mV): %d\n", __func__, adc->vref_mv); in mcp3564_probe()
1446 mcp3564_fill_scale_tbls(adc); in mcp3564_probe()
1448 indio_dev->name = adc->chip_info->name; in mcp3564_probe()
1451 if (!adc->vref) in mcp3564_probe()
1456 mutex_init(&adc->lock); in mcp3564_probe()