From: Daniel Scheller <d.schel...@gmx.net>

This patch adds back the IOCTL API/functionality which is present in the
upstream dddvb driver package. In comparison, the IOCTL handler has been
factored to a separate object (and with that, some functionality from
-core has been moved there aswell), the IOCTLs are defined in an include
in the uAPI, and ioctl-number.txt is updated to document that there are
IOCTLs present in this driver.

Signed-off-by: Daniel Scheller <d.schel...@gmx.net>
---
This patch depends on the ddbridge-0.9.29 bump, see [1]. The
functionality was part of the driver before.

[1] http://www.spinics.net/lists/linux-media/msg119911.html

 Documentation/ioctl/ioctl-number.txt        |   1 +
 MAINTAINERS                                 |   1 +
 drivers/media/pci/ddbridge/Makefile         |   2 +-
 drivers/media/pci/ddbridge/ddbridge-core.c  | 111 +--------
 drivers/media/pci/ddbridge/ddbridge-ioctl.c | 334 ++++++++++++++++++++++++++++
 drivers/media/pci/ddbridge/ddbridge-ioctl.h |  32 +++
 include/uapi/linux/ddbridge-ioctl.h         | 110 +++++++++
 7 files changed, 481 insertions(+), 110 deletions(-)
 create mode 100644 drivers/media/pci/ddbridge/ddbridge-ioctl.c
 create mode 100644 drivers/media/pci/ddbridge/ddbridge-ioctl.h
 create mode 100644 include/uapi/linux/ddbridge-ioctl.h

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 3e3fdae5f3ed..d78d1cd092d2 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -215,6 +215,7 @@ Code  Seq#(hex)     Include File            Comments
 'c'    A0-AF   arch/x86/include/asm/msr.h      conflict!
 'd'    00-FF   linux/char/drm/drm.h    conflict!
 'd'    02-40   pcmcia/ds.h             conflict!
+'d'    00-0B   linux/ddbridge-ioctl.h  conflict!
 'd'    F0-FF   linux/digi1.h
 'e'    all     linux/digi1.h           conflict!
 'e'    00-1F   drivers/net/irda/irtty-sir.h    conflict!
diff --git a/MAINTAINERS b/MAINTAINERS
index 0453a1365c3a..2fd5055f8a60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8428,6 +8428,7 @@ W:        https://linuxtv.org
 T:     git git://linuxtv.org/media_tree.git
 S:     Maintained
 F:     drivers/media/pci/ddbridge/*
+F:     include/uapi/linux/ddbridge-ioctl.h
 
 MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
 M:     Mauro Carvalho Chehab <mche...@s-opensource.com>
diff --git a/drivers/media/pci/ddbridge/Makefile 
b/drivers/media/pci/ddbridge/Makefile
index 3ef3048a89ac..2cde91b376f6 100644
--- a/drivers/media/pci/ddbridge/Makefile
+++ b/drivers/media/pci/ddbridge/Makefile
@@ -3,7 +3,7 @@
 #
 
 ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-hw.o \
-               ddbridge-i2c.o
+               ddbridge-i2c.o ddbridge-ioctl.o
 
 obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
 
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c 
b/drivers/media/pci/ddbridge/ddbridge-core.c
index e051a691eb42..5c514b814cd8 100644
--- a/drivers/media/pci/ddbridge/ddbridge-core.c
+++ b/drivers/media/pci/ddbridge/ddbridge-core.c
@@ -38,6 +38,7 @@
 #include "ddbridge-i2c.h"
 #include "ddbridge-regs.h"
 #include "ddbridge-io.h"
+#include "ddbridge-ioctl.h"
 
 #include "tda18271c2dd.h"
 #include "stv6110x.h"
@@ -2750,112 +2751,14 @@ irqreturn_t ddb_irq_handler(int irq, void *dev_id)
 /****************************************************************************/
 /****************************************************************************/
 
