1484 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * IIO driver for MCP356X/MCP356XR and MCP346X/MCP346XR series ADC chip family4 *5 * Copyright (C) 2022-2023 Microchip Technology Inc. and its subsidiaries6 *7 * Author: Marius Cristea <marius.cristea@microchip.com>8 *9 * Datasheet for MCP3561, MCP3562, MCP3564 can be found here:10 * https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP3561-2-4-Family-Data-Sheet-DS20006181C.pdf11 * Datasheet for MCP3561R, MCP3562R, MCP3564R can be found here:12 * https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ProductDocuments/DataSheets/MCP3561_2_4R-Data-Sheet-DS200006391C.pdf13 * Datasheet for MCP3461, MCP3462, MCP3464 can be found here:14 * https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ProductDocuments/DataSheets/MCP3461-2-4-Two-Four-Eight-Channel-153.6-ksps-Low-Noise-16-Bit-Delta-Sigma-ADC-Data-Sheet-20006180D.pdf15 * Datasheet for MCP3461R, MCP3462R, MCP3464R can be found here:16 * https://ww1.microchip.com/downloads/aemDocuments/documents/APID/ProductDocuments/DataSheets/MCP3461-2-4R-Family-Data-Sheet-DS20006404C.pdf17 */18 19#include <linux/bitfield.h>20#include <linux/iopoll.h>21#include <linux/regulator/consumer.h>22#include <linux/spi/spi.h>23#include <linux/units.h>24#include <linux/util_macros.h>25 26#include <linux/iio/iio.h>27#include <linux/iio/sysfs.h>28 29#define MCP3564_ADCDATA_REG 0x0030 31#define MCP3564_CONFIG0_REG 0x0132#define MCP3564_CONFIG0_ADC_MODE_MASK GENMASK(1, 0)33/* Current Source/Sink Selection Bits for Sensor Bias */34#define MCP3564_CONFIG0_CS_SEL_MASK GENMASK(3, 2)35/* Internal clock is selected and AMCLK is present on the analog master clock output pin */36#define MCP3564_CONFIG0_USE_INT_CLK_OUTPUT_EN 0x0337/* Internal clock is selected and no clock output is present on the CLK pin */38#define MCP3564_CONFIG0_USE_INT_CLK 0x0239/* External digital clock */40#define MCP3564_CONFIG0_USE_EXT_CLK 0x0141/* External digital clock (default) */42#define MCP3564_CONFIG0_USE_EXT_CLK_DEFAULT 0x0043#define MCP3564_CONFIG0_CLK_SEL_MASK GENMASK(5, 4)44#define MCP3456_CONFIG0_BIT6_DEFAULT BIT(6)45#define MCP3456_CONFIG0_VREF_MASK BIT(7)46 47#define MCP3564_CONFIG1_REG 0x0248#define MCP3564_CONFIG1_OVERSPL_RATIO_MASK GENMASK(5, 2)49 50#define MCP3564_CONFIG2_REG 0x0351#define MCP3564_CONFIG2_AZ_REF_MASK BIT(1)52#define MCP3564_CONFIG2_AZ_MUX_MASK BIT(2)53 54#define MCP3564_CONFIG2_HARDWARE_GAIN_MASK GENMASK(5, 3)55#define MCP3564_DEFAULT_HARDWARE_GAIN 0x0156#define MCP3564_CONFIG2_BOOST_CURRENT_MASK GENMASK(7, 6)57 58#define MCP3564_CONFIG3_REG 0x0459#define MCP3464_CONFIG3_EN_GAINCAL_MASK BIT(0)60#define MCP3464_CONFIG3_EN_OFFCAL_MASK BIT(1)61#define MCP3464_CONFIG3_EN_CRCCOM_MASK BIT(2)62#define MCP3464_CONFIG3_CRC_FORMAT_MASK BIT(3)63/*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.66 * It allows overrange with the SGN extension.67 */68#define MCP3464_CONFIG3_DATA_FMT_32B_WITH_CH_ID 369/*70 * ADC Output Data Format 32-bit (25-bit right justified data):71 * SGN extension (8-bit) + 24-bit ADC data.72 * It allows overrange with the SGN extension.73 */74#define MCP3464_CONFIG3_DATA_FMT_32B_SGN_EXT 275/*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).79 */80#define MCP3464_CONFIG3_DATA_FMT_32B_LEFT_JUSTIFIED 181/*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).85 */86#define MCP3464_CONFIG3_DATA_FMT_24B 087#define MCP3464_CONFIG3_DATA_FORMAT_MASK GENMASK(5, 4)88 89/* Continuous Conversion mode or continuous conversion cycle in SCAN mode. */90#define MCP3464_CONFIG3_CONV_MODE_CONTINUOUS 391/*92 * One-shot conversion or one-shot cycle in SCAN mode. It sets ADC_MODE[1:0] to ‘10’93 * (standby) at the end of the conversion or at the end of the conversion cycle in SCAN mode.94 */95#define MCP3464_CONFIG3_CONV_MODE_ONE_SHOT_STANDBY 296/*97 * One-shot conversion or one-shot cycle in SCAN mode. It sets ADC_MODE[1:0] to ‘0x’ (ADC98 * Shutdown) at the end of the conversion or at the end of the conversion cycle in SCAN99 * mode (default).100 */101#define MCP3464_CONFIG3_CONV_MODE_ONE_SHOT_SHUTDOWN 0102#define MCP3464_CONFIG3_CONV_MODE_MASK GENMASK(7, 6)103 104#define MCP3564_IRQ_REG 0x05105#define MCP3464_EN_STP_MASK BIT(0)106#define MCP3464_EN_FASTCMD_MASK BIT(1)107#define MCP3464_IRQ_MODE_0_MASK BIT(2)108#define MCP3464_IRQ_MODE_1_MASK BIT(3)109#define MCP3564_POR_STATUS_MASK BIT(4)110#define MCP3564_CRCCFG_STATUS_MASK BIT(5)111#define MCP3564_DATA_READY_MASK BIT(6)112 113#define MCP3564_MUX_REG 0x06114#define MCP3564_MUX_VIN_P_MASK GENMASK(7, 4)115#define MCP3564_MUX_VIN_N_MASK GENMASK(3, 0)116#define MCP3564_MUX_SET(x, y) (FIELD_PREP(MCP3564_MUX_VIN_P_MASK, (x)) | \117 FIELD_PREP(MCP3564_MUX_VIN_N_MASK, (y)))118 119#define MCP3564_SCAN_REG 0x07120#define MCP3564_SCAN_CH_SEL_MASK GENMASK(15, 0)121#define MCP3564_SCAN_CH_SEL_SET(x) FIELD_PREP(MCP3564_SCAN_CH_SEL_MASK, (x))122#define MCP3564_SCAN_DELAY_TIME_MASK GENMASK(23, 21)123#define MCP3564_SCAN_DELAY_TIME_SET(x) FIELD_PREP(MCP3564_SCAN_DELAY_TIME_MASK, (x))124#define MCP3564_SCAN_DEFAULT_VALUE 0125 126#define MCP3564_TIMER_REG 0x08127#define MCP3564_TIMER_DEFAULT_VALUE 0128 129#define MCP3564_OFFSETCAL_REG 0x09130#define MCP3564_DEFAULT_OFFSETCAL 0131 132#define MCP3564_GAINCAL_REG 0x0A133#define MCP3564_DEFAULT_GAINCAL 0x00800000134 135#define MCP3564_RESERVED_B_REG 0x0B136 137#define MCP3564_RESERVED_C_REG 0x0C138#define MCP3564_C_REG_DEFAULT 0x50139#define MCP3564R_C_REG_DEFAULT 0x30140 141#define MCP3564_LOCK_REG 0x0D142#define MCP3564_LOCK_WRITE_ACCESS_PASSWORD 0xA5143#define MCP3564_RESERVED_E_REG 0x0E144#define MCP3564_CRCCFG_REG 0x0F145 146#define MCP3564_CMD_HW_ADDR_MASK GENMASK(7, 6)147#define MCP3564_CMD_ADDR_MASK GENMASK(5, 2)148 149#define MCP3564_HW_ADDR_MASK GENMASK(1, 0)150 151#define MCP3564_FASTCMD_START 0x0A152#define MCP3564_FASTCMD_RESET 0x0E153 154#define MCP3461_HW_ID 0x0008155#define MCP3462_HW_ID 0x0009156#define MCP3464_HW_ID 0x000B157 158#define MCP3561_HW_ID 0x000C159#define MCP3562_HW_ID 0x000D160#define MCP3564_HW_ID 0x000F161#define MCP3564_HW_ID_MASK GENMASK(3, 0)162 163#define MCP3564R_INT_VREF_MV 2400164 165#define MCP3564_DATA_READY_TIMEOUT_MS 2000166 167#define MCP3564_MAX_PGA 8168#define MCP3564_MAX_BURNOUT_IDX 4169#define MCP3564_MAX_CHANNELS 66170 171enum mcp3564_ids {172 mcp3461,173 mcp3462,174 mcp3464,175 mcp3561,176 mcp3562,177 mcp3564,178 mcp3461r,179 mcp3462r,180 mcp3464r,181 mcp3561r,182 mcp3562r,183 mcp3564r,184};185 186enum mcp3564_delay_time {187 MCP3564_NO_DELAY,188 MCP3564_DELAY_8_DMCLK,189 MCP3564_DELAY_16_DMCLK,190 MCP3564_DELAY_32_DMCLK,191 MCP3564_DELAY_64_DMCLK,192 MCP3564_DELAY_128_DMCLK,193 MCP3564_DELAY_256_DMCLK,194 MCP3564_DELAY_512_DMCLK195};196 197enum mcp3564_adc_conversion_mode {198 MCP3564_ADC_MODE_DEFAULT,199 MCP3564_ADC_MODE_SHUTDOWN,200 MCP3564_ADC_MODE_STANDBY,201 MCP3564_ADC_MODE_CONVERSION202};203 204enum mcp3564_adc_bias_current {205 MCP3564_BOOST_CURRENT_x0_50,206 MCP3564_BOOST_CURRENT_x0_66,207 MCP3564_BOOST_CURRENT_x1_00,208 MCP3564_BOOST_CURRENT_x2_00209};210 211enum mcp3564_burnout {212 MCP3564_CONFIG0_CS_SEL_0_0_uA,213 MCP3564_CONFIG0_CS_SEL_0_9_uA,214 MCP3564_CONFIG0_CS_SEL_3_7_uA,215 MCP3564_CONFIG0_CS_SEL_15_uA216};217 218enum mcp3564_channel_names {219 MCP3564_CH0,220 MCP3564_CH1,221 MCP3564_CH2,222 MCP3564_CH3,223 MCP3564_CH4,224 MCP3564_CH5,225 MCP3564_CH6,226 MCP3564_CH7,227 MCP3564_AGND,228 MCP3564_AVDD,229 MCP3564_RESERVED, /* do not use */230 MCP3564_REFIN_POZ,231 MCP3564_REFIN_NEG,232 MCP3564_TEMP_DIODE_P,233 MCP3564_TEMP_DIODE_M,234 MCP3564_INTERNAL_VCM,235};236 237enum mcp3564_oversampling {238 MCP3564_OVERSAMPLING_RATIO_32,239 MCP3564_OVERSAMPLING_RATIO_64,240 MCP3564_OVERSAMPLING_RATIO_128,241 MCP3564_OVERSAMPLING_RATIO_256,242 MCP3564_OVERSAMPLING_RATIO_512,243 MCP3564_OVERSAMPLING_RATIO_1024,244 MCP3564_OVERSAMPLING_RATIO_2048,245 MCP3564_OVERSAMPLING_RATIO_4096,246 MCP3564_OVERSAMPLING_RATIO_8192,247 MCP3564_OVERSAMPLING_RATIO_16384,248 MCP3564_OVERSAMPLING_RATIO_20480,249 MCP3564_OVERSAMPLING_RATIO_24576,250 MCP3564_OVERSAMPLING_RATIO_40960,251 MCP3564_OVERSAMPLING_RATIO_49152,252 MCP3564_OVERSAMPLING_RATIO_81920,253 MCP3564_OVERSAMPLING_RATIO_98304254};255 256static const unsigned int mcp3564_oversampling_avail[] = {257 [MCP3564_OVERSAMPLING_RATIO_32] = 32,258 [MCP3564_OVERSAMPLING_RATIO_64] = 64,259 [MCP3564_OVERSAMPLING_RATIO_128] = 128,260 [MCP3564_OVERSAMPLING_RATIO_256] = 256,261 [MCP3564_OVERSAMPLING_RATIO_512] = 512,262 [MCP3564_OVERSAMPLING_RATIO_1024] = 1024,263 [MCP3564_OVERSAMPLING_RATIO_2048] = 2048,264 [MCP3564_OVERSAMPLING_RATIO_4096] = 4096,265 [MCP3564_OVERSAMPLING_RATIO_8192] = 8192,266 [MCP3564_OVERSAMPLING_RATIO_16384] = 16384,267 [MCP3564_OVERSAMPLING_RATIO_20480] = 20480,268 [MCP3564_OVERSAMPLING_RATIO_24576] = 24576,269 [MCP3564_OVERSAMPLING_RATIO_40960] = 40960,270 [MCP3564_OVERSAMPLING_RATIO_49152] = 49152,271 [MCP3564_OVERSAMPLING_RATIO_81920] = 81920,272 [MCP3564_OVERSAMPLING_RATIO_98304] = 98304273};274 275/*276 * Current Source/Sink Selection Bits for Sensor Bias (source on VIN+/sink on VIN-)277 */278static const int mcp3564_burnout_avail[][2] = {279 [MCP3564_CONFIG0_CS_SEL_0_0_uA] = { 0, 0 },280 [MCP3564_CONFIG0_CS_SEL_0_9_uA] = { 0, 900 },281 [MCP3564_CONFIG0_CS_SEL_3_7_uA] = { 0, 3700 },282 [MCP3564_CONFIG0_CS_SEL_15_uA] = { 0, 15000 }283};284 285/*286 * BOOST[1:0]: ADC Bias Current Selection287 */288static const char * const mcp3564_boost_current_avail[] = {289 [MCP3564_BOOST_CURRENT_x0_50] = "0.5",290 [MCP3564_BOOST_CURRENT_x0_66] = "0.66",291 [MCP3564_BOOST_CURRENT_x1_00] = "1",292 [MCP3564_BOOST_CURRENT_x2_00] = "2",293};294 295/*296 * Calibration bias values297 */298static const int mcp3564_calib_bias[] = {299 -8388608, /* min: -2^23 */300 1, /* step: 1 */301 8388607 /* max: 2^23 - 1 */302};303 304/*305 * Calibration scale values306 * The Gain Error Calibration register (GAINCAL) is an307 * unsigned 24-bit register that holds the digital gain error308 * calibration value, GAINCAL which could be calculated by309 * GAINCAL (V/V) = (GAINCAL[23:0])/8388608310 * The gain error calibration value range in equivalent voltage is [0; 2-2^(-23)]311 */312static const unsigned int mcp3564_calib_scale[] = {313 0, /* min: 0 */314 1, /* step: 1/8388608 */315 16777215 /* max: 2 - 2^(-23) */316};317 318/* Programmable hardware gain x1/3, x1, x2, x4, x8, x16, x32, x64 */319static const int mcp3564_hwgain_frac[] = {320 3, 10,321 1, 1,322 2, 1,323 4, 1,324 8, 1,325 16, 1,326 32, 1,327 64, 1328};329 330static const char *mcp3564_channel_labels[2] = {331 "burnout_current", "temperature",332};333 334/**335 * struct mcp3564_chip_info - chip specific data336 * @name: device name337 * @num_channels: number of channels338 * @resolution: ADC resolution339 * @have_vref: does the hardware have an internal voltage reference?340 */341struct mcp3564_chip_info {342 const char *name;343 unsigned int num_channels;344 unsigned int resolution;345 bool have_vref;346};347 348/**349 * struct mcp3564_state - working data for a ADC device350 * @chip_info: chip specific data351 * @spi: SPI device structure352 * @vref_mv: voltage reference value in miliVolts353 * @lock: synchronize access to driver's state members354 * @dev_addr: hardware device address355 * @oversampling: the index inside oversampling list of the ADC356 * @hwgain: the index inside hardware gain list of the ADC357 * @scale_tbls: table with precalculated scale358 * @calib_bias: calibration bias value359 * @calib_scale: calibration scale value360 * @current_boost_mode: the index inside current boost list of the ADC361 * @burnout_mode: the index inside current bias list of the ADC362 * @auto_zeroing_mux: set if ADC auto-zeroing algorithm is enabled363 * @auto_zeroing_ref: set if ADC auto-Zeroing Reference Buffer Setting is enabled364 * @have_vref: does the ADC have an internal voltage reference?365 * @labels: table with channels labels366 */367struct mcp3564_state {368 const struct mcp3564_chip_info *chip_info;369 struct spi_device *spi;370 unsigned short vref_mv;371 struct mutex lock; /* Synchronize access to driver's state members */372 u8 dev_addr;373 enum mcp3564_oversampling oversampling;374 unsigned int hwgain;375 unsigned int scale_tbls[MCP3564_MAX_PGA][2];376 int calib_bias;377 int calib_scale;378 unsigned int current_boost_mode;379 enum mcp3564_burnout burnout_mode;380 bool auto_zeroing_mux;381 bool auto_zeroing_ref;382 bool have_vref;383 const char *labels[MCP3564_MAX_CHANNELS];384};385 386static inline u8 mcp3564_cmd_write(u8 chip_addr, u8 reg)387{388 return FIELD_PREP(MCP3564_CMD_HW_ADDR_MASK, chip_addr) |389 FIELD_PREP(MCP3564_CMD_ADDR_MASK, reg) |390 BIT(1);391}392 393static inline u8 mcp3564_cmd_read(u8 chip_addr, u8 reg)394{395 return FIELD_PREP(MCP3564_CMD_HW_ADDR_MASK, chip_addr) |396 FIELD_PREP(MCP3564_CMD_ADDR_MASK, reg) |397 BIT(0);398}399 400static int mcp3564_read_8bits(struct mcp3564_state *adc, u8 reg, u8 *val)401{402 int ret;403 u8 tx_buf;404 u8 rx_buf;405 406 tx_buf = mcp3564_cmd_read(adc->dev_addr, reg);407 408 ret = spi_write_then_read(adc->spi, &tx_buf, sizeof(tx_buf),409 &rx_buf, sizeof(rx_buf));410 *val = rx_buf;411 412 return ret;413}414 415static int mcp3564_read_16bits(struct mcp3564_state *adc, u8 reg, u16 *val)416{417 int ret;418 u8 tx_buf;419 __be16 rx_buf;420 421 tx_buf = mcp3564_cmd_read(adc->dev_addr, reg);422 423 ret = spi_write_then_read(adc->spi, &tx_buf, sizeof(tx_buf),424 &rx_buf, sizeof(rx_buf));425 *val = be16_to_cpu(rx_buf);426 427 return ret;428}429 430static int mcp3564_read_32bits(struct mcp3564_state *adc, u8 reg, u32 *val)431{432 int ret;433 u8 tx_buf;434 __be32 rx_buf;435 436 tx_buf = mcp3564_cmd_read(adc->dev_addr, reg);437 438 ret = spi_write_then_read(adc->spi, &tx_buf, sizeof(tx_buf),439 &rx_buf, sizeof(rx_buf));440 *val = be32_to_cpu(rx_buf);441 442 return ret;443}444 445static int mcp3564_write_8bits(struct mcp3564_state *adc, u8 reg, u8 val)446{447 u8 tx_buf[2];448 449 tx_buf[0] = mcp3564_cmd_write(adc->dev_addr, reg);450 tx_buf[1] = val;451 452 return spi_write_then_read(adc->spi, tx_buf, sizeof(tx_buf), NULL, 0);453}454 455static int mcp3564_write_24bits(struct mcp3564_state *adc, u8 reg, u32 val)456{457 __be32 val_be;458 459 val |= (mcp3564_cmd_write(adc->dev_addr, reg) << 24);460 val_be = cpu_to_be32(val);461 462 return spi_write_then_read(adc->spi, &val_be, sizeof(val_be), NULL, 0);463}464 465static int mcp3564_fast_cmd(struct mcp3564_state *adc, u8 fast_cmd)466{467 u8 val;468 469 val = FIELD_PREP(MCP3564_CMD_HW_ADDR_MASK, adc->dev_addr) |470 FIELD_PREP(MCP3564_CMD_ADDR_MASK, fast_cmd);471 472 return spi_write_then_read(adc->spi, &val, 1, NULL, 0);473}474 475static int mcp3564_update_8bits(struct mcp3564_state *adc, u8 reg, u32 mask, u8 val)476{477 u8 tmp;478 int ret;479 480 val &= mask;481 482 ret = mcp3564_read_8bits(adc, reg, &tmp);483 if (ret < 0)484 return ret;485 486 tmp &= ~mask;487 tmp |= val;488 489 return mcp3564_write_8bits(adc, reg, tmp);490}491 492static int mcp3564_set_current_boost_mode(struct iio_dev *indio_dev,493 const struct iio_chan_spec *chan,494 unsigned int mode)495{496 struct mcp3564_state *adc = iio_priv(indio_dev);497 int ret;498 499 dev_dbg(&indio_dev->dev, "%s: %d\n", __func__, mode);500 501 mutex_lock(&adc->lock);502 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG2_REG, MCP3564_CONFIG2_BOOST_CURRENT_MASK,503 FIELD_PREP(MCP3564_CONFIG2_BOOST_CURRENT_MASK, mode));504 505 if (ret)506 dev_err(&indio_dev->dev, "Failed to configure CONFIG2 register\n");507 else508 adc->current_boost_mode = mode;509 510 mutex_unlock(&adc->lock);511 512 return ret;513}514 515static int mcp3564_get_current_boost_mode(struct iio_dev *indio_dev,516 const struct iio_chan_spec *chan)517{518 struct mcp3564_state *adc = iio_priv(indio_dev);519 520 return adc->current_boost_mode;521}522 523static const struct iio_enum mcp3564_current_boost_mode_enum = {524 .items = mcp3564_boost_current_avail,525 .num_items = ARRAY_SIZE(mcp3564_boost_current_avail),526 .set = mcp3564_set_current_boost_mode,527 .get = mcp3564_get_current_boost_mode,528};529 530static const struct iio_chan_spec_ext_info mcp3564_ext_info[] = {531 IIO_ENUM("boost_current_gain", IIO_SHARED_BY_ALL, &mcp3564_current_boost_mode_enum),532 {533 .name = "boost_current_gain_available",534 .shared = IIO_SHARED_BY_ALL,535 .read = iio_enum_available_read,536 .private = (uintptr_t)&mcp3564_current_boost_mode_enum,537 },538 { }539};540 541static ssize_t mcp3564_auto_zeroing_mux_show(struct device *dev,542 struct device_attribute *attr,543 char *buf)544{545 struct iio_dev *indio_dev = dev_to_iio_dev(dev);546 struct mcp3564_state *adc = iio_priv(indio_dev);547 548 return sysfs_emit(buf, "%d\n", adc->auto_zeroing_mux);549}550 551static ssize_t mcp3564_auto_zeroing_mux_store(struct device *dev,552 struct device_attribute *attr,553 const char *buf, size_t len)554{555 struct iio_dev *indio_dev = dev_to_iio_dev(dev);556 struct mcp3564_state *adc = iio_priv(indio_dev);557 bool auto_zero;558 int ret;559 560 ret = kstrtobool(buf, &auto_zero);561 if (ret)562 return ret;563 564 mutex_lock(&adc->lock);565 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG2_REG, MCP3564_CONFIG2_AZ_MUX_MASK,566 FIELD_PREP(MCP3564_CONFIG2_AZ_MUX_MASK, auto_zero));567 568 if (ret)569 dev_err(&indio_dev->dev, "Failed to update CONFIG2 register\n");570 else571 adc->auto_zeroing_mux = auto_zero;572 573 mutex_unlock(&adc->lock);574 575 return ret ? ret : len;576}577 578static ssize_t mcp3564_auto_zeroing_ref_show(struct device *dev,579 struct device_attribute *attr,580 char *buf)581{582 struct iio_dev *indio_dev = dev_to_iio_dev(dev);583 struct mcp3564_state *adc = iio_priv(indio_dev);584 585 return sysfs_emit(buf, "%d\n", adc->auto_zeroing_ref);586}587 588static ssize_t mcp3564_auto_zeroing_ref_store(struct device *dev,589 struct device_attribute *attr,590 const char *buf, size_t len)591{592 struct iio_dev *indio_dev = dev_to_iio_dev(dev);593 struct mcp3564_state *adc = iio_priv(indio_dev);594 bool auto_zero;595 int ret;596 597 ret = kstrtobool(buf, &auto_zero);598 if (ret)599 return ret;600 601 mutex_lock(&adc->lock);602 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG2_REG, MCP3564_CONFIG2_AZ_REF_MASK,603 FIELD_PREP(MCP3564_CONFIG2_AZ_REF_MASK, auto_zero));604 605 if (ret)606 dev_err(&indio_dev->dev, "Failed to update CONFIG2 register\n");607 else608 adc->auto_zeroing_ref = auto_zero;609 610 mutex_unlock(&adc->lock);611 612 return ret ? ret : len;613}614 615static const struct iio_chan_spec mcp3564_channel_template = {616 .type = IIO_VOLTAGE,617 .indexed = 1,618 .differential = 1,619 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),620 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) |621 BIT(IIO_CHAN_INFO_CALIBSCALE) |622 BIT(IIO_CHAN_INFO_CALIBBIAS) |623 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),624 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SCALE) |625 BIT(IIO_CHAN_INFO_CALIBSCALE) |626 BIT(IIO_CHAN_INFO_CALIBBIAS) |627 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),628 .ext_info = mcp3564_ext_info,629};630 631static const struct iio_chan_spec mcp3564_temp_channel_template = {632 .type = IIO_TEMP,633 .channel = 0,634 .address = ((MCP3564_TEMP_DIODE_P << 4) | MCP3564_TEMP_DIODE_M),635 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),636 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) |637 BIT(IIO_CHAN_INFO_CALIBSCALE) |638 BIT(IIO_CHAN_INFO_CALIBBIAS) |639 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),640 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SCALE) |641 BIT(IIO_CHAN_INFO_CALIBSCALE) |642 BIT(IIO_CHAN_INFO_CALIBBIAS) |643 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),644};645 646static const struct iio_chan_spec mcp3564_burnout_channel_template = {647 .type = IIO_CURRENT,648 .output = true,649 .channel = 0,650 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),651 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),652};653 654/*655 * Number of channels could be calculated:656 * num_channels = single_ended_input + differential_input + temperature + burnout657 * Eg. for MCP3561 (only 2 channels available: CH0 and CH1)658 * single_ended_input = (CH0 - GND), (CH1 - GND) = 2659 * differential_input = (CH0 - CH1), (CH0 - CH0) = 2660 * num_channels = 2 + 2 + 2661 * Generic formula is:662 * num_channels = P^R(Number_of_single_ended_channels, 2) + 2 (temperature + burnout channels)663 * P^R(Number_of_single_ended_channels, 2) is Permutations with Replacement of664 * Number_of_single_ended_channels taken by 2665 */666static const struct mcp3564_chip_info mcp3564_chip_infos_tbl[] = {667 [mcp3461] = {668 .name = "mcp3461",669 .num_channels = 6,670 .resolution = 16,671 .have_vref = false,672 },673 [mcp3462] = {674 .name = "mcp3462",675 .num_channels = 18,676 .resolution = 16,677 .have_vref = false,678 },679 [mcp3464] = {680 .name = "mcp3464",681 .num_channels = 66,682 .resolution = 16,683 .have_vref = false,684 },685 [mcp3561] = {686 .name = "mcp3561",687 .num_channels = 6,688 .resolution = 24,689 .have_vref = false,690 },691 [mcp3562] = {692 .name = "mcp3562",693 .num_channels = 18,694 .resolution = 24,695 .have_vref = false,696 },697 [mcp3564] = {698 .name = "mcp3564",699 .num_channels = 66,700 .resolution = 24,701 .have_vref = false,702 },703 [mcp3461r] = {704 .name = "mcp3461r",705 .num_channels = 6,706 .resolution = 16,707 .have_vref = false,708 },709 [mcp3462r] = {710 .name = "mcp3462r",711 .num_channels = 18,712 .resolution = 16,713 .have_vref = true,714 },715 [mcp3464r] = {716 .name = "mcp3464r",717 .num_channels = 66,718 .resolution = 16,719 .have_vref = true,720 },721 [mcp3561r] = {722 .name = "mcp3561r",723 .num_channels = 6,724 .resolution = 24,725 .have_vref = true,726 },727 [mcp3562r] = {728 .name = "mcp3562r",729 .num_channels = 18,730 .resolution = 24,731 .have_vref = true,732 },733 [mcp3564r] = {734 .name = "mcp3564r",735 .num_channels = 66,736 .resolution = 24,737 .have_vref = true,738 },739};740 741static int mcp3564_read_single_value(struct iio_dev *indio_dev,742 struct iio_chan_spec const *channel,743 int *val)744{745 struct mcp3564_state *adc = iio_priv(indio_dev);746 int ret;747 u8 tmp;748 int ret_read = 0;749 750 ret = mcp3564_write_8bits(adc, MCP3564_MUX_REG, channel->address);751 if (ret)752 return ret;753 754 /* Start ADC Conversion using fast command (overwrites ADC_MODE[1:0] = 11) */755 ret = mcp3564_fast_cmd(adc, MCP3564_FASTCMD_START);756 if (ret)757 return ret;758 759 /*760 * Check if the conversion is ready. If not, wait a little bit, and761 * in case of timeout exit with an error.762 */763 ret = read_poll_timeout(mcp3564_read_8bits, ret_read,764 ret_read || !(tmp & MCP3564_DATA_READY_MASK),765 20000, MCP3564_DATA_READY_TIMEOUT_MS * 1000, true,766 adc, MCP3564_IRQ_REG, &tmp);767 768 /* failed to read status register */769 if (ret_read)770 return ret_read;771 772 if (ret)773 return ret;774 775 if (tmp & MCP3564_DATA_READY_MASK)776 /* failing to finish conversion */777 return -EBUSY;778 779 return mcp3564_read_32bits(adc, MCP3564_ADCDATA_REG, val);780}781 782static int mcp3564_read_avail(struct iio_dev *indio_dev,783 struct iio_chan_spec const *channel,784 const int **vals, int *type,785 int *length, long mask)786{787 struct mcp3564_state *adc = iio_priv(indio_dev);788 789 switch (mask) {790 case IIO_CHAN_INFO_RAW:791 if (!channel->output)792 return -EINVAL;793 794 *vals = mcp3564_burnout_avail[0];795 *length = ARRAY_SIZE(mcp3564_burnout_avail) * 2;796 *type = IIO_VAL_INT_PLUS_MICRO;797 return IIO_AVAIL_LIST;798 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:799 *vals = mcp3564_oversampling_avail;800 *length = ARRAY_SIZE(mcp3564_oversampling_avail);801 *type = IIO_VAL_INT;802 return IIO_AVAIL_LIST;803 case IIO_CHAN_INFO_SCALE:804 *vals = (int *)adc->scale_tbls;805 *length = ARRAY_SIZE(adc->scale_tbls) * 2;806 *type = IIO_VAL_INT_PLUS_NANO;807 return IIO_AVAIL_LIST;808 case IIO_CHAN_INFO_CALIBBIAS:809 *vals = mcp3564_calib_bias;810 *type = IIO_VAL_INT;811 return IIO_AVAIL_RANGE;812 case IIO_CHAN_INFO_CALIBSCALE:813 *vals = mcp3564_calib_scale;814 *type = IIO_VAL_INT;815 return IIO_AVAIL_RANGE;816 default:817 return -EINVAL;818 }819}820 821static int mcp3564_read_raw(struct iio_dev *indio_dev,822 struct iio_chan_spec const *channel,823 int *val, int *val2, long mask)824{825 struct mcp3564_state *adc = iio_priv(indio_dev);826 int ret;827 828 switch (mask) {829 case IIO_CHAN_INFO_RAW:830 if (channel->output) {831 mutex_lock(&adc->lock);832 *val = mcp3564_burnout_avail[adc->burnout_mode][0];833 *val2 = mcp3564_burnout_avail[adc->burnout_mode][1];834 mutex_unlock(&adc->lock);835 return IIO_VAL_INT_PLUS_MICRO;836 }837 838 ret = mcp3564_read_single_value(indio_dev, channel, val);839 if (ret)840 return -EINVAL;841 return IIO_VAL_INT;842 case IIO_CHAN_INFO_SCALE:843 mutex_lock(&adc->lock);844 *val = adc->scale_tbls[adc->hwgain][0];845 *val2 = adc->scale_tbls[adc->hwgain][1];846 mutex_unlock(&adc->lock);847 return IIO_VAL_INT_PLUS_NANO;848 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:849 *val = mcp3564_oversampling_avail[adc->oversampling];850 return IIO_VAL_INT;851 case IIO_CHAN_INFO_CALIBBIAS:852 *val = adc->calib_bias;853 return IIO_VAL_INT;854 case IIO_CHAN_INFO_CALIBSCALE:855 *val = adc->calib_scale;856 return IIO_VAL_INT;857 default:858 return -EINVAL;859 }860}861 862static int mcp3564_write_raw_get_fmt(struct iio_dev *indio_dev,863 struct iio_chan_spec const *chan,864 long info)865{866 switch (info) {867 case IIO_CHAN_INFO_RAW:868 return IIO_VAL_INT_PLUS_MICRO;869 case IIO_CHAN_INFO_CALIBBIAS:870 case IIO_CHAN_INFO_CALIBSCALE:871 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:872 return IIO_VAL_INT;873 case IIO_CHAN_INFO_SCALE:874 return IIO_VAL_INT_PLUS_NANO;875 default:876 return -EINVAL;877 }878}879 880static int mcp3564_write_raw(struct iio_dev *indio_dev,881 struct iio_chan_spec const *channel, int val,882 int val2, long mask)883{884 struct mcp3564_state *adc = iio_priv(indio_dev);885 int tmp;886 unsigned int hwgain;887 enum mcp3564_burnout burnout;888 int ret = 0;889 890 switch (mask) {891 case IIO_CHAN_INFO_RAW:892 if (!channel->output)893 return -EINVAL;894 895 for (burnout = 0; burnout < MCP3564_MAX_BURNOUT_IDX; burnout++)896 if (val == mcp3564_burnout_avail[burnout][0] &&897 val2 == mcp3564_burnout_avail[burnout][1])898 break;899 900 if (burnout == MCP3564_MAX_BURNOUT_IDX)901 return -EINVAL;902 903 if (burnout == adc->burnout_mode)904 return ret;905 906 mutex_lock(&adc->lock);907 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG0_REG,908 MCP3564_CONFIG0_CS_SEL_MASK,909 FIELD_PREP(MCP3564_CONFIG0_CS_SEL_MASK, burnout));910 911 if (ret)912 dev_err(&indio_dev->dev, "Failed to configure burnout current\n");913 else914 adc->burnout_mode = burnout;915 mutex_unlock(&adc->lock);916 return ret;917 case IIO_CHAN_INFO_CALIBBIAS:918 if (val < mcp3564_calib_bias[0] || val > mcp3564_calib_bias[2])919 return -EINVAL;920 921 mutex_lock(&adc->lock);922 ret = mcp3564_write_24bits(adc, MCP3564_OFFSETCAL_REG, val);923 if (!ret)924 adc->calib_bias = val;925 mutex_unlock(&adc->lock);926 return ret;927 case IIO_CHAN_INFO_CALIBSCALE:928 if (val < mcp3564_calib_scale[0] || val > mcp3564_calib_scale[2])929 return -EINVAL;930 931 if (adc->calib_scale == val)932 return ret;933 934 mutex_lock(&adc->lock);935 ret = mcp3564_write_24bits(adc, MCP3564_GAINCAL_REG, val);936 if (!ret)937 adc->calib_scale = val;938 mutex_unlock(&adc->lock);939 return ret;940 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:941 if (val < 0)942 return -EINVAL;943 944 tmp = find_closest(val, mcp3564_oversampling_avail,945 ARRAY_SIZE(mcp3564_oversampling_avail));946 947 if (adc->oversampling == tmp)948 return ret;949 950 mutex_lock(&adc->lock);951 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG1_REG,952 MCP3564_CONFIG1_OVERSPL_RATIO_MASK,953 FIELD_PREP(MCP3564_CONFIG1_OVERSPL_RATIO_MASK,954 adc->oversampling));955 if (!ret)956 adc->oversampling = tmp;957 mutex_unlock(&adc->lock);958 return ret;959 case IIO_CHAN_INFO_SCALE:960 for (hwgain = 0; hwgain < MCP3564_MAX_PGA; hwgain++)961 if (val == adc->scale_tbls[hwgain][0] &&962 val2 == adc->scale_tbls[hwgain][1])963 break;964 965 if (hwgain == MCP3564_MAX_PGA)966 return -EINVAL;967 968 if (hwgain == adc->hwgain)969 return ret;970 971 mutex_lock(&adc->lock);972 ret = mcp3564_update_8bits(adc, MCP3564_CONFIG2_REG,973 MCP3564_CONFIG2_HARDWARE_GAIN_MASK,974 FIELD_PREP(MCP3564_CONFIG2_HARDWARE_GAIN_MASK, hwgain));975 if (!ret)976 adc->hwgain = hwgain;977 978 mutex_unlock(&adc->lock);979 return ret;980 default:981 return -EINVAL;982 }983}984 985static int mcp3564_read_label(struct iio_dev *indio_dev,986 struct iio_chan_spec const *chan, char *label)987{988 struct mcp3564_state *adc = iio_priv(indio_dev);989 990 return sprintf(label, "%s\n", adc->labels[chan->scan_index]);991}992 993static int mcp3564_parse_fw_children(struct iio_dev *indio_dev)994{995 struct mcp3564_state *adc = iio_priv(indio_dev);996 struct device *dev = &adc->spi->dev;997 struct iio_chan_spec *channels;998 struct iio_chan_spec chanspec = mcp3564_channel_template;999 struct iio_chan_spec temp_chanspec = mcp3564_temp_channel_template;1000 struct iio_chan_spec burnout_chanspec = mcp3564_burnout_channel_template;1001 int chan_idx = 0;1002 unsigned int num_ch;1003 u32 inputs[2];1004 const char *node_name;1005 const char *label;1006 int ret;1007 1008 num_ch = device_get_child_node_count(dev);1009 if (num_ch == 0)1010 return dev_err_probe(&indio_dev->dev, -ENODEV,1011 "FW has no channels defined\n");1012 1013 /* Reserve space for burnout and temperature channel */1014 num_ch += 2;1015 1016 if (num_ch > adc->chip_info->num_channels)1017 return dev_err_probe(dev, -EINVAL, "Too many channels %d > %d\n",1018 num_ch, adc->chip_info->num_channels);1019 1020 channels = devm_kcalloc(dev, num_ch, sizeof(*channels), GFP_KERNEL);1021 if (!channels)1022 return dev_err_probe(dev, -ENOMEM, "Can't allocate memory\n");1023 1024 device_for_each_child_node_scoped(dev, child) {1025 node_name = fwnode_get_name(child);1026 1027 if (fwnode_property_present(child, "diff-channels")) {1028 ret = fwnode_property_read_u32_array(child,1029 "diff-channels",1030 inputs,1031 ARRAY_SIZE(inputs));1032 if (ret)1033 return ret;1034 1035 chanspec.differential = 1;1036 } else {1037 ret = fwnode_property_read_u32(child, "reg", &inputs[0]);1038 if (ret)1039 return ret;1040 1041 chanspec.differential = 0;1042 inputs[1] = MCP3564_AGND;1043 }1044 1045 if (inputs[0] > MCP3564_INTERNAL_VCM ||1046 inputs[1] > MCP3564_INTERNAL_VCM)1047 return dev_err_probe(&indio_dev->dev, -EINVAL,1048 "Channel index > %d, for %s\n",1049 MCP3564_INTERNAL_VCM + 1,1050 node_name);1051 1052 chanspec.address = (inputs[0] << 4) | inputs[1];1053 chanspec.channel = inputs[0];1054 chanspec.channel2 = inputs[1];1055 chanspec.scan_index = chan_idx;1056 1057 if (fwnode_property_present(child, "label")) {1058 fwnode_property_read_string(child, "label", &label);1059 adc->labels[chan_idx] = label;1060 }1061 1062 channels[chan_idx] = chanspec;1063 chan_idx++;1064 }1065 1066 /* Add burnout current channel */1067 burnout_chanspec.scan_index = chan_idx;1068 channels[chan_idx] = burnout_chanspec;1069 adc->labels[chan_idx] = mcp3564_channel_labels[0];1070 chanspec.scan_index = chan_idx;1071 chan_idx++;1072 1073 /* Add temperature channel */1074 temp_chanspec.scan_index = chan_idx;1075 channels[chan_idx] = temp_chanspec;1076 adc->labels[chan_idx] = mcp3564_channel_labels[1];1077 chan_idx++;1078 1079 indio_dev->num_channels = chan_idx;1080 indio_dev->channels = channels;1081 1082 return 0;1083}1084 1085static void mcp3564_fill_scale_tbls(struct mcp3564_state *adc)1086{1087 unsigned int pow = adc->chip_info->resolution - 1;1088 int ref;1089 unsigned int i;1090 int tmp0;1091 u64 tmp1;1092 1093 for (i = 0; i < MCP3564_MAX_PGA; i++) {1094 ref = adc->vref_mv;1095 tmp1 = ((u64)ref * NANO) >> pow;1096 div_u64_rem(tmp1, NANO, &tmp0);1097 1098 tmp1 = tmp1 * mcp3564_hwgain_frac[(2 * i) + 1];1099 tmp0 = (int)div_u64(tmp1, mcp3564_hwgain_frac[2 * i]);1100 1101 adc->scale_tbls[i][1] = tmp0;1102 }1103}1104 1105static int mcp3564_config(struct iio_dev *indio_dev, bool *use_internal_vref_attr)1106{1107 struct mcp3564_state *adc = iio_priv(indio_dev);1108 struct device *dev = &adc->spi->dev;1109 u8 tmp_reg;1110 u16 tmp_u16;1111 enum mcp3564_ids ids;1112 int ret = 0;1113 unsigned int tmp = 0x01;1114 bool internal_vref;1115 bool err = false;1116 1117 /*1118 * The address is set on a per-device basis by fuses in the factory,1119 * configured on request. If not requested, the fuses are set for 0x1.1120 * The device address is part of the device markings to avoid1121 * potential confusion. This address is coded on two bits, so four possible1122 * addresses are available when multiple devices are present on the same1123 * SPI bus with only one Chip Select line for all devices.1124 */1125 device_property_read_u32(dev, "microchip,hw-device-address", &tmp);1126 1127 if (tmp > 3) {1128 dev_err_probe(dev, tmp,1129 "invalid device address. Must be in range 0-3.\n");1130 return -EINVAL;1131 }1132 1133 adc->dev_addr = FIELD_GET(MCP3564_HW_ADDR_MASK, tmp);1134 1135 dev_dbg(dev, "use HW device address %i\n", adc->dev_addr);1136 1137 ret = mcp3564_read_8bits(adc, MCP3564_RESERVED_C_REG, &tmp_reg);1138 if (ret < 0)1139 return ret;1140 1141 switch (tmp_reg) {1142 case MCP3564_C_REG_DEFAULT:1143 adc->have_vref = false;1144 break;1145 case MCP3564R_C_REG_DEFAULT:1146 adc->have_vref = true;1147 break;1148 default:1149 dev_info(dev, "Unknown chip found: %d\n", tmp_reg);1150 err = true;1151 }1152 1153 if (!err) {1154 ret = mcp3564_read_16bits(adc, MCP3564_RESERVED_E_REG, &tmp_u16);1155 if (ret < 0)1156 return ret;1157 1158 switch (tmp_u16 & MCP3564_HW_ID_MASK) {1159 case MCP3461_HW_ID:1160 if (adc->have_vref)1161 ids = mcp3461r;1162 else1163 ids = mcp3461;1164 break;1165 case MCP3462_HW_ID:1166 if (adc->have_vref)1167 ids = mcp3462r;1168 else1169 ids = mcp3462;1170 break;1171 case MCP3464_HW_ID:1172 if (adc->have_vref)1173 ids = mcp3464r;1174 else1175 ids = mcp3464;1176 break;1177 case MCP3561_HW_ID:1178 if (adc->have_vref)1179 ids = mcp3561r;1180 else1181 ids = mcp3561;1182 break;1183 case MCP3562_HW_ID:1184 if (adc->have_vref)1185 ids = mcp3562r;1186 else1187 ids = mcp3562;1188 break;1189 case MCP3564_HW_ID:1190 if (adc->have_vref)1191 ids = mcp3564r;1192 else1193 ids = mcp3564;1194 break;1195 default:1196 dev_info(dev, "Unknown chip found: %d\n", tmp_u16);1197 err = true;1198 }1199 }1200 1201 if (err) {1202 /*1203 * If failed to identify the hardware based on internal registers,1204 * try using fallback compatible in device tree to deal with some newer part number.1205 */1206 adc->chip_info = spi_get_device_match_data(adc->spi);1207 adc->have_vref = adc->chip_info->have_vref;1208 } else {1209 adc->chip_info = &mcp3564_chip_infos_tbl[ids];1210 }1211 1212 dev_dbg(dev, "Found %s chip\n", adc->chip_info->name);1213 1214 ret = devm_regulator_get_enable_read_voltage(dev, "vref");1215 if (ret < 0 && ret != -ENODEV)1216 return dev_err_probe(dev, ret, "Failed to get vref voltage\n");1217 1218 internal_vref = ret == -ENODEV;1219 adc->vref_mv = internal_vref ? MCP3564R_INT_VREF_MV : ret / MILLI;1220 *use_internal_vref_attr = internal_vref;1221 1222 if (internal_vref) {1223 /* Check if chip has internal vref */1224 if (!adc->have_vref)1225 return dev_err_probe(dev, -ENODEV, "Unknown Vref\n");1226 1227 dev_dbg(dev, "%s: Using internal Vref\n", __func__);1228 } else {1229 dev_dbg(dev, "%s: Using External Vref\n", __func__);1230 }1231 1232 ret = mcp3564_parse_fw_children(indio_dev);1233 if (ret)1234 return ret;1235 1236 /*1237 * Command sequence that ensures a recovery with the desired settings1238 * in any cases of loss-of-power scenario (Full Chip Reset):1239 * - Write LOCK register to 0xA51240 * - Write IRQ register to 0x031241 * - Send "Device Full Reset" fast command1242 * - Wait 1ms for "Full Reset" to complete1243 */1244 ret = mcp3564_write_8bits(adc, MCP3564_LOCK_REG, MCP3564_LOCK_WRITE_ACCESS_PASSWORD);1245 if (ret)1246 return ret;1247 1248 ret = mcp3564_write_8bits(adc, MCP3564_IRQ_REG, 0x03);1249 if (ret)1250 return ret;1251 1252 ret = mcp3564_fast_cmd(adc, MCP3564_FASTCMD_RESET);1253 if (ret)1254 return ret;1255 1256 /*1257 * After Full reset wait some time to be able to fully reset the part and place1258 * it back in a default configuration.1259 * From datasheet: POR (Power On Reset Time) is ~1us1260 * 1ms should be enough.1261 */1262 mdelay(1);1263 1264 /* set a gain of 1x for GAINCAL */1265 ret = mcp3564_write_24bits(adc, MCP3564_GAINCAL_REG, MCP3564_DEFAULT_GAINCAL);1266 if (ret)1267 return ret;1268 1269 adc->calib_scale = MCP3564_DEFAULT_GAINCAL;1270 1271 ret = mcp3564_write_24bits(adc, MCP3564_OFFSETCAL_REG, MCP3564_DEFAULT_OFFSETCAL);1272 if (ret)1273 return ret;1274 1275 ret = mcp3564_write_24bits(adc, MCP3564_TIMER_REG, MCP3564_TIMER_DEFAULT_VALUE);1276 if (ret)1277 return ret;1278 1279 ret = mcp3564_write_24bits(adc, MCP3564_SCAN_REG,1280 MCP3564_SCAN_DELAY_TIME_SET(MCP3564_NO_DELAY) |1281 MCP3564_SCAN_CH_SEL_SET(MCP3564_SCAN_DEFAULT_VALUE));1282 if (ret)1283 return ret;1284 1285 ret = mcp3564_write_8bits(adc, MCP3564_MUX_REG, MCP3564_MUX_SET(MCP3564_CH0, MCP3564_CH1));1286 if (ret)1287 return ret;1288 1289 ret = mcp3564_write_8bits(adc, MCP3564_IRQ_REG,1290 FIELD_PREP(MCP3464_EN_FASTCMD_MASK, 1) |1291 FIELD_PREP(MCP3464_EN_STP_MASK, 1));1292 if (ret)1293 return ret;1294 1295 tmp_reg = FIELD_PREP(MCP3464_CONFIG3_CONV_MODE_MASK,1296 MCP3464_CONFIG3_CONV_MODE_ONE_SHOT_STANDBY);1297 tmp_reg |= FIELD_PREP(MCP3464_CONFIG3_DATA_FORMAT_MASK,1298 MCP3464_CONFIG3_DATA_FMT_32B_SGN_EXT);1299 tmp_reg |= MCP3464_CONFIG3_EN_OFFCAL_MASK;1300 tmp_reg |= MCP3464_CONFIG3_EN_GAINCAL_MASK;1301 1302 ret = mcp3564_write_8bits(adc, MCP3564_CONFIG3_REG, tmp_reg);1303 if (ret)1304 return ret;1305 1306 tmp_reg = FIELD_PREP(MCP3564_CONFIG2_BOOST_CURRENT_MASK, MCP3564_BOOST_CURRENT_x1_00);1307 tmp_reg |= FIELD_PREP(MCP3564_CONFIG2_HARDWARE_GAIN_MASK, 0x01);1308 tmp_reg |= FIELD_PREP(MCP3564_CONFIG2_AZ_MUX_MASK, 1);1309 1310 ret = mcp3564_write_8bits(adc, MCP3564_CONFIG2_REG, tmp_reg);1311 if (ret)1312 return ret;1313 1314 adc->hwgain = 0x01;1315 adc->auto_zeroing_mux = true;1316 adc->auto_zeroing_ref = false;1317 adc->current_boost_mode = MCP3564_BOOST_CURRENT_x1_00;1318 1319 tmp_reg = FIELD_PREP(MCP3564_CONFIG1_OVERSPL_RATIO_MASK, MCP3564_OVERSAMPLING_RATIO_98304);1320 1321 ret = mcp3564_write_8bits(adc, MCP3564_CONFIG1_REG, tmp_reg);1322 if (ret)1323 return ret;1324 1325 adc->oversampling = MCP3564_OVERSAMPLING_RATIO_98304;1326 1327 tmp_reg = FIELD_PREP(MCP3564_CONFIG0_ADC_MODE_MASK, MCP3564_ADC_MODE_STANDBY);1328 tmp_reg |= FIELD_PREP(MCP3564_CONFIG0_CS_SEL_MASK, MCP3564_CONFIG0_CS_SEL_0_0_uA);1329 tmp_reg |= FIELD_PREP(MCP3564_CONFIG0_CLK_SEL_MASK, MCP3564_CONFIG0_USE_INT_CLK);1330 tmp_reg |= MCP3456_CONFIG0_BIT6_DEFAULT;1331 1332 if (internal_vref)1333 tmp_reg |= FIELD_PREP(MCP3456_CONFIG0_VREF_MASK, 1);1334 1335 ret = mcp3564_write_8bits(adc, MCP3564_CONFIG0_REG, tmp_reg);1336 1337 adc->burnout_mode = MCP3564_CONFIG0_CS_SEL_0_0_uA;1338 1339 return ret;1340}1341 1342static IIO_DEVICE_ATTR(auto_zeroing_ref_enable, 0644,1343 mcp3564_auto_zeroing_ref_show,1344 mcp3564_auto_zeroing_ref_store, 0);1345 1346static IIO_DEVICE_ATTR(auto_zeroing_mux_enable, 0644,1347 mcp3564_auto_zeroing_mux_show,1348 mcp3564_auto_zeroing_mux_store, 0);1349 1350static struct attribute *mcp3564_attributes[] = {1351 &iio_dev_attr_auto_zeroing_mux_enable.dev_attr.attr,1352 NULL1353};1354 1355static struct attribute *mcp3564r_attributes[] = {1356 &iio_dev_attr_auto_zeroing_mux_enable.dev_attr.attr,1357 &iio_dev_attr_auto_zeroing_ref_enable.dev_attr.attr,1358 NULL1359};1360 1361static struct attribute_group mcp3564_attribute_group = {1362 .attrs = mcp3564_attributes,1363};1364 1365static struct attribute_group mcp3564r_attribute_group = {1366 .attrs = mcp3564r_attributes,1367};1368 1369static const struct iio_info mcp3564_info = {1370 .read_raw = mcp3564_read_raw,1371 .read_avail = mcp3564_read_avail,1372 .write_raw = mcp3564_write_raw,1373 .write_raw_get_fmt = mcp3564_write_raw_get_fmt,1374 .read_label = mcp3564_read_label,1375 .attrs = &mcp3564_attribute_group,1376};1377 1378static const struct iio_info mcp3564r_info = {1379 .read_raw = mcp3564_read_raw,1380 .read_avail = mcp3564_read_avail,1381 .write_raw = mcp3564_write_raw,1382 .write_raw_get_fmt = mcp3564_write_raw_get_fmt,1383 .read_label = mcp3564_read_label,1384 .attrs = &mcp3564r_attribute_group,1385};1386 1387static int mcp3564_probe(struct spi_device *spi)1388{1389 int ret;1390 struct iio_dev *indio_dev;1391 struct mcp3564_state *adc;1392 bool use_internal_vref_attr;1393 1394 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));1395 if (!indio_dev)1396 return -ENOMEM;1397 1398 adc = iio_priv(indio_dev);1399 adc->spi = spi;1400 1401 dev_dbg(&spi->dev, "%s: probe(spi = 0x%p)\n", __func__, spi);1402 1403 /*1404 * Do any chip specific initialization, e.g:1405 * read/write some registers1406 * enable/disable certain channels1407 * change the sampling rate to the requested value1408 */1409 ret = mcp3564_config(indio_dev, &use_internal_vref_attr);1410 if (ret)1411 return dev_err_probe(&spi->dev, ret,1412 "Can't configure MCP356X device\n");1413 1414 dev_dbg(&spi->dev, "%s: Vref (mV): %d\n", __func__, adc->vref_mv);1415 1416 mcp3564_fill_scale_tbls(adc);1417 1418 indio_dev->name = adc->chip_info->name;1419 indio_dev->modes = INDIO_DIRECT_MODE;1420 1421 if (use_internal_vref_attr)1422 indio_dev->info = &mcp3564r_info;1423 else1424 indio_dev->info = &mcp3564_info;1425 1426 mutex_init(&adc->lock);1427 1428 ret = devm_iio_device_register(&spi->dev, indio_dev);1429 if (ret)1430 return dev_err_probe(&spi->dev, ret,1431 "Can't register IIO device\n");1432 1433 return 0;1434}1435 1436static const struct of_device_id mcp3564_dt_ids[] = {1437 { .compatible = "microchip,mcp3461", .data = &mcp3564_chip_infos_tbl[mcp3461] },1438 { .compatible = "microchip,mcp3462", .data = &mcp3564_chip_infos_tbl[mcp3462] },1439 { .compatible = "microchip,mcp3464", .data = &mcp3564_chip_infos_tbl[mcp3464] },1440 { .compatible = "microchip,mcp3561", .data = &mcp3564_chip_infos_tbl[mcp3561] },1441 { .compatible = "microchip,mcp3562", .data = &mcp3564_chip_infos_tbl[mcp3562] },1442 { .compatible = "microchip,mcp3564", .data = &mcp3564_chip_infos_tbl[mcp3564] },1443 { .compatible = "microchip,mcp3461r", .data = &mcp3564_chip_infos_tbl[mcp3461r] },1444 { .compatible = "microchip,mcp3462r", .data = &mcp3564_chip_infos_tbl[mcp3462r] },1445 { .compatible = "microchip,mcp3464r", .data = &mcp3564_chip_infos_tbl[mcp3464r] },1446 { .compatible = "microchip,mcp3561r", .data = &mcp3564_chip_infos_tbl[mcp3561r] },1447 { .compatible = "microchip,mcp3562r", .data = &mcp3564_chip_infos_tbl[mcp3562r] },1448 { .compatible = "microchip,mcp3564r", .data = &mcp3564_chip_infos_tbl[mcp3564r] },1449 { }1450};1451MODULE_DEVICE_TABLE(of, mcp3564_dt_ids);1452 1453static const struct spi_device_id mcp3564_id[] = {1454 { "mcp3461", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3461] },1455 { "mcp3462", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3462] },1456 { "mcp3464", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3464] },1457 { "mcp3561", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3561] },1458 { "mcp3562", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3562] },1459 { "mcp3564", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3564] },1460 { "mcp3461r", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3461r] },1461 { "mcp3462r", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3462r] },1462 { "mcp3464r", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3464r] },1463 { "mcp3561r", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3561r] },1464 { "mcp3562r", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3562r] },1465 { "mcp3564r", (kernel_ulong_t)&mcp3564_chip_infos_tbl[mcp3564r] },1466 { }1467};1468MODULE_DEVICE_TABLE(spi, mcp3564_id);1469 1470static struct spi_driver mcp3564_driver = {1471 .driver = {1472 .name = "mcp3564",1473 .of_match_table = mcp3564_dt_ids,1474 },1475 .probe = mcp3564_probe,1476 .id_table = mcp3564_id,1477};1478 1479module_spi_driver(mcp3564_driver);1480 1481MODULE_AUTHOR("Marius Cristea <marius.cristea@microchip.com>");1482MODULE_DESCRIPTION("Microchip MCP346x/MCP346xR and MCP356x/MCP356xR ADCs");1483MODULE_LICENSE("GPL v2");1484