386 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Texas Instruments LMP92064 SPI ADC driver4 *5 * Copyright (c) 2022 Leonard Göhrs <kernel@pengutronix.de>, Pengutronix6 *7 * Based on linux/drivers/iio/adc/ti-tsc2046.c8 * Copyright (c) 2021 Oleksij Rempel <kernel@pengutronix.de>, Pengutronix9 */10 11#include <linux/delay.h>12#include <linux/gpio/consumer.h>13#include <linux/module.h>14#include <linux/regmap.h>15#include <linux/regulator/consumer.h>16#include <linux/spi/spi.h>17 18#include <linux/iio/iio.h>19#include <linux/iio/buffer.h>20#include <linux/iio/driver.h>21#include <linux/iio/triggered_buffer.h>22#include <linux/iio/trigger_consumer.h>23 24#define TI_LMP92064_REG_CONFIG_A 0x000025#define TI_LMP92064_REG_CONFIG_B 0x000126#define TI_LMP92064_REG_CHIP_REV 0x000627 28#define TI_LMP92064_REG_MFR_ID1 0x000C29#define TI_LMP92064_REG_MFR_ID2 0x000D30 31#define TI_LMP92064_REG_REG_UPDATE 0x000F32#define TI_LMP92064_REG_CONFIG_REG 0x010033#define TI_LMP92064_REG_STATUS 0x010334 35#define TI_LMP92064_REG_DATA_VOUT_LSB 0x020036#define TI_LMP92064_REG_DATA_VOUT_MSB 0x020137#define TI_LMP92064_REG_DATA_COUT_LSB 0x020238#define TI_LMP92064_REG_DATA_COUT_MSB 0x020339 40#define TI_LMP92064_VAL_CONFIG_A 0x9941#define TI_LMP92064_VAL_CONFIG_B 0x0042#define TI_LMP92064_VAL_STATUS_OK 0x0143 44/*45 * Channel number definitions for the two channels of the device46 * - IN Current (INC)47 * - IN Voltage (INV)48 */49#define TI_LMP92064_CHAN_INC 050#define TI_LMP92064_CHAN_INV 151 52static const struct regmap_range lmp92064_readable_reg_ranges[] = {53 regmap_reg_range(TI_LMP92064_REG_CONFIG_A, TI_LMP92064_REG_CHIP_REV),54 regmap_reg_range(TI_LMP92064_REG_MFR_ID1, TI_LMP92064_REG_MFR_ID2),55 regmap_reg_range(TI_LMP92064_REG_REG_UPDATE, TI_LMP92064_REG_REG_UPDATE),56 regmap_reg_range(TI_LMP92064_REG_CONFIG_REG, TI_LMP92064_REG_CONFIG_REG),57 regmap_reg_range(TI_LMP92064_REG_STATUS, TI_LMP92064_REG_STATUS),58 regmap_reg_range(TI_LMP92064_REG_DATA_VOUT_LSB, TI_LMP92064_REG_DATA_COUT_MSB),59};60 61static const struct regmap_access_table lmp92064_readable_regs = {62 .yes_ranges = lmp92064_readable_reg_ranges,63 .n_yes_ranges = ARRAY_SIZE(lmp92064_readable_reg_ranges),64};65 66static const struct regmap_range lmp92064_writable_reg_ranges[] = {67 regmap_reg_range(TI_LMP92064_REG_CONFIG_A, TI_LMP92064_REG_CONFIG_B),68 regmap_reg_range(TI_LMP92064_REG_REG_UPDATE, TI_LMP92064_REG_REG_UPDATE),69 regmap_reg_range(TI_LMP92064_REG_CONFIG_REG, TI_LMP92064_REG_CONFIG_REG),70};71 72static const struct regmap_access_table lmp92064_writable_regs = {73 .yes_ranges = lmp92064_writable_reg_ranges,74 .n_yes_ranges = ARRAY_SIZE(lmp92064_writable_reg_ranges),75};76 77static const struct regmap_config lmp92064_spi_regmap_config = {78 .reg_bits = 16,79 .val_bits = 8,80 .max_register = TI_LMP92064_REG_DATA_COUT_MSB,81 .rd_table = &lmp92064_readable_regs,82 .wr_table = &lmp92064_writable_regs,83};84 85struct lmp92064_adc_priv {86 int shunt_resistor_uohm;87 struct spi_device *spi;88 struct regmap *regmap;89};90 91static const struct iio_chan_spec lmp92064_adc_channels[] = {92 {93 .type = IIO_CURRENT,94 .address = TI_LMP92064_CHAN_INC,95 .info_mask_separate =96 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),97 .scan_index = TI_LMP92064_CHAN_INC,98 .scan_type = {99 .sign = 'u',100 .realbits = 12,101 .storagebits = 16,102 },103 .datasheet_name = "INC",104 },105 {106 .type = IIO_VOLTAGE,107 .address = TI_LMP92064_CHAN_INV,108 .info_mask_separate =109 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),110 .scan_index = TI_LMP92064_CHAN_INV,111 .scan_type = {112 .sign = 'u',113 .realbits = 12,114 .storagebits = 16,115 },116 .datasheet_name = "INV",117 },118 IIO_CHAN_SOFT_TIMESTAMP(2),119};120 121static const unsigned long lmp92064_scan_masks[] = {122 BIT(TI_LMP92064_CHAN_INC) | BIT(TI_LMP92064_CHAN_INV),123 0124};125 126static int lmp92064_read_meas(struct lmp92064_adc_priv *priv, u16 *res)127{128 __be16 raw[2];129 int ret;130 131 /*132 * The ADC only latches in new samples if all DATA registers are read133 * in descending sequential order.134 * The ADC auto-decrements the register index with each clocked byte.135 * Read both channels in single SPI transfer by selecting the highest136 * register using the command below and clocking out all four data137 * bytes.138 */139 140 ret = regmap_bulk_read(priv->regmap, TI_LMP92064_REG_DATA_COUT_MSB,141 &raw, sizeof(raw));142 143 if (ret) {144 dev_err(&priv->spi->dev, "regmap_bulk_read failed: %pe\n",145 ERR_PTR(ret));146 return ret;147 }148 149 res[0] = be16_to_cpu(raw[0]);150 res[1] = be16_to_cpu(raw[1]);151 152 return 0;153}154 155static int lmp92064_read_raw(struct iio_dev *indio_dev,156 struct iio_chan_spec const *chan, int *val,157 int *val2, long mask)158{159 struct lmp92064_adc_priv *priv = iio_priv(indio_dev);160 u16 raw[2];161 int ret;162 163 switch (mask) {164 case IIO_CHAN_INFO_RAW:165 ret = lmp92064_read_meas(priv, raw);166 if (ret < 0)167 return ret;168 169 *val = (chan->address == TI_LMP92064_CHAN_INC) ? raw[0] : raw[1];170 171 return IIO_VAL_INT;172 case IIO_CHAN_INFO_SCALE:173 if (chan->address == TI_LMP92064_CHAN_INC) {174 /*175 * processed (mA) = raw * current_lsb (mA)176 * current_lsb (mA) = shunt_voltage_lsb (nV) / shunt_resistor (uOhm)177 * shunt_voltage_lsb (nV) = 81920000 / 4096 = 20000178 */179 *val = 20000;180 *val2 = priv->shunt_resistor_uohm;181 } else {182 /*183 * processed (mV) = raw * voltage_lsb (mV)184 * voltage_lsb (mV) = 2048 / 4096185 */186 *val = 2048;187 *val2 = 4096;188 }189 return IIO_VAL_FRACTIONAL;190 default:191 return -EINVAL;192 }193}194 195static irqreturn_t lmp92064_trigger_handler(int irq, void *p)196{197 struct iio_poll_func *pf = p;198 struct iio_dev *indio_dev = pf->indio_dev;199 struct lmp92064_adc_priv *priv = iio_priv(indio_dev);200 struct {201 u16 values[2];202 int64_t timestamp __aligned(8);203 } data;204 int ret;205 206 memset(&data, 0, sizeof(data));207 208 ret = lmp92064_read_meas(priv, data.values);209 if (ret)210 goto err;211 212 iio_push_to_buffers_with_timestamp(indio_dev, &data,213 iio_get_time_ns(indio_dev));214 215err:216 iio_trigger_notify_done(indio_dev->trig);217 218 return IRQ_HANDLED;219}220 221static int lmp92064_reset(struct lmp92064_adc_priv *priv,222 struct gpio_desc *gpio_reset)223{224 unsigned int status;225 int ret, i;226 227 if (gpio_reset) {228 /*229 * Perform a hard reset if gpio_reset is available.230 * The datasheet specifies a very low 3.5ns reset pulse duration and does not231 * specify how long to wait after a reset to access the device.232 * Use more conservative pulse lengths to allow analog RC filtering of the233 * reset line at the board level (as recommended in the datasheet).234 */235 gpiod_set_value_cansleep(gpio_reset, 1);236 usleep_range(1, 10);237 gpiod_set_value_cansleep(gpio_reset, 0);238 usleep_range(500, 750);239 } else {240 /*241 * Perform a soft-reset if not.242 * Also write default values to the config registers that are not243 * affected by soft reset.244 */245 ret = regmap_write(priv->regmap, TI_LMP92064_REG_CONFIG_A,246 TI_LMP92064_VAL_CONFIG_A);247 if (ret < 0)248 return ret;249 250 ret = regmap_write(priv->regmap, TI_LMP92064_REG_CONFIG_B,251 TI_LMP92064_VAL_CONFIG_B);252 if (ret < 0)253 return ret;254 }255 256 /*257 * Wait for the device to signal readiness to prevent reading bogus data258 * and make sure device is actually connected.259 * The datasheet does not specify how long this takes but usually it is260 * not more than 3-4 iterations of this loop.261 */262 for (i = 0; i < 10; i++) {263 ret = regmap_read(priv->regmap, TI_LMP92064_REG_STATUS, &status);264 if (ret < 0)265 return ret;266 267 if (status == TI_LMP92064_VAL_STATUS_OK)268 return 0;269 270 usleep_range(1000, 2000);271 }272 273 /*274 * No (correct) response received.275 * Device is mostly likely not connected to the bus.276 */277 return -ENXIO;278}279 280static const struct iio_info lmp92064_adc_info = {281 .read_raw = lmp92064_read_raw,282};283 284static int lmp92064_adc_probe(struct spi_device *spi)285{286 struct device *dev = &spi->dev;287 struct lmp92064_adc_priv *priv;288 struct gpio_desc *gpio_reset;289 struct iio_dev *indio_dev;290 u32 shunt_resistor_uohm;291 struct regmap *regmap;292 int ret;293 294 ret = spi_setup(spi);295 if (ret < 0)296 return dev_err_probe(dev, ret, "Error in SPI setup\n");297 298 regmap = devm_regmap_init_spi(spi, &lmp92064_spi_regmap_config);299 if (IS_ERR(regmap))300 return dev_err_probe(dev, PTR_ERR(regmap),301 "Failed to set up SPI regmap\n");302 303 indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));304 if (!indio_dev)305 return -ENOMEM;306 307 priv = iio_priv(indio_dev);308 309 priv->spi = spi;310 priv->regmap = regmap;311 312 ret = device_property_read_u32(dev, "shunt-resistor-micro-ohms",313 &shunt_resistor_uohm);314 if (ret < 0)315 return dev_err_probe(dev, ret,316 "Failed to get shunt-resistor value\n");317 318 /*319 * The shunt resistance is passed to userspace as the denominator of an iio320 * fraction. Make sure it is in range for that.321 */322 if (shunt_resistor_uohm == 0 || shunt_resistor_uohm > INT_MAX) {323 dev_err(dev, "Shunt resistance is out of range\n");324 return -EINVAL;325 }326 327 priv->shunt_resistor_uohm = shunt_resistor_uohm;328 329 ret = devm_regulator_get_enable(dev, "vdd");330 if (ret)331 return ret;332 333 ret = devm_regulator_get_enable(dev, "vdig");334 if (ret)335 return ret;336 337 gpio_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);338 if (IS_ERR(gpio_reset))339 return dev_err_probe(dev, PTR_ERR(gpio_reset),340 "Failed to get GPIO reset pin\n");341 342 ret = lmp92064_reset(priv, gpio_reset);343 if (ret < 0)344 return dev_err_probe(dev, ret, "Failed to reset device\n");345 346 indio_dev->name = "lmp92064";347 indio_dev->modes = INDIO_DIRECT_MODE;348 indio_dev->channels = lmp92064_adc_channels;349 indio_dev->num_channels = ARRAY_SIZE(lmp92064_adc_channels);350 indio_dev->info = &lmp92064_adc_info;351 indio_dev->available_scan_masks = lmp92064_scan_masks;352 353 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,354 lmp92064_trigger_handler, NULL);355 if (ret)356 return dev_err_probe(dev, ret, "Failed to setup buffered read\n");357 358 return devm_iio_device_register(dev, indio_dev);359}360 361static const struct spi_device_id lmp92064_id_table[] = {362 { "lmp92064" },363 { }364};365MODULE_DEVICE_TABLE(spi, lmp92064_id_table);366 367static const struct of_device_id lmp92064_of_table[] = {368 { .compatible = "ti,lmp92064" },369 {}370};371MODULE_DEVICE_TABLE(of, lmp92064_of_table);372 373static struct spi_driver lmp92064_adc_driver = {374 .driver = {375 .name = "lmp92064",376 .of_match_table = lmp92064_of_table,377 },378 .probe = lmp92064_adc_probe,379 .id_table = lmp92064_id_table,380};381module_spi_driver(lmp92064_adc_driver);382 383MODULE_AUTHOR("Leonard Göhrs <kernel@pengutronix.de>");384MODULE_DESCRIPTION("TI LMP92064 ADC");385MODULE_LICENSE("GPL");386