Commit 7804027d authored by Jorge Machado's avatar Jorge Machado

SW changes from Maciej feedback

parent 947a5c7c
......@@ -121,8 +121,20 @@ static int fmc_dio_int_cmd_pulse(struct fmc_dio *dev,
/* First, configure this bit as DIO output */
reg = readl(base + dio.iomode_reg);
writel(reg | (1 << 4*ch), base + dio.iomode_reg);
/* Clear width and period registers */
writel(0, base + map->pulse_per);
writel(1, base + map->pulse); //Set to 1 to avoid 3 second pulse due to compensation into gw
writel(1 << ch, base + dio.latch_reg);
writel(1 << ch, base + dio.pulse_reg);
atomic_set(&c->count, 0);
writel(ts[1].tv_nsec / 8, base + map->pulse); /* width */
if(cmd->value == 0)
return 0;
if (cmd->flags & WR_DIO_F_NOW) {
/* Generate a pulse train from current time in V2 DIO version*/
if(dev->version == 1) {
......@@ -165,7 +177,7 @@ static int fmc_dio_int_cmd_pulse(struct fmc_dio *dev,
else {
writel(ts[2].tv_nsec / 8, base + map->pulse_per);
if (cmd->value > 1) {
cmd->value-=2;
cmd->value-=1;
}
}
......@@ -177,6 +189,42 @@ static int fmc_dio_int_cmd_pulse(struct fmc_dio *dev,
return 0;
}
static int fmc_dio_int_cmd_update_width(struct fmc_dio *dev,
struct wr_dio_cmd *cmd)
{
void __iomem *base = dev->dio;
struct dio_device *d = dev->priv;
struct dio_channel *c;
struct regmap *map;
struct timespec *ts;
int ch;
struct regmap_common dio;
uint32_t period;
dio = get_regmap_common(dev->version);
ch = cmd->channel;
if (ch > 4)
return -EINVAL; /* mask not supported */
c = d->ch + ch;
map = get_regmap(dev->version);
map += ch;
ts = cmd->t;
period = readl(base + map->pulse_per);
if(ts[1].tv_nsec / 8 < period)
{
writel(ts[1].tv_nsec / 8, base + map->pulse);
writel(1 << ch, base + dio.latch_reg);
}
else
return -1;
return 0;
}
static int fmc_dio_int_cmd_stamp(struct fmc_dio *dev,
struct wr_dio_cmd *cmd)
{
......@@ -424,6 +472,9 @@ int fmc_dio_int_ioctl(struct fmc_dio *dev, unsigned int ioctlcmd,
case WR_DIO_CMD_IRQ:
ret = fmc_dio_int_cmd_irq(dev, cmd);
break;
case WR_DIO_CMD_UPDATE_WIDTH:
ret = fmc_dio_int_cmd_update_width(dev, cmd);
break;
default:
ret = -EINVAL;
goto out;
......
......@@ -108,6 +108,7 @@ enum wr_dio_cmd_name {
WR_DIO_CMD_DAC,
WR_DIO_CMD_INOUT,
WR_DIO_CMD_IRQ,
WR_DIO_CMD_UPDATE_WIDTH,
};
/*
......
......@@ -93,11 +93,12 @@ static int scan_pulse(int argc, char **argv)
prgname, argv[0], argv[2]);
return -1;
}
if (cmd->t[1].tv_sec) {
fprintf(stderr, "%s: %s: duration must be < 1s (got \"%s\")\n",
if (cmd->t[1].tv_sec || !cmd->t[1].tv_nsec) {
fprintf(stderr, "%s: %s: duration must be < 1s and > 0s (got \"%s\")\n",
prgname, argv[0], argv[2]);
return -1;
}
/* Next argument is the "when", position 0 in ioctl timestamp array */
if (!strcmp(argv[3], "now")) {
......@@ -126,10 +127,23 @@ static int scan_pulse(int argc, char **argv)
prgname, argv[0], argv[4]);
return -1;
}
if(cmd->t[2].tv_nsec < 1000000)
if (cmd->t[2].tv_nsec < 1000000)
{
fprintf(stderr, "%s: %s: Frequency is greater than 1 kHz \n",
prgname, argv[0]);
return -1;
}
if(cmd->t[2].tv_nsec % 8)
{
fprintf(stderr, "%s: %s: Period value is not a multiple of reference frequency \n",
prgname, argv[0]);
return -1;
}
if (cmd->t[1].tv_nsec >= cmd->t[2].tv_nsec)
{
fprintf(stderr, "%s: %s: Pulse length can not be greater than period \n",
prgname, argv[0]);
return -1;
}
if (sscanf(argv[5], "%i%c", &cmd->value, &c) != 1) {
fprintf(stderr, "%s: %s: invalid count \"%s\"\n",
......@@ -146,6 +160,43 @@ static int scan_pulse(int argc, char **argv)
return 0;
}
static int scan_width(int argc, char **argv)
{
char c;
if (argc != 3) {
fprintf(stderr, "%s: %s: wrong number of arguments\n",
prgname, argv[0]);
fprintf(stderr, "Use: %s <channel> <duration> \n", argv[0]);
return -1;
}
if (sscanf(argv[1], "%hi%c", &cmd->channel, &c) != 1
|| cmd->channel > 4) {
fprintf(stderr, "%s: %s: not a channel number \"%s\"\n",
prgname, argv[0], argv[1]);
return -1;
}
/* Duration is first time argument but position 1 for ioctl */
if (parse_ts(argv[2], cmd->t + 1) < 0) {
fprintf(stderr, "%s: %s: invalid time \"%s\"\n",
prgname, argv[0], argv[2]);
return -1;
}
if (cmd->t[1].tv_sec || !cmd->t[1].tv_nsec) {
fprintf(stderr, "%s: %s: duration must be < 1s and > 0s (got \"%s\")\n",
prgname, argv[0], argv[2]);
return -1;
}
if (ioctl(fd, PRIV_MEZZANINE_CMD, (unsigned long) cmd) < 0) {
fprintf(stderr, "%s: ioctl(PRIV_MEZZANINE_CMD(%s)): %s\n",
prgname, devname, strerror(errno));
return -1;
}
return 0;
}
static int scan_stamp(int argc, char **argv, int ismask)
{
int i, ch;
......@@ -350,10 +401,17 @@ static int scan_irq(int argc, char **argv)
prgname, argv[0], argv[1]);
return -1;
}
if(cmd->t[1].tv_nsec < 1000000)
if(cmd->t[1].tv_nsec < 1000000 || cmd->t[1].tv_sec)
{
fprintf(stderr, "%s: %s: Frequency is greater than 1 kHz \n",
fprintf(stderr, "%s: %s: Frequency is greater than 1 kHz and lower than 1 Hz\n",
prgname, argv[0]);
return -1;
}
if(cmd->t[1].tv_nsec % 8)
{
fprintf(stderr, "%s: %s: Period value is not a multiple of reference frequency \n",
prgname, argv[0]);
return -1;
}
if (sscanf(argv[3], "%i%c", &cmd->value, &c) != 1) {
fprintf(stderr, "%s: %s: invalid count \"%s\"\n",
......@@ -445,6 +503,10 @@ int main(int argc, char **argv)
cmd->command = WR_DIO_CMD_IRQ;
if (scan_irq(argc, argv) < 0)
exit(1);
} else if (!strcmp(argv[0], "update_width")) {
cmd->command = WR_DIO_CMD_UPDATE_WIDTH;
if (scan_width(argc, argv) < 0)
exit(1);
} else {
fprintf(stderr, "%s: unknown command \"%s\"\n", prgname,
argv[0]);
......
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