@ -12,27 +12,15 @@
# include <fdtdec.h>
# include <fdtdec.h>
# include <i2c.h>
# include <i2c.h>
# include <asm/io.h>
# include <asm/io.h>
# ifdef CONFIG_TEGRA186
# include <clk.h>
# include <clk.h>
# include <reset.h>
# include <reset.h>
# else
# ifndef CONFIG_TEGRA186
# include <asm/arch/clock.h>
# include <asm/arch/clock.h>
# include <asm/arch/funcmux.h>
# include <asm/arch/funcmux.h>
# include <asm/arch/pinmux.h>
# include <asm/arch-tegra/clk_rst.h>
# endif
# endif
# include <asm/arch/gpio.h>
# include <asm/arch/gpio.h>
# include <asm/arch-tegra/tegra_i2c.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 ;
DECLARE_GLOBAL_DATA_PTR ;
enum i2c_type {
enum i2c_type {
@ -44,12 +32,8 @@ enum i2c_type {
/* Information about i2c controller */
/* Information about i2c controller */
struct i2c_bus {
struct i2c_bus {
int id ;
int id ;
# ifdef CONFIG_TEGRA186
struct reset_ctl reset_ctl ;
struct reset_ctl reset_ctl ;
struct clk clk ;
struct clk clk ;
# else
enum periph_id periph_id ;
# endif
int speed ;
int speed ;
int pinmux_config ;
int pinmux_config ;
struct i2c_control * control ;
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 )
static void i2c_reset_controller ( struct i2c_bus * i2c_bus )
{
{
/* Reset I2C controller. */
/* Reset I2C controller. */
# ifdef CONFIG_TEGRA186
reset_assert ( & i2c_bus - > reset_ctl ) ;
reset_assert ( & i2c_bus - > reset_ctl ) ;
udelay ( 1 ) ;
udelay ( 1 ) ;
reset_deassert ( & i2c_bus - > reset_ctl ) ;
reset_deassert ( & i2c_bus - > reset_ctl ) ;
udelay ( 1 ) ;
udelay ( 1 ) ;
# else
reset_periph ( i2c_bus - > periph_id , 1 ) ;
# endif
/* re-program config register to packet mode */
/* re-program config register to packet mode */
set_packet_mode ( i2c_bus ) ;
set_packet_mode ( i2c_bus ) ;
}
}
# ifdef CONFIG_TEGRA186
static int i2c_init_clock ( struct i2c_bus * i2c_bus , unsigned rate )
static int i2c_init_clock ( struct i2c_bus * i2c_bus , unsigned rate )
{
{
int ret ;
int ret ;
@ -114,7 +93,6 @@ static int i2c_init_clock(struct i2c_bus *i2c_bus, unsigned rate)
return 0 ;
return 0 ;
}
}
# endif
static void i2c_init_controller ( struct i2c_bus * i2c_bus )
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
* here , in section 23.3 .1 , but in fact we seem to need a factor of
* 16 to get the right frequency .
* 16 to get the right frequency .
*/
*/
# ifdef CONFIG_TEGRA186
i2c_init_clock ( i2c_bus , i2c_bus - > speed * 2 * 8 ) ;
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 ) {
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__ ,
debug ( " %s: CLK_DIV_STD_FAST_MODE setting = %d \n " , __func__ ,
clk_div_stdfst_mode ) ;
clk_div_stdfst_mode ) ;
# ifdef CONFIG_TEGRA186
i2c_init_clock ( i2c_bus , rate ) ;
i2c_init_clock ( i2c_bus , rate ) ;
# else
clock_start_periph_pll ( i2c_bus - > periph_id , CLOCK_ID_PERIPH ,
rate ) ;
# endif
}
}
/* Reset I2C controller. */
/* Reset I2C controller. */
@ -170,7 +138,7 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus)
}
}
# ifndef CONFIG_TEGRA186
# ifndef CONFIG_TEGRA186
funcmux_select ( i2c_bus - > periph_ id, i2c_bus - > pinmux_config ) ;
funcmux_select ( i2c_bus - > clk . id , i2c_bus - > pinmux_config ) ;
# endif
# 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 )
static int tegra_i2c_probe ( struct udevice * dev )
{
{
struct i2c_bus * i2c_bus = dev_get_priv ( dev ) ;
struct i2c_bus * i2c_bus = dev_get_priv ( dev ) ;
# ifdef CONFIG_TEGRA186
int ret ;
int ret ;
# else
const void * blob = gd - > fdt_blob ;
int node = dev - > of_offset ;
# endif
bool is_dvc ;
bool is_dvc ;
i2c_bus - > id = dev - > seq ;
i2c_bus - > id = dev - > seq ;
i2c_bus - > type = dev_get_driver_data ( dev ) ;
i2c_bus - > type = dev_get_driver_data ( dev ) ;
i2c_bus - > regs = ( struct i2c_ctlr * ) dev_get_addr ( 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 ) ;
ret = reset_get_by_name ( dev , " i2c " , & i2c_bus - > reset_ctl ) ;
if ( ret ) {
if ( ret ) {
error ( " reset_get_by_name() failed: %d \n " , 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 ) ;
error ( " clk_get_by_name() failed: %d \n " , ret ) ;
return 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 - > 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
* 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 .
* You could add in this little hack if you need to use it .
* The correct solution is a pinmux binding in the fdt .
* 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 ;
* i2c_bus - > pinmux_config = FUNCMUX_I2C2_PTA ;
*/
*/
if ( i2c_bus - > periph_id = = - 1 )
return - EINVAL ;
# endif
# endif
is_dvc = dev_get_driver_data ( dev ) = = TYPE_DVC ;
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_bus - > control = & i2c_bus - > regs - > control ;
}
}
i2c_init_controller ( i2c_bus ) ;
i2c_init_controller ( i2c_bus ) ;
debug ( " %s: controller bus %d at %p, periph_id %d, speed %d: " ,
debug ( " %s: controller bus %d at %p, speed %d: " ,
is_dvc ? " dvc " : " i2c " , dev - > seq , i2c_bus - > regs ,
is_dvc ? " dvc " : " i2c " , dev - > seq , i2c_bus - > regs , i2c_bus - > speed ) ;
# ifndef CONFIG_TEGRA186
i2c_bus - > periph_id ,
# else
- 1 ,
# endif
i2c_bus - > speed ) ;
return 0 ;
return 0 ;
}
}