diff options
author | Adrian Schmutzler <freifunk@adrianschmutzler.de> | 2020-08-07 16:35:05 +0200 |
---|---|---|
committer | Adrian Schmutzler <freifunk@adrianschmutzler.de> | 2020-09-02 16:29:23 +0200 |
commit | 66ab1fb395f85e018cb1c6ae0d3a14aa46373f84 (patch) | |
tree | 35f50dd6b7f14e0e31c851529b91773883e186c9 /target/linux/ramips/patches-4.14/0045-i2c-add-mt7621-driver.patch | |
parent | e68c017e9315fb246e820565ec3e18cf0bd8649e (diff) | |
download | upstream-66ab1fb395f85e018cb1c6ae0d3a14aa46373f84.tar.gz upstream-66ab1fb395f85e018cb1c6ae0d3a14aa46373f84.tar.bz2 upstream-66ab1fb395f85e018cb1c6ae0d3a14aa46373f84.zip |
ramips: drop support for kernel 4.14
The target seems to be working on 5.4, so drop 4.14 support in
preparation for removing it from master entirely.
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
Diffstat (limited to 'target/linux/ramips/patches-4.14/0045-i2c-add-mt7621-driver.patch')
-rw-r--r-- | target/linux/ramips/patches-4.14/0045-i2c-add-mt7621-driver.patch | 473 |
1 files changed, 0 insertions, 473 deletions
diff --git a/target/linux/ramips/patches-4.14/0045-i2c-add-mt7621-driver.patch b/target/linux/ramips/patches-4.14/0045-i2c-add-mt7621-driver.patch deleted file mode 100644 index a848085520..0000000000 --- a/target/linux/ramips/patches-4.14/0045-i2c-add-mt7621-driver.patch +++ /dev/null @@ -1,473 +0,0 @@ -From d5c54ff3d1db0a4348fa04d8e78f3bf6063e3afc Mon Sep 17 00:00:00 2001 -From: John Crispin <blogic@openwrt.org> -Date: Mon, 7 Dec 2015 17:21:27 +0100 -Subject: [PATCH 45/53] i2c: add mt7621 driver - -Signed-off-by: John Crispin <blogic@openwrt.org> ---- - drivers/i2c/busses/Kconfig | 4 + - drivers/i2c/busses/Makefile | 1 + - drivers/i2c/busses/i2c-mt7621.c | 303 +++++++++++++++++++++++++++++++++++++++ - 3 files changed, 308 insertions(+) - create mode 100644 drivers/i2c/busses/i2c-mt7621.c - ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -869,6 +869,11 @@ config I2C_RALINK - depends on RALINK && !SOC_MT7621 - select OF_I2C - -+config I2C_MT7621 -+ tristate "MT7621/MT7628 I2C Controller" -+ depends on RALINK && (SOC_MT7620 || SOC_MT7621) -+ select OF_I2C -+ - config HAVE_S3C2410_I2C - bool - help ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -85,6 +85,7 @@ obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o - obj-$(CONFIG_I2C_PXA) += i2c-pxa.o - obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o - obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o -+obj-$(CONFIG_I2C_MT7621) += i2c-mt7621.o - obj-$(CONFIG_I2C_QUP) += i2c-qup.o - obj-$(CONFIG_I2C_RIIC) += i2c-riic.o - obj-$(CONFIG_I2C_RK3X) += i2c-rk3x.o ---- /dev/null -+++ b/drivers/i2c/busses/i2c-mt7621.c -@@ -0,0 +1,433 @@ -+/* -+ * drivers/i2c/busses/i2c-mt7621.c -+ * -+ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com> -+ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com> -+ * -+ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus. -+ * (C) 2014 Sittisak <sittisaks@hotmail.com> -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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/interrupt.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/reset.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/init.h> -+#include <linux/errno.h> -+#include <linux/platform_device.h> -+#include <linux/of_platform.h> -+#include <linux/i2c.h> -+#include <linux/io.h> -+#include <linux/err.h> -+#include <linux/clk.h> -+ -+#define REG_SM0CFG0 0x08 -+#define REG_SM0DOUT 0x10 -+#define REG_SM0DIN 0x14 -+#define REG_SM0ST 0x18 -+#define REG_SM0AUTO 0x1C -+#define REG_SM0CFG1 0x20 -+#define REG_SM0CFG2 0x28 -+#define REG_SM0CTL0 0x40 -+#define REG_SM0CTL1 0x44 -+#define REG_SM0D0 0x50 -+#define REG_SM0D1 0x54 -+#define REG_PINTEN 0x5C -+#define REG_PINTST 0x60 -+#define REG_PINTCL 0x64 -+ -+/* REG_SM0CFG0 */ -+#define I2C_DEVADDR_MASK 0x7f -+ -+/* REG_SM0ST */ -+#define I2C_DATARDY BIT(2) -+#define I2C_SDOEMPTY BIT(1) -+#define I2C_BUSY BIT(0) -+ -+/* REG_SM0AUTO */ -+#define READ_CMD BIT(0) -+ -+/* REG_SM0CFG1 */ -+#define BYTECNT_MAX 64 -+#define SET_BYTECNT(x) (x - 1) -+ -+/* REG_SM0CFG2 */ -+#define AUTOMODE_EN BIT(0) -+ -+/* REG_SM0CTL0 */ -+#define ODRAIN_HIGH_SM0 BIT(31) -+#define VSYNC_SHIFT 28 -+#define VSYNC_MASK 0x3 -+#define VSYNC_PULSE (0x1 << VSYNC_SHIFT) -+#define VSYNC_RISING (0x2 << VSYNC_SHIFT) -+#define CLK_DIV_SHIFT 16 -+#define CLK_DIV_MASK 0xfff -+#define DEG_CNT_SHIFT 8 -+#define DEG_CNT_MASK 0xff -+#define WAIT_HIGH BIT(6) -+#define DEG_EN BIT(5) -+#define CS_STATUA BIT(4) -+#define SCL_STATUS BIT(3) -+#define SDA_STATUS BIT(2) -+#define SM0_EN BIT(1) -+#define SCL_STRECH BIT(0) -+ -+/* REG_SM0CTL1 */ -+#define ACK_SHIFT 16 -+#define ACK_MASK 0xff -+#define PGLEN_SHIFT 8 -+#define PGLEN_MASK 0x7 -+#define SM0_MODE_SHIFT 4 -+#define SM0_MODE_MASK 0x7 -+#define SM0_MODE_START 0x1 -+#define SM0_MODE_WRITE 0x2 -+#define SM0_MODE_STOP 0x3 -+#define SM0_MODE_READ_NACK 0x4 -+#define SM0_MODE_READ_ACK 0x5 -+#define SM0_TRI_BUSY BIT(0) -+ -+/* timeout waiting for I2C devices to respond (clock streching) */ -+#define TIMEOUT_MS 1000 -+#define DELAY_INTERVAL_US 100 -+ -+struct mtk_i2c { -+ void __iomem *base; -+ struct clk *clk; -+ struct device *dev; -+ struct i2c_adapter adap; -+ u32 cur_clk; -+ u32 clk_div; -+ u32 flags; -+}; -+ -+static void mtk_i2c_w32(struct mtk_i2c *i2c, u32 val, unsigned reg) -+{ -+ iowrite32(val, i2c->base + reg); -+} -+ -+static u32 mtk_i2c_r32(struct mtk_i2c *i2c, unsigned reg) -+{ -+ return ioread32(i2c->base + reg); -+} -+ -+static int poll_down_timeout(void __iomem *addr, u32 mask) -+{ -+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); -+ -+ do { -+ if (!(readl_relaxed(addr) & mask)) -+ return 0; -+ -+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); -+ } while (time_before(jiffies, timeout)); -+ -+ return (readl_relaxed(addr) & mask) ? -EAGAIN : 0; -+} -+ -+static int mtk_i2c_wait_idle(struct mtk_i2c *i2c) -+{ -+ int ret; -+ -+ ret = poll_down_timeout(i2c->base + REG_SM0ST, I2C_BUSY); -+ if (ret < 0) -+ dev_dbg(i2c->dev, "idle err(%d)\n", ret); -+ -+ return ret; -+} -+ -+static int poll_up_timeout(void __iomem *addr, u32 mask) -+{ -+ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); -+ u32 status; -+ -+ do { -+ status = readl_relaxed(addr); -+ if (status & mask) -+ return 0; -+ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); -+ } while (time_before(jiffies, timeout)); -+ -+ return -ETIMEDOUT; -+} -+ -+static int mtk_i2c_wait_rx_done(struct mtk_i2c *i2c) -+{ -+ int ret; -+ -+ ret = poll_up_timeout(i2c->base + REG_SM0ST, I2C_DATARDY); -+ if (ret < 0) -+ dev_dbg(i2c->dev, "rx err(%d)\n", ret); -+ -+ return ret; -+} -+ -+static int mtk_i2c_wait_tx_done(struct mtk_i2c *i2c) -+{ -+ int ret; -+ -+ ret = poll_up_timeout(i2c->base + REG_SM0ST, I2C_SDOEMPTY); -+ if (ret < 0) -+ dev_dbg(i2c->dev, "tx err(%d)\n", ret); -+ -+ return ret; -+} -+ -+static void mtk_i2c_reset(struct mtk_i2c *i2c) -+{ -+ u32 reg; -+ device_reset(i2c->adap.dev.parent); -+ barrier(); -+ -+ /* ctrl0 */ -+ reg = ODRAIN_HIGH_SM0 | VSYNC_PULSE | (i2c->clk_div << CLK_DIV_SHIFT) | -+ WAIT_HIGH | SM0_EN; -+ mtk_i2c_w32(i2c, reg, REG_SM0CTL0); -+ -+ /* auto mode */ -+ mtk_i2c_w32(i2c, AUTOMODE_EN, REG_SM0CFG2); -+} -+ -+static void mtk_i2c_dump_reg(struct mtk_i2c *i2c) -+{ -+ dev_dbg(i2c->dev, "cfg0 %08x, dout %08x, din %08x, " \ -+ "status %08x, auto %08x, cfg1 %08x, " \ -+ "cfg2 %08x, ctl0 %08x, ctl1 %08x\n", -+ mtk_i2c_r32(i2c, REG_SM0CFG0), -+ mtk_i2c_r32(i2c, REG_SM0DOUT), -+ mtk_i2c_r32(i2c, REG_SM0DIN), -+ mtk_i2c_r32(i2c, REG_SM0ST), -+ mtk_i2c_r32(i2c, REG_SM0AUTO), -+ mtk_i2c_r32(i2c, REG_SM0CFG1), -+ mtk_i2c_r32(i2c, REG_SM0CFG2), -+ mtk_i2c_r32(i2c, REG_SM0CTL0), -+ mtk_i2c_r32(i2c, REG_SM0CTL1)); -+} -+ -+static int mtk_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, -+ int num) -+{ -+ struct mtk_i2c *i2c; -+ struct i2c_msg *pmsg; -+ int i, j, ret; -+ u32 cmd; -+ -+ i2c = i2c_get_adapdata(adap); -+ -+ for (i = 0; i < num; i++) { -+ pmsg = &msgs[i]; -+ cmd = 0; -+ -+ dev_dbg(i2c->dev, "addr: 0x%x, len: %d, flags: 0x%x\n", -+ pmsg->addr, pmsg->len, pmsg->flags); -+ -+ /* wait hardware idle */ -+ if ((ret = mtk_i2c_wait_idle(i2c))) -+ goto err_timeout; -+ -+ if (pmsg->flags & I2C_M_TEN) { -+ dev_dbg(i2c->dev, "10 bits addr not supported\n"); -+ return -EINVAL; -+ } else { -+ /* 7 bits address */ -+ mtk_i2c_w32(i2c, pmsg->addr & I2C_DEVADDR_MASK, -+ REG_SM0CFG0); -+ } -+ -+ /* buffer length */ -+ if (pmsg->len == 0) { -+ dev_dbg(i2c->dev, "length is 0\n"); -+ return -EINVAL; -+ } else -+ mtk_i2c_w32(i2c, SET_BYTECNT(pmsg->len), -+ REG_SM0CFG1); -+ -+ j = 0; -+ if (pmsg->flags & I2C_M_RD) { -+ cmd |= READ_CMD; -+ /* start transfer */ -+ barrier(); -+ mtk_i2c_w32(i2c, cmd, REG_SM0AUTO); -+ do { -+ /* wait */ -+ if ((ret = mtk_i2c_wait_rx_done(i2c))) -+ goto err_timeout; -+ /* read data */ -+ if (pmsg->len) -+ pmsg->buf[j] = mtk_i2c_r32(i2c, -+ REG_SM0DIN); -+ j++; -+ } while (j < pmsg->len); -+ } else { -+ do { -+ /* write data */ -+ if (pmsg->len) -+ mtk_i2c_w32(i2c, pmsg->buf[j], -+ REG_SM0DOUT); -+ /* start transfer */ -+ if (j == 0) { -+ barrier(); -+ mtk_i2c_w32(i2c, cmd, REG_SM0AUTO); -+ } -+ /* wait */ -+ if ((ret = mtk_i2c_wait_tx_done(i2c))) -+ goto err_timeout; -+ j++; -+ } while (j < pmsg->len); -+ } -+ } -+ /* the return value is number of executed messages */ -+ ret = i; -+ -+ return ret; -+ -+err_timeout: -+ mtk_i2c_dump_reg(i2c); -+ mtk_i2c_reset(i2c); -+ return ret; -+} -+ -+static u32 mtk_i2c_func(struct i2c_adapter *a) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -+} -+ -+static const struct i2c_algorithm mtk_i2c_algo = { -+ .master_xfer = mtk_i2c_master_xfer, -+ .functionality = mtk_i2c_func, -+}; -+ -+static const struct of_device_id i2c_mtk_dt_ids[] = { -+ { .compatible = "mediatek,mt7621-i2c" }, -+ { /* sentinel */ } -+}; -+ -+MODULE_DEVICE_TABLE(of, i2c_mtk_dt_ids); -+ -+static struct i2c_adapter_quirks mtk_i2c_quirks = { -+ .max_write_len = BYTECNT_MAX, -+ .max_read_len = BYTECNT_MAX, -+}; -+ -+static void mtk_i2c_init(struct mtk_i2c *i2c) -+{ -+ i2c->clk_div = clk_get_rate(i2c->clk) / i2c->cur_clk; -+ if (i2c->clk_div > CLK_DIV_MASK) -+ i2c->clk_div = CLK_DIV_MASK; -+ -+ mtk_i2c_reset(i2c); -+} -+ -+static int mtk_i2c_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ struct mtk_i2c *i2c; -+ struct i2c_adapter *adap; -+ const struct of_device_id *match; -+ int ret; -+ -+ match = of_match_device(i2c_mtk_dt_ids, &pdev->dev); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no memory resource found\n"); -+ return -ENODEV; -+ } -+ -+ i2c = devm_kzalloc(&pdev->dev, sizeof(struct mtk_i2c), GFP_KERNEL); -+ if (!i2c) { -+ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n"); -+ return -ENOMEM; -+ } -+ -+ i2c->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(i2c->base)) -+ return PTR_ERR(i2c->base); -+ -+ i2c->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(i2c->clk)) { -+ dev_err(&pdev->dev, "no clock defined\n"); -+ return -ENODEV; -+ } -+ clk_prepare_enable(i2c->clk); -+ i2c->dev = &pdev->dev; -+ -+ if (of_property_read_u32(pdev->dev.of_node, -+ "clock-frequency", &i2c->cur_clk)) -+ i2c->cur_clk = 100000; -+ -+ adap = &i2c->adap; -+ adap->owner = THIS_MODULE; -+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; -+ adap->algo = &mtk_i2c_algo; -+ adap->retries = 3; -+ adap->dev.parent = &pdev->dev; -+ i2c_set_adapdata(adap, i2c); -+ adap->dev.of_node = pdev->dev.of_node; -+ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); -+ adap->quirks = &mtk_i2c_quirks; -+ -+ platform_set_drvdata(pdev, i2c); -+ -+ mtk_i2c_init(i2c); -+ -+ ret = i2c_add_adapter(adap); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "failed to add adapter\n"); -+ clk_disable_unprepare(i2c->clk); -+ return ret; -+ } -+ -+ dev_info(&pdev->dev, "clock %uKHz, re-start not support\n", -+ i2c->cur_clk/1000); -+ -+ return ret; -+} -+ -+static int mtk_i2c_remove(struct platform_device *pdev) -+{ -+ struct mtk_i2c *i2c = platform_get_drvdata(pdev); -+ -+ i2c_del_adapter(&i2c->adap); -+ clk_disable_unprepare(i2c->clk); -+ -+ return 0; -+} -+ -+static struct platform_driver mtk_i2c_driver = { -+ .probe = mtk_i2c_probe, -+ .remove = mtk_i2c_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "i2c-mt7621", -+ .of_match_table = i2c_mtk_dt_ids, -+ }, -+}; -+ -+static int __init i2c_mtk_init (void) -+{ -+ return platform_driver_register(&mtk_i2c_driver); -+} -+subsys_initcall(i2c_mtk_init); -+ -+static void __exit i2c_mtk_exit (void) -+{ -+ platform_driver_unregister(&mtk_i2c_driver); -+} -+module_exit(i2c_mtk_exit); -+ -+MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>"); -+MODULE_DESCRIPTION("MT7621 I2c host driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:MT7621-I2C"); |