-static int reg_wait(struct ddb *dev, u32 reg, u32 bit)
-{
-       u32 count = 0;
-
-       while (safe_ddbreadl(dev, reg) & bit) {
-               ndelay(10);
-               if (++count == 100)
-                       return -1;
-       }
-       return 0;
-}
-
-static int flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf,
-       u32 rlen)
-{
-       u32 data, shift;
-       u32 tag = DDB_LINK_TAG(lnr);
-       struct ddb_link *link = &dev->link[lnr];
-
-       mutex_lock(&link->flash_mutex);
-       if (wlen > 4)
-               ddbwritel(dev, 1, tag | SPI_CONTROL);
-       while (wlen > 4) {
-               /* FIXME: check for big-endian */
-               data = swab32(*(u32 *) wbuf);
-               wbuf += 4;
-               wlen -= 4;
-               ddbwritel(dev, data, tag | SPI_DATA);
-               if (reg_wait(dev, tag | SPI_CONTROL, 4))
-                       goto fail;
-       }
-       if (rlen)
-               ddbwritel(dev, 0x0001 | ((wlen << (8 + 3)) & 0x1f00),
-                         tag | SPI_CONTROL);
-       else
-               ddbwritel(dev, 0x0003 | ((wlen << (8 + 3)) & 0x1f00),
-                         tag | SPI_CONTROL);
-
-       data = 0;
-       shift = ((4 - wlen) * 8);
-       while (wlen) {
-               data <<= 8;
-               data |= *wbuf;
-               wlen--;
-               wbuf++;
-       }
-       if (shift)
-               data <<= shift;
-       ddbwritel(dev, data, tag | SPI_DATA);
-       if (reg_wait(dev, tag | SPI_CONTROL, 4))
-               goto fail;
-
-       if (!rlen) {
-               ddbwritel(dev, 0, tag | SPI_CONTROL);
-               goto exit;
-       }
-       if (rlen > 4)
-               ddbwritel(dev, 1, tag | SPI_CONTROL);
-
-       while (rlen > 4) {
-               ddbwritel(dev, 0xffffffff, tag | SPI_DATA);
-               if (reg_wait(dev, tag | SPI_CONTROL, 4))
-                       goto fail;
-               data = ddbreadl(dev, tag | SPI_DATA);
-               *(u32 *) rbuf = swab32(data);
-               rbuf += 4;
-               rlen -= 4;
-       }
-       ddbwritel(dev, 0x0003 | ((rlen << (8 + 3)) & 0x1F00),
-               tag | SPI_CONTROL);
-       ddbwritel(dev, 0xffffffff, tag | SPI_DATA);
-       if (reg_wait(dev, tag | SPI_CONTROL, 4))
-               goto fail;
-
-       data = ddbreadl(dev, tag | SPI_DATA);
-       ddbwritel(dev, 0, tag | SPI_CONTROL);
-
-       if (rlen < 4)
-               data <<= ((4 - rlen) * 8);
-
-       while (rlen > 0) {
-               *rbuf = ((data >> 24) & 0xff);
-               data <<= 8;
-               rbuf++;
-               rlen--;
-       }
-exit:
-       mutex_unlock(&link->flash_mutex);
-       return 0;
-fail:
-       mutex_unlock(&link->flash_mutex);
-       return -1;
-}
-
 int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len)
 {
        u8 cmd[4] = {0x03, (addr >> 16) & 0xff,
                     (addr >> 8) & 0xff, addr & 0xff};
 
-       return flashio(dev, link, cmd, 4, buf, len);
+       return ddb_flashio(dev, link, cmd, 4, buf, len);
 }
 
-/*
- * TODO/FIXME: add/implement IOCTLs from upstream driver
- */
-
 #define DDB_NAME "ddbridge"
 
 static u32 ddb_num;
@@ -2881,16 +2784,6 @@ static int ddb_open(struct inode *inode, struct file 
*file)
        return 0;
 }
 
