Skip to content

Commit

Permalink
i2c:aspeed:support ast2600 i2c new register mode driver
Browse files Browse the repository at this point in the history
Add i2c new register mode driver to support AST2600 i2c
new register set. AST2600 i2c controller have legacy and
new register mode. The new register mode have global register
support 4 base clock for scl clock selection, and new clock
divider mode. And i2c new register mode have separate register
set to control i2c master and slave.

Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
  • Loading branch information
aspeedtech authored and intel-lab-lkp committed Mar 23, 2022
1 parent 1f1d466 commit 4fa1d6c
Show file tree
Hide file tree
Showing 5 changed files with 1,820 additions and 0 deletions.
11 changes: 11 additions & 0 deletions drivers/i2c/busses/Kconfig
Expand Up @@ -387,6 +387,17 @@ config I2C_ALTERA
This driver can also be built as a module. If so, the module
will be called i2c-altera.

config I2C_NEW_ASPEED
tristate "Aspeed New I2C Controller"
depends on ARCH_ASPEED || MACH_ASPEED_G6 || COMPILE_TEST
select I2C_SMBUS
help
If you say yes to this option, support will be included for the
Aspeed I2C controller with new register set.

This driver can also be built as a module. If so, the module
will be called i2c-new-aspeed.

config I2C_ASPEED
tristate "Aspeed I2C Controller"
depends on ARCH_ASPEED || COMPILE_TEST
Expand Down
1 change: 1 addition & 0 deletions drivers/i2c/busses/Makefile
Expand Up @@ -38,6 +38,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
obj-$(CONFIG_I2C_ALTERA) += i2c-altera.o
obj-$(CONFIG_I2C_AMD_MP2) += i2c-amd-mp2-pci.o i2c-amd-mp2-plat.o
obj-$(CONFIG_I2C_ASPEED) += i2c-aspeed.o
obj-$(CONFIG_I2C_NEW_ASPEED) += aspeed-i2c-new-global.o i2c-new-aspeed.o
obj-$(CONFIG_I2C_AT91) += i2c-at91.o
i2c-at91-objs := i2c-at91-core.o i2c-at91-master.o
ifeq ($(CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL),y)
Expand Down
91 changes: 91 additions & 0 deletions drivers/i2c/busses/aspeed-i2c-new-global.c
@@ -0,0 +1,91 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Aspeed I2C Global Controller Driver.
*
* Copyright (C) ASPEED Technology Inc.
*/
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/module.h>
#include <linux/reset.h>
#include <linux/delay.h>
#include <linux/io.h>
#include "aspeed-i2c-new-global.h"

struct aspeed_i2c_new_global {
void __iomem *base;
struct reset_control *rst;
};

static const struct of_device_id aspeed_i2c_ic_of_match[] = {
{ .compatible = "aspeed,ast2600-i2c-global", },
{ },
};
MODULE_DEVICE_TABLE(of, aspeed_i2c_ic_of_match);

#define I2CCG_DIV_CTRL 0x6C411208
/*
* APB clk : 100Mhz
* div : scl : baseclk [APB/((div/2) + 1)] : tBuf [1/bclk * 16]
* I2CG10[31:24] base clk4 for i2c auto recovery timeout counter
* I2CG10[23:16] base clk3 for Standard-mode (100Khz) min tBuf 4.7us
* 0x3c : 100.8Khz : 3.225Mhz : 4.96us
* 0x3d : 99.2Khz : 3.174Mhz : 5.04us
* 0x3e : 97.65Khz : 3.125Mhz : 5.12us
* 0x40 : 97.75Khz : 3.03Mhz : 5.28us
* 0x41 : 99.5Khz : 2.98Mhz : 5.36us (default)
* I2CG10[15:8] base clk2 for Fast-mode (400Khz) min tBuf 1.3us
* 0x12 : 400Khz : 10Mhz : 1.6us
* I2CG10[7:0] base clk1 for Fast-mode Plus (1Mhz) min tBuf 0.5us
* 0x08 : 1Mhz : 20Mhz : 0.8us
*/

static int aspeed_i2c_global_probe(struct platform_device *pdev)
{
struct aspeed_i2c_new_global *i2c_global;
struct resource *res;

i2c_global = devm_kzalloc(&pdev->dev, sizeof(*i2c_global), GFP_KERNEL);
if (IS_ERR(i2c_global))
return PTR_ERR(i2c_global);

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
i2c_global->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(i2c_global->base))
return PTR_ERR(i2c_global->base);

i2c_global->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(i2c_global->rst))
return IS_ERR(i2c_global->rst);

reset_control_assert(i2c_global->rst);
udelay(3);
reset_control_deassert(i2c_global->rst);

writel(ASPEED_I2CG_SLAVE_PKT_NAK | ASPEED_I2CG_CTRL_NEW_REG | ASPEED_I2CG_CTRL_NEW_CLK_DIV,
i2c_global->base + ASPEED_I2CG_CTRL);
writel(I2CCG_DIV_CTRL, i2c_global->base + ASPEED_I2CG_CLK_DIV_CTRL);

pr_info("i2c global registered\n");

return 0;
}

static struct platform_driver aspeed_i2c_ic_driver = {
.probe = aspeed_i2c_global_probe,
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = aspeed_i2c_ic_of_match,
},
};

static int __init aspeed_i2c_global_init(void)
{
return platform_driver_register(&aspeed_i2c_ic_driver);
}
postcore_initcall(aspeed_i2c_global_init);

MODULE_AUTHOR("Ryan Chen");
MODULE_DESCRIPTION("ASPEED I2C Global Driver");
MODULE_LICENSE("GPL v2");
19 changes: 19 additions & 0 deletions drivers/i2c/busses/aspeed-i2c-new-global.h
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#ifndef AST2600_I2C_NEW_GLOBAL_H
#define AST2600_I2C_NEW_GLOBAL_H

#include <linux/bits.h>

#define ASPEED_I2CG_ISR 0x00
#define ASPEED_I2CG_SLAVE_ISR 0x04
#define ASPEED_I2CG_OWNER 0x08
#define ASPEED_I2CG_CTRL 0x0C
#define ASPEED_I2CG_CLK_DIV_CTRL 0x10

#define ASPEED_I2CG_SLAVE_PKT_NAK BIT(4)
#define ASPEED_I2CG_M_S_SEPARATE_INTR BIT(3)
#define ASPEED_I2CG_CTRL_NEW_REG BIT(2)
#define ASPEED_I2CG_CTRL_NEW_CLK_DIV BIT(1)

#endif /* AST2600_I2C_NEW_GLOBAL_H */

0 comments on commit 4fa1d6c

Please sign in to comment.