Skip to content
Snippets Groups Projects
Commit 5decbf53 authored by Przemyslaw Marczak's avatar Przemyslaw Marczak Committed by Minkyu Kang
Browse files

dm: adc: add simple ADC uclass implementation


This commit adds:
- new uclass id: UCLASS_ADC
- new uclass driver: drivers/adc/adc-uclass.c

The new uclass's API allows for ADC operation on:
* single-channel with channel selection by a number
* multti-channel with channel selection by bit mask

ADC uclass's functions:
* single-channel:
  - adc_start_channel()        - start channel conversion
  - adc_channel_data()         - get conversion data
  - adc_channel_single_shot()  - start/get conversion data
* multi-channel:
  - adc_start_channels()       - start selected channels conversion
  - adc_channels_data()        - get conversion data
  - adc_channels_single_shot() - start/get conversion data for channels
                                 selected by bit mask
* general:
  - adc_stop()      - stop the conversion
  - adc_vdd_value() - positive reference Voltage value with polarity [uV]
  - adc_vss_value() - negative reference Voltage value with polarity [uV]
  - adc_data_mask() - conversion data bit mask

The device tree can provide below constraints/properties:
- vdd-polarity-negative: if true: Vdd = vdd-microvolts * (-1)
- vss-polarity-negative: if true: Vss = vss-microvolts * (-1)
- vdd-supply:            phandle to Vdd regulator's node
- vss-supply:            phandle to Vss regulator's node
And optional, checked only if the above corresponding, doesn't exist:
  - vdd-microvolts:      positive reference Voltage [uV]
  - vss-microvolts:      negative reference Voltage [uV]

