Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9eb0b1f
LiteX: driver for LiteETH network interface
shenki Dec 22, 2020
fddb0b1
LiteX: driver for LiteSPI
fkokosinski Dec 22, 2020
a8e755f
LiteX: driver for LiteSDCard (mmc)
kamilrakoczy Dec 22, 2020
e8c460f
LiteX: add defconfig files for linux-on-litex-rocket design
gsomlo Dec 22, 2020
15ca79a
LiteX: driver for LiteGPIO interface
rw1nkler Dec 22, 2020
f6f825b
fixup over ("LiteX: driver for LiteGPIO interface")
gsomlo Dec 28, 2020
401938f
LiteX: driver for I2CMaster
rw1nkler Dec 22, 2020
0b372a1
fixup over ("LiteX: driver for I2CMaster")
gsomlo Dec 28, 2020
fb24472
LiteX: driver for XADC hwmon
rw1nkler Dec 22, 2020
66d8a9e
fixup over ("LiteX: driver for XADC hwmon")
gsomlo Dec 28, 2020
2b4bc43
LiteX: driver for PWM
craviee Dec 22, 2020
e75f40e
fixup over ("LiteX: driver for PWM")
gsomlo Dec 28, 2020
eff5664
LiteX: driver for SPI Flash (mtd) device
craviee Dec 22, 2020
e1e96eb
fixup over ("LiteX: driver for SPI Flash (mtd) device")
gsomlo Dec 28, 2020
ddff598
dt-bindings: mtd: Fix litex,spiflash
geertu Mar 26, 2021
464aaee
LiteX: driver for ICAPBitstream fpga manager
rw1nkler Dec 22, 2020
1de2b5e
fixup over ("LiteX: driver for ICAPBitstream fpga manager")
gsomlo Dec 27, 2020
36c0889
LiteX: support for VexRiscV interrupt controller
fkokosinski Dec 22, 2020
1398ca7
LiteX: driver for LiteVideo
rw1nkler Dec 22, 2020
e79fccc
fixup over ("LiteX: driver for LiteVideo")
gsomlo Dec 28, 2020
33f271c
LiteX: driver for MMCM
lpawelcz Dec 22, 2020
4869c30
fixup over ("LiteX: driver for MMCM")
gsomlo Dec 27, 2020
6d0adec
dt-bindings: clock: Fix litex,clock
geertu Mar 26, 2021
4a9c51e
litex_mmc: clarify how/why bus-width is configured
gsomlo Jan 11, 2021
94d261d
litex_mmc: don't overwrite capabilities parsed by mmc_of_parse()
gsomlo Jan 11, 2021
19bf4a6
litex-mmc: ensure probe fails with appropriate code & log message
gsomlo Jan 14, 2021
3a07b7d
litex_mmc: align internal error checks to hw. "event register" layout
gsomlo Feb 17, 2021
504079d
litex_mmc: redo max_[seg,req]_size, max_blk_count settings
gsomlo Jan 11, 2021
b0ced35
litex-mmc: enable multi-block data transfers
gsomlo Mar 22, 2021
3480dba
litex_mmc: force single-block data transfers
gsomlo Apr 3, 2021
521ce2b
spi: litespi: fix litespi cs handling for bulk transfers
Mar 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
LiteX: driver for I2CMaster
Signed-off-by: Robert Winkler <[email protected]>

FIXME: not updated or tested for 32-bit CSR data width, 64-bit CPU (gls)
  • Loading branch information
rw1nkler authored and gsomlo committed Mar 27, 2021
commit 401938fc15623fcbc5688e1233fbc59853142640
12 changes: 12 additions & 0 deletions Documentation/devicetree/bindings/i2c/i2c-litex.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
LiteX I2C controller

Required properties:
- compatible: should be "litex,i2c"
- reg: base address of configuration registers with length

Examples:

i2c@f0003000 {
compatible = "litex,i2c";
reg = <0x0 0xf0003000 0x0 0x5>;
};
7 changes: 7 additions & 0 deletions drivers/i2c/busses/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,13 @@ config I2C_KEMPLD
This driver can also be built as a module. If so, the module
will be called i2c-kempld.

config I2C_LITEX
tristate "LiteX I2C support"
depends on OF && HAS_IOMEM && LITEX_SOC_CONTROLLER
select I2C_ALGOBIT
help
This enables I2C bitbang driver for LiteX SoC builder.

