Skip to content

Commit

Permalink
iio: adc: aspeed: Get and set trimming data.
Browse files Browse the repository at this point in the history
The ADC controller has a trimming register for fine-tune the reference
voltage. The trimming value comes from the OTP register which will be
written during chip production. This patch will read this OTP value and
configure it to the ADC register when the ADC controller probes and using
dts property "aspeed,trim-data-valid" to determine whether to execute this
flow.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
Link: https://lore.kernel.org/r/20210922081520.30580-12-billy_tsai@aspeedtech.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
  • Loading branch information
billy-tsai authored and jic23 committed Oct 19, 2021
1 parent df05f38 commit d0a4c17
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions drivers/iio/adc/aspeed_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/bitfield.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>

#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
Expand Down Expand Up @@ -80,6 +82,11 @@
*/
#define ASPEED_ADC_DEF_SAMPLING_RATE 65000

struct aspeed_adc_trim_locate {
const unsigned int offset;
const unsigned int field;
};

struct aspeed_adc_model_data {
const char *model_name;
unsigned int min_sampling_rate; // Hz
Expand All @@ -90,6 +97,7 @@ struct aspeed_adc_model_data {
bool bat_sense_sup;
u8 scaler_bit_width;
unsigned int num_channels;
const struct aspeed_adc_trim_locate *trim_locate;
};

struct adc_gain {
Expand Down Expand Up @@ -165,6 +173,44 @@ static const struct iio_chan_spec aspeed_adc_iio_bat_channels[] = {
ASPEED_BAT_CHAN(7, 0x1E),
};

static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev)
{
struct device_node *syscon;
struct regmap *scu;
u32 scu_otp, trimming_val;
struct aspeed_adc_data *data = iio_priv(indio_dev);

syscon = of_find_node_by_name(NULL, "syscon");
if (syscon == NULL) {
dev_warn(data->dev, "Couldn't find syscon node\n");
return -EOPNOTSUPP;
}
scu = syscon_node_to_regmap(syscon);
if (IS_ERR(scu)) {
dev_warn(data->dev, "Failed to get syscon regmap\n");
return -EOPNOTSUPP;
}
if (data->model_data->trim_locate) {
if (regmap_read(scu, data->model_data->trim_locate->offset,
&scu_otp)) {
dev_warn(data->dev,
"Failed to get adc trimming data\n");
trimming_val = 0x8;
} else {
trimming_val =
((scu_otp) &
(data->model_data->trim_locate->field)) >>
__ffs(data->model_data->trim_locate->field);
}
dev_dbg(data->dev,
"trimming val = %d, offset = %08x, fields = %08x\n",
trimming_val, data->model_data->trim_locate->offset,
data->model_data->trim_locate->field);
writel(trimming_val, data->base + ASPEED_REG_COMPENSATION_TRIM);
}
return 0;
}

static int aspeed_adc_compensation(struct iio_dev *indio_dev)
{
struct aspeed_adc_data *data = iio_priv(indio_dev);
Expand Down Expand Up @@ -513,6 +559,13 @@ static int aspeed_adc_probe(struct platform_device *pdev)
if (ret)
return ret;

if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid",
NULL)) {
ret = aspeed_adc_set_trim_data(indio_dev);
if (ret)
return ret;
}

if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
NULL)) {
if (data->model_data->bat_sense_sup) {
Expand Down Expand Up @@ -589,6 +642,21 @@ static int aspeed_adc_probe(struct platform_device *pdev)
return ret;
}

static const struct aspeed_adc_trim_locate ast2500_adc_trim = {
.offset = 0x154,
.field = GENMASK(31, 28),
};

static const struct aspeed_adc_trim_locate ast2600_adc0_trim = {
.offset = 0x5d0,
.field = GENMASK(3, 0),
};

static const struct aspeed_adc_trim_locate ast2600_adc1_trim = {
.offset = 0x5d0,
.field = GENMASK(7, 4),
};

static const struct aspeed_adc_model_data ast2400_model_data = {
.model_name = "ast2400-adc",
.vref_fixed_mv = 2500,
Expand All @@ -608,6 +676,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
.need_prescaler = true,
.scaler_bit_width = 10,
.num_channels = 16,
.trim_locate = &ast2500_adc_trim,
};

static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
Expand All @@ -618,6 +687,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
.bat_sense_sup = true,
.scaler_bit_width = 16,
.num_channels = 8,
.trim_locate = &ast2600_adc0_trim,
};

static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
Expand All @@ -628,6 +698,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
.bat_sense_sup = true,
.scaler_bit_width = 16,
.num_channels = 8,
.trim_locate = &ast2600_adc1_trim,
};

static const struct of_device_id aspeed_adc_matches[] = {
Expand Down

0 comments on commit d0a4c17

Please sign in to comment.