Signed-off-by: default avatarPrzemyslaw Marczak <p.marczak@samsung.com>
Cc: Simon Glass <sjg@chromium.org>
Signed-off-by: default avatarMinkyu Kang <mk7.kang@samsung.com>
parent 7c816e24
No related branches found
No related tags found
No related merge requests found
ADC device binding
There are no mandatory properties for ADC. However, if Voltage info is required,
then there are two options:
- use microvolts constraint or
- use regulator phandle to enable/read supply's Voltage
Properties and constraints:
*optional and always checked, Voltage polarity info:
- vdd-polarity-negative: positive reference Voltage has a negative polarity
- vss-polarity-negative: negative reference Voltage has a negative polarity
Chose one option, for each supply (Vdd/Vss):
*optional and always checked, supply Voltage constants:
- vdd-supply: phandle to Vdd regulator's node
- vss-supply: phandle to Vss regulator's node
*optional and checked only if the above corresponding, doesn't exist:
- vdd-microvolts: positive reference Voltage value [uV]
- vss-microvolts: negative reference Voltage value [uV]
Example with constant 'Vdd' value:
adc@1000000 {
compatible = "some-adc";
reg = <0xaabb000 0x100>;
status = "enabled";
vdd-microvolts = <1800000>;
};
Example of supply phandle usage, for the ADC's VDD/VSS references as below:
_______ _______
|Sandbox| |Sandbox|
: PMIC : : ADC :
. . . .
| | (Vdd) | AIN0|-->
| BUCK2|-------|VDDref |
| (3.3V)| _|VSSref |
|_______| | |_______|
_|_
For the above PMIC, the node can be defined as follows:
sandbox_pmic {
compatible = "sandbox,pmic";
...
buck2: buck2 {
regulator-name = "SUPPLY_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
...
};
For the above ADC, the node can be defined as follows:
adc@0 {
compatible = "sandbox,adc";
vdd-supply = <&buck2>;
vss-microvolts = <0>;
};
The ADC uclass code, will enable the supply before start of the conversion,
but it will not configure the regulator settings.
...@@ -4,6 +4,8 @@ source "drivers/core/Kconfig" ...@@ -4,6 +4,8 @@ source "drivers/core/Kconfig"
# types of drivers sorted in alphabetical order # types of drivers sorted in alphabetical order
source "drivers/adc/Kconfig"
source "drivers/block/Kconfig" source "drivers/block/Kconfig"
source "drivers/clk/Kconfig" source "drivers/clk/Kconfig"
......
...@@ -35,6 +35,7 @@ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/ ...@@ -35,6 +35,7 @@ obj-$(CONFIG_SPL_SATA_SUPPORT) += block/
else else
obj-y += adc/
obj-$(CONFIG_DM_DEMO) += demo/ obj-$(CONFIG_DM_DEMO) += demo/
obj-$(CONFIG_BIOSEMU) += bios_emulator/ obj-$(CONFIG_BIOSEMU) += bios_emulator/
obj-y += block/ obj-y += block/
......
config ADC
bool "Enable ADC drivers using Driver Model"
help
This enables ADC API for drivers, which allows driving ADC features
by single and multi-channel methods for:
- start/stop/get data for conversion of a single-channel selected by
a number or multi-channels selected by a bitmask
- get data mask (ADC resolution)
ADC reference Voltage supply options:
- methods for get Vdd/Vss reference Voltage values with polarity
- support supply's phandle with auto-enable
- supply polarity setting in fdt
#
# Copyright (C) 2015 Samsung Electronics
# Przemyslaw Marczak <p.marczak@samsung.com>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_ADC) += adc-uclass.o
/*
* Copyright (C) 2015 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <dm.h>
#include <dm/lists.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <adc.h>
#include <power/regulator.h>
DECLARE_GLOBAL_DATA_PTR;
#define ADC_UCLASS_PLATDATA_SIZE sizeof(struct adc_uclass_platdata)
#define CHECK_NUMBER true
#define CHECK_MASK (!CHECK_NUMBER)
/* TODO: add support for timer uclass (for early calls) */
#ifdef CONFIG_SANDBOX_ARCH
#define sdelay(x) udelay(x)
#else
extern void sdelay(unsigned long loops);
#endif
static int check_channel(struct udevice *dev, int value, bool number_or_mask,
const char *caller_function)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
unsigned mask = number_or_mask ? (1 << value) : value;
/* For the real ADC hardware, some ADC channels can be inactive.
* For example if device has 4 analog channels, and only channels
* 1-st and 3-rd are valid, then channel mask is: 0b1010, so request
* with mask 0b1110 should return an error.
*/
if ((uc_pdata->channel_mask >= mask) && (uc_pdata->channel_mask & mask))
return 0;
printf("Error in %s/%s().\nWrong channel selection for device: %s\n",
__FILE__, caller_function, dev->name);
return -EINVAL;
}
static int adc_supply_enable(struct udevice *dev)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
const char *supply_type;
int ret = 0;
if (uc_pdata->vdd_supply) {
supply_type = "vdd";
ret = regulator_set_enable(uc_pdata->vdd_supply, true);
}
if (!ret && uc_pdata->vss_supply) {
supply_type = "vss";
ret = regulator_set_enable(uc_pdata->vss_supply, true);
}
if (ret)
error("%s: can't enable %s-supply!", dev->name, supply_type);
return ret;
}
int adc_data_mask(struct udevice *dev, unsigned int *data_mask)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
if (!uc_pdata)
return -ENOSYS;
*data_mask = uc_pdata->data_mask;
return 0;
}
int adc_stop(struct udevice *dev)
{
const struct adc_ops *ops = dev_get_driver_ops(dev);
if (!ops->stop)
return -ENOSYS;
return ops->stop(dev);
}
int adc_start_channel(struct udevice *dev, int channel)
{
const struct adc_ops *ops = dev_get_driver_ops(dev);
int ret;
if (!ops->start_channel)
return -ENOSYS;
ret = check_channel(dev, channel, CHECK_NUMBER, __func__);
if (ret)
return ret;
ret = adc_supply_enable(dev);
if (ret)
return ret;
return ops->start_channel(dev, channel);
}
int adc_start_channels(struct udevice *dev, unsigned int channel_mask)
{
const struct adc_ops *ops = dev_get_driver_ops(dev);
int ret;
if (!ops->start_channels)
return -ENOSYS;
ret = check_channel(dev, channel_mask, CHECK_MASK, __func__);
if (ret)
return ret;
ret = adc_supply_enable(dev);
if (ret)
return ret;
return ops->start_channels(dev, channel_mask);
}
int adc_channel_data(struct udevice *dev, int channel, unsigned int *data)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
const struct adc_ops *ops = dev_get_driver_ops(dev);
unsigned int timeout_us = uc_pdata->data_timeout_us;
int ret;
if (!ops->channel_data)
return -ENOSYS;
ret = check_channel(dev, channel, CHECK_NUMBER, __func__);
if (ret)
return ret;
do {
ret = ops->channel_data(dev, channel, data);
if (!ret || ret != -EBUSY)
break;
/* TODO: use timer uclass (for early calls). */
sdelay(5);
} while (timeout_us--);
return ret;
}
int adc_channels_data(struct udevice *dev, unsigned int channel_mask,
struct adc_channel *channels)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
unsigned int timeout_us = uc_pdata->multidata_timeout_us;
const struct adc_ops *ops = dev_get_driver_ops(dev);
int ret;
if (!ops->channels_data)
return -ENOSYS;
ret = check_channel(dev, channel_mask, CHECK_MASK, __func__);
if (ret)
return ret;
do {
ret = ops->channels_data(dev, channel_mask, channels);
if (!ret || ret != -EBUSY)
break;
/* TODO: use timer uclass (for early calls). */
sdelay(5);
} while (timeout_us--);
return ret;
}
int adc_channel_single_shot(const char *name, int channel, unsigned int *data)
{
struct udevice *dev;
int ret;
ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev);
if (ret)
return ret;
ret = adc_start_channel(dev, channel);
if (ret)
return ret;
ret = adc_channel_data(dev, channel, data);
if (ret)
return ret;
return 0;
}
static int _adc_channels_single_shot(struct udevice *dev,
unsigned int channel_mask,
struct adc_channel *channels)
{
unsigned int data;
int channel, ret;
for (channel = 0; channel <= ADC_MAX_CHANNEL; channel++) {
/* Check channel bit. */
if (!((channel_mask >> channel) & 0x1))
continue;
ret = adc_start_channel(dev, channel);
if (ret)
return ret;
ret = adc_channel_data(dev, channel, &data);
if (ret)
return ret;
channels->id = channel;
channels->data = data;
channels++;
}
return 0;
}
int adc_channels_single_shot(const char *name, unsigned int channel_mask,
struct adc_channel *channels)
{
struct udevice *dev;
int ret;
ret = uclass_get_device_by_name(UCLASS_ADC, name, &dev);
if (ret)
return ret;
ret = adc_start_channels(dev, channel_mask);
if (ret)
goto try_manual;
ret = adc_channels_data(dev, channel_mask, channels);
if (ret)
return ret;
return 0;
try_manual:
if (ret != -ENOSYS)
return ret;
return _adc_channels_single_shot(dev, channel_mask, channels);
}
static int adc_vdd_platdata_update(struct udevice *dev)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
int ret;
/* Warning!
* This function can't return supply device before its bind.
* Please pay attention to proper fdt scan sequence. If ADC device
* will bind before its supply regulator device, then the below 'get'
* will return an error.
*/
ret = device_get_supply_regulator(dev, "vdd-supply",
&uc_pdata->vdd_supply);
if (ret)
return ret;
ret = regulator_get_value(uc_pdata->vdd_supply);
if (ret < 0)
return ret;
uc_pdata->vdd_microvolts = ret;
return 0;
}
static int adc_vss_platdata_update(struct udevice *dev)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
int ret;
ret = device_get_supply_regulator(dev, "vss-supply",
&uc_pdata->vss_supply);
if (ret)
return ret;
ret = regulator_get_value(uc_pdata->vss_supply);
if (ret < 0)
return ret;
uc_pdata->vss_microvolts = ret;
return 0;
}
int adc_vdd_value(struct udevice *dev, int *uV)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
int ret, value_sign = uc_pdata->vdd_polarity_negative ? -1 : 1;
if (!uc_pdata->vdd_supply)
goto nodev;
/* Update the regulator Value. */
ret = adc_vdd_platdata_update(dev);
if (ret)
return ret;
nodev:
if (uc_pdata->vdd_microvolts == -ENODATA)
return -ENODATA;
*uV = uc_pdata->vdd_microvolts * value_sign;
return 0;
}
int adc_vss_value(struct udevice *dev, int *uV)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
int ret, value_sign = uc_pdata->vss_polarity_negative ? -1 : 1;
if (!uc_pdata->vss_supply)
goto nodev;
/* Update the regulator Value. */
ret = adc_vss_platdata_update(dev);
if (ret)
return ret;
nodev:
if (uc_pdata->vss_microvolts == -ENODATA)
return -ENODATA;
*uV = uc_pdata->vss_microvolts * value_sign;
return 0;
}
static int adc_vdd_platdata_set(struct udevice *dev)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
int ret, offset = dev->of_offset;
const void *fdt = gd->fdt_blob;
char *prop;
prop = "vdd-polarity-negative";
uc_pdata->vdd_polarity_negative = fdtdec_get_bool(fdt, offset, prop);
ret = adc_vdd_platdata_update(dev);
if (ret != -ENOENT)
return ret;
/* No vdd-supply phandle. */
prop = "vdd-microvolts";
uc_pdata->vdd_microvolts = fdtdec_get_int(fdt, offset, prop, -ENODATA);
return 0;
}
static int adc_vss_platdata_set(struct udevice *dev)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
int ret, offset = dev->of_offset;
const void *fdt = gd->fdt_blob;
char *prop;
prop = "vss-polarity-negative";
uc_pdata->vss_polarity_negative = fdtdec_get_bool(fdt, offset, prop);
ret = adc_vss_platdata_update(dev);
if (ret != -ENOENT)
return ret;
/* No vss-supply phandle. */
prop = "vss-microvolts";
uc_pdata->vss_microvolts = fdtdec_get_int(fdt, offset, prop, -ENODATA);
return 0;
}
static int adc_pre_probe(struct udevice *dev)
{
int ret;
/* Set ADC VDD platdata: polarity, uV, regulator (phandle). */
ret = adc_vdd_platdata_set(dev);
if (ret)
error("%s: Can't update Vdd. Error: %d", dev->name, ret);
/* Set ADC VSS platdata: polarity, uV, regulator (phandle). */
ret = adc_vss_platdata_set(dev);
if (ret)
error("%s: Can't update Vss. Error: %d", dev->name, ret);
return 0;
}
UCLASS_DRIVER(adc) = {
.id = UCLASS_ADC,
.name = "adc",
.pre_probe = adc_pre_probe,
.per_device_platdata_auto_alloc_size = ADC_UCLASS_PLATDATA_SIZE,
};
/*
* Copyright (C) 2015 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ADC_H_
#define _ADC_H_
/* ADC_CHANNEL() - ADC channel bit mask, to select only required channels */
#define ADC_CHANNEL(x) (1 << x)
/* The last possible selected channel with 32-bit mask */
#define ADC_MAX_CHANNEL 31
/**
* adc_data_format: define the ADC output data format, can be useful when
* the device's input Voltage range is bipolar.
* - ADC_DATA_FORMAT_BIN - binary offset
* - ADC_DATA_FORMAT_2S - two's complement
*
* Note: Device's driver should fill the 'data_format' field of its uclass's
* platform data using one of the above data format types.
*/
enum adc_data_format {
ADC_DATA_FORMAT_BIN,
ADC_DATA_FORMAT_2S,
};
/**
* struct adc_channel - structure to hold channel conversion data.
* Useful to keep the result of a multi-channel conversion output.
*
* @id - channel id
* @data - channel conversion data
*/
struct adc_channel {
int id;
unsigned int data;
};
/**
* struct adc_uclass_platdata - basic ADC info
*
* Note: The positive/negative reference Voltage is only a name and it doesn't
* provide an information about the value polarity. It is possible, for both
* values to be a negative or positive. For this purpose the uclass's platform
* data provides a bool fields: 'vdd/vss_supply_is_negative'. This is useful,
* since the regulator API returns only a positive Voltage values.
*
* To get the reference Voltage values with polarity, use functions:
* - adc_vdd_value()
* - adc_vss_value()
* Those are useful for some cases of ADC's references, e.g.:
* * Vdd: +3.3V; Vss: -3.3V -> 6.6 Vdiff
* * Vdd: +3.3V; Vss: +0.3V -> 3.0 Vdiff
* * Vdd: +3.3V; Vss: 0.0V -> 3.3 Vdiff
* The last one is usually standard and doesn't require the fdt polarity info.
*
* For more informations read binding info:
* - doc/device-tree-bindings/adc/adc.txt
*
* @data_mask - conversion output data mask
* @data_timeout_us - single channel conversion timeout
* @multidata_timeout_us - multi channel conversion timeout
* @channel_mask - bit mask of available channels [0:31]
* @vdd_supply - positive reference Voltage supply (regulator)
* @vss_supply - negative reference Voltage supply (regulator)
* @vdd_polarity_negative - positive reference Voltage has negative polarity
* @vss_polarity_negative - negative reference Voltage has negative polarity
* @vdd_microvolts - positive reference Voltage value
* @vss_microvolts - negative reference Voltage value
*/
struct adc_uclass_platdata {
int data_format;
unsigned int data_mask;
unsigned int data_timeout_us;
unsigned int multidata_timeout_us;
unsigned int channel_mask;
struct udevice *vdd_supply;
struct udevice *vss_supply;
bool vdd_polarity_negative;
bool vss_polarity_negative;
int vdd_microvolts;
int vss_microvolts;
};
/**
* struct adc_ops - ADC device operations for single/multi-channel operation.
*/
struct adc_ops {
/**
* start_channel() - start conversion with its default parameters
* for the given channel number.
*
* @dev: ADC device to init
* @channel: analog channel number
* @return: 0 if OK, -ve on error
*/
int (*start_channel)(struct udevice *dev, int channel);
/**
* start_channels() - start conversion with its default parameters
* for the channel numbers selected by the bit mask.
*
* This is optional, useful when the hardware supports multichannel
* conversion by the single software trigger.
*
* @dev: ADC device to init
* @channel_mask: bit mask of selected analog channels
* @return: 0 if OK, -ve on error
*/
int (*start_channels)(struct udevice *dev, unsigned int channel_mask);
/**
* channel_data() - get conversion output data for the given channel.
*
* Note: The implementation of this function should only check, that
* the conversion data is available at the call time. If the hardware
* requires some delay to get the data, then this function should
* return with -EBUSY value. The ADC API will call it in a loop,
* until the data is available or the timeout expires. The maximum
* timeout for this operation is defined by the field 'data_timeout_us'
* in ADC uclasses platform data structure.
*
* @dev: ADC device to trigger
* @channel: selected analog channel number
* @data: returned pointer to selected channel's output data
* @return: 0 if OK, -EBUSY if busy, and other negative on error
*/
int (*channel_data)(struct udevice *dev, int channel,
unsigned int *data);
/**
* channels_data() - get conversion data for the selected channels.
*
* This is optional, useful when multichannel conversion is supported
* by the hardware, by the single software trigger.
*
* For the proper implementation, please look at the 'Note' for the
* above method. The only difference is in used timeout value, which
* is defined by field 'multidata_timeout_us'.
*
* @dev: ADC device to trigger
* @channel_mask: bit mask of selected analog channels
* @channels: returned pointer to array of output data for channels
* selected by the given mask
* @return: 0 if OK, -ve on error
*/
int (*channels_data)(struct udevice *dev, unsigned int channel_mask,
struct adc_channel *channels);
/**
* stop() - stop conversion of the given ADC device
*
* @dev: ADC device to stop
* @return: 0 if OK, -ve on error
*/
int (*stop)(struct udevice *dev);
};
/**
* adc_start_channel() - start conversion for given device/channel and exit.
*
* @dev: ADC device
* @channel: analog channel number
* @return: 0 if OK, -ve on error
*/
int adc_start_channel(struct udevice *dev, int channel);
/**
* adc_start_channels() - start conversion for given device/channels and exit.
*
* Note:
* To use this function, device must implement method: start_channels().
*
* @dev: ADC device to start
* @channel_mask: channel selection - a bit mask
* @channel_mask: bit mask of analog channels
* @return: 0 if OK, -ve on error
*/
int adc_start_channels(struct udevice *dev, unsigned int channel_mask);
/**
* adc_channel_data() - get conversion data for the given device channel number.
*
* @dev: ADC device to read
* @channel: analog channel number
* @data: pointer to returned channel's data
* @return: 0 if OK, -ve on error
*/
int adc_channel_data(struct udevice *dev, int channel, unsigned int *data);
/**
* adc_channels_data() - get conversion data for the channels selected by mask
*
* Note:
* To use this function, device must implement methods:
* - start_channels()
* - channels_data()
*
* @dev: ADC device to read
* @channel_mask: channel selection - a bit mask
* @channels: pointer to structure array of returned data for each channel
* @return: 0 if OK, -ve on error
*/
int adc_channels_data(struct udevice *dev, unsigned int channel_mask,
struct adc_channel *channels);
/**
* adc_data_mask() - get data mask (ADC resolution bitmask) for given ADC device
*
* This can be used if adc uclass platform data is filled.
*
* @dev: ADC device to check
* @data_mask: pointer to the returned data bitmask
* @return: 0 if OK, -ve on error
*/
int adc_data_mask(struct udevice *dev, unsigned int *data_mask);
/**
* adc_channel_single_shot() - get output data of conversion for the ADC
* device's channel. This function searches for the device with the given name,
* starts the given channel conversion and returns the output data.
*
* Note: To use this function, device must implement metods:
* - start_channel()
* - channel_data()
*
* @name: device's name to search
* @channel: device's input channel to init
* @data: pointer to conversion output data
* @return: 0 if OK, -ve on error
*/
int adc_channel_single_shot(const char *name, int channel, unsigned int *data);
/**
* adc_channels_single_shot() - get ADC conversion output data for the selected
* device's channels. This function searches for the device by the given name,
* starts the selected channels conversion and returns the output data as array
* of type 'struct adc_channel'.
*
* Note: This function can be used if device implements one of ADC's single
* or multi-channel operation API. If multi-channel operation is not supported,
* then each selected channel is triggered by the sequence start/data in a loop.
*
* @name: device's name to search
* @channel_mask: channel selection - a bit mask
* @channels: pointer to conversion output data for the selected channels
* @return: 0 if OK, -ve on error
*/
int adc_channels_single_shot(const char *name, unsigned int channel_mask,
struct adc_channel *channels);
/**
* adc_vdd_value() - get the ADC device's positive reference Voltage value
*
* Note: Depending on bool value 'vdd_supply_is_negative' of platform data,
* the returned uV value can be negative, and it's not an error.
*
* @dev: ADC device to check
* @uV: Voltage value with polarization sign (uV)
* @return: 0 on success or -ve on error
*/
int adc_vdd_value(struct udevice *dev, int *uV);
/**
* adc_vss_value() - get the ADC device's negative reference Voltage value
*
* Note: Depending on bool value 'vdd_supply_is_negative' of platform data,
* the returned uV value can be negative, and it's not an error.
*
* @dev: ADC device to check
* @uV: Voltage value with polarization sign (uV)
* @return: 0 on success or -ve on error
*/
int adc_vss_value(struct udevice *dev, int *uV);
/**
* adc_stop() - stop operation for given ADC device.
*
* @dev: ADC device to stop
* @return: 0 if OK, -ve on error
*/
int adc_stop(struct udevice *dev);
#endif
...@@ -25,6 +25,7 @@ enum uclass_id { ...@@ -25,6 +25,7 @@ enum uclass_id {
UCLASS_SIMPLE_BUS, /* bus with child devices */ UCLASS_SIMPLE_BUS, /* bus with child devices */
/* U-Boot uclasses start here - in alphabetical order */ /* U-Boot uclasses start here - in alphabetical order */
UCLASS_ADC, /* Analog-to-digital converter */
UCLASS_CLK, /* Clock source, e.g. used by peripherals */ UCLASS_CLK, /* Clock source, e.g. used by peripherals */
UCLASS_CPU, /* CPU, typically part of an SoC */ UCLASS_CPU, /* CPU, typically part of an SoC */
UCLASS_CROS_EC, /* Chrome OS EC */ UCLASS_CROS_EC, /* Chrome OS EC */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment