blob: eab49d09bab341a1fe39f7f7418ce23015d925d3 [file] [log] [blame]
wdenk1fe2c702003-03-06 21:55:29 +00001/*
2 * (C) Copyright 2002
3 * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
4 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
wdenk1fe2c702003-03-06 21:55:29 +00006 */
7
8/* This code should work for both the S3C2400 and the S3C2410
9 * as they seem to have the same I2C controller inside.
10 * The different address mapping is handled by the s3c24xx.h files below.
11 */
wdenk1fe2c702003-03-06 21:55:29 +000012#include <common.h>
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +010013#include <errno.h>
14#include <dm.h>
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +000015#include <fdtdec.h>
Piotr Wilczekb35cd1c2012-11-20 02:19:05 +000016#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +000017#include <asm/arch/clk.h>
18#include <asm/arch/cpu.h>
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +000019#include <asm/arch/pinmux.h>
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +000020#else
kevin.morfitt@fearnside-systems.co.uke0d81312009-11-17 18:30:34 +090021#include <asm/arch/s3c24x0_cpu.h>
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +000022#endif
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +090023#include <asm/io.h>
wdenk1fe2c702003-03-06 21:55:29 +000024#include <i2c.h>
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +000025#include "s3c24x0_i2c.h"
wdenk1fe2c702003-03-06 21:55:29 +000026
wdenk7539dea2003-06-19 23:01:32 +000027#define I2C_WRITE 0
28#define I2C_READ 1
wdenk1fe2c702003-03-06 21:55:29 +000029
wdenk7539dea2003-06-19 23:01:32 +000030#define I2C_OK 0
31#define I2C_NOK 1
32#define I2C_NACK 2
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +090033#define I2C_NOK_LA 3 /* Lost arbitration */
34#define I2C_NOK_TOUT 4 /* time out */
wdenk1fe2c702003-03-06 21:55:29 +000035
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +053036/* HSI2C specific register description */
37
38/* I2C_CTL Register bits */
39#define HSI2C_FUNC_MODE_I2C (1u << 0)
40#define HSI2C_MASTER (1u << 3)
41#define HSI2C_RXCHON (1u << 6) /* Write/Send */
42#define HSI2C_TXCHON (1u << 7) /* Read/Receive */
43#define HSI2C_SW_RST (1u << 31)
44
45/* I2C_FIFO_CTL Register bits */
46#define HSI2C_RXFIFO_EN (1u << 0)
47#define HSI2C_TXFIFO_EN (1u << 1)
48#define HSI2C_TXFIFO_TRIGGER_LEVEL (0x20 << 16)
49#define HSI2C_RXFIFO_TRIGGER_LEVEL (0x20 << 4)
50
51/* I2C_TRAILING_CTL Register bits */
52#define HSI2C_TRAILING_COUNT (0xff)
53
54/* I2C_INT_EN Register bits */
55#define HSI2C_TX_UNDERRUN_EN (1u << 2)
56#define HSI2C_TX_OVERRUN_EN (1u << 3)
57#define HSI2C_RX_UNDERRUN_EN (1u << 4)
58#define HSI2C_RX_OVERRUN_EN (1u << 5)
59#define HSI2C_INT_TRAILING_EN (1u << 6)
60#define HSI2C_INT_I2C_EN (1u << 9)
61
62#define HSI2C_INT_ERROR_MASK (HSI2C_TX_UNDERRUN_EN |\
63 HSI2C_TX_OVERRUN_EN |\
64 HSI2C_RX_UNDERRUN_EN |\
65 HSI2C_RX_OVERRUN_EN |\
66 HSI2C_INT_TRAILING_EN)
67
68/* I2C_CONF Register bits */
69#define HSI2C_AUTO_MODE (1u << 31)
70#define HSI2C_10BIT_ADDR_MODE (1u << 30)
71#define HSI2C_HS_MODE (1u << 29)
72
73/* I2C_AUTO_CONF Register bits */
74#define HSI2C_READ_WRITE (1u << 16)
75#define HSI2C_STOP_AFTER_TRANS (1u << 17)
76#define HSI2C_MASTER_RUN (1u << 31)
77
78/* I2C_TIMEOUT Register bits */
79#define HSI2C_TIMEOUT_EN (1u << 31)
80
81/* I2C_TRANS_STATUS register bits */
82#define HSI2C_MASTER_BUSY (1u << 17)
83#define HSI2C_SLAVE_BUSY (1u << 16)
84#define HSI2C_TIMEOUT_AUTO (1u << 4)
85#define HSI2C_NO_DEV (1u << 3)
86#define HSI2C_NO_DEV_ACK (1u << 2)
87#define HSI2C_TRANS_ABORT (1u << 1)
88#define HSI2C_TRANS_SUCCESS (1u << 0)
89#define HSI2C_TRANS_ERROR_MASK (HSI2C_TIMEOUT_AUTO |\
90 HSI2C_NO_DEV | HSI2C_NO_DEV_ACK |\
91 HSI2C_TRANS_ABORT)
92#define HSI2C_TRANS_FINISHED_MASK (HSI2C_TRANS_ERROR_MASK | HSI2C_TRANS_SUCCESS)
93
94
95/* I2C_FIFO_STAT Register bits */
96#define HSI2C_RX_FIFO_EMPTY (1u << 24)
97#define HSI2C_RX_FIFO_FULL (1u << 23)
98#define HSI2C_TX_FIFO_EMPTY (1u << 8)
99#define HSI2C_TX_FIFO_FULL (1u << 7)
100#define HSI2C_RX_FIFO_LEVEL(x) (((x) >> 16) & 0x7f)
101#define HSI2C_TX_FIFO_LEVEL(x) ((x) & 0x7f)
102
103#define HSI2C_SLV_ADDR_MAS(x) ((x & 0x3ff) << 10)
104
105/* S3C I2C Controller bits */
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900106#define I2CSTAT_BSY 0x20 /* Busy bit */
107#define I2CSTAT_NACK 0x01 /* Nack bit */
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000108#define I2CCON_ACKGEN 0x80 /* Acknowledge generation */
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900109#define I2CCON_IRPND 0x10 /* Interrupt pending bit */
110#define I2C_MODE_MT 0xC0 /* Master Transmit Mode */
111#define I2C_MODE_MR 0x80 /* Master Receive Mode */
112#define I2C_START_STOP 0x20 /* START / STOP */
113#define I2C_TXRX_ENA 0x10 /* I2C Tx/Rx enable */
wdenk1fe2c702003-03-06 21:55:29 +0000114
Przemyslaw Marczaka99827f2015-01-27 13:36:35 +0100115#define I2C_TIMEOUT_MS 10 /* 10 ms */
wdenk1fe2c702003-03-06 21:55:29 +0000116
Przemyslaw Marczaka99827f2015-01-27 13:36:35 +0100117#define HSI2C_TIMEOUT_US 10000 /* 10 ms, finer granularity */
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530118
119
120/* To support VCMA9 boards and other who dont define max_i2c_num */
121#ifndef CONFIG_MAX_I2C_NUM
122#define CONFIG_MAX_I2C_NUM 1
123#endif
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000124
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100125DECLARE_GLOBAL_DATA_PTR;
126
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +0000127/*
128 * For SPL boot some boards need i2c before SDRAM is initialised so force
129 * variables to live in SRAM
130 */
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100131#ifdef CONFIG_SYS_I2C
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +0000132static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
133 __attribute__((section(".data")));
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100134#endif
135
136enum exynos_i2c_type {
137 EXYNOS_I2C_STD,
138 EXYNOS_I2C_HS,
139};
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530140
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100141#ifdef CONFIG_SYS_I2C
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530142/**
143 * Get a pointer to the given bus index
144 *
145 * @bus_idx: Bus index to look up
146 * @return pointer to bus, or NULL if invalid or not available
147 */
148static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx)
149{
150 if (bus_idx < ARRAY_SIZE(i2c_bus)) {
151 struct s3c24x0_i2c_bus *bus;
152
153 bus = &i2c_bus[bus_idx];
154 if (bus->active)
155 return bus;
156 }
157
158 debug("Undefined bus: %d\n", bus_idx);
159 return NULL;
160}
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100161#endif
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000162
Piotr Wilczekb35cd1c2012-11-20 02:19:05 +0000163#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
wdenk7539dea2003-06-19 23:01:32 +0000164static int GetI2CSDA(void)
wdenk1fe2c702003-03-06 21:55:29 +0000165{
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900166 struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
wdenk7539dea2003-06-19 23:01:32 +0000167
Marek Vasut4e922372014-10-11 18:42:56 +0200168#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
C Nauman383c43e2010-10-26 23:04:31 +0900169 return (readl(&gpio->gpedat) & 0x8000) >> 15;
wdenkca9bc762003-07-15 07:45:49 +0000170#endif
171#ifdef CONFIG_S3C2400
C Nauman383c43e2010-10-26 23:04:31 +0900172 return (readl(&gpio->pgdat) & 0x0020) >> 5;
wdenkca9bc762003-07-15 07:45:49 +0000173#endif
wdenk1fe2c702003-03-06 21:55:29 +0000174}
175
wdenk7539dea2003-06-19 23:01:32 +0000176static void SetI2CSCL(int x)
wdenk1fe2c702003-03-06 21:55:29 +0000177{
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900178 struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
wdenk7539dea2003-06-19 23:01:32 +0000179
Marek Vasut4e922372014-10-11 18:42:56 +0200180#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000181 writel((readl(&gpio->gpedat) & ~0x4000) |
182 (x & 1) << 14, &gpio->gpedat);
wdenkca9bc762003-07-15 07:45:49 +0000183#endif
184#ifdef CONFIG_S3C2400
C Nauman383c43e2010-10-26 23:04:31 +0900185 writel((readl(&gpio->pgdat) & ~0x0040) | (x & 1) << 6, &gpio->pgdat);
wdenkca9bc762003-07-15 07:45:49 +0000186#endif
wdenk1fe2c702003-03-06 21:55:29 +0000187}
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000188#endif
wdenk1fe2c702003-03-06 21:55:29 +0000189
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530190/*
191 * Wait til the byte transfer is completed.
192 *
193 * @param i2c- pointer to the appropriate i2c register bank.
194 * @return I2C_OK, if transmission was ACKED
195 * I2C_NACK, if transmission was NACKED
196 * I2C_NOK_TIMEOUT, if transaction did not complete in I2C_TIMEOUT_MS
197 */
198
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000199static int WaitForXfer(struct s3c24x0_i2c *i2c)
wdenk1fe2c702003-03-06 21:55:29 +0000200{
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530201 ulong start_time = get_timer(0);
wdenk1fe2c702003-03-06 21:55:29 +0000202
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530203 do {
204 if (readl(&i2c->iiccon) & I2CCON_IRPND)
205 return (readl(&i2c->iicstat) & I2CSTAT_NACK) ?
206 I2C_NACK : I2C_OK;
207 } while (get_timer(start_time) < I2C_TIMEOUT_MS);
wdenk1fe2c702003-03-06 21:55:29 +0000208
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530209 return I2C_NOK_TOUT;
wdenk1fe2c702003-03-06 21:55:29 +0000210}
211
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530212/*
213 * Wait for transfer completion.
214 *
215 * This function reads the interrupt status register waiting for the INT_I2C
216 * bit to be set, which indicates copletion of a transaction.
217 *
218 * @param i2c: pointer to the appropriate register bank
219 *
220 * @return: I2C_OK in case of successful completion, I2C_NOK_TIMEOUT in case
221 * the status bits do not get set in time, or an approrpiate error
222 * value in case of transfer errors.
223 */
224static int hsi2c_wait_for_trx(struct exynos5_hsi2c *i2c)
225{
226 int i = HSI2C_TIMEOUT_US;
227
228 while (i-- > 0) {
229 u32 int_status = readl(&i2c->usi_int_stat);
230
231 if (int_status & HSI2C_INT_I2C_EN) {
232 u32 trans_status = readl(&i2c->usi_trans_status);
233
234 /* Deassert pending interrupt. */
235 writel(int_status, &i2c->usi_int_stat);
236
237 if (trans_status & HSI2C_NO_DEV_ACK) {
238 debug("%s: no ACK from device\n", __func__);
239 return I2C_NACK;
240 }
241 if (trans_status & HSI2C_NO_DEV) {
242 debug("%s: no device\n", __func__);
243 return I2C_NOK;
244 }
245 if (trans_status & HSI2C_TRANS_ABORT) {
246 debug("%s: arbitration lost\n", __func__);
247 return I2C_NOK_LA;
248 }
249 if (trans_status & HSI2C_TIMEOUT_AUTO) {
250 debug("%s: device timed out\n", __func__);
251 return I2C_NOK_TOUT;
252 }
253 return I2C_OK;
254 }
255 udelay(1);
256 }
257 debug("%s: transaction timeout!\n", __func__);
258 return I2C_NOK_TOUT;
259}
260
Simon Glass824802d2015-07-02 18:15:46 -0600261static void read_write_byte(struct s3c24x0_i2c *i2c)
wdenk1fe2c702003-03-06 21:55:29 +0000262{
Simon Glass824802d2015-07-02 18:15:46 -0600263 clrbits_le32(&i2c->iiccon, I2CCON_IRPND);
wdenk1fe2c702003-03-06 21:55:29 +0000264}
265
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100266#ifdef CONFIG_SYS_I2C
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100267static struct s3c24x0_i2c *get_base_i2c(int bus)
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000268{
Piotr Wilczekb35cd1c2012-11-20 02:19:05 +0000269#ifdef CONFIG_EXYNOS4
270 struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()
271 + (EXYNOS4_I2C_SPACING
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100272 * bus));
Piotr Wilczekb35cd1c2012-11-20 02:19:05 +0000273 return i2c;
274#elif defined CONFIG_EXYNOS5
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000275 struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()
276 + (EXYNOS5_I2C_SPACING
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100277 * bus));
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000278 return i2c;
279#else
280 return s3c24x0_get_base_i2c();
281#endif
282}
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100283#endif
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000284
285static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
286{
287 ulong freq, pres = 16, div;
Piotr Wilczekb35cd1c2012-11-20 02:19:05 +0000288#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000289 freq = get_i2c_clk();
290#else
291 freq = get_PCLK();
292#endif
293 /* calculate prescaler and divisor values */
294 if ((freq / pres / (16 + 1)) > speed)
295 /* set prescaler to 512 */
296 pres = 512;
297
298 div = 0;
299 while ((freq / pres / (div + 1)) > speed)
300 div++;
301
302 /* set prescaler, divisor according to freq, also set ACKGEN, IRQ */
303 writel((div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0), &i2c->iiccon);
304
305 /* init to SLAVE REVEIVE and set slaveaddr */
306 writel(0, &i2c->iicstat);
307 writel(slaveadd, &i2c->iicadd);
308 /* program Master Transmit (and implicit STOP) */
309 writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);
310}
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530311
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530312static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)
313{
314 struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
315 ulong clkin;
316 unsigned int op_clk = i2c_bus->clock_frequency;
317 unsigned int i = 0, utemp0 = 0, utemp1 = 0;
318 unsigned int t_ftl_cycle;
319
Piotr Wilczeka7bae152013-11-20 10:43:50 +0100320#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530321 clkin = get_i2c_clk();
Piotr Wilczeka7bae152013-11-20 10:43:50 +0100322#else
323 clkin = get_PCLK();
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530324#endif
325 /* FPCLK / FI2C =
326 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE
327 * uTemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
328 * uTemp1 = (TSCLK_L + TSCLK_H + 2)
329 * uTemp2 = TSCLK_L + TSCLK_H
330 */
331 t_ftl_cycle = (readl(&hsregs->usi_conf) >> 16) & 0x7;
332 utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle;
333
334 /* CLK_DIV max is 256 */
335 for (i = 0; i < 256; i++) {
336 utemp1 = utemp0 / (i + 1);
337 if ((utemp1 < 512) && (utemp1 > 4)) {
338 i2c_bus->clk_cycle = utemp1 - 2;
339 i2c_bus->clk_div = i;
340 return 0;
341 }
342 }
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100343 return -EINVAL;
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530344}
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530345
346static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus)
347{
348 struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
349 unsigned int t_sr_release;
350 unsigned int n_clkdiv;
351 unsigned int t_start_su, t_start_hd;
352 unsigned int t_stop_su;
353 unsigned int t_data_su, t_data_hd;
354 unsigned int t_scl_l, t_scl_h;
355 u32 i2c_timing_s1;
356 u32 i2c_timing_s2;
357 u32 i2c_timing_s3;
358 u32 i2c_timing_sla;
359
360 n_clkdiv = i2c_bus->clk_div;
361 t_scl_l = i2c_bus->clk_cycle / 2;
362 t_scl_h = i2c_bus->clk_cycle / 2;
363 t_start_su = t_scl_l;
364 t_start_hd = t_scl_l;
365 t_stop_su = t_scl_l;
366 t_data_su = t_scl_l / 2;
367 t_data_hd = t_scl_l / 2;
368 t_sr_release = i2c_bus->clk_cycle;
369
370 i2c_timing_s1 = t_start_su << 24 | t_start_hd << 16 | t_stop_su << 8;
371 i2c_timing_s2 = t_data_su << 24 | t_scl_l << 8 | t_scl_h << 0;
372 i2c_timing_s3 = n_clkdiv << 16 | t_sr_release << 0;
373 i2c_timing_sla = t_data_hd << 0;
374
375 writel(HSI2C_TRAILING_COUNT, &hsregs->usi_trailing_ctl);
376
377 /* Clear to enable Timeout */
378 clrsetbits_le32(&hsregs->usi_timeout, HSI2C_TIMEOUT_EN, 0);
379
380 /* set AUTO mode */
381 writel(readl(&hsregs->usi_conf) | HSI2C_AUTO_MODE, &hsregs->usi_conf);
382
383 /* Enable completion conditions' reporting. */
384 writel(HSI2C_INT_I2C_EN, &hsregs->usi_int_en);
385
386 /* Enable FIFOs */
387 writel(HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN, &hsregs->usi_fifo_ctl);
388
389 /* Currently operating in Fast speed mode. */
390 writel(i2c_timing_s1, &hsregs->usi_timing_fs1);
391 writel(i2c_timing_s2, &hsregs->usi_timing_fs2);
392 writel(i2c_timing_s3, &hsregs->usi_timing_fs3);
393 writel(i2c_timing_sla, &hsregs->usi_timing_sla);
394}
395
396/* SW reset for the high speed bus */
397static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus)
398{
399 struct exynos5_hsi2c *i2c = i2c_bus->hsregs;
400 u32 i2c_ctl;
401
402 /* Set and clear the bit for reset */
403 i2c_ctl = readl(&i2c->usi_ctl);
404 i2c_ctl |= HSI2C_SW_RST;
405 writel(i2c_ctl, &i2c->usi_ctl);
406
407 i2c_ctl = readl(&i2c->usi_ctl);
408 i2c_ctl &= ~HSI2C_SW_RST;
409 writel(i2c_ctl, &i2c->usi_ctl);
410
411 /* Initialize the configure registers */
412 hsi2c_ch_init(i2c_bus);
413}
Rajeshwari Shindec07c11d2012-07-23 21:23:54 +0000414
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100415#ifdef CONFIG_SYS_I2C
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100416static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
wdenk1fe2c702003-03-06 21:55:29 +0000417{
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000418 struct s3c24x0_i2c *i2c;
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100419 struct s3c24x0_i2c_bus *bus;
Piotr Wilczekb35cd1c2012-11-20 02:19:05 +0000420#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900421 struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000422#endif
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530423 ulong start_time = get_timer(0);
wdenk1fe2c702003-03-06 21:55:29 +0000424
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100425 i2c = get_base_i2c(adap->hwadapnr);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100426 bus = &i2c_bus[adap->hwadapnr];
427 if (!bus)
428 return;
wdenk1fe2c702003-03-06 21:55:29 +0000429
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530430 /*
431 * In case the previous transfer is still going, wait to give it a
432 * chance to finish.
433 */
434 while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
435 if (get_timer(start_time) > I2C_TIMEOUT_MS) {
436 printf("%s: I2C bus busy for %p\n", __func__,
437 &i2c->iicstat);
438 return;
439 }
wdenk49c3f672003-10-08 22:33:00 +0000440 }
wdenk1fe2c702003-03-06 21:55:29 +0000441
Piotr Wilczekb35cd1c2012-11-20 02:19:05 +0000442#if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530443 int i;
444
C Nauman383c43e2010-10-26 23:04:31 +0900445 if ((readl(&i2c->iicstat) & I2CSTAT_BSY) || GetI2CSDA() == 0) {
Marek Vasut4e922372014-10-11 18:42:56 +0200446#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
C Nauman383c43e2010-10-26 23:04:31 +0900447 ulong old_gpecon = readl(&gpio->gpecon);
wdenkca9bc762003-07-15 07:45:49 +0000448#endif
449#ifdef CONFIG_S3C2400
C Nauman383c43e2010-10-26 23:04:31 +0900450 ulong old_gpecon = readl(&gpio->pgcon);
wdenkca9bc762003-07-15 07:45:49 +0000451#endif
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900452 /* bus still busy probably by (most) previously interrupted
453 transfer */
wdenk1fe2c702003-03-06 21:55:29 +0000454
Marek Vasut4e922372014-10-11 18:42:56 +0200455#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
wdenk49c3f672003-10-08 22:33:00 +0000456 /* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */
C Nauman383c43e2010-10-26 23:04:31 +0900457 writel((readl(&gpio->gpecon) & ~0xF0000000) | 0x10000000,
458 &gpio->gpecon);
wdenkca9bc762003-07-15 07:45:49 +0000459#endif
460#ifdef CONFIG_S3C2400
wdenk49c3f672003-10-08 22:33:00 +0000461 /* set I2CSDA and I2CSCL (PG5, PG6) to GPIO */
C Nauman383c43e2010-10-26 23:04:31 +0900462 writel((readl(&gpio->pgcon) & ~0x00003c00) | 0x00001000,
463 &gpio->pgcon);
wdenkca9bc762003-07-15 07:45:49 +0000464#endif
wdenk1fe2c702003-03-06 21:55:29 +0000465
wdenk49c3f672003-10-08 22:33:00 +0000466 /* toggle I2CSCL until bus idle */
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900467 SetI2CSCL(0);
468 udelay(1000);
wdenk49c3f672003-10-08 22:33:00 +0000469 i = 10;
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900470 while ((i > 0) && (GetI2CSDA() != 1)) {
471 SetI2CSCL(1);
472 udelay(1000);
473 SetI2CSCL(0);
474 udelay(1000);
wdenk49c3f672003-10-08 22:33:00 +0000475 i--;
476 }
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900477 SetI2CSCL(1);
478 udelay(1000);
wdenk1fe2c702003-03-06 21:55:29 +0000479
wdenk49c3f672003-10-08 22:33:00 +0000480 /* restore pin functions */
Marek Vasut4e922372014-10-11 18:42:56 +0200481#if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
C Nauman383c43e2010-10-26 23:04:31 +0900482 writel(old_gpecon, &gpio->gpecon);
wdenkca9bc762003-07-15 07:45:49 +0000483#endif
484#ifdef CONFIG_S3C2400
C Nauman383c43e2010-10-26 23:04:31 +0900485 writel(old_gpecon, &gpio->pgcon);
wdenkca9bc762003-07-15 07:45:49 +0000486#endif
wdenk49c3f672003-10-08 22:33:00 +0000487 }
Piotr Wilczekb35cd1c2012-11-20 02:19:05 +0000488#endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100489
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000490 i2c_ch_init(i2c, speed, slaveadd);
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100491
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100492 bus->active = true;
493 bus->regs = i2c;
wdenk1fe2c702003-03-06 21:55:29 +0000494}
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100495#endif /* CONFIG_SYS_I2C */
wdenk1fe2c702003-03-06 21:55:29 +0000496
497/*
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530498 * Poll the appropriate bit of the fifo status register until the interface is
499 * ready to process the next byte or timeout expires.
500 *
501 * In addition to the FIFO status register this function also polls the
502 * interrupt status register to be able to detect unexpected transaction
503 * completion.
504 *
505 * When FIFO is ready to process the next byte, this function returns I2C_OK.
506 * If in course of polling the INT_I2C assertion is detected, the function
507 * returns I2C_NOK. If timeout happens before any of the above conditions is
508 * met - the function returns I2C_NOK_TOUT;
509
510 * @param i2c: pointer to the appropriate i2c register bank.
511 * @param rx_transfer: set to True if the receive transaction is in progress.
512 * @return: as described above.
513 */
514static unsigned hsi2c_poll_fifo(struct exynos5_hsi2c *i2c, bool rx_transfer)
515{
516 u32 fifo_bit = rx_transfer ? HSI2C_RX_FIFO_EMPTY : HSI2C_TX_FIFO_FULL;
517 int i = HSI2C_TIMEOUT_US;
518
519 while (readl(&i2c->usi_fifo_stat) & fifo_bit) {
520 if (readl(&i2c->usi_int_stat) & HSI2C_INT_I2C_EN) {
521 /*
522 * There is a chance that assertion of
523 * HSI2C_INT_I2C_EN and deassertion of
524 * HSI2C_RX_FIFO_EMPTY happen simultaneously. Let's
525 * give FIFO status priority and check it one more
526 * time before reporting interrupt. The interrupt will
527 * be reported next time this function is called.
528 */
529 if (rx_transfer &&
530 !(readl(&i2c->usi_fifo_stat) & fifo_bit))
531 break;
532 return I2C_NOK;
533 }
534 if (!i--) {
535 debug("%s: FIFO polling timeout!\n", __func__);
536 return I2C_NOK_TOUT;
537 }
538 udelay(1);
539 }
540 return I2C_OK;
541}
542
543/*
544 * Preapre hsi2c transaction, either read or write.
545 *
546 * Set up transfer as described in section 27.5.1.2 'I2C Channel Auto Mode' of
547 * the 5420 UM.
548 *
549 * @param i2c: pointer to the appropriate i2c register bank.
550 * @param chip: slave address on the i2c bus (with read/write bit exlcuded)
551 * @param len: number of bytes expected to be sent or received
552 * @param rx_transfer: set to true for receive transactions
553 * @param: issue_stop: set to true if i2c stop condition should be generated
554 * after this transaction.
555 * @return: I2C_NOK_TOUT in case the bus remained busy for HSI2C_TIMEOUT_US,
556 * I2C_OK otherwise.
557 */
558static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c,
559 u8 chip,
560 u16 len,
561 bool rx_transfer,
562 bool issue_stop)
563{
564 u32 conf;
565
566 conf = len | HSI2C_MASTER_RUN;
567
568 if (issue_stop)
569 conf |= HSI2C_STOP_AFTER_TRANS;
570
571 /* Clear to enable Timeout */
572 writel(readl(&i2c->usi_timeout) & ~HSI2C_TIMEOUT_EN, &i2c->usi_timeout);
573
574 /* Set slave address */
575 writel(HSI2C_SLV_ADDR_MAS(chip), &i2c->i2c_addr);
576
577 if (rx_transfer) {
578 /* i2c master, read transaction */
579 writel((HSI2C_RXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER),
580 &i2c->usi_ctl);
581
582 /* read up to len bytes, stop after transaction is finished */
583 writel(conf | HSI2C_READ_WRITE, &i2c->usi_auto_conf);
584 } else {
585 /* i2c master, write transaction */
586 writel((HSI2C_TXCHON | HSI2C_FUNC_MODE_I2C | HSI2C_MASTER),
587 &i2c->usi_ctl);
588
589 /* write up to len bytes, stop after transaction is finished */
590 writel(conf, &i2c->usi_auto_conf);
591 }
592
593 /* Reset all pending interrupt status bits we care about, if any */
594 writel(HSI2C_INT_I2C_EN, &i2c->usi_int_stat);
595
596 return I2C_OK;
597}
598
599/*
600 * Wait while i2c bus is settling down (mostly stop gets completed).
601 */
602static int hsi2c_wait_while_busy(struct exynos5_hsi2c *i2c)
603{
604 int i = HSI2C_TIMEOUT_US;
605
606 while (readl(&i2c->usi_trans_status) & HSI2C_MASTER_BUSY) {
607 if (!i--) {
608 debug("%s: bus busy\n", __func__);
609 return I2C_NOK_TOUT;
610 }
611 udelay(1);
612 }
613 return I2C_OK;
614}
615
616static int hsi2c_write(struct exynos5_hsi2c *i2c,
617 unsigned char chip,
618 unsigned char addr[],
619 unsigned char alen,
620 unsigned char data[],
621 unsigned short len,
622 bool issue_stop)
623{
624 int i, rv = 0;
625
626 if (!(len + alen)) {
627 /* Writes of zero length not supported in auto mode. */
628 debug("%s: zero length writes not supported\n", __func__);
629 return I2C_NOK;
630 }
631
632 rv = hsi2c_prepare_transaction
633 (i2c, chip, len + alen, false, issue_stop);
634 if (rv != I2C_OK)
635 return rv;
636
637 /* Move address, if any, and the data, if any, into the FIFO. */
638 for (i = 0; i < alen; i++) {
639 rv = hsi2c_poll_fifo(i2c, false);
640 if (rv != I2C_OK) {
641 debug("%s: address write failed\n", __func__);
642 goto write_error;
643 }
644 writel(addr[i], &i2c->usi_txdata);
645 }
646
647 for (i = 0; i < len; i++) {
648 rv = hsi2c_poll_fifo(i2c, false);
649 if (rv != I2C_OK) {
650 debug("%s: data write failed\n", __func__);
651 goto write_error;
652 }
653 writel(data[i], &i2c->usi_txdata);
654 }
655
656 rv = hsi2c_wait_for_trx(i2c);
657
658 write_error:
659 if (issue_stop) {
660 int tmp_ret = hsi2c_wait_while_busy(i2c);
661 if (rv == I2C_OK)
662 rv = tmp_ret;
663 }
664
665 writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */
666 return rv;
667}
668
669static int hsi2c_read(struct exynos5_hsi2c *i2c,
670 unsigned char chip,
671 unsigned char addr[],
672 unsigned char alen,
673 unsigned char data[],
674 unsigned short len)
675{
676 int i, rv, tmp_ret;
677 bool drop_data = false;
678
679 if (!len) {
680 /* Reads of zero length not supported in auto mode. */
681 debug("%s: zero length read adjusted\n", __func__);
682 drop_data = true;
683 len = 1;
684 }
685
686 if (alen) {
687 /* Internal register adress needs to be written first. */
688 rv = hsi2c_write(i2c, chip, addr, alen, NULL, 0, false);
689 if (rv != I2C_OK)
690 return rv;
691 }
692
693 rv = hsi2c_prepare_transaction(i2c, chip, len, true, true);
694
695 if (rv != I2C_OK)
696 return rv;
697
698 for (i = 0; i < len; i++) {
699 rv = hsi2c_poll_fifo(i2c, true);
700 if (rv != I2C_OK)
701 goto read_err;
702 if (drop_data)
703 continue;
704 data[i] = readl(&i2c->usi_rxdata);
705 }
706
707 rv = hsi2c_wait_for_trx(i2c);
708
709 read_err:
710 tmp_ret = hsi2c_wait_while_busy(i2c);
711 if (rv == I2C_OK)
712 rv = tmp_ret;
713
714 writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */
715 return rv;
716}
717
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100718#ifdef CONFIG_SYS_I2C
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100719static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap,
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100720 unsigned int speed)
721#else
722static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
723#endif
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100724{
725 struct s3c24x0_i2c_bus *i2c_bus;
726
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100727#ifdef CONFIG_SYS_I2C
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100728 i2c_bus = get_bus(adap->hwadapnr);
729 if (!i2c_bus)
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100730 return -EFAULT;
731#else
732 i2c_bus = dev_get_priv(dev);
733#endif
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100734 i2c_bus->clock_frequency = speed;
735
736 if (i2c_bus->is_highspeed) {
737 if (hsi2c_get_clk_details(i2c_bus))
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100738 return -EFAULT;
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100739 hsi2c_ch_init(i2c_bus);
740 } else {
741 i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
742 CONFIG_SYS_I2C_S3C24X0_SLAVE);
743 }
744
745 return 0;
746}
747
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530748/*
wdenk49c3f672003-10-08 22:33:00 +0000749 * cmd_type is 0 for write, 1 for read.
750 *
751 * addr_len can take any value from 0-255, it is only limited
752 * by the char, we could make it larger if needed. If it is
753 * 0 we skip the address write cycle.
754 */
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000755static int i2c_transfer(struct s3c24x0_i2c *i2c,
756 unsigned char cmd_type,
757 unsigned char chip,
758 unsigned char addr[],
759 unsigned char addr_len,
760 unsigned char data[],
761 unsigned short data_len)
wdenk1fe2c702003-03-06 21:55:29 +0000762{
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530763 int i = 0, result;
764 ulong start_time = get_timer(0);
wdenk1fe2c702003-03-06 21:55:29 +0000765
wdenk49c3f672003-10-08 22:33:00 +0000766 if (data == 0 || data_len == 0) {
767 /*Don't support data transfer of no length or to address 0 */
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000768 debug("i2c_transfer: bad call\n");
wdenk49c3f672003-10-08 22:33:00 +0000769 return I2C_NOK;
770 }
wdenk1fe2c702003-03-06 21:55:29 +0000771
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530772 while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
773 if (get_timer(start_time) > I2C_TIMEOUT_MS)
774 return I2C_NOK_TOUT;
wdenk49c3f672003-10-08 22:33:00 +0000775 }
wdenk1fe2c702003-03-06 21:55:29 +0000776
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000777 writel(readl(&i2c->iiccon) | I2CCON_ACKGEN, &i2c->iiccon);
wdenk1fe2c702003-03-06 21:55:29 +0000778
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530779 /* Get the slave chip address going */
780 writel(chip, &i2c->iicds);
781 if ((cmd_type == I2C_WRITE) || (addr && addr_len))
782 writel(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP,
783 &i2c->iicstat);
784 else
785 writel(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP,
786 &i2c->iicstat);
787
788 /* Wait for chip address to transmit. */
789 result = WaitForXfer(i2c);
790 if (result != I2C_OK)
791 goto bailout;
wdenk1fe2c702003-03-06 21:55:29 +0000792
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530793 /* If register address needs to be transmitted - do it now. */
794 if (addr && addr_len) {
795 while ((i < addr_len) && (result == I2C_OK)) {
796 writel(addr[i++], &i2c->iicds);
Simon Glass824802d2015-07-02 18:15:46 -0600797 read_write_byte(i2c);
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000798 result = WaitForXfer(i2c);
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530799 }
800 i = 0;
801 if (result != I2C_OK)
802 goto bailout;
803 }
wdenk1fe2c702003-03-06 21:55:29 +0000804
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530805 switch (cmd_type) {
806 case I2C_WRITE:
807 while ((i < data_len) && (result == I2C_OK)) {
808 writel(data[i++], &i2c->iicds);
Simon Glass824802d2015-07-02 18:15:46 -0600809 read_write_byte(i2c);
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530810 result = WaitForXfer(i2c);
811 }
wdenk49c3f672003-10-08 22:33:00 +0000812 break;
wdenk1fe2c702003-03-06 21:55:29 +0000813
wdenk7539dea2003-06-19 23:01:32 +0000814 case I2C_READ:
wdenk49c3f672003-10-08 22:33:00 +0000815 if (addr && addr_len) {
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530816 /*
817 * Register address has been sent, now send slave chip
818 * address again to start the actual read transaction.
819 */
C Nauman383c43e2010-10-26 23:04:31 +0900820 writel(chip, &i2c->iicds);
wdenk1fe2c702003-03-06 21:55:29 +0000821
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530822 /* Generate a re-START. */
Rajeshwari Shindee076adf2013-02-19 02:19:45 +0000823 writel(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP,
824 &i2c->iicstat);
Simon Glass824802d2015-07-02 18:15:46 -0600825 read_write_byte(i2c);
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000826 result = WaitForXfer(i2c);
wdenk49c3f672003-10-08 22:33:00 +0000827
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530828 if (result != I2C_OK)
829 goto bailout;
wdenk1fe2c702003-03-06 21:55:29 +0000830 }
wdenk1fe2c702003-03-06 21:55:29 +0000831
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530832 while ((i < data_len) && (result == I2C_OK)) {
833 /* disable ACK for final READ */
834 if (i == data_len - 1)
835 writel(readl(&i2c->iiccon)
836 & ~I2CCON_ACKGEN,
837 &i2c->iiccon);
Simon Glass824802d2015-07-02 18:15:46 -0600838 read_write_byte(i2c);
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530839 result = WaitForXfer(i2c);
840 data[i++] = readl(&i2c->iicds);
841 }
842 if (result == I2C_NACK)
843 result = I2C_OK; /* Normal terminated read. */
wdenk49c3f672003-10-08 22:33:00 +0000844 break;
wdenk1fe2c702003-03-06 21:55:29 +0000845
846 default:
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000847 debug("i2c_transfer: bad call\n");
wdenk49c3f672003-10-08 22:33:00 +0000848 result = I2C_NOK;
849 break;
850 }
wdenk1fe2c702003-03-06 21:55:29 +0000851
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530852bailout:
853 /* Send STOP. */
854 writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
Simon Glass824802d2015-07-02 18:15:46 -0600855 read_write_byte(i2c);
Naveen Krishna Ch40e1e7b2013-10-15 16:01:43 +0530856
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000857 return result;
wdenk1fe2c702003-03-06 21:55:29 +0000858}
859
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100860#ifdef CONFIG_SYS_I2C
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100861static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip)
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100862#else
863static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags)
864#endif
wdenk1fe2c702003-03-06 21:55:29 +0000865{
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530866 struct s3c24x0_i2c_bus *i2c_bus;
wdenk49c3f672003-10-08 22:33:00 +0000867 uchar buf[1];
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530868 int ret;
wdenk1fe2c702003-03-06 21:55:29 +0000869
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100870#ifdef CONFIG_SYS_I2C
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100871 i2c_bus = get_bus(adap->hwadapnr);
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530872 if (!i2c_bus)
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100873 return -EFAULT;
874#else
875 i2c_bus = dev_get_priv(dev);
876#endif
wdenk49c3f672003-10-08 22:33:00 +0000877 buf[0] = 0;
wdenk1fe2c702003-03-06 21:55:29 +0000878
wdenk49c3f672003-10-08 22:33:00 +0000879 /*
880 * What is needed is to send the chip address and verify that the
881 * address was <ACK>ed (i.e. there was a chip at that address which
882 * drove the data line low).
883 */
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530884 if (i2c_bus->is_highspeed) {
885 ret = hsi2c_read(i2c_bus->hsregs,
886 chip, 0, 0, buf, 1);
887 } else {
888 ret = i2c_transfer(i2c_bus->regs,
889 I2C_READ, chip << 1, 0, 0, buf, 1);
890 }
891
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530892 return ret != I2C_OK;
wdenk1fe2c702003-03-06 21:55:29 +0000893}
894
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100895#ifdef CONFIG_SYS_I2C
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100896static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
897 int alen, uchar *buffer, int len)
wdenk1fe2c702003-03-06 21:55:29 +0000898{
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530899 struct s3c24x0_i2c_bus *i2c_bus;
wdenk49c3f672003-10-08 22:33:00 +0000900 uchar xaddr[4];
901 int ret;
wdenk1fe2c702003-03-06 21:55:29 +0000902
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100903 i2c_bus = get_bus(adap->hwadapnr);
904 if (!i2c_bus)
905 return -EFAULT;
906
wdenk49c3f672003-10-08 22:33:00 +0000907 if (alen > 4) {
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000908 debug("I2C read: addr len %d not supported\n", alen);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100909 return -EADDRNOTAVAIL;
wdenk49c3f672003-10-08 22:33:00 +0000910 }
wdenk1fe2c702003-03-06 21:55:29 +0000911
wdenk49c3f672003-10-08 22:33:00 +0000912 if (alen > 0) {
913 xaddr[0] = (addr >> 24) & 0xFF;
914 xaddr[1] = (addr >> 16) & 0xFF;
915 xaddr[2] = (addr >> 8) & 0xFF;
916 xaddr[3] = addr & 0xFF;
917 }
wdenk1fe2c702003-03-06 21:55:29 +0000918
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200919#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
wdenk49c3f672003-10-08 22:33:00 +0000920 /*
921 * EEPROM chips that implement "address overflow" are ones
922 * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
923 * address and the extra bits end up in the "chip address"
924 * bit slots. This makes a 24WC08 (1Kbyte) chip look like
925 * four 256 byte chips.
926 *
927 * Note that we consider the length of the address field to
928 * still be one byte because the extra address bits are
929 * hidden in the chip address.
930 */
931 if (alen > 0)
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900932 chip |= ((addr >> (alen * 8)) &
933 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
wdenk1fe2c702003-03-06 21:55:29 +0000934#endif
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530935 if (i2c_bus->is_highspeed)
936 ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen],
937 alen, buffer, len);
938 else
939 ret = i2c_transfer(i2c_bus->regs, I2C_READ, chip << 1,
940 &xaddr[4 - alen], alen, buffer, len);
941
942 if (ret) {
943 if (i2c_bus->is_highspeed)
944 exynos5_i2c_reset(i2c_bus);
945 debug("I2c read failed %d\n", ret);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100946 return -EIO;
wdenk49c3f672003-10-08 22:33:00 +0000947 }
948 return 0;
wdenk1fe2c702003-03-06 21:55:29 +0000949}
950
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +0100951static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
952 int alen, uchar *buffer, int len)
wdenk1fe2c702003-03-06 21:55:29 +0000953{
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530954 struct s3c24x0_i2c_bus *i2c_bus;
wdenk49c3f672003-10-08 22:33:00 +0000955 uchar xaddr[4];
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530956 int ret;
wdenk1fe2c702003-03-06 21:55:29 +0000957
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100958 i2c_bus = get_bus(adap->hwadapnr);
959 if (!i2c_bus)
960 return -EFAULT;
961
wdenk49c3f672003-10-08 22:33:00 +0000962 if (alen > 4) {
Rajeshwari Shinde4b4480a2012-07-23 21:23:53 +0000963 debug("I2C write: addr len %d not supported\n", alen);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +0100964 return -EINVAL;
wdenk49c3f672003-10-08 22:33:00 +0000965 }
wdenk1fe2c702003-03-06 21:55:29 +0000966
wdenk49c3f672003-10-08 22:33:00 +0000967 if (alen > 0) {
968 xaddr[0] = (addr >> 24) & 0xFF;
969 xaddr[1] = (addr >> 16) & 0xFF;
970 xaddr[2] = (addr >> 8) & 0xFF;
971 xaddr[3] = addr & 0xFF;
972 }
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200973#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
wdenk49c3f672003-10-08 22:33:00 +0000974 /*
975 * EEPROM chips that implement "address overflow" are ones
976 * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
977 * address and the extra bits end up in the "chip address"
978 * bit slots. This makes a 24WC08 (1Kbyte) chip look like
979 * four 256 byte chips.
980 *
981 * Note that we consider the length of the address field to
982 * still be one byte because the extra address bits are
983 * hidden in the chip address.
984 */
985 if (alen > 0)
kevin.morfitt@fearnside-systems.co.uk1464f4d2009-10-10 13:33:11 +0900986 chip |= ((addr >> (alen * 8)) &
987 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
wdenk1fe2c702003-03-06 21:55:29 +0000988#endif
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +0530989 if (i2c_bus->is_highspeed)
990 ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen],
991 alen, buffer, len, true);
992 else
993 ret = i2c_transfer(i2c_bus->regs, I2C_WRITE, chip << 1,
994 &xaddr[4 - alen], alen, buffer, len);
995
996 if (ret != 0) {
997 if (i2c_bus->is_highspeed)
998 exynos5_i2c_reset(i2c_bus);
999 return 1;
1000 } else {
1001 return 0;
1002 }
wdenk1fe2c702003-03-06 21:55:29 +00001003}
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001004
Masahiro Yamada366b24f2015-08-12 07:31:55 +09001005#if CONFIG_IS_ENABLED(OF_CONTROL)
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301006static void process_nodes(const void *blob, int node_list[], int count,
1007 int is_highspeed)
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001008{
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301009 struct s3c24x0_i2c_bus *bus;
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001010 int i, flags;
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001011
1012 for (i = 0; i < count; i++) {
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001013 int node = node_list[i];
1014
1015 if (node <= 0)
1016 continue;
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301017
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001018 bus = &i2c_bus[i];
Simon Glass2ccb6f42013-10-15 16:02:10 +05301019 bus->active = true;
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301020 bus->is_highspeed = is_highspeed;
1021
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001022 if (is_highspeed) {
1023 flags = PINMUX_FLAG_HS_MODE;
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301024 bus->hsregs = (struct exynos5_hsi2c *)
1025 fdtdec_get_addr(blob, node, "reg");
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001026 } else {
1027 flags = 0;
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301028 bus->regs = (struct s3c24x0_i2c *)
1029 fdtdec_get_addr(blob, node, "reg");
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001030 }
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301031
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001032 bus->id = pinmux_decode_periph_id(blob, node);
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301033 bus->clock_frequency = fdtdec_get_int(blob, node,
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +01001034 "clock-frequency",
1035 CONFIG_SYS_I2C_S3C24X0_SPEED);
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001036 bus->node = node;
Simon Glass2ccb6f42013-10-15 16:02:10 +05301037 bus->bus_num = i;
Simon Glass8db5f472015-07-02 18:15:44 -06001038 exynos_pinmux_config(bus->id, flags);
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301039
1040 /* Mark position as used */
1041 node_list[i] = -1;
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001042 }
1043}
1044
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301045void board_i2c_init(const void *blob)
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001046{
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301047 int node_list[CONFIG_MAX_I2C_NUM];
1048 int count;
Simon Glass2ccb6f42013-10-15 16:02:10 +05301049
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301050 /* First get the normal i2c ports */
1051 count = fdtdec_find_aliases_for_id(blob, "i2c",
1052 COMPAT_SAMSUNG_S3C2440_I2C, node_list,
1053 CONFIG_MAX_I2C_NUM);
1054 process_nodes(blob, node_list, count, 0);
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001055
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301056 /* Now look for high speed i2c ports */
1057 count = fdtdec_find_aliases_for_id(blob, "i2c",
1058 COMPAT_SAMSUNG_EXYNOS5_I2C, node_list,
1059 CONFIG_MAX_I2C_NUM);
1060 process_nodes(blob, node_list, count, 1);
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001061}
1062
1063int i2c_get_bus_num_fdt(int node)
1064{
1065 int i;
1066
Simon Glass2ccb6f42013-10-15 16:02:10 +05301067 for (i = 0; i < ARRAY_SIZE(i2c_bus); i++) {
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001068 if (node == i2c_bus[i].node)
1069 return i;
1070 }
1071
1072 debug("%s: Can't find any matched I2C bus\n", __func__);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001073 return -EINVAL;
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001074}
1075
1076int i2c_reset_port_fdt(const void *blob, int node)
1077{
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301078 struct s3c24x0_i2c_bus *i2c_bus;
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001079 int bus;
1080
1081 bus = i2c_get_bus_num_fdt(node);
1082 if (bus < 0) {
1083 debug("could not get bus for node %d\n", node);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001084 return bus;
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001085 }
1086
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301087 i2c_bus = get_bus(bus);
1088 if (!i2c_bus) {
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001089 debug("get_bus() failed for node %d\n", node);
1090 return -EFAULT;
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001091 }
1092
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301093 if (i2c_bus->is_highspeed) {
1094 if (hsi2c_get_clk_details(i2c_bus))
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001095 return -EINVAL;
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301096 hsi2c_ch_init(i2c_bus);
1097 } else {
1098 i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +01001099 CONFIG_SYS_I2C_S3C24X0_SLAVE);
Naveen Krishna Ch64a191f2013-10-15 16:02:44 +05301100 }
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001101
1102 return 0;
1103}
Masahiro Yamada366b24f2015-08-12 07:31:55 +09001104#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001105
1106#ifdef CONFIG_EXYNOS5
1107static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
1108{
1109 /* This will override the speed selected in the fdt for that port */
1110 debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
1111 if (i2c_set_bus_speed(speed))
1112 error("i2c_init: failed to init bus for speed = %d", speed);
1113}
1114#endif /* CONFIG_EXYNOS5 */
Rajeshwari Shinde53cfac52012-12-26 20:03:12 +00001115
Piotr Wilczek58bbd2b2013-11-20 10:43:49 +01001116/*
1117 * Register s3c24x0 i2c adapters
1118 */
Naveen Krishna Ch5d5efd32013-12-06 12:12:38 +05301119#if defined(CONFIG_EXYNOS5420)
1120U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1121 s3c24x0_i2c_read, s3c24x0_i2c_write,
1122 s3c24x0_i2c_set_bus_speed,
1123 CONFIG_SYS_I2C_S3C24X0_SPEED,
1124 CONFIG_SYS_I2C_S3C24X0_SLAVE, 0)
1125U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1126 s3c24x0_i2c_read, s3c24x0_i2c_write,
1127 s3c24x0_i2c_set_bus_speed,
1128 CONFIG_SYS_I2C_S3C24X0_SPEED,
1129 CONFIG_SYS_I2C_S3C24X0_SLAVE, 1)
1130U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1131 s3c24x0_i2c_read, s3c24x0_i2c_write,
1132 s3c24x0_i2c_set_bus_speed,
1133 CONFIG_SYS_I2C_S3C24X0_SPEED,
1134 CONFIG_SYS_I2C_S3C24X0_SLAVE, 2)
1135U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe,
1136 s3c24x0_i2c_read, s3c24x0_i2c_write,
1137 s3c24x0_i2c_set_bus_speed,
1138 CONFIG_SYS_I2C_S3C24X0_SPEED,
1139 CONFIG_SYS_I2C_S3C24X0_SLAVE, 3)
1140U_BOOT_I2C_ADAP_COMPLETE(i2c04, exynos_i2c_init, s3c24x0_i2c_probe,
1141 s3c24x0_i2c_read, s3c24x0_i2c_write,
1142 s3c24x0_i2c_set_bus_speed,
1143 CONFIG_SYS_I2C_S3C24X0_SPEED,
1144 CONFIG_SYS_I2C_S3C24X0_SLAVE, 4)
1145U_BOOT_I2C_ADAP_COMPLETE(i2c05, exynos_i2c_init, s3c24x0_i2c_probe,
1146 s3c24x0_i2c_read, s3c24x0_i2c_write,
1147 s3c24x0_i2c_set_bus_speed,
1148 CONFIG_SYS_I2C_S3C24X0_SPEED,
1149 CONFIG_SYS_I2C_S3C24X0_SLAVE, 5)
1150U_BOOT_I2C_ADAP_COMPLETE(i2c06, exynos_i2c_init, s3c24x0_i2c_probe,
1151 s3c24x0_i2c_read, s3c24x0_i2c_write,
1152 s3c24x0_i2c_set_bus_speed,
1153 CONFIG_SYS_I2C_S3C24X0_SPEED,
1154 CONFIG_SYS_I2C_S3C24X0_SLAVE, 6)
1155U_BOOT_I2C_ADAP_COMPLETE(i2c07, exynos_i2c_init, s3c24x0_i2c_probe,
1156 s3c24x0_i2c_read, s3c24x0_i2c_write,
1157 s3c24x0_i2c_set_bus_speed,
1158 CONFIG_SYS_I2C_S3C24X0_SPEED,
1159 CONFIG_SYS_I2C_S3C24X0_SLAVE, 7)
1160U_BOOT_I2C_ADAP_COMPLETE(i2c08, exynos_i2c_init, s3c24x0_i2c_probe,
1161 s3c24x0_i2c_read, s3c24x0_i2c_write,
1162 s3c24x0_i2c_set_bus_speed,
1163 CONFIG_SYS_I2C_S3C24X0_SPEED,
1164 CONFIG_SYS_I2C_S3C24X0_SLAVE, 8)
1165U_BOOT_I2C_ADAP_COMPLETE(i2c09, exynos_i2c_init, s3c24x0_i2c_probe,
1166 s3c24x0_i2c_read, s3c24x0_i2c_write,
1167 s3c24x0_i2c_set_bus_speed,
1168 CONFIG_SYS_I2C_S3C24X0_SPEED,
1169 CONFIG_SYS_I2C_S3C24X0_SLAVE, 9)
1170U_BOOT_I2C_ADAP_COMPLETE(i2c10, exynos_i2c_init, s3c24x0_i2c_probe,
1171 s3c24x0_i2c_read, s3c24x0_i2c_write,
1172 s3c24x0_i2c_set_bus_speed,
1173 CONFIG_SYS_I2C_S3C24X0_SPEED,
1174 CONFIG_SYS_I2C_S3C24X0_SLAVE, 10)
1175#elif defined(CONFIG_EXYNOS5250)
1176U_BOOT_I2C_ADAP_COMPLETE(i2c00, exynos_i2c_init, s3c24x0_i2c_probe,
1177 s3c24x0_i2c_read, s3c24x0_i2c_write,
1178 s3c24x0_i2c_set_bus_speed,
1179 CONFIG_SYS_I2C_S3C24X0_SPEED,
1180 CONFIG_SYS_I2C_S3C24X0_SLAVE, 0)
1181U_BOOT_I2C_ADAP_COMPLETE(i2c01, exynos_i2c_init, s3c24x0_i2c_probe,
1182 s3c24x0_i2c_read, s3c24x0_i2c_write,
1183 s3c24x0_i2c_set_bus_speed,
1184 CONFIG_SYS_I2C_S3C24X0_SPEED,
1185 CONFIG_SYS_I2C_S3C24X0_SLAVE, 1)
1186U_BOOT_I2C_ADAP_COMPLETE(i2c02, exynos_i2c_init, s3c24x0_i2c_probe,
1187 s3c24x0_i2c_read, s3c24x0_i2c_write,
1188 s3c24x0_i2c_set_bus_speed,
1189 CONFIG_SYS_I2C_S3C24X0_SPEED,
1190 CONFIG_SYS_I2C_S3C24X0_SLAVE, 2)
1191U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe,
1192 s3c24x0_i2c_read, s3c24x0_i2c_write,
1193 s3c24x0_i2c_set_bus_speed,
1194 CONFIG_SYS_I2C_S3C24X0_SPEED,
1195 CONFIG_SYS_I2C_S3C24X0_SLAVE, 3)
1196U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1197 s3c24x0_i2c_read, s3c24x0_i2c_write,
1198 s3c24x0_i2c_set_bus_speed,
1199 CONFIG_SYS_I2C_S3C24X0_SPEED,
1200 CONFIG_SYS_I2C_S3C24X0_SLAVE, 4)
1201U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1202 s3c24x0_i2c_read, s3c24x0_i2c_write,
1203 s3c24x0_i2c_set_bus_speed,
1204 CONFIG_SYS_I2C_S3C24X0_SPEED,
1205 CONFIG_SYS_I2C_S3C24X0_SLAVE, 5)
1206U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1207 s3c24x0_i2c_read, s3c24x0_i2c_write,
1208 s3c24x0_i2c_set_bus_speed,
1209 CONFIG_SYS_I2C_S3C24X0_SPEED,
1210 CONFIG_SYS_I2C_S3C24X0_SLAVE, 6)
1211U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1212 s3c24x0_i2c_read, s3c24x0_i2c_write,
1213 s3c24x0_i2c_set_bus_speed,
1214 CONFIG_SYS_I2C_S3C24X0_SPEED,
1215 CONFIG_SYS_I2C_S3C24X0_SLAVE, 7)
1216U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1217 s3c24x0_i2c_read, s3c24x0_i2c_write,
1218 s3c24x0_i2c_set_bus_speed,
1219 CONFIG_SYS_I2C_S3C24X0_SPEED,
1220 CONFIG_SYS_I2C_S3C24X0_SLAVE, 8)
1221U_BOOT_I2C_ADAP_COMPLETE(i2c09, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1222 s3c24x0_i2c_read, s3c24x0_i2c_write,
1223 s3c24x0_i2c_set_bus_speed,
1224 CONFIG_SYS_I2C_S3C24X0_SPEED,
1225 CONFIG_SYS_I2C_S3C24X0_SLAVE, 9)
1226U_BOOT_I2C_ADAP_COMPLETE(s3c10, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1227 s3c24x0_i2c_read, s3c24x0_i2c_write,
1228 s3c24x0_i2c_set_bus_speed,
1229 CONFIG_SYS_I2C_S3C24X0_SPEED,
1230 CONFIG_SYS_I2C_S3C24X0_SLAVE, 10)
1231#elif defined(CONFIG_EXYNOS4)
1232U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1233 s3c24x0_i2c_read, s3c24x0_i2c_write,
1234 s3c24x0_i2c_set_bus_speed,
1235 CONFIG_SYS_I2C_S3C24X0_SPEED,
1236 CONFIG_SYS_I2C_S3C24X0_SLAVE, 0)
1237U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1238 s3c24x0_i2c_read, s3c24x0_i2c_write,
1239 s3c24x0_i2c_set_bus_speed,
1240 CONFIG_SYS_I2C_S3C24X0_SPEED,
1241 CONFIG_SYS_I2C_S3C24X0_SLAVE, 1)
1242U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1243 s3c24x0_i2c_read, s3c24x0_i2c_write,
1244 s3c24x0_i2c_set_bus_speed,
1245 CONFIG_SYS_I2C_S3C24X0_SPEED,
1246 CONFIG_SYS_I2C_S3C24X0_SLAVE, 2)
1247U_BOOT_I2C_ADAP_COMPLETE(i2c03, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1248 s3c24x0_i2c_read, s3c24x0_i2c_write,
1249 s3c24x0_i2c_set_bus_speed,
1250 CONFIG_SYS_I2C_S3C24X0_SPEED,
1251 CONFIG_SYS_I2C_S3C24X0_SLAVE, 3)
1252U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1253 s3c24x0_i2c_read, s3c24x0_i2c_write,
1254 s3c24x0_i2c_set_bus_speed,
1255 CONFIG_SYS_I2C_S3C24X0_SPEED,
1256 CONFIG_SYS_I2C_S3C24X0_SLAVE, 4)
1257U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1258 s3c24x0_i2c_read, s3c24x0_i2c_write,
1259 s3c24x0_i2c_set_bus_speed,
1260 CONFIG_SYS_I2C_S3C24X0_SPEED,
1261 CONFIG_SYS_I2C_S3C24X0_SLAVE, 5)
1262U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1263 s3c24x0_i2c_read, s3c24x0_i2c_write,
1264 s3c24x0_i2c_set_bus_speed,
1265 CONFIG_SYS_I2C_S3C24X0_SPEED,
1266 CONFIG_SYS_I2C_S3C24X0_SLAVE, 6)
1267U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1268 s3c24x0_i2c_read, s3c24x0_i2c_write,
1269 s3c24x0_i2c_set_bus_speed,
1270 CONFIG_SYS_I2C_S3C24X0_SPEED,
1271 CONFIG_SYS_I2C_S3C24X0_SLAVE, 7)
1272U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1273 s3c24x0_i2c_read, s3c24x0_i2c_write,
1274 s3c24x0_i2c_set_bus_speed,
1275 CONFIG_SYS_I2C_S3C24X0_SPEED,
1276 CONFIG_SYS_I2C_S3C24X0_SLAVE, 8)
1277#else
1278U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe,
1279 s3c24x0_i2c_read, s3c24x0_i2c_write,
1280 s3c24x0_i2c_set_bus_speed,
1281 CONFIG_SYS_I2C_S3C24X0_SPEED,
1282 CONFIG_SYS_I2C_S3C24X0_SLAVE, 0)
1283#endif
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001284#endif /* CONFIG_SYS_I2C */
1285
1286#ifdef CONFIG_DM_I2C
Simon Glasse3b8c862015-07-02 18:15:47 -06001287static int exynos_hs_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
1288 int nmsgs)
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001289{
Simon Glasse3b8c862015-07-02 18:15:47 -06001290 struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
1291 struct exynos5_hsi2c *hsregs = i2c_bus->hsregs;
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001292 int ret;
1293
Simon Glasse3b8c862015-07-02 18:15:47 -06001294 for (; nmsgs > 0; nmsgs--, msg++) {
1295 if (msg->flags & I2C_M_RD) {
1296 ret = hsi2c_read(hsregs, msg->addr, 0, 0, msg->buf,
1297 msg->len);
1298 } else {
1299 ret = hsi2c_write(hsregs, msg->addr, 0, 0, msg->buf,
1300 msg->len, true);
1301 }
1302 if (ret) {
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001303 exynos5_i2c_reset(i2c_bus);
Simon Glasse3b8c862015-07-02 18:15:47 -06001304 return -EREMOTEIO;
1305 }
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001306 }
1307
Simon Glasse3b8c862015-07-02 18:15:47 -06001308 return 0;
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001309}
1310
Simon Glasse3b8c862015-07-02 18:15:47 -06001311static int s3c24x0_do_msg(struct s3c24x0_i2c_bus *i2c_bus, struct i2c_msg *msg,
1312 int seq)
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001313{
Simon Glasse3b8c862015-07-02 18:15:47 -06001314 struct s3c24x0_i2c *i2c = i2c_bus->regs;
1315 bool is_read = msg->flags & I2C_M_RD;
1316 uint status;
1317 uint addr;
1318 int ret, i;
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001319
Simon Glasse3b8c862015-07-02 18:15:47 -06001320 if (!seq)
1321 setbits_le32(&i2c->iiccon, I2CCON_ACKGEN);
1322
1323 /* Get the slave chip address going */
1324 addr = msg->addr << 1;
1325 writel(addr, &i2c->iicds);
1326 status = I2C_TXRX_ENA | I2C_START_STOP;
1327 if (is_read)
1328 status |= I2C_MODE_MR;
1329 else
1330 status |= I2C_MODE_MT;
1331 writel(status, &i2c->iicstat);
1332 if (seq)
1333 read_write_byte(i2c);
1334
1335 /* Wait for chip address to transmit */
1336 ret = WaitForXfer(i2c);
1337 if (ret)
1338 goto err;
1339
1340 if (is_read) {
1341 for (i = 0; !ret && i < msg->len; i++) {
1342 /* disable ACK for final READ */
1343 if (i == msg->len - 1)
1344 clrbits_le32(&i2c->iiccon, I2CCON_ACKGEN);
1345 read_write_byte(i2c);
1346 ret = WaitForXfer(i2c);
1347 msg->buf[i] = readl(&i2c->iicds);
1348 }
1349 if (ret == I2C_NACK)
1350 ret = I2C_OK; /* Normal terminated read */
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001351 } else {
Simon Glasse3b8c862015-07-02 18:15:47 -06001352 for (i = 0; !ret && i < msg->len; i++) {
1353 writel(msg->buf[i], &i2c->iicds);
1354 read_write_byte(i2c);
1355 ret = WaitForXfer(i2c);
1356 }
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001357 }
1358
Simon Glasse3b8c862015-07-02 18:15:47 -06001359err:
1360 return ret;
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001361}
1362
1363static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
1364 int nmsgs)
1365{
1366 struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
Simon Glasse3b8c862015-07-02 18:15:47 -06001367 struct s3c24x0_i2c *i2c = i2c_bus->regs;
1368 ulong start_time;
1369 int ret, i;
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001370
Simon Glasse3b8c862015-07-02 18:15:47 -06001371 start_time = get_timer(0);
1372 while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
1373 if (get_timer(start_time) > I2C_TIMEOUT_MS) {
1374 debug("Timeout\n");
1375 return -ETIMEDOUT;
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001376 }
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001377 }
1378
Simon Glasse3b8c862015-07-02 18:15:47 -06001379 for (ret = 0, i = 0; !ret && i < nmsgs; i++)
1380 ret = s3c24x0_do_msg(i2c_bus, &msg[i], i);
1381
1382 /* Send STOP */
1383 writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
1384 read_write_byte(i2c);
1385
1386 return ret ? -EREMOTEIO : 0;
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001387}
1388
1389static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
1390{
1391 const void *blob = gd->fdt_blob;
1392 struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
1393 int node, flags;
1394
Simon Glass46227bd2015-03-25 12:21:55 -06001395 i2c_bus->is_highspeed = dev_get_driver_data(dev);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001396 node = dev->of_offset;
1397
1398 if (i2c_bus->is_highspeed) {
1399 flags = PINMUX_FLAG_HS_MODE;
Simon Glass09717782015-08-11 08:33:29 -06001400 i2c_bus->hsregs = (struct exynos5_hsi2c *)dev_get_addr(dev);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001401 } else {
1402 flags = 0;
Simon Glass09717782015-08-11 08:33:29 -06001403 i2c_bus->regs = (struct s3c24x0_i2c *)dev_get_addr(dev);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001404 }
1405
1406 i2c_bus->id = pinmux_decode_periph_id(blob, node);
1407
1408 i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
Simon Glasse3b8c862015-07-02 18:15:47 -06001409 "clock-frequency", 100000);
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001410 i2c_bus->node = node;
1411 i2c_bus->bus_num = dev->seq;
1412
1413 exynos_pinmux_config(i2c_bus->id, flags);
1414
1415 i2c_bus->active = true;
1416
1417 return 0;
1418}
1419
1420static const struct dm_i2c_ops s3c_i2c_ops = {
1421 .xfer = s3c24x0_i2c_xfer,
1422 .probe_chip = s3c24x0_i2c_probe,
1423 .set_bus_speed = s3c24x0_i2c_set_bus_speed,
1424};
1425
1426static const struct udevice_id s3c_i2c_ids[] = {
1427 { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD },
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001428 { }
1429};
1430
1431U_BOOT_DRIVER(i2c_s3c) = {
1432 .name = "i2c_s3c",
1433 .id = UCLASS_I2C,
1434 .of_match = s3c_i2c_ids,
1435 .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001436 .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
1437 .ops = &s3c_i2c_ops,
1438};
Simon Glasse3b8c862015-07-02 18:15:47 -06001439
1440/*
1441 * TODO(sjg@chromium.org): Move this to a separate file when everything uses
1442 * driver model
1443 */
1444static const struct dm_i2c_ops exynos_hs_i2c_ops = {
1445 .xfer = exynos_hs_i2c_xfer,
1446 .probe_chip = s3c24x0_i2c_probe,
1447 .set_bus_speed = s3c24x0_i2c_set_bus_speed,
1448};
1449
1450static const struct udevice_id exynos_hs_i2c_ids[] = {
1451 { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS },
1452 { }
1453};
1454
1455U_BOOT_DRIVER(hs_i2c) = {
1456 .name = "i2c_s3c_hs",
1457 .id = UCLASS_I2C,
1458 .of_match = exynos_hs_i2c_ids,
1459 .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
Simon Glasse3b8c862015-07-02 18:15:47 -06001460 .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
1461 .ops = &exynos_hs_i2c_ops,
1462};
Przemyslaw Marczak2a4f8112015-01-27 13:36:36 +01001463#endif /* CONFIG_DM_I2C */