blob: f1bfd5d02cf745b4aece4ceee07a9c6febd01e32 [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 */
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200211static int twsi_wait(struct i2c_adapter *adap, int expected_status)
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200212{
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200213 struct mvtwsi_registers *twsi = twsi_get_base(adap);
Albert Aribaud306563a2010-08-27 18:26:05 +0200214 int control, status;
215 int timeout = 1000;
216
217 do {
218 control = readl(&twsi->control);
219 if (control & MVTWSI_CONTROL_IFLG) {
220 status = readl(&twsi->status);
221 if (status == expected_status)
222 return 0;
223 else
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +0200224 return mvtwsi_error(
Albert Aribaud306563a2010-08-27 18:26:05 +0200225 MVTWSI_ERROR_WRONG_STATUS,
226 control, status, expected_status);
227 }
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200228 udelay(10); /* One clock cycle at 100 kHz */
Albert Aribaud306563a2010-08-27 18:26:05 +0200229 } while (timeout--);
230 status = readl(&twsi->status);
mario.six@gdsys.ccdfc39582016-07-21 11:57:02 +0200231 return mvtwsi_error(MVTWSI_ERROR_TIMEOUT, control, status,
232 expected_status);
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200233}
234
Albert Aribaud306563a2010-08-27 18:26:05 +0200235/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200236 * Assert the START condition, either in a single I2C transaction
237 * or inside back-to-back ones (repeated starts).
238 */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200239static int twsi_start(struct i2c_adapter *adap, int expected_status)
Albert Aribaud306563a2010-08-27 18:26:05 +0200240{
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200241 struct mvtwsi_registers *twsi = twsi_get_base(adap);
242
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200243 /* Assert START */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200244 writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_START |
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200245 MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
246 /* Wait for controller to process START */
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200247 return twsi_wait(adap, expected_status);
Albert Aribaud306563a2010-08-27 18:26:05 +0200248}
249
250/*
251 * Send a byte (i2c address or data).
252 */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200253static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status)
Albert Aribaud306563a2010-08-27 18:26:05 +0200254{
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200255 struct mvtwsi_registers *twsi = twsi_get_base(adap);
256
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200257 /* Write byte to data register for sending */
Albert Aribaud306563a2010-08-27 18:26:05 +0200258 writel(byte, &twsi->data);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200259 /* Clear any pending interrupt -- that will cause sending */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200260 writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_CLEAR_IFLG,
261 &twsi->control);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200262 /* Wait for controller to receive byte, and check ACK */
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200263 return twsi_wait(adap, expected_status);
Albert Aribaud306563a2010-08-27 18:26:05 +0200264}
265
266/*
267 * Receive a byte.
Albert Aribaud306563a2010-08-27 18:26:05 +0200268 */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200269static int twsi_recv(struct i2c_adapter *adap, u8 *byte, int ack_flag)
Albert Aribaud306563a2010-08-27 18:26:05 +0200270{
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200271 struct mvtwsi_registers *twsi = twsi_get_base(adap);
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200272 int expected_status, status, control;
Albert Aribaud306563a2010-08-27 18:26:05 +0200273
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200274 /* Compute expected status based on passed ACK flag */
275 expected_status = ack_flag ? MVTWSI_STATUS_DATA_R_ACK :
276 MVTWSI_STATUS_DATA_R_NAK;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200277 /* Acknowledge *previous state*, and launch receive */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200278 control = MVTWSI_CONTROL_TWSIEN;
279 control |= ack_flag == MVTWSI_READ_ACK ? MVTWSI_CONTROL_ACK : 0;
280 writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200281 /* Wait for controller to receive byte, and assert ACK or NAK */
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200282 status = twsi_wait(adap, expected_status);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200283 /* If we did receive the expected byte, store it */
Albert Aribaud306563a2010-08-27 18:26:05 +0200284 if (status == 0)
285 *byte = readl(&twsi->data);
Albert Aribaud306563a2010-08-27 18:26:05 +0200286 return status;
287}
288
289/*
290 * Assert the STOP condition.
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200291 * This is also used to force the bus back to idle (SDA = SCL = 1).
Albert Aribaud306563a2010-08-27 18:26:05 +0200292 */
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200293static int twsi_stop(struct i2c_adapter *adap)
Albert Aribaud306563a2010-08-27 18:26:05 +0200294{
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200295 struct mvtwsi_registers *twsi = twsi_get_base(adap);
Albert Aribaud306563a2010-08-27 18:26:05 +0200296 int control, stop_status;
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200297 int status = 0;
Albert Aribaud306563a2010-08-27 18:26:05 +0200298 int timeout = 1000;
299
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200300 /* Assert STOP */
Albert Aribaud306563a2010-08-27 18:26:05 +0200301 control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP;
Hans de Goede904dfbf2016-01-14 14:06:25 +0100302 writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200303 /* Wait for IDLE; IFLG won't rise, so we can't use twsi_wait() */
Albert Aribaud306563a2010-08-27 18:26:05 +0200304 do {
305 stop_status = readl(&twsi->status);
306 if (stop_status == MVTWSI_STATUS_IDLE)
307 break;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200308 udelay(10); /* One clock cycle at 100 kHz */
Albert Aribaud306563a2010-08-27 18:26:05 +0200309 } while (timeout--);
310 control = readl(&twsi->control);
311 if (stop_status != MVTWSI_STATUS_IDLE)
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200312 status = mvtwsi_error(MVTWSI_ERROR_TIMEOUT,
313 control, status, MVTWSI_STATUS_IDLE);
Albert Aribaud306563a2010-08-27 18:26:05 +0200314 return status;
315}
316
mario.six@gdsys.cce0758282016-07-21 11:57:06 +0200317static uint twsi_calc_freq(const int n, const int m)
Stefan Roesef582a152015-03-18 09:30:54 +0100318{
319#ifdef CONFIG_SUNXI
320 return CONFIG_SYS_TCLK / (10 * (m + 1) * (1 << n));
321#else
322 return CONFIG_SYS_TCLK / (10 * (m + 1) * (2 << n));
323#endif
324}
Albert Aribaud306563a2010-08-27 18:26:05 +0200325
326/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200327 * Reset controller.
Albert Aribaud306563a2010-08-27 18:26:05 +0200328 * Controller reset also resets the baud rate and slave address, so
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200329 * they must be re-established afterwards.
Albert Aribaud306563a2010-08-27 18:26:05 +0200330 */
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200331static void twsi_reset(struct i2c_adapter *adap)
Albert Aribaud306563a2010-08-27 18:26:05 +0200332{
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200333 struct mvtwsi_registers *twsi = twsi_get_base(adap);
Chris Packhamd6b77572016-05-13 15:19:31 +1200334
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200335 /* Reset controller */
Albert Aribaud306563a2010-08-27 18:26:05 +0200336 writel(0, &twsi->soft_reset);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200337 /* Wait 2 ms -- this is what the Marvell LSP does */
Albert Aribaud306563a2010-08-27 18:26:05 +0200338 udelay(20000);
Albert Aribaud306563a2010-08-27 18:26:05 +0200339}
340
341/*
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200342 * Sets baud to the highest possible value not exceeding the requested one.
Albert Aribaud306563a2010-08-27 18:26:05 +0200343 */
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200344static uint __twsi_i2c_set_bus_speed(struct i2c_adapter *adap,
345 uint requested_speed)
Albert Aribaud306563a2010-08-27 18:26:05 +0200346{
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200347 struct mvtwsi_registers *twsi = twsi_get_base(adap);
mario.six@gdsys.cce0758282016-07-21 11:57:06 +0200348 uint tmp_speed, highest_speed, n, m;
349 uint baud = 0x44; /* Baud rate after controller reset */
Albert Aribaud306563a2010-08-27 18:26:05 +0200350
Albert Aribaud306563a2010-08-27 18:26:05 +0200351 highest_speed = 0;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200352 /* Successively try m, n combinations, and use the combination
353 * resulting in the largest speed that's not above the requested
354 * speed */
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200355 for (n = 0; n < 8; n++) {
356 for (m = 0; m < 16; m++) {
Stefan Roesef582a152015-03-18 09:30:54 +0100357 tmp_speed = twsi_calc_freq(n, m);
mario.six@gdsys.cc9ec43b02016-07-21 11:57:01 +0200358 if ((tmp_speed <= requested_speed) &&
359 (tmp_speed > highest_speed)) {
Albert Aribaud306563a2010-08-27 18:26:05 +0200360 highest_speed = tmp_speed;
361 baud = (m << 3) | n;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200362 }
363 }
364 }
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200365 writel(baud, &twsi->baudrate);
366 return 0;
367}
368
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200369static void __twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200370{
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200371 struct mvtwsi_registers *twsi = twsi_get_base(adap);
372
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200373 /* Reset controller */
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200374 twsi_reset(adap);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200375 /* Set speed */
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200376 __twsi_i2c_set_bus_speed(adap, speed);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200377 /* Set slave address; even though we don't use it */
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200378 writel(slaveadd, &twsi->slave_address);
379 writel(0, &twsi->xtnd_slave_addr);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200380 /* Assert STOP, but don't care for the result */
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200381 (void) twsi_stop(adap);
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200382}
383
Albert Aribaud306563a2010-08-27 18:26:05 +0200384/*
385 * Begin I2C transaction with expected start status, at given address.
Albert Aribaud306563a2010-08-27 18:26:05 +0200386 * Expected address status will derive from direction bit (bit 0) in addr.
387 */
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200388static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200389 u8 addr)
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200390{
Albert Aribaud306563a2010-08-27 18:26:05 +0200391 int status, expected_addr_status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200392
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200393 /* Compute the expected address status from the direction bit in
394 * the address byte */
395 if (addr & 1) /* Reading */
Albert Aribaud306563a2010-08-27 18:26:05 +0200396 expected_addr_status = MVTWSI_STATUS_ADDR_R_ACK;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200397 else /* Writing */
Albert Aribaud306563a2010-08-27 18:26:05 +0200398 expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200399 /* Assert START */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200400 status = twsi_start(adap, expected_start_status);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200401 /* Send out the address if the start went well */
Albert Aribaud306563a2010-08-27 18:26:05 +0200402 if (status == 0)
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200403 status = twsi_send(adap, addr, expected_addr_status);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200404 /* Return 0, or the status of the first failure */
Albert Aribaud306563a2010-08-27 18:26:05 +0200405 return status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200406}
407
Albert Aribaud306563a2010-08-27 18:26:05 +0200408/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200409 * Begin read, nak data byte, end.
410 */
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200411static int __twsi_i2c_probe_chip(struct i2c_adapter *adap, uchar chip)
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200412{
Albert Aribaud306563a2010-08-27 18:26:05 +0200413 u8 dummy_byte;
414 int status;
415
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200416 /* Begin i2c read */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200417 status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200418 /* Dummy read was accepted: receive byte, but NAK it. */
Albert Aribaud306563a2010-08-27 18:26:05 +0200419 if (status == 0)
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200420 status = twsi_recv(adap, &dummy_byte, MVTWSI_READ_NAK);
Albert Aribaud306563a2010-08-27 18:26:05 +0200421 /* Stop transaction */
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200422 twsi_stop(adap);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200423 /* Return 0, or the status of the first failure */
Albert Aribaud306563a2010-08-27 18:26:05 +0200424 return status;
425}
426
427/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200428 * Begin write, send address byte(s), begin read, receive data bytes, end.
429 *
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200430 * NOTE: Some devices want a stop right before the second start, while some
431 * will choke if it is there. Since deciding this is not yet supported in
432 * higher level APIs, we need to make a decision here, and for the moment that
433 * will be a repeated start without a preceding stop.
Albert Aribaud306563a2010-08-27 18:26:05 +0200434 */
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200435static int __twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
436 int alen, uchar *data, int length)
Albert Aribaud306563a2010-08-27 18:26:05 +0200437{
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200438 int status = 0;
439 int stop_status;
Albert Aribaud306563a2010-08-27 18:26:05 +0200440
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200441 /* Begin i2c write to send the address bytes */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200442 status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200443 /* Send address bytes */
Albert Aribaud306563a2010-08-27 18:26:05 +0200444 while ((status == 0) && alen--)
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200445 status = twsi_send(adap, addr >> (8*alen),
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200446 MVTWSI_STATUS_DATA_W_ACK);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200447 /* Begin i2c read to receive data bytes */
Albert Aribaud306563a2010-08-27 18:26:05 +0200448 if (status == 0)
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200449 status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START,
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200450 (chip << 1) | 1);
451 /* Receive actual data bytes; set NAK if we if we have nothing more to
452 * read */
453 while ((status == 0) && length--)
454 status = twsi_recv(adap, data++,
455 length > 0 ?
456 MVTWSI_READ_ACK : MVTWSI_READ_NAK);
Albert Aribaud306563a2010-08-27 18:26:05 +0200457 /* Stop transaction */
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200458 stop_status = twsi_stop(adap);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200459 /* Return 0, or the status of the first failure */
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200460 return status != 0 ? status : stop_status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200461}
462
Albert Aribaud306563a2010-08-27 18:26:05 +0200463/*
Albert Aribaud306563a2010-08-27 18:26:05 +0200464 * Begin write, send address byte(s), send data bytes, end.
465 */
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200466static int __twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
467 int alen, uchar *data, int length)
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200468{
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200469 int status, stop_status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200470
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200471 /* Begin i2c write to send first the address bytes, then the
472 * data bytes */
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200473 status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200474 /* Send address bytes */
Albert Aribaud306563a2010-08-27 18:26:05 +0200475 while ((status == 0) && alen--)
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200476 status = twsi_send(adap, addr >> (8*alen),
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200477 MVTWSI_STATUS_DATA_W_ACK);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200478 /* Send data bytes */
Albert Aribaud306563a2010-08-27 18:26:05 +0200479 while ((status == 0) && (length-- > 0))
mario.six@gdsys.cc670514f2016-07-21 11:57:04 +0200480 status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK);
Albert Aribaud306563a2010-08-27 18:26:05 +0200481 /* Stop transaction */
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200482 stop_status = twsi_stop(adap);
mario.six@gdsys.cc49c801b2016-07-21 11:57:03 +0200483 /* Return 0, or the status of the first failure */
mario.six@gdsys.cc059fce92016-07-21 11:57:05 +0200484 return status != 0 ? status : stop_status;
Heiko Schocher4ce5a722009-07-20 09:59:37 +0200485}
486
mario.six@gdsys.cc61bc02b2016-07-21 11:57:07 +0200487static void twsi_i2c_init(struct i2c_adapter *adap, int speed,
488 int slaveadd)
489{
490 __twsi_i2c_init(adap, speed, slaveadd);
491}
492
493static uint twsi_i2c_set_bus_speed(struct i2c_adapter *adap,
494 uint requested_speed)
495{
496 return __twsi_i2c_set_bus_speed(adap, requested_speed);
497}
498
499static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip)
500{
501 return __twsi_i2c_probe_chip(adap, chip);
502}
503
504static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
505 int alen, uchar *data, int length)
506{
507 return __twsi_i2c_read(adap, chip, addr, alen, data, length);
508}
509
510static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
511 int alen, uchar *data, int length)
512{
513 return __twsi_i2c_write(adap, chip, addr, alen, data, length);
514}
515
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200516#ifdef CONFIG_I2C_MVTWSI_BASE0
Hans de Goede0db2bbd2014-06-13 22:55:48 +0200517U_BOOT_I2C_ADAP_COMPLETE(twsi0, twsi_i2c_init, twsi_i2c_probe,
518 twsi_i2c_read, twsi_i2c_write,
519 twsi_i2c_set_bus_speed,
520 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 0)
Paul Kocialkowskidd822422015-04-10 23:09:51 +0200521#endif
522#ifdef CONFIG_I2C_MVTWSI_BASE1
523U_BOOT_I2C_ADAP_COMPLETE(twsi1, twsi_i2c_init, twsi_i2c_probe,
524 twsi_i2c_read, twsi_i2c_write,
525 twsi_i2c_set_bus_speed,
526 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 1)
527
528#endif
529#ifdef CONFIG_I2C_MVTWSI_BASE2
530U_BOOT_I2C_ADAP_COMPLETE(twsi2, 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, 2)
534
535#endif
536#ifdef CONFIG_I2C_MVTWSI_BASE3
537U_BOOT_I2C_ADAP_COMPLETE(twsi3, 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, 3)
541
542#endif
543#ifdef CONFIG_I2C_MVTWSI_BASE4
544U_BOOT_I2C_ADAP_COMPLETE(twsi4, 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, 4)
548
549#endif
Jelle van der Waa9d082682016-01-14 14:06:26 +0100550#ifdef CONFIG_I2C_MVTWSI_BASE5
551U_BOOT_I2C_ADAP_COMPLETE(twsi5, 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, 5)
555
556#endif