blob: 3325c4bd468f3bdaa78e290f00e089c542e01600 [file] [log] [blame]
Heiko Schocher4ce5a722009-07-20 09:59:37 +02001/*
Albert Aribaud306563a2010-08-27 18:26:05 +02002 * Driver for the TWSI (i2c) controller found on the Marvell
3 * orion5x and kirkwood SoC families.
Heiko Schocher4ce5a722009-07-20 09:59:37 +02004 *
Albert ARIBAUD57b4bce2011-04-22 19:41:02 +02005 * Author: Albert Aribaud <albert.u.boot@aribaud.net>
Albert Aribaud306563a2010-08-27 18:26:05 +02006 * Copyright (c) 2010 Albert Aribaud.
Heiko Schocher4ce5a722009-07-20 09:59:37 +02007 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
Heiko Schocher4ce5a722009-07-20 09:59:37 +02009 */
Albert Aribaud306563a2010-08-27 18:26:05 +020010
Heiko Schocher4ce5a722009-07-20 09:59:37 +020011#include <common.h>
12#include <i2c.h>
Heiko Schocher4ce5a722009-07-20 09:59:37 +020013#include <asm/errno.h>
14#include <asm/io.h>
15
Heiko Schocher4ce5a722009-07-20 09:59:37 +020016/*
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +020017 * Include a file that will provide CONFIG_I2C_MVTWSI_BASE*, and possibly other
18 * settings
Heiko Schocher4ce5a722009-07-20 09:59:37 +020019 */
20
Albert Aribaud306563a2010-08-27 18:26:05 +020021#if defined(CONFIG_ORION5X)
22#include <asm/arch/orion5x.h>
Stefan Roese81e33f42015-12-21 13:56:33 +010023#elif (defined(CONFIG_KIRKWOOD) || defined(CONFIG_ARCH_MVEBU))
Stefan Roese3dc23f72014-10-22 12:13:06 +020024#include <asm/arch/soc.h>
Hans de Goede66203772014-06-13 22:55:49 +020025#elif defined(CONFIG_SUNXI)
26#include <asm/arch/i2c.h>
Albert Aribaud306563a2010-08-27 18:26:05 +020027#else
28#error Driver mvtwsi not supported by SoC or board
29#endif
30
31/*
32 * TWSI register structure
33 */
34
Hans de Goede66203772014-06-13 22:55:49 +020035#ifdef CONFIG_SUNXI
36
37struct mvtwsi_registers {
38 u32 slave_address;
39 u32 xtnd_slave_addr;
40 u32 data;
41 u32 control;
42 u32 status;
43 u32 baudrate;
44 u32 soft_reset;
45};
46
47#else
48
Albert Aribaud306563a2010-08-27 18:26:05 +020049struct mvtwsi_registers {
50 u32 slave_address;
51 u32 data;
52 u32 control;
53 union {
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +020054 u32 status; /* When reading */
55 u32 baudrate; /* When writing */
Albert Aribaud306563a2010-08-27 18:26:05 +020056 };
57 u32 xtnd_slave_addr;
58 u32 reserved[2];
59 u32 soft_reset;
60};
61
Hans de Goede66203772014-06-13 22:55:49 +020062#endif
63
Albert Aribaud306563a2010-08-27 18:26:05 +020064/*
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +020065 * enum mvtwsi_ctrl_register_fields - Bit masks for flags in the control
66 * register
Albert Aribaud306563a2010-08-27 18:26:05 +020067 */
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +020068enum mvtwsi_ctrl_register_fields {
69 /* Acknowledge bit */
70 MVTWSI_CONTROL_ACK = 0x00000004,
71 /* Interrupt flag */
72 MVTWSI_CONTROL_IFLG = 0x00000008,
73 /* Stop bit */
74 MVTWSI_CONTROL_STOP = 0x00000010,
75 /* Start bit */
76 MVTWSI_CONTROL_START = 0x00000020,
77 /* I2C enable */
78 MVTWSI_CONTROL_TWSIEN = 0x00000040,
79 /* Interrupt enable */
80 MVTWSI_CONTROL_INTEN = 0x00000080,
81};
Albert Aribaud306563a2010-08-27 18:26:05 +020082
83/*
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +020084 * On sun6i and newer, IFLG is a write-clear bit, which is cleared by writing 1;
85 * on other platforms, it is a normal r/w bit, which is cleared by writing 0.
Hans de Goede904dfbf2016-01-14 14:06:25 +010086 */
87
88#ifdef CONFIG_SUNXI_GEN_SUN6I
89#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000008
90#else
91#define MVTWSI_CONTROL_CLEAR_IFLG 0x00000000
92#endif
93
94/*
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +020095 * enum mvstwsi_status_values - Possible values of I2C controller's status
96 * register
97 *
98 * Only those statuses expected in normal master operation on
99 * non-10-bit-address devices are specified.
100 *
101 * Every status that's unexpected during normal operation (bus errors,
102 * arbitration losses, missing ACKs...) is passed back to the caller as an error
Albert Aribaud306563a2010-08-27 18:26:05 +0200103 * code.
104 */
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +0200105enum mvstwsi_status_values {
106 /* START condition transmitted */
107 MVTWSI_STATUS_START = 0x08,
108 /* Repeated START condition transmitted */
109 MVTWSI_STATUS_REPEATED_START = 0x10,
110 /* Address + write bit transmitted, ACK received */
111 MVTWSI_STATUS_ADDR_W_ACK = 0x18,
112 /* Data transmitted, ACK received */
113 MVTWSI_STATUS_DATA_W_ACK = 0x28,
114 /* Address + read bit transmitted, ACK received */
115 MVTWSI_STATUS_ADDR_R_ACK = 0x40,
116 /* Address + read bit transmitted, ACK not received */
117 MVTWSI_STATUS_ADDR_R_NAK = 0x48,
118 /* Data received, ACK transmitted */
119 MVTWSI_STATUS_DATA_R_ACK = 0x50,
120 /* Data received, ACK not transmitted */
121 MVTWSI_STATUS_DATA_R_NAK = 0x58,
122 /* No relevant status */
123 MVTWSI_STATUS_IDLE = 0xF8,
124};
Albert Aribaud306563a2010-08-27 18:26:05 +0200125
126/*
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200127 * enum mvstwsi_ack_flags - Determine whether a read byte should be
128 * acknowledged or not.
129 */
130enum mvtwsi_ack_flags {
131 /* Send NAK after received byte */
132 MVTWSI_READ_NAK = 0,
133 /* Send ACK after received byte */
134 MVTWSI_READ_ACK = 1,
135};
136
137/*
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200138 * MVTWSI controller base
Albert Aribaud306563a2010-08-27 18:26:05 +0200139 */
140
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200141static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap)
142{
143 switch (adap->hwadapnr) {
144#ifdef CONFIG_I2C_MVTWSI_BASE0
145 case 0:
mario.six@gdsys.cc9ec43b02016-07-21 11:57:01 +0200146 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE0;
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200147#endif
148#ifdef CONFIG_I2C_MVTWSI_BASE1
149 case 1:
mario.six@gdsys.cc9ec43b02016-07-21 11:57:01 +0200150 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE1;
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200151#endif
152#ifdef CONFIG_I2C_MVTWSI_BASE2
153 case 2:
mario.six@gdsys.cc9ec43b02016-07-21 11:57:01 +0200154 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE2;
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200155#endif
156#ifdef CONFIG_I2C_MVTWSI_BASE3
157 case 3:
mario.six@gdsys.cc9ec43b02016-07-21 11:57:01 +0200158 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE3;
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200159#endif
160#ifdef CONFIG_I2C_MVTWSI_BASE4
161 case 4:
mario.six@gdsys.cc9ec43b02016-07-21 11:57:01 +0200162 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE4;
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200163#endif
Jelle van der Waa9d082682016-01-14 14:06:26 +0100164#ifdef CONFIG_I2C_MVTWSI_BASE5
165 case 5:
mario.six@gdsys.cc9ec43b02016-07-21 11:57:01 +0200166 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE5;
Jelle van der Waa9d082682016-01-14 14:06:26 +0100167#endif
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200168 default:
169 printf("Missing mvtwsi controller %d base\n", adap->hwadapnr);
170 break;
171 }
172
173 return NULL;
174}
Albert Aribaud306563a2010-08-27 18:26:05 +0200175
176/*
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +0200177 * enum mvtwsi_error_class - types of I2C errors
Albert Aribaud306563a2010-08-27 18:26:05 +0200178 */
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +0200179enum mvtwsi_error_class {
180 /* The controller returned a different status than expected */
181 MVTWSI_ERROR_WRONG_STATUS = 0x01,
182 /* The controller timed out */
183 MVTWSI_ERROR_TIMEOUT = 0x02,
184};
Albert Aribaud306563a2010-08-27 18:26:05 +0200185
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +0200186/*
187 * mvtwsi_error() - Build I2C return code from error information
188 *
189 * For debugging purposes, this function packs some information of an occurred
190 * error into a return code. These error codes are returned from I2C API
191 * functions (i2c_{read,write}, dm_i2c_{read,write}, etc.).
192 *
193 * @ec: The error class of the error (enum mvtwsi_error_class).
194 * @lc: The last value of the control register.
195 * @ls: The last value of the status register.
196 * @es: The expected value of the status register.
197 * @return The generated error code.
198 */
199inline uint mvtwsi_error(uint ec, uint lc, uint ls, uint es)
200{
201 return ((ec << 24) & 0xFF000000)
202 | ((lc << 16) & 0x00FF0000)
203 | ((ls << 8) & 0x0000FF00)
204 | (es & 0xFF);
205}
Albert Aribaud306563a2010-08-27 18:26:05 +0200206
207/*
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200208 * Wait for IFLG to raise, or return 'timeout.' Then, if the status is as
209 * expected, return 0 (ok) or 'wrong status' otherwise.
Albert Aribaud306563a2010-08-27 18:26:05 +0200210 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200211static int twsi_wait(struct mvtwsi_registers *twsi, int expected_status)
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200212{
Albert Aribaud306563a2010-08-27 18:26:05 +0200213 int control, status;
214 int timeout = 1000;
215
216 do {
217 control = readl(&twsi->control);
218 if (control & MVTWSI_CONTROL_IFLG) {
219 status = readl(&twsi->status);
220 if (status == expected_status)
221 return 0;
222 else
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +0200223 return mvtwsi_error(
Albert Aribaud306563a2010-08-27 18:26:05 +0200224 MVTWSI_ERROR_WRONG_STATUS,
225 control, status, expected_status);
226 }
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200227 udelay(10); /* One clock cycle at 100 kHz */
Albert Aribaud306563a2010-08-27 18:26:05 +0200228 } while (timeout--);
229 status = readl(&twsi->status);
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +0200230 return mvtwsi_error(MVTWSI_ERROR_TIMEOUT, control, status,
231 expected_status);
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200232}
233
Albert Aribaud306563a2010-08-27 18:26:05 +0200234/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200235 * Assert the START condition, either in a single I2C transaction
236 * or inside back-to-back ones (repeated starts).
237 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200238static int twsi_start(struct mvtwsi_registers *twsi, int expected_status)
Albert Aribaud306563a2010-08-27 18:26:05 +0200239{
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200240 /* Assert START */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200241 writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_START |
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200242 MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
243 /* Wait for controller to process START */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200244 return twsi_wait(twsi, expected_status);
Albert Aribaud306563a2010-08-27 18:26:05 +0200245}
246
247/*
248 * Send a byte (i2c address or data).
249 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200250static int twsi_send(struct mvtwsi_registers *twsi, u8 byte,
251 int expected_status)
Albert Aribaud306563a2010-08-27 18:26:05 +0200252{
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200253 /* Write byte to data register for sending */
Albert Aribaud306563a2010-08-27 18:26:05 +0200254 writel(byte, &twsi->data);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200255 /* Clear any pending interrupt -- that will cause sending */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200256 writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_CLEAR_IFLG,
257 &twsi->control);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200258 /* Wait for controller to receive byte, and check ACK */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200259 return twsi_wait(twsi, expected_status);
Albert Aribaud306563a2010-08-27 18:26:05 +0200260}
261
262/*
263 * Receive a byte.
Albert Aribaud306563a2010-08-27 18:26:05 +0200264 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200265static int twsi_recv(struct mvtwsi_registers *twsi, u8 *byte, int ack_flag)
Albert Aribaud306563a2010-08-27 18:26:05 +0200266{
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200267 int expected_status, status, control;
Albert Aribaud306563a2010-08-27 18:26:05 +0200268
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200269 /* Compute expected status based on passed ACK flag */
270 expected_status = ack_flag ? MVTWSI_STATUS_DATA_R_ACK :
271 MVTWSI_STATUS_DATA_R_NAK;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200272 /* Acknowledge *previous state*, and launch receive */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200273 control = MVTWSI_CONTROL_TWSIEN;
274 control |= ack_flag == MVTWSI_READ_ACK ? MVTWSI_CONTROL_ACK : 0;
275 writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200276 /* Wait for controller to receive byte, and assert ACK or NAK */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200277 status = twsi_wait(twsi, expected_status);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200278 /* If we did receive the expected byte, store it */
Albert Aribaud306563a2010-08-27 18:26:05 +0200279 if (status == 0)
280 *byte = readl(&twsi->data);
Albert Aribaud306563a2010-08-27 18:26:05 +0200281 return status;
282}
283
284/*
285 * Assert the STOP condition.
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200286 * This is also used to force the bus back to idle (SDA = SCL = 1).
Albert Aribaud306563a2010-08-27 18:26:05 +0200287 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200288static int twsi_stop(struct mvtwsi_registers *twsi)
Albert Aribaud306563a2010-08-27 18:26:05 +0200289{
290 int control, stop_status;
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200291 int status = 0;
Albert Aribaud306563a2010-08-27 18:26:05 +0200292 int timeout = 1000;
293
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200294 /* Assert STOP */
Albert Aribaud306563a2010-08-27 18:26:05 +0200295 control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP;
Hans de Goede904dfbf2016-01-14 14:06:25 +0100296 writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200297 /* Wait for IDLE; IFLG won't rise, so we can't use twsi_wait() */
Albert Aribaud306563a2010-08-27 18:26:05 +0200298 do {
299 stop_status = readl(&twsi->status);
300 if (stop_status == MVTWSI_STATUS_IDLE)
301 break;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200302 udelay(10); /* One clock cycle at 100 kHz */
Albert Aribaud306563a2010-08-27 18:26:05 +0200303 } while (timeout--);
304 control = readl(&twsi->control);
305 if (stop_status != MVTWSI_STATUS_IDLE)
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200306 status = mvtwsi_error(MVTWSI_ERROR_TIMEOUT,
307 control, status, MVTWSI_STATUS_IDLE);
Albert Aribaud306563a2010-08-27 18:26:05 +0200308 return status;
309}
310
mario.six@gdsys.cce0758282016-07-21 11:57:06 +0200311static uint twsi_calc_freq(const int n, const int m)
Stefan Roesef582a152015-03-18 09:30:54 +0100312{
313#ifdef CONFIG_SUNXI
314 return CONFIG_SYS_TCLK / (10 * (m + 1) * (1 << n));
315#else
316 return CONFIG_SYS_TCLK / (10 * (m + 1) * (2 << n));
317#endif
318}
Albert Aribaud306563a2010-08-27 18:26:05 +0200319
320/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200321 * Reset controller.
Albert Aribaud306563a2010-08-27 18:26:05 +0200322 * Controller reset also resets the baud rate and slave address, so
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200323 * they must be re-established afterwards.
Albert Aribaud306563a2010-08-27 18:26:05 +0200324 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200325static void twsi_reset(struct mvtwsi_registers *twsi)
Albert Aribaud306563a2010-08-27 18:26:05 +0200326{
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200327 /* Reset controller */
Albert Aribaud306563a2010-08-27 18:26:05 +0200328 writel(0, &twsi->soft_reset);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200329 /* Wait 2 ms -- this is what the Marvell LSP does */
Albert Aribaud306563a2010-08-27 18:26:05 +0200330 udelay(20000);
Albert Aribaud306563a2010-08-27 18:26:05 +0200331}
332
333/*
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200334 * Sets baud to the highest possible value not exceeding the requested one.
Albert Aribaud306563a2010-08-27 18:26:05 +0200335 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200336static uint __twsi_i2c_set_bus_speed(struct mvtwsi_registers *twsi,
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200337 uint requested_speed)
Albert Aribaud306563a2010-08-27 18:26:05 +0200338{
mario.six@gdsys.cce0758282016-07-21 11:57:06 +0200339 uint tmp_speed, highest_speed, n, m;
340 uint baud = 0x44; /* Baud rate after controller reset */
Albert Aribaud306563a2010-08-27 18:26:05 +0200341
Albert Aribaud306563a2010-08-27 18:26:05 +0200342 highest_speed = 0;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200343 /* Successively try m, n combinations, and use the combination
344 * resulting in the largest speed that's not above the requested
345 * speed */
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200346 for (n = 0; n < 8; n++) {
347 for (m = 0; m < 16; m++) {
Stefan Roesef582a152015-03-18 09:30:54 +0100348 tmp_speed = twsi_calc_freq(n, m);
mario.six@gdsys.cc9ec43b02016-07-21 11:57:01 +0200349 if ((tmp_speed <= requested_speed) &&
350 (tmp_speed > highest_speed)) {
Albert Aribaud306563a2010-08-27 18:26:05 +0200351 highest_speed = tmp_speed;
352 baud = (m << 3) | n;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200353 }
354 }
355 }
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200356 writel(baud, &twsi->baudrate);
357 return 0;
358}
359
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200360static void __twsi_i2c_init(struct mvtwsi_registers *twsi, int speed,
361 int slaveadd)
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200362{
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200363 /* Reset controller */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200364 twsi_reset(twsi);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200365 /* Set speed */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200366 __twsi_i2c_set_bus_speed(twsi, speed);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200367 /* Set slave address; even though we don't use it */
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200368 writel(slaveadd, &twsi->slave_address);
369 writel(0, &twsi->xtnd_slave_addr);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200370 /* Assert STOP, but don't care for the result */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200371 (void) twsi_stop(twsi);
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200372}
373
Albert Aribaud306563a2010-08-27 18:26:05 +0200374/*
375 * Begin I2C transaction with expected start status, at given address.
Albert Aribaud306563a2010-08-27 18:26:05 +0200376 * Expected address status will derive from direction bit (bit 0) in addr.
377 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200378static int i2c_begin(struct mvtwsi_registers *twsi, int expected_start_status,
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200379 u8 addr)
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200380{
Albert Aribaud306563a2010-08-27 18:26:05 +0200381 int status, expected_addr_status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200382
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200383 /* Compute the expected address status from the direction bit in
384 * the address byte */
385 if (addr & 1) /* Reading */
Albert Aribaud306563a2010-08-27 18:26:05 +0200386 expected_addr_status = MVTWSI_STATUS_ADDR_R_ACK;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200387 else /* Writing */
Albert Aribaud306563a2010-08-27 18:26:05 +0200388 expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200389 /* Assert START */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200390 status = twsi_start(twsi, expected_start_status);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200391 /* Send out the address if the start went well */
Albert Aribaud306563a2010-08-27 18:26:05 +0200392 if (status == 0)
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200393 status = twsi_send(twsi, addr, expected_addr_status);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200394 /* Return 0, or the status of the first failure */
Albert Aribaud306563a2010-08-27 18:26:05 +0200395 return status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200396}
397
Albert Aribaud306563a2010-08-27 18:26:05 +0200398/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200399 * Begin read, nak data byte, end.
400 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200401static int __twsi_i2c_probe_chip(struct mvtwsi_registers *twsi, uchar chip)
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200402{
Albert Aribaud306563a2010-08-27 18:26:05 +0200403 u8 dummy_byte;
404 int status;
405
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200406 /* Begin i2c read */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200407 status = i2c_begin(twsi, MVTWSI_STATUS_START, (chip << 1) | 1);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200408 /* Dummy read was accepted: receive byte, but NAK it. */
Albert Aribaud306563a2010-08-27 18:26:05 +0200409 if (status == 0)
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200410 status = twsi_recv(twsi, &dummy_byte, MVTWSI_READ_NAK);
Albert Aribaud306563a2010-08-27 18:26:05 +0200411 /* Stop transaction */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200412 twsi_stop(twsi);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200413 /* Return 0, or the status of the first failure */
Albert Aribaud306563a2010-08-27 18:26:05 +0200414 return status;
415}
416
417/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200418 * Begin write, send address byte(s), begin read, receive data bytes, end.
419 *
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200420 * NOTE: Some devices want a stop right before the second start, while some
421 * will choke if it is there. Since deciding this is not yet supported in
422 * higher level APIs, we need to make a decision here, and for the moment that
423 * will be a repeated start without a preceding stop.
Albert Aribaud306563a2010-08-27 18:26:05 +0200424 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200425static int __twsi_i2c_read(struct mvtwsi_registers *twsi, uchar chip,
mario.six@gdsys.ccf8a10ed2016-07-21 11:57:09 +0200426 u8 *addr, int alen, uchar *data, int length)
Albert Aribaud306563a2010-08-27 18:26:05 +0200427{
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200428 int status = 0;
429 int stop_status;
Albert Aribaud306563a2010-08-27 18:26:05 +0200430
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200431 /* Begin i2c write to send the address bytes */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200432 status = i2c_begin(twsi, MVTWSI_STATUS_START, (chip << 1));
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200433 /* Send address bytes */
Albert Aribaud306563a2010-08-27 18:26:05 +0200434 while ((status == 0) && alen--)
mario.six@gdsys.ccf8a10ed2016-07-21 11:57:09 +0200435 status = twsi_send(twsi, *(addr++), MVTWSI_STATUS_DATA_W_ACK);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200436 /* Begin i2c read to receive data bytes */
Albert Aribaud306563a2010-08-27 18:26:05 +0200437 if (status == 0)
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200438 status = i2c_begin(twsi, MVTWSI_STATUS_REPEATED_START,
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200439 (chip << 1) | 1);
440 /* Receive actual data bytes; set NAK if we if we have nothing more to
441 * read */
442 while ((status == 0) && length--)
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200443 status = twsi_recv(twsi, data++,
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200444 length > 0 ?
445 MVTWSI_READ_ACK : MVTWSI_READ_NAK);
Albert Aribaud306563a2010-08-27 18:26:05 +0200446 /* Stop transaction */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200447 stop_status = twsi_stop(twsi);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200448 /* Return 0, or the status of the first failure */
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200449 return status != 0 ? status : stop_status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200450}
451
Albert Aribaud306563a2010-08-27 18:26:05 +0200452/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200453 * Begin write, send address byte(s), send data bytes, end.
454 */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200455static int __twsi_i2c_write(struct mvtwsi_registers *twsi, uchar chip,
mario.six@gdsys.ccf8a10ed2016-07-21 11:57:09 +0200456 u8 *addr, int alen, uchar *data, int length)
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200457{
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200458 int status, stop_status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200459
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200460 /* Begin i2c write to send first the address bytes, then the
461 * data bytes */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200462 status = i2c_begin(twsi, MVTWSI_STATUS_START, (chip << 1));
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200463 /* Send address bytes */
mario.six@gdsys.ccf8a10ed2016-07-21 11:57:09 +0200464 while ((status == 0) && (alen-- > 0))
465 status = twsi_send(twsi, *(addr++), MVTWSI_STATUS_DATA_W_ACK);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200466 /* Send data bytes */
Albert Aribaud306563a2010-08-27 18:26:05 +0200467 while ((status == 0) && (length-- > 0))
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200468 status = twsi_send(twsi, *(data++), MVTWSI_STATUS_DATA_W_ACK);
Albert Aribaud306563a2010-08-27 18:26:05 +0200469 /* Stop transaction */
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200470 stop_status = twsi_stop(twsi);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200471 /* Return 0, or the status of the first failure */
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200472 return status != 0 ? status : stop_status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200473}
474
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200475static void twsi_i2c_init(struct i2c_adapter *adap, int speed,
476 int slaveadd)
477{
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200478 struct mvtwsi_registers *twsi = twsi_get_base(adap);
479 __twsi_i2c_init(twsi, speed, slaveadd);
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200480}
481
482static uint twsi_i2c_set_bus_speed(struct i2c_adapter *adap,
483 uint requested_speed)
484{
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200485 struct mvtwsi_registers *twsi = twsi_get_base(adap);
486 return __twsi_i2c_set_bus_speed(twsi, requested_speed);
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200487}
488
489static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip)
490{
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200491 struct mvtwsi_registers *twsi = twsi_get_base(adap);
492 return __twsi_i2c_probe_chip(twsi, chip);
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200493}
494
495static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
496 int alen, uchar *data, int length)
497{
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200498 struct mvtwsi_registers *twsi = twsi_get_base(adap);
mario.six@gdsys.ccf8a10ed2016-07-21 11:57:09 +0200499 u8 addr_bytes[4];
500
501 addr_bytes[0] = (addr >> 0) & 0xFF;
502 addr_bytes[1] = (addr >> 8) & 0xFF;
503 addr_bytes[2] = (addr >> 16) & 0xFF;
504 addr_bytes[3] = (addr >> 24) & 0xFF;
505
506 return __twsi_i2c_read(twsi, chip, addr_bytes, alen, data, length);
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200507}
508
509static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
510 int alen, uchar *data, int length)
511{
mario.six@gdsys.cc3c4db632016-07-21 11:57:08 +0200512 struct mvtwsi_registers *twsi = twsi_get_base(adap);
mario.six@gdsys.ccf8a10ed2016-07-21 11:57:09 +0200513 u8 addr_bytes[4];
514
515 addr_bytes[0] = (addr >> 0) & 0xFF;
516 addr_bytes[1] = (addr >> 8) & 0xFF;
517 addr_bytes[2] = (addr >> 16) & 0xFF;
518 addr_bytes[3] = (addr >> 24) & 0xFF;
519
520 return __twsi_i2c_write(twsi, chip, addr_bytes, alen, data, length);
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200521}
522
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200523#ifdef CONFIG_I2C_MVTWSI_BASE0
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200524U_BOOT_I2C_ADAP_COMPLETE(twsi0, twsi_i2c_init, twsi_i2c_probe,
525 twsi_i2c_read, twsi_i2c_write,
526 twsi_i2c_set_bus_speed,
527 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 0)
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200528#endif
529#ifdef CONFIG_I2C_MVTWSI_BASE1
530U_BOOT_I2C_ADAP_COMPLETE(twsi1, twsi_i2c_init, twsi_i2c_probe,
531 twsi_i2c_read, twsi_i2c_write,
532 twsi_i2c_set_bus_speed,
533 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 1)
534
535#endif
536#ifdef CONFIG_I2C_MVTWSI_BASE2
537U_BOOT_I2C_ADAP_COMPLETE(twsi2, twsi_i2c_init, twsi_i2c_probe,
538 twsi_i2c_read, twsi_i2c_write,
539 twsi_i2c_set_bus_speed,
540 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 2)
541
542#endif
543#ifdef CONFIG_I2C_MVTWSI_BASE3
544U_BOOT_I2C_ADAP_COMPLETE(twsi3, twsi_i2c_init, twsi_i2c_probe,
545 twsi_i2c_read, twsi_i2c_write,
546 twsi_i2c_set_bus_speed,
547 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 3)
548
549#endif
550#ifdef CONFIG_I2C_MVTWSI_BASE4
551U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe,
552 twsi_i2c_read, twsi_i2c_write,
553 twsi_i2c_set_bus_speed,
554 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4)
555
556#endif
Jelle van der Waa9d082682016-01-14 14:06:26 +0100557#ifdef CONFIG_I2C_MVTWSI_BASE5
558U_BOOT_I2C_ADAP_COMPLETE(twsi5, twsi_i2c_init, twsi_i2c_probe,
559 twsi_i2c_read, twsi_i2c_write,
560 twsi_i2c_set_bus_speed,
561 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 5)
562
563#endif