Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/iio/adc/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 6 kB image not shown  

Quelle  ltc2497-core.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * ltc2497-core.c - Common code for Analog Devices/Linear Technology
 * LTC2496 and LTC2497 ADCs
 *
 * Copyright (C) 2017 Analog Devices Inc.
 */


#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/regulator/consumer.h>

#include "ltc2497.h"

#define LTC2497_SGL   BIT(4)
#define LTC2497_DIFF   0
#define LTC2497_SIGN   BIT(3)

static int ltc2497core_wait_conv(struct ltc2497core_driverdata *ddata)
{
 s64 time_elapsed;

 time_elapsed = ktime_ms_delta(ktime_get(), ddata->time_prev);

 if (time_elapsed < LTC2497_CONVERSION_TIME_MS) {
  /* delay if conversion time not passed
 * since last read or write
 */

  if (msleep_interruptible(
      LTC2497_CONVERSION_TIME_MS - time_elapsed))
   return -ERESTARTSYS;

  return 0;
 }

 if (time_elapsed - LTC2497_CONVERSION_TIME_MS <= 0) {
  /* We're in automatic mode -
 * so the last reading is still not outdated
 */

  return 0;
 }

 return 1;
}

static int ltc2497core_read(struct ltc2497core_driverdata *ddata, u8 address, int *val)
{
 int ret;

 ret = ltc2497core_wait_conv(ddata);
 if (ret < 0)
  return ret;

 if (ret || ddata->addr_prev != address) {
  ret = ddata->result_and_measure(ddata, address, NULL);
  if (ret < 0)
   return ret;
  ddata->addr_prev = address;

  if (msleep_interruptible(LTC2497_CONVERSION_TIME_MS))
   return -ERESTARTSYS;
 }

 ret = ddata->result_and_measure(ddata, address, val);
 if (ret < 0)
  return ret;

 ddata->time_prev = ktime_get();

 return ret;
}

static int ltc2497core_read_raw(struct iio_dev *indio_dev,
       struct iio_chan_spec const *chan,
       int *val, int *val2, long mask)
{
 struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);
 int ret;

 switch (mask) {
 case IIO_CHAN_INFO_RAW:
  mutex_lock(&ddata->lock);
  ret = ltc2497core_read(ddata, chan->address, val);
  mutex_unlock(&ddata->lock);
  if (ret < 0)
   return ret;

  return IIO_VAL_INT;

 case IIO_CHAN_INFO_SCALE:
  ret = regulator_get_voltage(ddata->ref);
  if (ret < 0)
   return ret;

  *val = ret / 1000;
  *val2 = ddata->chip_info->resolution + 1;

  return IIO_VAL_FRACTIONAL_LOG2;

 default:
  return -EINVAL;
 }
}

#define LTC2497_CHAN(_chan, _addr, _ds_name) { \
 .type = IIO_VOLTAGE, \
 .indexed = 1, \
 .channel = (_chan), \
 .address = (_addr | (_chan / 2) | ((_chan & 1) ? LTC2497_SIGN : 0)), \
 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 .datasheet_name = (_ds_name), \
}

#define LTC2497_CHAN_DIFF(_chan, _addr) { \
 .type = IIO_VOLTAGE, \
 .indexed = 1, \
 .channel = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 1 : 0), \
 .channel2 = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 0 : 1),\
 .address = (_addr | _chan), \
 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 .differential = 1, \
}