-static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct ddb *dev = file->private_data;
-
-       dev_warn(dev->dev, "DDB IOCTLs unsupported (cmd: %d, arg: %lu)\n",
-                cmd, arg);
-
-       return -ENOTTY;
-}
-
 static const struct file_operations ddb_fops = {
        .unlocked_ioctl = ddb_ioctl,
        .open           = ddb_open,
diff --git a/drivers/media/pci/ddbridge/ddbridge-ioctl.c 
b/drivers/media/pci/ddbridge/ddbridge-ioctl.c
new file mode 100644
index 000000000000..c95a18ae7f80
--- /dev/null
+++ b/drivers/media/pci/ddbridge/ddbridge-ioctl.c
@@ -0,0 +1,334 @@
+/*
+ * ddbridge-ioctl.c: Digital Devices bridge IOCTL handler
+ *
+ * Copyright (C) 2010-2017 Digital Devices GmbH
+ *                         Ralph Metzler <r...@metzlerbros.de>
+ *                         Marcus Metzler <m...@metzlerbros.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/vmalloc.h>
+
+#include "ddbridge.h"
+#include "ddbridge-i2c.h"
+#include "ddbridge-regs.h"
+#include "ddbridge-io.h"
+#include "ddbridge-ioctl.h"
+
+/******************************************************************************/
+
+static int reg_wait(struct ddb *dev, u32 reg, u32 bit)
+{
+       u32 count = 0;
+
+       while (safe_ddbreadl(dev, reg) & bit) {
+               ndelay(10);
+               if (++count == 100)
+                       return -1;
+       }
+       return 0;
+}
+
+static int mdio_write(struct ddb *dev, u8 adr, u8 reg, u16 val)
+{
+       ddbwritel(dev, adr, MDIO_ADR);
+       ddbwritel(dev, reg, MDIO_REG);
+       ddbwritel(dev, val, MDIO_VAL);
+       ddbwritel(dev, 0x03, MDIO_CTRL);
+       while (ddbreadl(dev, MDIO_CTRL) & 0x02)
+               ndelay(500);
+       return 0;
+}
+
+static u16 mdio_read(struct ddb *dev, u8 adr, u8 reg)
+{
+       ddbwritel(dev, adr, MDIO_ADR);
+       ddbwritel(dev, reg, MDIO_REG);
+       ddbwritel(dev, 0x07, MDIO_CTRL);
+       while (ddbreadl(dev, MDIO_CTRL) & 0x02)
+               ndelay(500);
+       return ddbreadl(dev, MDIO_VAL);
+}
+
+/******************************************************************************/
+
+int ddb_flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf,
+               u32 rlen)
+{
+       u32 data, shift;
+       u32 tag = DDB_LINK_TAG(lnr);
+       struct ddb_link *link = &dev->link[lnr];
+
+       mutex_lock(&link->flash_mutex);
+       if (wlen > 4)
+               ddbwritel(dev, 1, tag | SPI_CONTROL);
+       while (wlen > 4) {
+               /* FIXME: check for big-endian */
+               data = swab32(*(u32 *)wbuf);
+               wbuf += 4;
+               wlen -= 4;
+               ddbwritel(dev, data, tag | SPI_DATA);
+               if (reg_wait(dev, tag | SPI_CONTROL, 4))
+                       goto fail;
+       }
+       if (rlen)
+               ddbwritel(dev, 0x0001 | ((wlen << (8 + 3)) & 0x1f00),
+                         tag | SPI_CONTROL);
+       else
+               ddbwritel(dev, 0x0003 | ((wlen << (8 + 3)) & 0x1f00),
+                         tag | SPI_CONTROL);
+
+       data = 0;
+       shift = ((4 - wlen) * 8);
+       while (wlen) {
+               data <<= 8;
+               data |= *wbuf;
+               wlen--;
+               wbuf++;
+       }
+       if (shift)
+               data <<= shift;
+       ddbwritel(dev, data, tag | SPI_DATA);
+       if (reg_wait(dev, tag | SPI_CONTROL, 4))
+               goto fail;
+
+       if (!rlen) {
+               ddbwritel(dev, 0, tag | SPI_CONTROL);
+               goto exit;
+       }
+       if (rlen > 4)
+               ddbwritel(dev, 1, tag | SPI_CONTROL);
+
+       while (rlen > 4) {
+               ddbwritel(dev, 0xffffffff, tag | SPI_DATA);
+               if (reg_wait(dev, tag | SPI_CONTROL, 4))
+                       goto fail;
+               data = ddbreadl(dev, tag | SPI_DATA);
+               *(u32 *)rbuf = swab32(data);
+               rbuf += 4;
+               rlen -= 4;
+       }
+       ddbwritel(dev, 0x0003 | ((rlen << (8 + 3)) & 0x1F00),
+                 tag | SPI_CONTROL);
+       ddbwritel(dev, 0xffffffff, tag | SPI_DATA);
+       if (reg_wait(dev, tag | SPI_CONTROL, 4))
+               goto fail;
+
+       data = ddbreadl(dev, tag | SPI_DATA);
+       ddbwritel(dev, 0, tag | SPI_CONTROL);
+
+       if (rlen < 4)
+               data <<= ((4 - rlen) * 8);
+
+       while (rlen > 0) {
+               *rbuf = ((data >> 24) & 0xff);
+               data <<= 8;
+               rbuf++;
+               rlen--;
+       }
+exit:
+       mutex_unlock(&link->flash_mutex);
+       return 0;
+fail:
+       mutex_unlock(&link->flash_mutex);
+       return -1;
+}
+
+long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct ddb *dev = file->private_data;
+       __user void *parg = (__user void *)arg;
+       int res;
+
+       switch (cmd) {
+       case IOCTL_DDB_FLASHIO:
+       {
+               struct ddb_flash_io fio;
+               u8 *rbuf, *wbuf;
+
+               if (copy_from_user(&fio, parg, sizeof(fio)))
+                       return -EFAULT;
+               if (fio.write_len > 1028 || fio.read_len > 1028)
+                       return -EINVAL;
+               if (fio.write_len + fio.read_len > 1028)
+                       return -EINVAL;
+               if (fio.link > 3)
+                       return -EINVAL;
+
+               wbuf = dev->iobuf;
+               rbuf = wbuf + fio.write_len;
+
+               if (copy_from_user(wbuf, fio.write_buf, fio.write_len))
+                       return -EFAULT;
+               res = ddb_flashio(dev, fio.link, wbuf, fio.write_len,
+                                 rbuf, fio.read_len);
+               if (res)
+                       return res;
+               if (copy_to_user(fio.read_buf, rbuf, fio.read_len))
+                       return -EFAULT;
+               break;
+       }
+       case IOCTL_DDB_GPIO_OUT:
+       {
+               struct ddb_gpio gpio;
+
+               if (copy_from_user(&gpio, parg, sizeof(gpio)))
+                       return -EFAULT;
+               ddbwritel(dev, gpio.mask, GPIO_DIRECTION);
+               ddbwritel(dev, gpio.data, GPIO_OUTPUT);
+               break;
+       }
+       case IOCTL_DDB_ID:
+       {
+               struct ddb_id ddbid;
+
+               ddbid.vendor = dev->link[0].ids.vendor;
+               ddbid.device = dev->link[0].ids.device;
+               ddbid.subvendor = dev->link[0].ids.subvendor;
+               ddbid.subdevice = dev->link[0].ids.subdevice;
+               ddbid.hw = ddbreadl(dev, 0);
+               ddbid.regmap = ddbreadl(dev, 4);
+               if (copy_to_user(parg, &ddbid, sizeof(ddbid)))
+                       return -EFAULT;
+               break;
+       }
+       case IOCTL_DDB_READ_REG:
+       {
+               struct ddb_reg reg;
+
+               if (copy_from_user(&reg, parg, sizeof(reg)))
+                       return -EFAULT;
+               if ((reg.reg & 0xfffffff) >= dev->regs_len)
+                       return -EINVAL;
+               reg.val = ddbreadl(dev, reg.reg);
+               if (copy_to_user(parg, &reg, sizeof(reg)))
+                       return -EFAULT;
+               break;
+       }
+       case IOCTL_DDB_WRITE_REG:
+       {
+               struct ddb_reg reg;
+
+               if (copy_from_user(&reg, parg, sizeof(reg)))
+                       return -EFAULT;
+               if ((reg.reg & 0xfffffff) >= dev->regs_len)
+                       return -EINVAL;
+               ddbwritel(dev, reg.val, reg.reg);
+               break;
+       }
+       case IOCTL_DDB_READ_MDIO:
+       {
+               struct ddb_mdio mdio;
+
+               if (!dev->link[0].info->mdio_num)
+                       return -EIO;
+               if (copy_from_user(&mdio, parg, sizeof(mdio)))
+                       return -EFAULT;
+               mdio.val = mdio_read(dev, mdio.adr, mdio.reg);
+               if (copy_to_user(parg, &mdio, sizeof(mdio)))
+                       return -EFAULT;
+               break;
+       }
+       case IOCTL_DDB_WRITE_MDIO:
+       {
+               struct ddb_mdio mdio;
+
+               if (!dev->link[0].info->mdio_num)
+                       return -EIO;
+               if (copy_from_user(&mdio, parg, sizeof(mdio)))
+                       return -EFAULT;
+               mdio_write(dev, mdio.adr, mdio.reg, mdio.val);
+               break;
+       }
+       case IOCTL_DDB_READ_MEM:
+       {
+               struct ddb_mem mem;
+               u8 *buf = dev->iobuf;
+
+               if (copy_from_user(&mem, parg, sizeof(mem)))
+                       return -EFAULT;
+               if ((((mem.len + mem.off) & 0xfffffff) > dev->regs_len) ||
+                   mem.len > 1024)
+                       return -EINVAL;
+               ddbcpyfrom(dev, buf, mem.off, mem.len);
+               if (copy_to_user(mem.buf, buf, mem.len))
+                       return -EFAULT;
+               break;
+       }
+       case IOCTL_DDB_WRITE_MEM:
+       {
+               struct ddb_mem mem;
+               u8 *buf = dev->iobuf;
+
+               if (copy_from_user(&mem, parg, sizeof(mem)))
+                       return -EFAULT;
+               if ((((mem.len + mem.off) & 0xfffffff) > dev->regs_len) ||
+                   mem.len > 1024)
+                       return -EINVAL;
+               if (copy_from_user(buf, mem.buf, mem.len))
+                       return -EFAULT;
+               ddbcpyto(dev, mem.off, buf, mem.len);
+               break;
+       }
+       case IOCTL_DDB_READ_I2C:
+       {
+               struct ddb_i2c_msg i2c;
+               struct i2c_adapter *adap;
+               u8 *mbuf, *hbuf = dev->iobuf;
+
+               if (copy_from_user(&i2c, parg, sizeof(i2c)))
+                       return -EFAULT;
+               if (i2c.bus > dev->link[0].info->regmap->i2c->num)
+                       return -EINVAL;
+               if (i2c.mlen + i2c.hlen > 512)
+                       return -EINVAL;
+
+               adap = &dev->i2c[i2c.bus].adap;
+               mbuf = hbuf + i2c.hlen;
+
+               if (copy_from_user(hbuf, i2c.hdr, i2c.hlen))
+                       return -EFAULT;
+               if (i2c_io(adap, i2c.adr, hbuf, i2c.hlen, mbuf, i2c.mlen) < 0)
+                       return -EIO;
+               if (copy_to_user(i2c.msg, mbuf, i2c.mlen))
+                       return -EFAULT;
+               break;
+       }
+       case IOCTL_DDB_WRITE_I2C:
+       {
+               struct ddb_i2c_msg i2c;
+               struct i2c_adapter *adap;
+               u8 *buf = dev->iobuf;
+
+               if (copy_from_user(&i2c, parg, sizeof(i2c)))
+                       return -EFAULT;
+               if (i2c.bus > dev->link[0].info->regmap->i2c->num)
+                       return -EINVAL;
+               if (i2c.mlen + i2c.hlen > 250)
+                       return -EINVAL;
+
+               adap = &dev->i2c[i2c.bus].adap;
+               if (copy_from_user(buf, i2c.hdr, i2c.hlen))
+                       return -EFAULT;
+               if (copy_from_user(buf + i2c.hlen, i2c.msg, i2c.mlen))
+                       return -EFAULT;
+               if (i2c_write(adap, i2c.adr, buf, i2c.hlen + i2c.mlen) < 0)
+                       return -EIO;
+               break;
+       }
+       default:
+               return -ENOTTY;
+       }
+       return 0;
+}
diff --git a/drivers/media/pci/ddbridge/ddbridge-ioctl.h 
b/drivers/media/pci/ddbridge/ddbridge-ioctl.h
new file mode 100644
index 000000000000..90da239261ae
--- /dev/null
+++ b/drivers/media/pci/ddbridge/ddbridge-ioctl.h
@@ -0,0 +1,32 @@
+/*
+ * ddbridge-ioctl.h: Digital Devices bridge IOCTL handler
+ *
+ * Copyright (C) 2010-2017 Digital Devices GmbH
+ *                         Ralph Metzler <r...@metzlerbros.de>
+ *                         Marcus Metzler <m...@metzlerbros.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DDBRIDGE_IOCTL_H__
+#define __DDBRIDGE_IOCTL_H__
+
+#include <linux/ddbridge-ioctl.h>
+
+#include "ddbridge.h"
+
+/******************************************************************************/
+
+int ddb_flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf,
+               u32 rlen);
+long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
+#endif /* __DDBRIDGE_IOCTL_H__ */
diff --git a/include/uapi/linux/ddbridge-ioctl.h 
b/include/uapi/linux/ddbridge-ioctl.h
new file mode 100644
index 000000000000..3235637ad338
--- /dev/null
+++ b/include/uapi/linux/ddbridge-ioctl.h
@@ -0,0 +1,110 @@
+/*
+ * ddbridge-ioctl.h: Digital Devices bridge IOCTL API
+ *
+ * Copyright (C) 2010-2017 Digital Devices GmbH
+ *                         Ralph Metzler <r...@metzlerbros.de>
+ *                         Marcus Metzler <m...@metzlerbros.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __LINUX_DDBRIDGE_IOCTL_H__
+#define __LINUX_DDBRIDGE_IOCTL_H__
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+/******************************************************************************/
+
+#define DDB_MAGIC 'd'
+
+/* IOCTL_DDB_FLASHIO */
+struct ddb_flash_io {
+       /* write_*: userspace -> flash */
+       __user __u8 *write_buf;
+       __u32        write_len;
+       /* read_*: flash -> userspace */
+       __user __u8 *read_buf;
+       __u32        read_len;
+       /* card/addon link */
+       __u32        link;
+};
+
+/* IOCTL_DDB_GPIO_{IN,OUT} */
+struct ddb_gpio {
+       __u32 mask;
+       __u32 data;
+};
+
+/* IOCTL_DDB_ID */
+struct ddb_id {
+       /* card/PCI device data, FPGA/regmap info */
+       __u16 vendor;
+       __u16 device;
+       __u16 subvendor;
+       __u16 subdevice;
+       __u32 hw;
+       __u32 regmap;
+};
+
+/* IOCTL_DDB_{READ,WRITE}_REG */
+struct ddb_reg {
+       __u32 reg;
+       __u32 val;
+};
+
+/* IOCTL_DDB_{READ,WRITE}_MEM */
+struct ddb_mem {
+       /* read/write card mem, off = offset from base address */
+       __u32        off;
+       __user __u8 *buf;
+       __u32        len;
+};
+
+/* IOCTL_DDB_{READ,WRITE}_MDIO */
+struct ddb_mdio {
+       /* read/write from/to MDIO address/register/value */
+       __u8  adr;
+       __u8  reg;
+       __u16 val;
+};
+
+/* IOCTL_DDB_{READ,WRITE}_I2C */
+struct ddb_i2c_msg {
+       /* card's I2C bus number */
+       __u8   bus;
+       /* I2C address */
+       __u8   adr;
+       /* I2C IO header */
+       __u8  *hdr;
+       __u32  hlen;
+       /* I2C message */
+       __u8  *msg;
+       __u32  mlen;
+};
+
+/* IOCTLs */
+#define IOCTL_DDB_FLASHIO      _IOWR(DDB_MAGIC, 0x00, struct ddb_flash_io)
+#define IOCTL_DDB_GPIO_IN      _IOWR(DDB_MAGIC, 0x01, struct ddb_gpio)
+#define IOCTL_DDB_GPIO_OUT     _IOWR(DDB_MAGIC, 0x02, struct ddb_gpio)
+#define IOCTL_DDB_ID           _IOR(DDB_MAGIC,  0x03, struct ddb_id)
+#define IOCTL_DDB_READ_REG     _IOWR(DDB_MAGIC, 0x04, struct ddb_reg)
+#define IOCTL_DDB_WRITE_REG    _IOW(DDB_MAGIC,  0x05, struct ddb_reg)
+#define IOCTL_DDB_READ_MEM     _IOWR(DDB_MAGIC, 0x06, struct ddb_mem)
+#define IOCTL_DDB_WRITE_MEM    _IOR(DDB_MAGIC,  0x07, struct ddb_mem)
+#define IOCTL_DDB_READ_MDIO    _IOWR(DDB_MAGIC, 0x08, struct ddb_mdio)
+#define IOCTL_DDB_WRITE_MDIO   _IOR(DDB_MAGIC,  0x09, struct ddb_mdio)
+#define IOCTL_DDB_READ_I2C     _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg)
+#define IOCTL_DDB_WRITE_I2C    _IOR(DDB_MAGIC,  0x0b, struct ddb_i2c_msg)
+
+/******************************************************************************/
+
+#endif /* __LINUX_DDBRIDGE_IOCTL_H__ */
-- 
2.13.0

Reply via email to