diff --git a/ddbridge/Kbuild b/ddbridge/Kbuild index 41f3f6f..95a61bd 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-core.o ddbridge-hw.o ddbridge-i2c.o ddbridge-modulator.o ddbridge-ns.o -octonet-objs := octonet-main.o ddbridge-core.o ddbridge-hw.o ddbridge-i2c.o ddbridge-modulator.o ddbridge-ns.o +ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-hw.o ddbridge-i2c.o ddbridge-io.o ddbridge-modulator.o ddbridge-ns.o +octonet-objs := octonet-main.o ddbridge-core.o ddbridge-hw.o ddbridge-i2c.o ddbridge-io.o ddbridge-modulator.o ddbridge-ns.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 6acdbbe..645eec5 100644 --- a/ddbridge/ddbridge-core.c +++ b/ddbridge/ddbridge-core.c @@ -41,6 +41,7 @@ #include "ddbridge.h" #include "ddbridge-regs.h" #include "ddbridge-hw.h" +#include "ddbridge-io.h" #include "tda18271c2dd.h" #include "stv6110x.h" diff --git a/ddbridge/ddbridge-i2c.c b/ddbridge/ddbridge-i2c.c index 799f799..76c6241 100644 --- a/ddbridge/ddbridge-i2c.c +++ b/ddbridge/ddbridge-i2c.c @@ -39,6 +39,7 @@ #include "ddbridge.h" #include "ddbridge-regs.h" +#include "ddbridge-io.h" /******************************************************************************/ diff --git a/ddbridge/ddbridge-io.c b/ddbridge/ddbridge-io.c new file mode 100644 index 0000000..607ab77 --- /dev/null +++ b/ddbridge/ddbridge-io.c @@ -0,0 +1,177 @@ +/* + * ddbridge-io.h: Digital Devices bridge I/O (inline) 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. + * + */ + +#include + +#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))); +} + +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; + } +} + +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..ce83537 --- /dev/null +++ b/ddbridge/ddbridge-io.h @@ -0,0 +1,68 @@ +/* + * ddbridge-io.h: Digital Devices bridge I/O (inline) 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. + * + */ + +#ifndef __DDBRIDGE_IO_H__ +#define __DDBRIDGE_IO_H__ + +#include + +#include "ddbridge.h" + +/******************************************************************************/ + +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))); +} + +static inline void gtlw(struct ddb_link *link) +{ + while (1 & ddbreadl0(link, link->regs + 0x10)) + ; +} + +/******************************************************************************/ + +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 ddbcpyto(struct ddb *dev, u32 adr, void *src, long count); +void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count); + +/******************************************************************************/ + +#define ddbmemset(_dev, _adr, _val, _count) \ + memset_io((char *) (_dev->regs + (_adr)), (_val), (_count)) + +#endif /* __DDBRIDGE_IO_H__ */ diff --git a/ddbridge/ddbridge-main.c b/ddbridge/ddbridge-main.c index bba58cc..4db1263 100644 --- a/ddbridge/ddbridge-main.c +++ b/ddbridge/ddbridge-main.c @@ -30,6 +30,7 @@ #include "ddbridge.h" #include "ddbridge-regs.h" #include "ddbridge-hw.h" +#include "ddbridge-io.h" static struct workqueue_struct *ddb_wq; diff --git a/ddbridge/ddbridge-modulator.c b/ddbridge/ddbridge-modulator.c index 90a4062..69e6eca 100644 --- a/ddbridge/ddbridge-modulator.c +++ b/ddbridge/ddbridge-modulator.c @@ -25,6 +25,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 061f958..c399314 100644 --- a/ddbridge/ddbridge-ns.c +++ b/ddbridge/ddbridge-ns.c @@ -39,6 +39,7 @@ #include "ddbridge.h" #include "ddbridge-regs.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 0c80d52..a45445a 100644 --- a/ddbridge/ddbridge.h +++ b/ddbridge/ddbridge.h @@ -467,211 +467,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 da2f03a..7387117 100644 --- a/ddbridge/octonet-main.c +++ b/ddbridge/octonet-main.c @@ -40,6 +40,8 @@ #include "ddbridge.h" #include "ddbridge-regs.h" #include "ddbridge-hw.h" +#include "ddbridge-io.h" + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) #include #else