static const struct iio_chan_spec ltc2497core_channel[] = {
 LTC2497_CHAN(0, LTC2497_SGL, "CH0"),
 LTC2497_CHAN(1, LTC2497_SGL, "CH1"),
 LTC2497_CHAN(2, LTC2497_SGL, "CH2"),
 LTC2497_CHAN(3, LTC2497_SGL, "CH3"),
 LTC2497_CHAN(4, LTC2497_SGL, "CH4"),
 LTC2497_CHAN(5, LTC2497_SGL, "CH5"),
 LTC2497_CHAN(6, LTC2497_SGL, "CH6"),
 LTC2497_CHAN(7, LTC2497_SGL, "CH7"),
 LTC2497_CHAN(8, LTC2497_SGL, "CH8"),
 LTC2497_CHAN(9, LTC2497_SGL, "CH9"),
 LTC2497_CHAN(10, LTC2497_SGL, "CH10"),
 LTC2497_CHAN(11, LTC2497_SGL, "CH11"),
 LTC2497_CHAN(12, LTC2497_SGL, "CH12"),
 LTC2497_CHAN(13, LTC2497_SGL, "CH13"),
 LTC2497_CHAN(14, LTC2497_SGL, "CH14"),
 LTC2497_CHAN(15, LTC2497_SGL, "CH15"),
 LTC2497_CHAN_DIFF(0, LTC2497_DIFF),
 LTC2497_CHAN_DIFF(1, LTC2497_DIFF),
 LTC2497_CHAN_DIFF(2, LTC2497_DIFF),
 LTC2497_CHAN_DIFF(3, LTC2497_DIFF),
 LTC2497_CHAN_DIFF(4, LTC2497_DIFF),
 LTC2497_CHAN_DIFF(5, LTC2497_DIFF),
 LTC2497_CHAN_DIFF(6, LTC2497_DIFF),
 LTC2497_CHAN_DIFF(7, LTC2497_DIFF),
 LTC2497_CHAN_DIFF(0, LTC2497_DIFF | LTC2497_SIGN),
 LTC2497_CHAN_DIFF(1, LTC2497_DIFF | LTC2497_SIGN),
 LTC2497_CHAN_DIFF(2, LTC2497_DIFF | LTC2497_SIGN),
 LTC2497_CHAN_DIFF(3, LTC2497_DIFF | LTC2497_SIGN),
 LTC2497_CHAN_DIFF(4, LTC2497_DIFF | LTC2497_SIGN),
 LTC2497_CHAN_DIFF(5, LTC2497_DIFF | LTC2497_SIGN),
 LTC2497_CHAN_DIFF(6, LTC2497_DIFF | LTC2497_SIGN),
 LTC2497_CHAN_DIFF(7, LTC2497_DIFF | LTC2497_SIGN),
};

static const struct iio_info ltc2497core_info = {
 .read_raw = ltc2497core_read_raw,
};

int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev)
{
 struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);
 struct iio_map *plat_data = dev_get_platdata(dev);
 int ret;

 /*
 * Keep using dev_name() for the iio_dev's name on some of the parts,
 * since updating it would result in a ABI breakage.
 */

 if (ddata->chip_info->name)
  indio_dev->name = ddata->chip_info->name;
 else
  indio_dev->name = dev_name(dev);

 indio_dev->info = <c2497core_info;
 indio_dev->modes = INDIO_DIRECT_MODE;
 indio_dev->channels = ltc2497core_channel;
 indio_dev->num_channels = ARRAY_SIZE(ltc2497core_channel);

 ret = ddata->result_and_measure(ddata, LTC2497_CONFIG_DEFAULT, NULL);
 if (ret < 0)
  return ret;

 ddata->ref = devm_regulator_get(dev, "vref");
 if (IS_ERR(ddata->ref))
  return dev_err_probe(dev, PTR_ERR(ddata->ref),
         "Failed to get vref regulator\n");

 ret = regulator_enable(ddata->ref);
 if (ret < 0) {
  dev_err(dev, "Failed to enable vref regulator: %pe\n",
   ERR_PTR(ret));
  return ret;
 }

 ret = iio_map_array_register(indio_dev, plat_data);
 if (ret) {
  dev_err(&indio_dev->dev, "iio map err: %d\n", ret);
  goto err_regulator_disable;
 }

 ddata->addr_prev = LTC2497_CONFIG_DEFAULT;
 ddata->time_prev = ktime_get();

 mutex_init(&ddata->lock);

 ret = iio_device_register(indio_dev);
 if (ret < 0)
  goto err_array_unregister;

 return 0;

err_array_unregister:
 iio_map_array_unregister(indio_dev);

err_regulator_disable:
 regulator_disable(ddata->ref);

 return ret;
}
EXPORT_SYMBOL_NS(ltc2497core_probe, "LTC2497");

void ltc2497core_remove(struct iio_dev *indio_dev)
{
 struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);

 iio_device_unregister(indio_dev);

 iio_map_array_unregister(indio_dev);

 regulator_disable(ddata->ref);
}
EXPORT_SYMBOL_NS(ltc2497core_remove, "LTC2497");

MODULE_DESCRIPTION("common code for LTC2496/LTC2497 drivers");
MODULE_LICENSE("GPL v2");

Messung V0.5
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.