]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-imx/i2c-mxv7.c
2 * Copyright (C) 2012 Boundary Devices Inc.
4 * SPDX-License-Identifier: GPL-2.0+
8 #include <asm/arch/clock.h>
9 #include <asm/arch/imx-regs.h>
10 #include <linux/errno.h>
12 #include <asm/mach-imx/mxc_i2c.h>
15 int force_idle_bus(void *priv
)
19 ulong elapsed
, start_time
;
20 struct i2c_pads_info
*p
= (struct i2c_pads_info
*)priv
;
23 gpio_direction_input(p
->sda
.gp
);
24 gpio_direction_input(p
->scl
.gp
);
26 imx_iomux_v3_setup_pad(p
->sda
.gpio_mode
);
27 imx_iomux_v3_setup_pad(p
->scl
.gpio_mode
);
29 sda
= gpio_get_value(p
->sda
.gp
);
30 scl
= gpio_get_value(p
->scl
.gp
);
32 goto exit
; /* Bus is idle already */
34 printf("%s: sda=%d scl=%d sda.gp=0x%x scl.gp=0x%x\n", __func__
,
35 sda
, scl
, p
->sda
.gp
, p
->scl
.gp
);
36 /* Send high and low on the SCL line */
37 for (i
= 0; i
< 9; i
++) {
38 gpio_direction_output(p
->scl
.gp
, 0);
40 gpio_direction_input(p
->scl
.gp
);
43 start_time
= get_timer(0);
45 sda
= gpio_get_value(p
->sda
.gp
);
46 scl
= gpio_get_value(p
->scl
.gp
);
50 elapsed
= get_timer(start_time
);
51 if (elapsed
> (CONFIG_SYS_HZ
/ 5)) { /* .2 seconds */
53 printf("%s: failed to clear bus, sda=%d scl=%d\n",
59 imx_iomux_v3_setup_pad(p
->sda
.i2c_mode
);
60 imx_iomux_v3_setup_pad(p
->scl
.i2c_mode
);
64 static void * const i2c_bases
[] = {
65 (void *)I2C1_BASE_ADDR
,
66 (void *)I2C2_BASE_ADDR
,
68 (void *)I2C3_BASE_ADDR
,
71 (void *)I2C4_BASE_ADDR
,
75 /* i2c_index can be from 0 - 3 */
76 int setup_i2c(unsigned i2c_index
, int speed
, int slave_addr
,
77 struct i2c_pads_info
*p
)
82 if (i2c_index
>= ARRAY_SIZE(i2c_bases
))
85 snprintf(name
, sizeof(name
), "i2c_sda%01d", i2c_index
);
86 ret
= gpio_request(p
->sda
.gp
, name
);
90 snprintf(name
, sizeof(name
), "i2c_scl%01d", i2c_index
);
91 ret
= gpio_request(p
->scl
.gp
, name
);
95 /* Enable i2c clock */
96 ret
= enable_i2c_clk(1, i2c_index
);
100 /* Make sure bus is idle */
101 ret
= force_idle_bus(p
);
105 #ifndef CONFIG_DM_I2C
106 bus_i2c_init(i2c_index
, speed
, slave_addr
, force_idle_bus
, p
);
113 gpio_free(p
->scl
.gp
);
115 gpio_free(p
->sda
.gp
);