Commit 8fb1a9a6 authored by Michel Arruat's avatar Michel Arruat Committed by Alessandro Rubini

move calibration to its file (no technical change)

Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 6f47fdd5
......@@ -21,6 +21,7 @@ subdirs-ccflags-y = $(ccflags-y)
obj-m := fmc-adc-100m14b.o
fmc-adc-100m14b-objs = fa-core.o
fmc-adc-100m14b-objs += fa-zio-drv.o
fmc-adc-100m14b-objs += fa-calibration.o
fmc-adc-100m14b-objs += fa-regtable.o
fmc-adc-100m14b-objs += fa-zio-trg.o
fmc-adc-100m14b-objs += fa-dma.o
......
/*
* EEPROM calibration block retreival code for fa-dev
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include "fmc-adc.h"
/* This identity calibration is used as default */
static struct fa_calib_stanza fa_identity_calib = {
.offset = { 0, },
.gain = {0x8000, 0x8000, 0x8000, 0x8000},
.temperature = 50 * 100, /* 50 celsius degrees */
};
/* Max difference from identity thing */
#define FA_CALIB_MAX_DELTA_OFFSET 0x1000
#define FA_CALIB_MAX_DELTA_GAIN 0x1000
#define FA_CALIB_MAX_DELTA_TEMP (40 * 100) /* 10-90 celsius */
/* Actual verification code */
static int fa_verify_calib_stanza(struct device *msgdev, char *name, int r,
struct fa_calib_stanza *cal,
struct fa_calib_stanza *iden)
{
int i, err = 0;
for (i = 0; i < ARRAY_SIZE(cal->offset); i++) {
if (abs(cal->offset[i] - iden->offset[i])
> FA_CALIB_MAX_DELTA_OFFSET) {
dev_dbg(msgdev, "wrong offset 0x%x\n", cal->offset[i]);
err++;
}
if (abs((s16)(cal->gain[i] - iden->gain[i]))
> FA_CALIB_MAX_DELTA_GAIN) {
dev_dbg(msgdev, "wrong gain 0x%x\n", cal->gain[i]);
err++;
}
}
if (abs((s16)(cal->temperature - iden->temperature))
> FA_CALIB_MAX_DELTA_TEMP) {
dev_dbg(msgdev, "wrong temper 0x%x\n", cal->temperature);
err++;
}
if (err)
dev_dbg(msgdev, "%i errors in %s calibration, range %i\n",
err, name, r);
return err;
}
static void fa_verify_calib(struct device *msgdev,
struct fa_calib *calib,
struct fa_calib_stanza *identity)
{
int i, err = 0;
for (i = 0; i < ARRAY_SIZE(calib->adc); i++) {
err += fa_verify_calib_stanza(msgdev, "adc", i,
calib->adc + i, identity);
err += fa_verify_calib_stanza(msgdev, "dac", i,
calib->dac + i, identity);
}
if (!err)
return;
dev_info(msgdev, "Invalid calibration in EEPROM (%i errors)\n", err);
dev_info(msgdev, "Using identity calibration\n");
for (i = 0; i < ARRAY_SIZE(calib->adc); i++) {
calib->adc[i] = *identity;
calib->dac[i] = *identity;
}
}
static void fa_endian_calib(struct fa_calib *calib)
{
int i;
uint16_t *p = (void *)calib;
/* We know for sure that our structure is only made of 16bit fields */
for (i = 0; i < sizeof(*calib) / sizeof(uint16_t); i++)
le16_to_cpus(p + i); /* s == in situ */
}
void fa_read_eeprom_calib(struct fa_dev *fa)
{
/* Retrieve calibration data from the eeprom, then verify it */
memcpy(&fa->calib, fa->fmc->eeprom + FA_CAL_OFFSET, sizeof(fa->calib));
fa_endian_calib(&fa->calib);
fa_verify_calib(&fa->fmc->dev, &fa->calib, &fa_identity_calib);
dev_info(&fa->fmc->dev, "%s succeeds.\n", __func__);
}
......@@ -984,82 +984,6 @@ struct fmc_gpio zfat_gpio_cfg[] = {
}
};
/* * * * * * * * * * * * * * * * Calibration checks * * * * * * * * * * * */
/* This identity calibration is used as default */
static struct fa_calib_stanza fa_identity_calib = {
.offset = { 0, },
.gain = {0x8000, 0x8000, 0x8000, 0x8000},
.temperature = 50 * 100, /* 50 celsius degrees */
};
/* Max difference from identity thing */
#define FA_CALIB_MAX_DELTA_OFFSET 0x1000
#define FA_CALIB_MAX_DELTA_GAIN 0x1000
#define FA_CALIB_MAX_DELTA_TEMP (40 * 100) /* 10-90 celsius */
/* Actual verification code */
static int zfad_verify_calib_stanza(struct device *msgdev, char *name, int r,
struct fa_calib_stanza *cal,
struct fa_calib_stanza *iden)
{
int i, err = 0;
for (i = 0; i < ARRAY_SIZE(cal->offset); i++) {
if (abs(cal->offset[i] - iden->offset[i])
> FA_CALIB_MAX_DELTA_OFFSET) {
dev_dbg(msgdev, "wrong offset 0x%x\n", cal->offset[i]);
err++;
}
if (abs((s16)(cal->gain[i] - iden->gain[i]))
> FA_CALIB_MAX_DELTA_GAIN) {
dev_dbg(msgdev, "wrong gain 0x%x\n", cal->gain[i]);
err++;
}
}
if (abs((s16)(cal->temperature - iden->temperature))
> FA_CALIB_MAX_DELTA_TEMP) {
dev_dbg(msgdev, "wrong temper 0x%x\n", cal->temperature);
err++;
}
if (err)
dev_dbg(msgdev, "%i errors in %s calibration, range %i\n",
err, name, r);
return err;
}
static void zfad_verify_calib(struct device *msgdev,
struct fa_calib *calib,
struct fa_calib_stanza *identity)
{
int i, err = 0;
for (i = 0; i < ARRAY_SIZE(calib->adc); i++) {
err += zfad_verify_calib_stanza(msgdev, "adc", i,
calib->adc + i, identity);
err += zfad_verify_calib_stanza(msgdev, "dac", i,
calib->dac + i, identity);
}
if (!err)
return;
dev_info(msgdev, "Invalid calibration in EEPROM (%i errors)\n", err);
dev_info(msgdev, "Using identity calibration\n");
for (i = 0; i < ARRAY_SIZE(calib->adc); i++) {
calib->adc[i] = *identity;
calib->dac[i] = *identity;
}
}
static void zfad_endian_calib(struct fa_calib *calib)
{
int i;
uint16_t *p = (void *)calib;
/* We know for sure that our structure is only made of 16bit fields */
for (i = 0; i < sizeof(*calib) / sizeof(uint16_t); i++)
le16_to_cpus(p + i); /* s == in situ */
}
/* * * * * * * * * * * * * * * * Initialization * * * * * * * * * * * * * * */
/*
......@@ -1079,9 +1003,7 @@ static int zfad_zio_probe(struct zio_device *zdev)
fa->zdev = zdev;
/* Retrieve calibration data from the eeprom, then verify it */
memcpy(&fa->calib, fa->fmc->eeprom + FA_CAL_OFFSET, sizeof(fa->calib));
zfad_endian_calib(&fa->calib);
zfad_verify_calib(&fa->fmc->dev, &fa->calib, &fa_identity_calib);
fa_read_eeprom_calib(fa);
/* Configure GPIO for IRQ */
fa->fmc->op->gpio_config(fa->fmc, zfat_gpio_cfg,
......
......@@ -406,5 +406,8 @@ extern void fa_spi_exit(struct fa_dev *fd);
/* function in fa-zio-drv.c */
extern int zfad_fsm_command(struct fa_dev *fa, uint32_t command);
/* function exporetd by fa-calibration.c */
extern void fa_read_eeprom_calib(struct fa_dev *fa);
#endif /* __KERNEL__ */
#endif /* FMC_ADC_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment