diff --git a/ddbridge/Kbuild b/ddbridge/Kbuild index c6be98a..510e7d0 100644 --- a/ddbridge/Kbuild +++ b/ddbridge/Kbuild @@ -1,7 +1,7 @@ EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 -DCONFIG_DVB_LNBP21 -DCONFIG_DVB_STV090x -DCONFIG_DVB_STV6110x -DCONFIG_DVB_DRXK -DCONFIG_DVB_STV0910 -DCONFIG_DVB_STV6111 -DCONFIG_DVB_LNBH25 -DCONFIG_DVB_MXL5XX -ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o -octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o +ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o +octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o obj-$(CONFIG_DVB_OCTONET) += octonet.o diff --git a/ddbridge/Makefile.kernel b/ddbridge/Makefile.kernel index 7c27f43..b413e9e 100644 --- a/ddbridge/Makefile.kernel +++ b/ddbridge/Makefile.kernel @@ -2,8 +2,8 @@ # Makefile for the ddbridge device driver # -ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o -octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o +ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o +octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o obj-$(CONFIG_DVB_OCTONET) += octonet.o diff --git a/ddbridge/ddbridge-core.c b/ddbridge/ddbridge-core.c index 0526b35..95ce288 100644 --- a/ddbridge/ddbridge-core.c +++ b/ddbridge/ddbridge-core.c @@ -25,6 +25,9 @@ */ #include "ddbridge.h" +#include "ddbridge-i2c.h" +#include "ddbridge-io.h" +#include "dvb_net.h" struct workqueue_struct *ddb_wq; @@ -84,7 +87,6 @@ static struct ddb *ddbs[DDB_MAX_ADAPTER]; DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#include "ddbridge-i2c.h" /****************************************************************************/ /****************************************************************************/ diff --git a/ddbridge/ddbridge-i2c.c b/ddbridge/ddbridge-i2c.c index 4abacf7..293207b 100644 --- a/ddbridge/ddbridge-i2c.c +++ b/ddbridge/ddbridge-i2c.c @@ -24,6 +24,7 @@ */ #include "ddbridge.h" +#include "ddbridge-io.h" static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) { diff --git a/ddbridge/ddbridge-io.c b/ddbridge/ddbridge-io.c new file mode 100644 index 0000000..0c20fca --- /dev/null +++ b/ddbridge/ddbridge-io.c @@ -0,0 +1,183 @@ +/* + * ddbridge-io.c: Digital Devices bridge I/O functions + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * + * 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. + * + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +#include "ddbridge.h" +#include "ddbridge-io.h" + +u32 ddblreadl(struct ddb_link *link, u32 adr) +{ + if (unlikely(link->nr)) { + unsigned long flags; + u32 val; + + spin_lock_irqsave(&link->lock, flags); + gtlw(link); + ddbwritel0(link, adr & 0xfffc, link->regs + 0x14); + ddbwritel0(link, 3, link->regs + 0x10); + gtlw(link); + val = ddbreadl0(link, link->regs + 0x1c); + spin_unlock_irqrestore(&link->lock, flags); + return val; + } + return readl((char *) (link->dev->regs + (adr))); +} + +void ddblwritel(struct ddb_link *link, u32 val, u32 adr) +{ + if (unlikely(link->nr)) { + unsigned long flags; + + spin_lock_irqsave(&link->lock, flags); + gtlw(link); + ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14); + ddbwritel0(link, val, link->regs + 0x18); + ddbwritel0(link, 1, link->regs + 0x10); + spin_unlock_irqrestore(&link->lock, flags); + return; + } + writel(val, (char *) (link->dev->regs + (adr))); +} + +u32 ddbreadl(struct ddb *dev, u32 adr) +{ + if (unlikely(adr & 0xf0000000)) { + unsigned long flags; + u32 val, l = (adr >> DDB_LINK_SHIFT); + struct ddb_link *link = &dev->link[l]; + + spin_lock_irqsave(&link->lock, flags); + gtlw(link); + ddbwritel0(link, adr & 0xfffc, link->regs + 0x14); + ddbwritel0(link, 3, link->regs + 0x10); + gtlw(link); + val = ddbreadl0(link, link->regs + 0x1c); + spin_unlock_irqrestore(&link->lock, flags); + return val; + } + return readl((char *) (dev->regs + (adr))); +} + +void ddbwritel(struct ddb *dev, u32 val, u32 adr) +{ + if (unlikely(adr & 0xf0000000)) { + unsigned long flags; + u32 l = (adr >> DDB_LINK_SHIFT); + struct ddb_link *link = &dev->link[l]; + + spin_lock_irqsave(&link->lock, flags); + gtlw(link); + ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14); + ddbwritel0(link, val, link->regs + 0x18); + ddbwritel0(link, 1, link->regs + 0x10); + spin_unlock_irqrestore(&link->lock, flags); + return; + } + writel(val, (char *) (dev->regs + (adr))); +} + +void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf, + unsigned int count) +{ + u32 val = 0, p = adr; + u32 aa = p & 3; + + if (aa) { + while (p & 3 && count) { + val >>= 8; + val |= *buf << 24; + p++; + buf++; + count--; + } + ddbwritel(dev, val, adr); + } + while (count >= 4) { + val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + ddbwritel(dev, val, p); + p += 4; + buf += 4; + count -= 4; + } + if (count) { + val = buf[0]; + if (count > 1) + val |= buf[1] << 8; + if (count > 2) + val |= buf[2] << 16; + ddbwritel(dev, val, p); + } +} + +void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count) +{ + u32 val = 0, p = adr; + u32 a = p & 3; + + if (a) { + val = ddbreadl(dev, p) >> (8 * a); + while (p & 3 && count) { + *buf = val & 0xff; + val >>= 8; + p++; + buf++; + count--; + } + } + while (count >= 4) { + val = ddbreadl(dev, p); + buf[0] = val & 0xff; + buf[1] = (val >> 8) & 0xff; + buf[2] = (val >> 16) & 0xff; + buf[3] = (val >> 24) & 0xff; + p += 4; + buf += 4; + count -= 4; + } + if (count) { + val = ddbreadl(dev, p); + buf[0] = val & 0xff; + if (count > 1) + buf[1] = (val >> 8) & 0xff; + if (count > 2) + buf[2] = (val >> 16) & 0xff; + } +} + +void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count) +{ + if (unlikely(adr & 0xf0000000)) + return gtlcpyto(dev, adr, src, count); + return memcpy_toio((char *) (dev->regs + adr), src, count); +} + +void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) +{ + if (unlikely(adr & 0xf0000000)) + return gtlcpyfrom(dev, dst, adr, count); + return memcpy_fromio(dst, (char *) (dev->regs + adr), count); +} + + + diff --git a/ddbridge/ddbridge-io.h b/ddbridge/ddbridge-io.h new file mode 100644 index 0000000..f750ea9 --- /dev/null +++ b/ddbridge/ddbridge-io.h @@ -0,0 +1,89 @@ +/* + * ddbridge-io.h: Digital Devices bridge I/O functions + * + * Copyright (C) 2010-2017 Digital Devices GmbH + * Ralph Metzler + * Marcus Metzler + * + * 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. + * + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef _DDBRIDGE_IO_H_ +#define _DDBRIDGE_IO_H_ + +u32 ddblreadl(struct ddb_link *link, u32 adr); +void ddblwritel(struct ddb_link *link, u32 val, u32 adr); +u32 ddbreadl(struct ddb *dev, u32 adr); +void ddbwritel(struct ddb *dev, u32 val, u32 adr); +void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf, + unsigned int count); +void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count); +void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count); +void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count); + +static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr) +{ + writeb(val, (char *) (dev->regs + (adr))); +} + +static inline u32 ddbreadb(struct ddb *dev, u32 adr) +{ + return readb((char *) (dev->regs + (adr))); +} + +static inline void ddbwritel0(struct ddb_link *link, u32 val, u32 adr) +{ + writel(val, (char *) (link->dev->regs + (adr))); +} + +static inline u32 ddbreadl0(struct ddb_link *link, u32 adr) +{ + return readl((char *) (link->dev->regs + (adr))); +} + +#if 0 +static inline void gtlw(struct ddb_link *link) +{ + u32 count = 0; + static u32 max; + + while (1 & ddbreadl0(link, link->regs + 0x10)) { + if (++count == 1024) { + pr_info("LTO\n"); + break; + } + } + if (count > max) { + max = count; + pr_info("TO=%u\n", max); + } + if (ddbreadl0(link, link->regs + 0x10) & 0x8000) + pr_err("link error\n"); +} +#else +static inline void gtlw(struct ddb_link *link) +{ + while (1 & ddbreadl0(link, link->regs + 0x10)) + ; +} +#endif + +#define ddbmemset(_dev, _adr, _val, _count) \ + memset_io((char *) (_dev->regs + (_adr)), (_val), (_count)) + +#endif diff --git a/ddbridge/ddbridge-main.c b/ddbridge/ddbridge-main.c index 7d4a49c..82061d0 100644 --- a/ddbridge/ddbridge-main.c +++ b/ddbridge/ddbridge-main.c @@ -24,6 +24,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */ #include "ddbridge.h" +#include "ddbridge-io.h" #ifdef CONFIG_PCI_MSI static int msi = 1; diff --git a/ddbridge/ddbridge-modulator.c b/ddbridge/ddbridge-modulator.c index 8907df6..4c78f03 100644 --- a/ddbridge/ddbridge-modulator.c +++ b/ddbridge/ddbridge-modulator.c @@ -1,5 +1,5 @@ /* - * ddbridge.c: Digital Devices PCIe bridge driver + * ddbridge-modulator.c: Digital Devices modulator cards * * Copyright (C) 2010-2017 Digital Devices GmbH * Marcus Metzler @@ -24,7 +24,7 @@ */ #include "ddbridge.h" -#include "ddbridge-regs.h" +#include "ddbridge-io.h" #include diff --git a/ddbridge/ddbridge-ns.c b/ddbridge/ddbridge-ns.c index eca2bf5..0485829 100644 --- a/ddbridge/ddbridge-ns.c +++ b/ddbridge/ddbridge-ns.c @@ -24,6 +24,7 @@ */ #include "ddbridge.h" +#include "ddbridge-io.h" static u16 calc_pcs(struct dvb_ns_params *p) { diff --git a/ddbridge/ddbridge.h b/ddbridge/ddbridge.h index 7076e38..6441cad 100644 --- a/ddbridge/ddbridge.h +++ b/ddbridge/ddbridge.h @@ -486,211 +486,6 @@ struct ddb { }; -static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr) -{ - writeb(val, (char *) (dev->regs + (adr))); -} - -static inline u32 ddbreadb(struct ddb *dev, u32 adr) -{ - return readb((char *) (dev->regs + (adr))); -} - -static inline void ddbwritel0(struct ddb_link *link, u32 val, u32 adr) -{ - writel(val, (char *) (link->dev->regs + (adr))); -} - -static inline u32 ddbreadl0(struct ddb_link *link, u32 adr) -{ - return readl((char *) (link->dev->regs + (adr))); -} - -#if 0 -static inline void gtlw(struct ddb_link *link) -{ - u32 count = 0; - static u32 max; - - while (1 & ddbreadl0(link, link->regs + 0x10)) { - if (++count == 1024) { - pr_info("LTO\n"); - break; - } - } - if (count > max) { - max = count; - pr_info("TO=%u\n", max); - } - if (ddbreadl0(link, link->regs + 0x10) & 0x8000) - pr_err("link error\n"); -} -#else -static inline void gtlw(struct ddb_link *link) -{ - while (1 & ddbreadl0(link, link->regs + 0x10)) - ; -} -#endif - - -static u32 ddblreadl(struct ddb_link *link, u32 adr) -{ - if (unlikely(link->nr)) { - unsigned long flags; - u32 val; - - spin_lock_irqsave(&link->lock, flags); - gtlw(link); - ddbwritel0(link, adr & 0xfffc, link->regs + 0x14); - ddbwritel0(link, 3, link->regs + 0x10); - gtlw(link); - val = ddbreadl0(link, link->regs + 0x1c); - spin_unlock_irqrestore(&link->lock, flags); - return val; - } - return readl((char *) (link->dev->regs + (adr))); -} - -static void ddblwritel(struct ddb_link *link, u32 val, u32 adr) -{ - if (unlikely(link->nr)) { - unsigned long flags; - - spin_lock_irqsave(&link->lock, flags); - gtlw(link); - ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14); - ddbwritel0(link, val, link->regs + 0x18); - ddbwritel0(link, 1, link->regs + 0x10); - spin_unlock_irqrestore(&link->lock, flags); - return; - } - writel(val, (char *) (link->dev->regs + (adr))); -} - -static u32 ddbreadl(struct ddb *dev, u32 adr) -{ - if (unlikely(adr & 0xf0000000)) { - unsigned long flags; - u32 val, l = (adr >> DDB_LINK_SHIFT); - struct ddb_link *link = &dev->link[l]; - - spin_lock_irqsave(&link->lock, flags); - gtlw(link); - ddbwritel0(link, adr & 0xfffc, link->regs + 0x14); - ddbwritel0(link, 3, link->regs + 0x10); - gtlw(link); - val = ddbreadl0(link, link->regs + 0x1c); - spin_unlock_irqrestore(&link->lock, flags); - return val; - } - return readl((char *) (dev->regs + (adr))); -} - -static void ddbwritel(struct ddb *dev, u32 val, u32 adr) -{ - if (unlikely(adr & 0xf0000000)) { - unsigned long flags; - u32 l = (adr >> DDB_LINK_SHIFT); - struct ddb_link *link = &dev->link[l]; - - spin_lock_irqsave(&link->lock, flags); - gtlw(link); - ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14); - ddbwritel0(link, val, link->regs + 0x18); - ddbwritel0(link, 1, link->regs + 0x10); - spin_unlock_irqrestore(&link->lock, flags); - return; - } - writel(val, (char *) (dev->regs + (adr))); -} - -static void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf, - unsigned int count) -{ - u32 val = 0, p = adr; - u32 aa = p & 3; - - if (aa) { - while (p & 3 && count) { - val >>= 8; - val |= *buf << 24; - p++; - buf++; - count--; - } - ddbwritel(dev, val, adr); - } - while (count >= 4) { - val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); - ddbwritel(dev, val, p); - p += 4; - buf += 4; - count -= 4; - } - if (count) { - val = buf[0]; - if (count > 1) - val |= buf[1] << 8; - if (count > 2) - val |= buf[2] << 16; - ddbwritel(dev, val, p); - } -} - -static void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count) -{ - u32 val = 0, p = adr; - u32 a = p & 3; - - if (a) { - val = ddbreadl(dev, p) >> (8 * a); - while (p & 3 && count) { - *buf = val & 0xff; - val >>= 8; - p++; - buf++; - count--; - } - } - while (count >= 4) { - val = ddbreadl(dev, p); - buf[0] = val & 0xff; - buf[1] = (val >> 8) & 0xff; - buf[2] = (val >> 16) & 0xff; - buf[3] = (val >> 24) & 0xff; - p += 4; - buf += 4; - count -= 4; - } - if (count) { - val = ddbreadl(dev, p); - buf[0] = val & 0xff; - if (count > 1) - buf[1] = (val >> 8) & 0xff; - if (count > 2) - buf[2] = (val >> 16) & 0xff; - } -} - -static void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count) -{ - if (unlikely(adr & 0xf0000000)) - return gtlcpyto(dev, adr, src, count); - return memcpy_toio((char *) (dev->regs + adr), src, count); -} - -static void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) -{ - if (unlikely(adr & 0xf0000000)) - return gtlcpyfrom(dev, dst, adr, count); - return memcpy_fromio(dst, (char *) (dev->regs + adr), count); -} - -#define ddbmemset(_dev, _adr, _val, _count) \ - memset_io((char *) (_dev->regs + (_adr)), (_val), (_count)) - - /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ diff --git a/ddbridge/octonet-main.c b/ddbridge/octonet-main.c index cfab612..a1865f8 100644 --- a/ddbridge/octonet-main.c +++ b/ddbridge/octonet-main.c @@ -24,6 +24,7 @@ */ #include "ddbridge.h" +#include "ddbridge-io.h" static int __exit octonet_remove(struct platform_device *pdev) {