Commit 79c32cd9 authored by Federico Vaga's avatar Federico Vaga

drv:tools: fix endianess conversion

All calibration values are stored as little endian. For this reason we
should convert all incoming and outcoming values from little endian to
the host endianess.
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent b3ada1a4
......@@ -73,22 +73,39 @@ static void fa_verify_calib(struct device *msgdev,
}
}
static void fa_endian_calib(struct fa_calib *calib)
/**
* @calib: calibration data
*
* We know for sure that our structure is only made of 16bit fields
*/
static void fa_calib_le16_to_cpus(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 */
}
/**
* @calib: calibration data
*
* We know for sure that our structure is only made of 16bit fields
*/
static void fa_calib_cpu_to_le16s(struct fa_calib *calib)
{
int i;
uint16_t *p = (void *)calib;
for (i = 0; i < sizeof(*calib) / sizeof(uint16_t); i++)
cpu_to_le16s(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_calib_le16_to_cpus(&fa->calib);
fa_verify_calib(&fa->fmc->dev, &fa->calib, &fa_identity_calib);
}
......@@ -118,7 +135,7 @@ static ssize_t fa_write_eeprom(struct file *file, struct kobject *kobj,
if (off != 0 || count != sizeof(*calib))
return -EINVAL;
fa_endian_calib(calib);
fa_calib_le16_to_cpus(calib);
fa_verify_calib(dev, calib, &fa_identity_calib);
/*
......@@ -138,11 +155,14 @@ static ssize_t fa_read_eeprom(struct file *file, struct kobject *kobj,
{
struct device *dev = container_of(kobj, struct device, kobj);
struct fa_dev *fa = get_zfadc(dev);
struct fa_calib *calib = (struct fa_calib *) buf;
if (off != 0 || count < sizeof(fa->calib))
return -EINVAL;
memcpy(buf, &fa->calib, sizeof(fa->calib));
memcpy(calib, &fa->calib, sizeof(fa->calib));
fa_calib_cpu_to_le16s(calib);
return count;
}
......
......@@ -14,6 +14,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <endian.h>
#include <fmc-adc-100m14b4cha.h>
......@@ -28,6 +29,7 @@ static const char help_msg[] =
"This could be used to change the ADC calibration data at runtime\n"
"by redirectiong the binary output of this program to the proper \n"
"sysfs binary attribute\n"
"Rembember that we expect all values to be little endian\n"
"\n"
"General options:\n"
"-h Print this message\n"
......@@ -43,26 +45,31 @@ static const char help_msg[] =
/**
* Read calibration data from file
* @path: file path
* @data: data location
* @size: data size
* @calib: calibration data
* @offset: offset in file
*
* Return: number of bytes read
*/
static int fau_calibration_read(char *path, void *data,
size_t size, off_t offset)
static int fau_calibration_read(char *path, struct fa_calib *calib,
off_t offset)
{
int fd;
int ret = 0;
uint16_t *data16 = (uint16_t *)calib;
int i;
fd = open(path, O_RDONLY);
if (fd < 0)
return -1;
ret = lseek(fd, offset, SEEK_SET);
if (ret >= 0)
ret = read(fd, data, size);
ret = read(fd, calib, sizeof(*calib));
close(fd);
/* Fix endianess */
for (i = 0; i < sizeof(*calib) / 2; ++i)
data16[i] = le16toh(data16[i]);
return ret;
}
......@@ -117,25 +124,33 @@ static void fau_calibration_dump_machine(struct fa_calib *calib)
/**
* Write calibration data to device
* @devid: Device ID
* @data: data location
* @size: data size
* @calib: calibration data
*
* Return: number of bytes wrote
*/
static int fau_calibration_write(unsigned int devid,
void *data, size_t size)
static int fau_calibration_write(unsigned int devid, struct fa_calib *calib)
{
struct fa_calib calib_cp;
char path[128];
uint16_t *data16;
int i;
int fd;
int ret;
sprintf(path,
"/sys/bus/zio/devices/adc-100m14b-%04x/cset0/calibration_data",
devid);
/* Fix endianess */
memcpy(&calib_cp, calib, sizeof(calib_cp));
data16 = (uint16_t *) &calib_cp;
for (i = 0; i < sizeof(calib_cp) / 2; ++i)
data16[i] = htole16(data16[i]);
fd = open(path, O_WRONLY);
if (fd < 0)
return -1;
ret = write(fd, data, size);
ret = write(fd, &calib_cp, sizeof(calib_cp));
close(fd);
return ret;
......@@ -194,7 +209,7 @@ int main(int argc, char *argv[])
}
/* Read EEPROM file */
ret = fau_calibration_read(path, &calib, sizeof(calib), offset);
ret = fau_calibration_read(path, &calib, offset);
if (ret < 0) {
fprintf(stderr, "Can't read calibration data from '%s'. %s\n",
path, strerror(errno));
......@@ -215,7 +230,7 @@ int main(int argc, char *argv[])
/* Write calibration data */
if (write) {
ret = fau_calibration_write(devid, &calib, sizeof(calib));
ret = fau_calibration_write(devid, &calib);
if (ret < 0) {
fprintf(stderr,
"Can't write calibration data to '0x%x'. %s\n",
......
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