|
@@ -12,27 +12,15 @@
|
|
|
#include <fdtdec.h>
|
|
|
#include <i2c.h>
|
|
|
#include <asm/io.h>
|
|
|
-#ifdef CONFIG_TEGRA186
|
|
|
#include <clk.h>
|
|
|
#include <reset.h>
|
|
|
-#else
|
|
|
+#ifndef CONFIG_TEGRA186
|
|
|
#include <asm/arch/clock.h>
|
|
|
#include <asm/arch/funcmux.h>
|
|
|
-#include <asm/arch/pinmux.h>
|
|
|
-#include <asm/arch-tegra/clk_rst.h>
|
|
|
#endif
|
|
|
#include <asm/arch/gpio.h>
|
|
|
#include <asm/arch-tegra/tegra_i2c.h>
|
|
|
|
|
|
-/*
|
|
|
- * FIXME: TODO: This driver contains a number of ifdef CONFIG_TEGRA186 that
|
|
|
- * should not be present. These are needed because newer Tegra SoCs support
|
|
|
- * only the standard clock/reset APIs, whereas older Tegra SoCs support only
|
|
|
- * a custom Tegra-specific API. ASAP the older Tegra SoCs' code should be
|
|
|
- * fixed to implement the standard APIs, and all drivers converted to solely
|
|
|
- * use the new standard APIs, with no ifdefs.
|
|
|
- */
|
|
|
-
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
|
enum i2c_type {
|
|
@@ -44,12 +32,8 @@ enum i2c_type {
|
|
|
/* Information about i2c controller */
|
|
|
struct i2c_bus {
|
|
|
int id;
|
|
|
-#ifdef CONFIG_TEGRA186
|
|
|
struct reset_ctl reset_ctl;
|
|
|
struct clk clk;
|
|
|
-#else
|
|
|
- enum periph_id periph_id;
|
|
|
-#endif
|
|
|
int speed;
|
|
|
int pinmux_config;
|
|
|
struct i2c_control *control;
|
|
@@ -81,20 +65,15 @@ static void set_packet_mode(struct i2c_bus *i2c_bus)
|
|
|
static void i2c_reset_controller(struct i2c_bus *i2c_bus)
|
|
|
{
|
|
|
/* Reset I2C controller. */
|
|
|
-#ifdef CONFIG_TEGRA186
|
|
|
reset_assert(&i2c_bus->reset_ctl);
|
|
|
udelay(1);
|
|
|
reset_deassert(&i2c_bus->reset_ctl);
|
|
|
udelay(1);
|
|
|
-#else
|
|
|
- reset_periph(i2c_bus->periph_id, 1);
|
|
|
-#endif
|
|
|
|
|
|
/* re-program config register to packet mode */
|
|
|
set_packet_mode(i2c_bus);
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_TEGRA186
|
|
|
static int i2c_init_clock(struct i2c_bus *i2c_bus, unsigned rate)
|
|
|
{
|
|
|
int ret;
|
|
@@ -114,7 +93,6 @@ static int i2c_init_clock(struct i2c_bus *i2c_bus, unsigned rate)
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
static void i2c_init_controller(struct i2c_bus *i2c_bus)
|
|
|
{
|
|
@@ -126,12 +104,7 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus)
|
|
|
* here, in section 23.3.1, but in fact we seem to need a factor of
|
|
|
* 16 to get the right frequency.
|
|
|
*/
|
|
|
-#ifdef CONFIG_TEGRA186
|
|
|
i2c_init_clock(i2c_bus, i2c_bus->speed * 2 * 8);
|
|
|
-#else
|
|
|
- clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
|
|
|
- i2c_bus->speed * 2 * 8);
|
|
|
-#endif
|
|
|
|
|
|
if (i2c_bus->type == TYPE_114) {
|
|
|
/*
|
|
@@ -151,12 +124,7 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus)
|
|
|
debug("%s: CLK_DIV_STD_FAST_MODE setting = %d\n", __func__,
|
|
|
clk_div_stdfst_mode);
|
|
|
|
|
|
-#ifdef CONFIG_TEGRA186
|
|
|
i2c_init_clock(i2c_bus, rate);
|
|
|
-#else
|
|
|
- clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
|
|
|
- rate);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
/* Reset I2C controller. */
|
|
@@ -170,7 +138,7 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus)
|
|
|
}
|
|
|
|
|
|
#ifndef CONFIG_TEGRA186
|
|
|
- funcmux_select(i2c_bus->periph_id, i2c_bus->pinmux_config);
|
|
|
+ funcmux_select(i2c_bus->clk.id, i2c_bus->pinmux_config);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
@@ -392,23 +360,13 @@ static int tegra_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
|
|
|
static int tegra_i2c_probe(struct udevice *dev)
|
|
|
{
|
|
|
struct i2c_bus *i2c_bus = dev_get_priv(dev);
|
|
|
-#ifdef CONFIG_TEGRA186
|
|
|
int ret;
|
|
|
-#else
|
|
|
- const void *blob = gd->fdt_blob;
|
|
|
- int node = dev->of_offset;
|
|
|
-#endif
|
|
|
bool is_dvc;
|
|
|
|
|
|
i2c_bus->id = dev->seq;
|
|
|
i2c_bus->type = dev_get_driver_data(dev);
|
|
|
i2c_bus->regs = (struct i2c_ctlr *)dev_get_addr(dev);
|
|
|
|
|
|
- /*
|
|
|
- * We don't have a binding for pinmux yet. Leave it out for now. So
|
|
|
- * far no one needs anything other than the default.
|
|
|
- */
|
|
|
-#ifdef CONFIG_TEGRA186
|
|
|
ret = reset_get_by_name(dev, "i2c", &i2c_bus->reset_ctl);
|
|
|
if (ret) {
|
|
|
error("reset_get_by_name() failed: %d\n", ret);
|
|
@@ -419,9 +377,13 @@ static int tegra_i2c_probe(struct udevice *dev)
|
|
|
error("clk_get_by_name() failed: %d\n", ret);
|
|
|
return ret;
|
|
|
}
|
|
|
-#else
|
|
|
+
|
|
|
+#ifndef CONFIG_TEGRA186
|
|
|
+ /*
|
|
|
+ * We don't have a binding for pinmux yet. Leave it out for now. So
|
|
|
+ * far no one needs anything other than the default.
|
|
|
+ */
|
|
|
i2c_bus->pinmux_config = FUNCMUX_DEFAULT;
|
|
|
- i2c_bus->periph_id = clock_decode_periph_id(blob, node);
|
|
|
|
|
|
/*
|
|
|
* We can't specify the pinmux config in the fdt, so I2C2 will not
|
|
@@ -429,11 +391,9 @@ static int tegra_i2c_probe(struct udevice *dev)
|
|
|
* You could add in this little hack if you need to use it.
|
|
|
* The correct solution is a pinmux binding in the fdt.
|
|
|
*
|
|
|
- * if (i2c_bus->periph_id == PERIPH_ID_I2C2)
|
|
|
+ * if (i2c_bus->clk.id == PERIPH_ID_I2C2)
|
|
|
* i2c_bus->pinmux_config = FUNCMUX_I2C2_PTA;
|
|
|
*/
|
|
|
- if (i2c_bus->periph_id == -1)
|
|
|
- return -EINVAL;
|
|
|
#endif
|
|
|
|
|
|
is_dvc = dev_get_driver_data(dev) == TYPE_DVC;
|
|
@@ -444,14 +404,8 @@ static int tegra_i2c_probe(struct udevice *dev)
|
|
|
i2c_bus->control = &i2c_bus->regs->control;
|
|
|
}
|
|
|
i2c_init_controller(i2c_bus);
|
|
|
- debug("%s: controller bus %d at %p, periph_id %d, speed %d: ",
|
|
|
- is_dvc ? "dvc" : "i2c", dev->seq, i2c_bus->regs,
|
|
|
-#ifndef CONFIG_TEGRA186
|
|
|
- i2c_bus->periph_id,
|
|
|
-#else
|
|
|
- -1,
|
|
|
-#endif
|
|
|
- i2c_bus->speed);
|
|
|
+ debug("%s: controller bus %d at %p, speed %d: ",
|
|
|
+ is_dvc ? "dvc" : "i2c", dev->seq, i2c_bus->regs, i2c_bus->speed);
|
|
|
|
|
|
return 0;
|
|
|
}
|