2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #include <device/mmio.h>
21 #define I2C_CLK_HZ (UNIVPLL_HZ / 20)
23 struct mtk_i2c mtk_i2c_bus_controller
[] = {
26 .i2c_regs
= (void *)(I2C_BASE
+ 0x2000),
27 .i2c_dma_regs
= (void *)(I2C_DMA_BASE
),
32 .i2c_regs
= (void *)(I2C_BASE
+ 0xc000),
33 .i2c_dma_regs
= (void *)(I2C_DMA_BASE
+ 0x400),
38 .i2c_regs
= (void *)(I2C_BASE
+ 0x4000),
39 .i2c_dma_regs
= (void *)(I2C_DMA_BASE
+ 0x200),
44 .i2c_regs
= (void *)(I2C_BASE
+ 0xa000),
45 .i2c_dma_regs
= (void *)(I2C_DMA_BASE
+ 0x380),
50 .i2c_regs
= (void *)(I2C_BASE
+ 0x3000),
51 .i2c_dma_regs
= (void *)(I2C_DMA_BASE
+ 0x80),
56 .i2c_regs
= (void *)(I2C_BASE
+ 0x11000),
57 .i2c_dma_regs
= (void *)(I2C_DMA_BASE
+ 0x480),
62 .i2c_regs
= (void *)(I2C_BASE
),
63 .i2c_dma_regs
= (void *)(I2C_DMA_BASE
+ 0x580),
67 #define I2C_BUS_NUMBER ARRAY_SIZE(mtk_i2c_bus_controller)
74 #define PAD_FUNC(name, func) {GPIO(name), PAD_##name##_FUNC_##func}
76 static const struct pad_func i2c_funcs
[I2C_BUS_NUMBER
][2] = {
102 PAD_FUNC(SDA6
, SDA6
),
103 PAD_FUNC(SCL6
, SCL6
),
107 static void mtk_i2c_set_gpio_pinmux(uint8_t bus
)
109 assert(bus
< I2C_BUS_NUMBER
);
111 const struct pad_func
*ptr
= i2c_funcs
[bus
];
112 for (size_t i
= 0; i
< 2; i
++) {
113 gpio_set_mode(ptr
[i
].gpio
, ptr
[i
].func
);
114 gpio_set_pull(ptr
[i
].gpio
, GPIO_PULL_ENABLE
, GPIO_PULL_UP
);
118 static void mtk_i2c_speed_init(uint8_t bus
)
121 const uint8_t clock_div
= 5;
122 const uint8_t sample_div
= 1;
125 assert(bus
< ARRAY_SIZE(mtk_i2c_bus_controller
));
127 /* Calculate i2c frequency */
128 step_div
= DIV_ROUND_UP(I2C_CLK_HZ
,
129 (400 * KHz
* sample_div
* 2) * clock_div
);
130 i2c_freq
= I2C_CLK_HZ
/ (step_div
* sample_div
* 2 * clock_div
);
131 assert(sample_div
< 8 && step_div
< 64 && i2c_freq
<= 400 * KHz
&&
132 i2c_freq
>= 380 * KHz
);
134 /* Init i2c bus Timing register */
135 write32(&mtk_i2c_bus_controller
[bus
].i2c_regs
->timing
,
136 (sample_div
- 1) << 8 | (step_div
- 1));
137 write32(&mtk_i2c_bus_controller
[bus
].i2c_regs
->ltiming
,
138 (sample_div
- 1) << 6 | (step_div
- 1));
140 /* Init i2c bus clock_div register */
141 write32(&mtk_i2c_bus_controller
[bus
].i2c_regs
->clock_div
,
145 void mtk_i2c_bus_init(uint8_t bus
)
147 mtk_i2c_speed_init(bus
);
148 mtk_i2c_set_gpio_pinmux(bus
);