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, ...@@ -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; int i;
uint16_t *p = (void *)calib; 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++) for (i = 0; i < sizeof(*calib) / sizeof(uint16_t); i++)
le16_to_cpus(p + i); /* s == in situ */ 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) void fa_read_eeprom_calib(struct fa_dev *fa)
{ {
/* Retrieve calibration data from the eeprom, then verify it */ /* Retrieve calibration data from the eeprom, then verify it */
memcpy(&fa->calib, fa->fmc->eeprom + FA_CAL_OFFSET, sizeof(fa->calib)); 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); 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, ...@@ -118,7 +135,7 @@ static ssize_t fa_write_eeprom(struct file *file, struct kobject *kobj,
if (off != 0 || count != sizeof(*calib)) if (off != 0 || count != sizeof(*calib))
return -EINVAL; return -EINVAL;
fa_endian_calib(calib); fa_calib_le16_to_cpus(calib);
fa_verify_calib(dev, calib, &fa_identity_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, ...@@ -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 device *dev = container_of(kobj, struct device, kobj);
struct fa_dev *fa = get_zfadc(dev); struct fa_dev *fa = get_zfadc(dev);
struct fa_calib *calib = (struct fa_calib *) buf;
if (off != 0 || count < sizeof(fa->calib)) if (off != 0 || count < sizeof(fa->calib))
return -EINVAL; return -EINVAL;
memcpy(buf, &fa->calib, sizeof(fa->calib)); memcpy(calib, &fa->calib, sizeof(fa->calib));
fa_calib_cpu_to_le16s(calib);
return count; return count;
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <endian.h>
#include <fmc-adc-100m14b4cha.h> #include <fmc-adc-100m14b4cha.h>
...@@ -28,6 +29,7 @@ static const char help_msg[] = ...@@ -28,6 +29,7 @@ static const char help_msg[] =
"This could be used to change the ADC calibration data at runtime\n" "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" "by redirectiong the binary output of this program to the proper \n"
"sysfs binary attribute\n" "sysfs binary attribute\n"
"Rembember that we expect all values to be little endian\n"
"\n" "\n"
"General options:\n" "General options:\n"
"-h Print this message\n" "-h Print this message\n"
...@@ -43,26 +45,31 @@ static const char help_msg[] = ...@@ -43,26 +45,31 @@ static const char help_msg[] =
/** /**
* Read calibration data from file * Read calibration data from file
* @path: file path * @path: file path
* @data: data location * @calib: calibration data
* @size: data size
* @offset: offset in file * @offset: offset in file
* *
* Return: number of bytes read * Return: number of bytes read
*/ */
static int fau_calibration_read(char *path, void *data, static int fau_calibration_read(char *path, struct fa_calib *calib,
size_t size, off_t offset) off_t offset)
{ {
int fd; int fd;
int ret = 0; int ret = 0;
uint16_t *data16 = (uint16_t *)calib;
int i;
fd = open(path, O_RDONLY); fd = open(path, O_RDONLY);
if (fd < 0) if (fd < 0)
return -1; return -1;
ret = lseek(fd, offset, SEEK_SET); ret = lseek(fd, offset, SEEK_SET);
if (ret >= 0) if (ret >= 0)
ret = read(fd, data, size); ret = read(fd, calib, sizeof(*calib));
close(fd); close(fd);
/* Fix endianess */
for (i = 0; i < sizeof(*calib) / 2; ++i)
data16[i] = le16toh(data16[i]);
return ret; return ret;
} }
...@@ -117,25 +124,33 @@ static void fau_calibration_dump_machine(struct fa_calib *calib) ...@@ -117,25 +124,33 @@ static void fau_calibration_dump_machine(struct fa_calib *calib)
/** /**
* Write calibration data to device * Write calibration data to device
* @devid: Device ID * @devid: Device ID
* @data: data location * @calib: calibration data
* @size: data size
* *
* Return: number of bytes wrote * Return: number of bytes wrote
*/ */
static int fau_calibration_write(unsigned int devid, static int fau_calibration_write(unsigned int devid, struct fa_calib *calib)
void *data, size_t size)
{ {
struct fa_calib calib_cp;
char path[128]; char path[128];
uint16_t *data16;
int i;
int fd; int fd;
int ret; int ret;
sprintf(path, sprintf(path,
"/sys/bus/zio/devices/adc-100m14b-%04x/cset0/calibration_data", "/sys/bus/zio/devices/adc-100m14b-%04x/cset0/calibration_data",
devid); 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); fd = open(path, O_WRONLY);
if (fd < 0) if (fd < 0)
return -1; return -1;
ret = write(fd, data, size); ret = write(fd, &calib_cp, sizeof(calib_cp));
close(fd); close(fd);
return ret; return ret;
...@@ -194,7 +209,7 @@ int main(int argc, char *argv[]) ...@@ -194,7 +209,7 @@ int main(int argc, char *argv[])
} }
/* Read EEPROM file */ /* Read EEPROM file */
ret = fau_calibration_read(path, &calib, sizeof(calib), offset); ret = fau_calibration_read(path, &calib, offset);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Can't read calibration data from '%s'. %s\n", fprintf(stderr, "Can't read calibration data from '%s'. %s\n",
path, strerror(errno)); path, strerror(errno));
...@@ -215,7 +230,7 @@ int main(int argc, char *argv[]) ...@@ -215,7 +230,7 @@ int main(int argc, char *argv[])
/* Write calibration data */ /* Write calibration data */
if (write) { if (write) {
ret = fau_calibration_write(devid, &calib, sizeof(calib)); ret = fau_calibration_write(devid, &calib);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, fprintf(stderr,
"Can't write calibration data to '0x%x'. %s\n", "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