Commit 4522b6a6 authored by Jorge Machado's avatar Jorge Machado

Add mask irq command

parent 7804027d
......@@ -201,6 +201,10 @@ static int fmc_dio_int_cmd_update_width(struct fmc_dio *dev,
struct regmap_common dio;
uint32_t period;
if(dev->version == 0){
return -EINVAL;
}
dio = get_regmap_common(dev->version);
ch = cmd->channel;
......@@ -350,6 +354,41 @@ static int fmc_dio_int_cmd_inout(struct fmc_dio *dev,
return 0;
}
static int fmc_dio_int_cmd_mask_irq(struct fmc_dio *dev,
struct wr_dio_cmd *cmd)
{
struct fmc_dio_gpio_block __iomem *gpio = dev->gpio;
int mask, ch, last, bits;
uint32_t reg, iomode;
void __iomem *base = dev->dio;
if(dev->version == 0){ //Not implemented in old version
return -EINVAL;
}
struct regmap_common dio;
dio = get_regmap_common(dev->version);
if (cmd->value == WR_DIO_F_MASK_READ_IRQ) {
reg = readl(base + dio.eic_imr_reg);
if(reg & cmd->channel) {
cmd->value = WR_DIO_F_MASK_ENABLE_IRQ;
return 0;
} else {
cmd->value = WR_DIO_F_MASK_DISABLE_IRQ;
return 0;
}
} else if (cmd->value == WR_DIO_F_MASK_ENABLE_IRQ) {
writel(cmd->channel, base + dio.eic_ier_reg);
} else if (cmd->value == WR_DIO_F_MASK_DISABLE_IRQ) {
writel(cmd->channel, base + dio.eic_idr_reg);
} else {
return -1;
}
return 0;
}
static int fmc_dio_int_cmd_irq(struct fmc_dio *dev,
struct wr_dio_cmd *cmd)
{
......@@ -414,8 +453,9 @@ static int fmc_dio_int_cmd_irq(struct fmc_dio *dev,
if (cmd->flags & WR_DIO_F_LOOP && cmd->value != 1) {
c->target_channel = ch;
writel(ts[1].tv_nsec / 8, base + map->pulse_per);
/* Configure period */
writel( (ts[1].tv_nsec / 8) + (ts[1].tv_sec * 1000000000 / 8), base + map->pulse_per);
if (cmd->value > 1) {
cmd->value-=2;
}
......@@ -475,6 +515,9 @@ int fmc_dio_int_ioctl(struct fmc_dio *dev, unsigned int ioctlcmd,
case WR_DIO_CMD_UPDATE_WIDTH:
ret = fmc_dio_int_cmd_update_width(dev, cmd);
break;
case WR_DIO_CMD_MASK_IRQ:
ret = fmc_dio_int_cmd_mask_irq(dev, cmd);
break;
default:
ret = -EINVAL;
goto out;
......
......@@ -109,6 +109,7 @@ enum wr_dio_cmd_name {
WR_DIO_CMD_INOUT,
WR_DIO_CMD_IRQ,
WR_DIO_CMD_UPDATE_WIDTH,
WR_DIO_CMD_MASK_IRQ,
};
/*
......@@ -160,3 +161,6 @@ struct wr_dio_cmd {
#define WR_DIO_F_MASK 0x04 /* Channel is 0x00..0x1f */
#define WR_DIO_F_LOOP 0x08 /* Output should loop: t[2] is looping*/
#define WR_DIO_F_WAIT 0x10 /* Wait for event */
#define WR_DIO_F_MASK_READ_IRQ 0x20
#define WR_DIO_F_MASK_ENABLE_IRQ 0x40
#define WR_DIO_F_MASK_DISABLE_IRQ 0x80
\ No newline at end of file
......@@ -362,6 +362,64 @@ static int scan_inout(int argc, char **argv)
return 0;
}
static int scan_mask_irq(int argc, char **argv)
{
int i, ch;
char c;
uint32_t value_internal;
cmd->flags = WR_DIO_F_MASK;
cmd->channel = 0;
cmd->value = 0;
if (argc == 2) {
cmd->value = WR_DIO_F_MASK_READ_IRQ;
} else if (argc == 3){
if (argv[2][0] == 'Y') {
cmd->value = WR_DIO_F_MASK_ENABLE_IRQ;
}
else if (argv[2][0] == 'y') {
cmd->value = WR_DIO_F_MASK_DISABLE_IRQ;
}
else
fprintf(stderr, "%s: mask_irq: invalid argument "
"\"%s\"\n", prgname, argv[2]);
} else {
fprintf(stderr, "%s: %s: wrong number of arguments\n",
prgname, argv[0]);
fprintf(stderr, " Use: %s <channel> "
"[<Y/y>]\n", argv[0]);
return -1;
}
if (sscanf(argv[1], "%i", &ch) != 1 || ch < 0 || ch > 5) {
fprintf(stderr, "%s: mask_irq: invalid channel "
"\"%s\"\n", prgname, argv[1]);
return -1;
}
cmd->channel |= 1 << ch;
value_internal = cmd->value; //Save value to read mask
if (ioctl(fd, PRIV_MEZZANINE_CMD, cmd) < 0) {
fprintf(stderr, "%s: ioctl(PRIV_MEZZANINE_CMD(%s)): %s\n",
prgname, devname, strerror(errno));
return -1;
}
if ( value_internal == WR_DIO_F_MASK_READ_IRQ ) {
if(cmd->value == WR_DIO_F_MASK_ENABLE_IRQ)
printf("Ch %i interrupt enabled\n",ch);
else
printf("Ch %i interrupt disabled\n",ch);
}
return 0;
}
static int scan_irq(int argc, char **argv)
{
char c;
......@@ -401,9 +459,9 @@ static int scan_irq(int argc, char **argv)
prgname, argv[0], argv[1]);
return -1;
}
if(cmd->t[1].tv_nsec < 1000000 || cmd->t[1].tv_sec)
if(cmd->t[1].tv_nsec < 1000000 || cmd->t[1].tv_sec < 2)
{
fprintf(stderr, "%s: %s: Frequency is greater than 1 kHz and lower than 1 Hz\n",
fprintf(stderr, "%s: %s: Frequency is greater than 1 kHz and lower than 0.5 Hz\n",
prgname, argv[0]);
return -1;
}
......@@ -507,6 +565,10 @@ int main(int argc, char **argv)
cmd->command = WR_DIO_CMD_UPDATE_WIDTH;
if (scan_width(argc, argv) < 0)
exit(1);
} else if (!strcmp(argv[0], "mask_irq")) {
cmd->command = WR_DIO_CMD_MASK_IRQ;
if (scan_mask_irq(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