config I2C_LPC2K
tristate "I2C bus support for NXP LPC2K/LPC178x/18xx/43xx"
depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
Expand Down
1 change: 1 addition & 0 deletions drivers/i2c/busses/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ obj-$(CONFIG_I2C_IMX_LPI2C) += i2c-imx-lpi2c.o
obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
obj-$(CONFIG_I2C_LITEX) += i2c-litex.o
obj-$(CONFIG_I2C_LPC2K) += i2c-lpc2k.o
obj-$(CONFIG_I2C_MESON) += i2c-meson.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
Expand Down
156 changes: 156 additions & 0 deletions drivers/i2c/busses/i2c-litex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Antmicro <www.antmicro.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/bits.h>
#include <linux/litex.h>

#define REGISTER_SIZE 1
#define OFFSET_REG_W 0x0
#define OFFSET_REG_R 0x4

#define BITPOS_SCL 0
#define BITPOS_SDA_DIR 1
#define BITPOS_SDA_W 2
#define BITPOS_SDA_R 0

#define SETDIR_SDA_OUTPUT 1
#define SETDIR_SDA_INPUT 0

#define DRIVER_ALGO_BIT_UDELAY 20

struct litex_i2c {
void __iomem *reg_w;
void __iomem *reg_r;
struct i2c_adapter adapter;
struct i2c_algo_bit_data algo_data;
};

/* Helper functions */

static inline void litex_set_bit(void __iomem *mem, int bit, int val)
{
u32 regv, new_regv;

regv = litex_get_reg(mem, REGISTER_SIZE);
new_regv = (regv & ~BIT(bit)) | ((!!val) << bit);
litex_set_reg(mem, REGISTER_SIZE, new_regv);
}

static inline int litex_get_bit(void __iomem *mem, int bit)
{
u32 regv;

regv = litex_get_reg(mem, REGISTER_SIZE);
return !!(regv & BIT(bit));
}

/* API functions */

static void litex_i2c_setscl(void *data, int state)
{
struct litex_i2c *i2c = (struct litex_i2c *) data;

litex_set_bit(i2c->reg_w, BITPOS_SCL, state);
}

static void litex_i2c_setsda(void *data, int state)
{
struct litex_i2c *i2c = (struct litex_i2c *) data;

litex_set_bit(i2c->reg_w, BITPOS_SDA_DIR, SETDIR_SDA_OUTPUT);
litex_set_bit(i2c->reg_w, BITPOS_SDA_W, state);
}

static int litex_i2c_getsda(void *data)
{
struct litex_i2c *i2c = (struct litex_i2c *) data;

litex_set_bit(i2c->reg_w, BITPOS_SDA_DIR, SETDIR_SDA_INPUT);
return litex_get_bit(i2c->reg_r, BITPOS_SDA_R);
}

/* Driver functions */

static int litex_i2c_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
void __iomem *membase;
struct litex_i2c *i2c_s;
struct resource *res;

if (!node)
return -ENODEV;

i2c_s = devm_kzalloc(&pdev->dev, sizeof(*i2c_s), GFP_KERNEL);
if (!i2c_s)
return -ENOMEM;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EBUSY;

membase = devm_of_iomap(&pdev->dev, node, 0, &res->end);
if (IS_ERR_OR_NULL(membase))
return -EIO;

i2c_s->reg_w = membase + OFFSET_REG_W;
i2c_s->reg_r = membase + OFFSET_REG_R;

strncpy(i2c_s->adapter.name, "litex_i2c_adapter",
sizeof(i2c_s->adapter.name));
i2c_s->adapter.owner = THIS_MODULE;
i2c_s->adapter.algo_data = &i2c_s->algo_data;
i2c_s->adapter.dev.parent = &pdev->dev;
i2c_s->adapter.dev.of_node = node;
i2c_s->algo_data.data = i2c_s;

i2c_s->algo_data.setsda = litex_i2c_setsda;
i2c_s->algo_data.setscl = litex_i2c_setscl;
i2c_s->algo_data.getsda = litex_i2c_getsda;
i2c_s->algo_data.getscl = NULL;
i2c_s->algo_data.udelay = DRIVER_ALGO_BIT_UDELAY;
i2c_s->algo_data.timeout = HZ;

platform_set_drvdata(pdev, i2c_s);
return i2c_bit_add_bus(&i2c_s->adapter);
}

static const struct of_device_id litex_of_match[] = {
{.compatible = "litex,i2c"},
{},
};

MODULE_DEVICE_TABLE(of, litex_of_match);

static struct platform_driver litex_i2c_driver = {
.driver = {
.name = "litex-i2c",
.of_match_table = of_match_ptr(litex_of_match)
},
.probe = litex_i2c_probe,
};

module_platform_driver(litex_i2c_driver);

MODULE_DESCRIPTION("LiteX bitbang I2C Bus driver");
MODULE_AUTHOR("Antmicro <www.antmicro.com>");