blob: 9ddd3eea119248d9965c3b4c037c351d5f7304fa [file] [log] [blame]
Heiko Schocher5cd2a242009-07-20 09:59:37 +02001/*
Albert Aribaud04280c42010-08-27 18:26:05 +02002 * Driver for the TWSI (i2c) controller found on the Marvell
3 * orion5x and kirkwood SoC families.
Heiko Schocher5cd2a242009-07-20 09:59:37 +02004 *
Albert ARIBAUD340983d2011-04-22 19:41:02 +02005 * Author: Albert Aribaud <albert.u.boot@aribaud.net>
Albert Aribaud04280c42010-08-27 18:26:05 +02006 * Copyright (c) 2010 Albert Aribaud.
Heiko Schocher5cd2a242009-07-20 09:59:37 +02007 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
Heiko Schocher5cd2a242009-07-20 09:59:37 +02009 */
Albert Aribaud04280c42010-08-27 18:26:05 +020010
Heiko Schocher5cd2a242009-07-20 09:59:37 +020011#include <common.h>
12#include <i2c.h>
Heiko Schocher5cd2a242009-07-20 09:59:37 +020013#include <asm/errno.h>
14#include <asm/io.h>
15
Albert Aribaud04280c42010-08-27 18:26:05 +020016/*
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +020017 * Include a file that will provide CONFIG_I2C_MVTWSI_BASE*, and possibly other
18 * settings
Albert Aribaud04280c42010-08-27 18:26:05 +020019 */
Heiko Schocher5cd2a242009-07-20 09:59:37 +020020
Albert Aribaud04280c42010-08-27 18:26:05 +020021#if defined(CONFIG_ORION5X)
22#include <asm/arch/orion5x.h>
Stefan Roeseeb083e52015-12-21 13:56:33 +010023#elif (defined(CONFIG_KIRKWOOD) || defined(CONFIG_ARCH_MVEBU))
Stefan Roesec2437842014-10-22 12:13:06 +020024#include <asm/arch/soc.h>
Hans de Goede3352b222014-06-13 22:55:49 +020025#elif defined(CONFIG_SUNXI)
26#include <asm/arch/i2c.h>
Albert Aribaud04280c42010-08-27 18:26:05 +020027#else
28#error Driver mvtwsi not supported by SoC or board
Heiko Schocher5cd2a242009-07-20 09:59:37 +020029#endif
30
Albert Aribaud04280c42010-08-27 18:26:05 +020031/*
32 * TWSI register structure
33 */
Heiko Schocher5cd2a242009-07-20 09:59:37 +020034
Hans de Goede3352b222014-06-13 22:55:49 +020035#ifdef CONFIG_SUNXI
36
Albert Aribaud04280c42010-08-27 18:26:05 +020037struct mvtwsi_registers {
38 u32 slave_address;
Hans de Goede3352b222014-06-13 22:55:49 +020039 u32 xtnd_slave_addr;
Albert Aribaud04280c42010-08-27 18:26:05 +020040 u32 data;
41 u32 control;
Hans de Goede3352b222014-06-13 22:55:49 +020042 u32 status;
43 u32 baudrate;
44 u32 soft_reset;
45};
46
47#else
48
49struct mvtwsi_registers {
50 u32 slave_address;
51 u32 data;
52 u32 control;
Albert Aribaud04280c42010-08-27 18:26:05 +020053 union {
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +020054 u32 status; /* When reading */
55 u32 baudrate; /* When writing */
Albert Aribaud04280c42010-08-27 18:26:05 +020056 };
57 u32 xtnd_slave_addr;
58 u32 reserved[2];
59 u32 soft_reset;
Heiko Schocher5cd2a242009-07-20 09:59:37 +020060};
61
Hans de Goede3352b222014-06-13 22:55:49 +020062#endif
63
Albert Aribaud04280c42010-08-27 18:26:05 +020064/*
mario.six@gdsys.ccf43d3e92016-07-21 11:57:02 +020065 * enum mvtwsi_ctrl_register_fields - Bit masks for flags in the control
66 * register
Albert Aribaud04280c42010-08-27 18:26:05 +020067 */
mario.six@gdsys.ccf43d3e92016-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};
Heiko Schocher5cd2a242009-07-20 09:59:37 +020082
Albert Aribaud04280c42010-08-27 18:26:05 +020083/*
mario.six@gdsys.cc7b0c4312016-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 Goede6b703e02016-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.ccf43d3e92016-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 Aribaud04280c42010-08-27 18:26:05 +0200103 * code.
104 */
mario.six@gdsys.ccf43d3e92016-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};
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200125
Albert Aribaud04280c42010-08-27 18:26:05 +0200126/*
mario.six@gdsys.cc1cc2c282016-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 Kocialkowski2fae3e72015-04-10 23:09:51 +0200138 * MVTWSI controller base
Albert Aribaud04280c42010-08-27 18:26:05 +0200139 */
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200140
Paul Kocialkowski2fae3e72015-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.cc2b656eb2016-07-21 11:57:01 +0200146 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE0;
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200147#endif
148#ifdef CONFIG_I2C_MVTWSI_BASE1
149 case 1:
mario.six@gdsys.cc2b656eb2016-07-21 11:57:01 +0200150 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE1;
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200151#endif
152#ifdef CONFIG_I2C_MVTWSI_BASE2
153 case 2:
mario.six@gdsys.cc2b656eb2016-07-21 11:57:01 +0200154 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE2;
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200155#endif
156#ifdef CONFIG_I2C_MVTWSI_BASE3
157 case 3:
mario.six@gdsys.cc2b656eb2016-07-21 11:57:01 +0200158 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE3;
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200159#endif
160#ifdef CONFIG_I2C_MVTWSI_BASE4
161 case 4:
mario.six@gdsys.cc2b656eb2016-07-21 11:57:01 +0200162 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE4;
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200163#endif
Jelle van der Waa8d3d7c12016-01-14 14:06:26 +0100164#ifdef CONFIG_I2C_MVTWSI_BASE5
165 case 5:
mario.six@gdsys.cc2b656eb2016-07-21 11:57:01 +0200166 return (struct mvtwsi_registers *)CONFIG_I2C_MVTWSI_BASE5;
Jelle van der Waa8d3d7c12016-01-14 14:06:26 +0100167#endif
Paul Kocialkowski2fae3e72015-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}
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200175
176/*
mario.six@gdsys.ccf43d3e92016-07-21 11:57:02 +0200177 * enum mvtwsi_error_class - types of I2C errors
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200178 */
mario.six@gdsys.ccf43d3e92016-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};
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200185
mario.six@gdsys.ccf43d3e92016-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 Aribaud04280c42010-08-27 18:26:05 +0200206
207/*
mario.six@gdsys.cc7b0c4312016-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 Aribaud04280c42010-08-27 18:26:05 +0200210 */
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200211static int twsi_wait(struct i2c_adapter *adap, int expected_status)
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200212{
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200213 struct mvtwsi_registers *twsi = twsi_get_base(adap);
Albert Aribaud04280c42010-08-27 18:26:05 +0200214 int control, status;
215 int timeout = 1000;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200216
Albert Aribaud04280c42010-08-27 18:26:05 +0200217 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.ccf43d3e92016-07-21 11:57:02 +0200224 return mvtwsi_error(
Albert Aribaud04280c42010-08-27 18:26:05 +0200225 MVTWSI_ERROR_WRONG_STATUS,
226 control, status, expected_status);
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200227 }
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200228 udelay(10); /* One clock cycle at 100 kHz */
Albert Aribaud04280c42010-08-27 18:26:05 +0200229 } while (timeout--);
230 status = readl(&twsi->status);
mario.six@gdsys.ccf43d3e92016-07-21 11:57:02 +0200231 return mvtwsi_error(MVTWSI_ERROR_TIMEOUT, control, status,
232 expected_status);
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200233}
234
Albert Aribaud04280c42010-08-27 18:26:05 +0200235/*
Albert Aribaud04280c42010-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.cc1cc2c282016-07-21 11:57:04 +0200239static int twsi_start(struct i2c_adapter *adap, int expected_status)
Albert Aribaud04280c42010-08-27 18:26:05 +0200240{
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200241 struct mvtwsi_registers *twsi = twsi_get_base(adap);
242
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200243 /* Assert START */
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200244 writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_START |
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200245 MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
246 /* Wait for controller to process START */
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200247 return twsi_wait(adap, expected_status);
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200248}
249
Albert Aribaud04280c42010-08-27 18:26:05 +0200250/*
251 * Send a byte (i2c address or data).
252 */
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200253static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status)
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200254{
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200255 struct mvtwsi_registers *twsi = twsi_get_base(adap);
256
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200257 /* Write byte to data register for sending */
Albert Aribaud04280c42010-08-27 18:26:05 +0200258 writel(byte, &twsi->data);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200259 /* Clear any pending interrupt -- that will cause sending */
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200260 writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_CLEAR_IFLG,
261 &twsi->control);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200262 /* Wait for controller to receive byte, and check ACK */
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200263 return twsi_wait(adap, expected_status);
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200264}
265
Albert Aribaud04280c42010-08-27 18:26:05 +0200266/*
267 * Receive a byte.
Albert Aribaud04280c42010-08-27 18:26:05 +0200268 */
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200269static int twsi_recv(struct i2c_adapter *adap, u8 *byte, int ack_flag)
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200270{
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200271 struct mvtwsi_registers *twsi = twsi_get_base(adap);
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200272 int expected_status, status, control;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200273
mario.six@gdsys.cc1cc2c282016-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.cc7b0c4312016-07-21 11:57:03 +0200277 /* Acknowledge *previous state*, and launch receive */
mario.six@gdsys.cc1cc2c282016-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.cc7b0c4312016-07-21 11:57:03 +0200281 /* Wait for controller to receive byte, and assert ACK or NAK */
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200282 status = twsi_wait(adap, expected_status);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200283 /* If we did receive the expected byte, store it */
Albert Aribaud04280c42010-08-27 18:26:05 +0200284 if (status == 0)
285 *byte = readl(&twsi->data);
Albert Aribaud04280c42010-08-27 18:26:05 +0200286 return status;
287}
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200288
Albert Aribaud04280c42010-08-27 18:26:05 +0200289/*
290 * Assert the STOP condition.
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200291 * This is also used to force the bus back to idle (SDA = SCL = 1).
Albert Aribaud04280c42010-08-27 18:26:05 +0200292 */
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200293static int twsi_stop(struct i2c_adapter *adap)
Albert Aribaud04280c42010-08-27 18:26:05 +0200294{
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200295 struct mvtwsi_registers *twsi = twsi_get_base(adap);
Albert Aribaud04280c42010-08-27 18:26:05 +0200296 int control, stop_status;
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200297 int status = 0;
Albert Aribaud04280c42010-08-27 18:26:05 +0200298 int timeout = 1000;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200299
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200300 /* Assert STOP */
Albert Aribaud04280c42010-08-27 18:26:05 +0200301 control = MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_STOP;
Hans de Goede6b703e02016-01-14 14:06:25 +0100302 writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200303 /* Wait for IDLE; IFLG won't rise, so we can't use twsi_wait() */
Albert Aribaud04280c42010-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.cc7b0c4312016-07-21 11:57:03 +0200308 udelay(10); /* One clock cycle at 100 kHz */
Albert Aribaud04280c42010-08-27 18:26:05 +0200309 } while (timeout--);
310 control = readl(&twsi->control);
311 if (stop_status != MVTWSI_STATUS_IDLE)
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200312 status = mvtwsi_error(MVTWSI_ERROR_TIMEOUT,
313 control, status, MVTWSI_STATUS_IDLE);
Albert Aribaud04280c42010-08-27 18:26:05 +0200314 return status;
315}
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200316
mario.six@gdsys.cc9e118b32016-07-21 11:57:06 +0200317static uint twsi_calc_freq(const int n, const int m)
Stefan Roesecca56a72015-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}
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200325
Albert Aribaud04280c42010-08-27 18:26:05 +0200326/*
Albert Aribaud04280c42010-08-27 18:26:05 +0200327 * Reset controller.
Albert Aribaud04280c42010-08-27 18:26:05 +0200328 * Controller reset also resets the baud rate and slave address, so
Hans de Goede9830f1c2014-06-13 22:55:48 +0200329 * they must be re-established afterwards.
Albert Aribaud04280c42010-08-27 18:26:05 +0200330 */
Hans de Goede9830f1c2014-06-13 22:55:48 +0200331static void twsi_reset(struct i2c_adapter *adap)
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200332{
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200333 struct mvtwsi_registers *twsi = twsi_get_base(adap);
Chris Packhamc42be012016-05-13 15:19:31 +1200334
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200335 /* Reset controller */
Albert Aribaud04280c42010-08-27 18:26:05 +0200336 writel(0, &twsi->soft_reset);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200337 /* Wait 2 ms -- this is what the Marvell LSP does */
Albert Aribaud04280c42010-08-27 18:26:05 +0200338 udelay(20000);
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200339}
340
Albert Aribaud04280c42010-08-27 18:26:05 +0200341/*
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200342 * Sets baud to the highest possible value not exceeding the requested one.
Albert Aribaud04280c42010-08-27 18:26:05 +0200343 */
mario.six@gdsys.cc9e118b32016-07-21 11:57:06 +0200344static uint twsi_i2c_set_bus_speed(struct i2c_adapter *adap,
345 uint requested_speed)
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200346{
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200347 struct mvtwsi_registers *twsi = twsi_get_base(adap);
mario.six@gdsys.cc9e118b32016-07-21 11:57:06 +0200348 uint tmp_speed, highest_speed, n, m;
349 uint baud = 0x44; /* Baud rate after controller reset */
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200350
Albert Aribaud04280c42010-08-27 18:26:05 +0200351 highest_speed = 0;
mario.six@gdsys.cc7b0c4312016-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 */
Albert Aribaud04280c42010-08-27 18:26:05 +0200355 for (n = 0; n < 8; n++) {
356 for (m = 0; m < 16; m++) {
Stefan Roesecca56a72015-03-18 09:30:54 +0100357 tmp_speed = twsi_calc_freq(n, m);
mario.six@gdsys.cc2b656eb2016-07-21 11:57:01 +0200358 if ((tmp_speed <= requested_speed) &&
359 (tmp_speed > highest_speed)) {
Albert Aribaud04280c42010-08-27 18:26:05 +0200360 highest_speed = tmp_speed;
361 baud = (m << 3) | n;
362 }
363 }
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200364 }
Hans de Goede9830f1c2014-06-13 22:55:48 +0200365 writel(baud, &twsi->baudrate);
366 return 0;
367}
368
369static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
370{
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200371 struct mvtwsi_registers *twsi = twsi_get_base(adap);
372
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200373 /* Reset controller */
Hans de Goede9830f1c2014-06-13 22:55:48 +0200374 twsi_reset(adap);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200375 /* Set speed */
Hans de Goede9830f1c2014-06-13 22:55:48 +0200376 twsi_i2c_set_bus_speed(adap, speed);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200377 /* Set slave address; even though we don't use it */
Hans de Goede9830f1c2014-06-13 22:55:48 +0200378 writel(slaveadd, &twsi->slave_address);
379 writel(0, &twsi->xtnd_slave_addr);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200380 /* Assert STOP, but don't care for the result */
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200381 (void) twsi_stop(adap);
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200382}
383
Albert Aribaud04280c42010-08-27 18:26:05 +0200384/*
385 * Begin I2C transaction with expected start status, at given address.
Albert Aribaud04280c42010-08-27 18:26:05 +0200386 * Expected address status will derive from direction bit (bit 0) in addr.
387 */
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200388static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200389 u8 addr)
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200390{
Albert Aribaud04280c42010-08-27 18:26:05 +0200391 int status, expected_addr_status;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200392
mario.six@gdsys.cc7b0c4312016-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 Aribaud04280c42010-08-27 18:26:05 +0200396 expected_addr_status = MVTWSI_STATUS_ADDR_R_ACK;
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200397 else /* Writing */
Albert Aribaud04280c42010-08-27 18:26:05 +0200398 expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200399 /* Assert START */
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200400 status = twsi_start(adap, expected_start_status);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200401 /* Send out the address if the start went well */
Albert Aribaud04280c42010-08-27 18:26:05 +0200402 if (status == 0)
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200403 status = twsi_send(adap, addr, expected_addr_status);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200404 /* Return 0, or the status of the first failure */
Albert Aribaud04280c42010-08-27 18:26:05 +0200405 return status;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200406}
407
Albert Aribaud04280c42010-08-27 18:26:05 +0200408/*
Albert Aribaud04280c42010-08-27 18:26:05 +0200409 * Begin read, nak data byte, end.
410 */
Hans de Goede9830f1c2014-06-13 22:55:48 +0200411static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip)
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200412{
Albert Aribaud04280c42010-08-27 18:26:05 +0200413 u8 dummy_byte;
414 int status;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200415
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200416 /* Begin i2c read */
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200417 status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200418 /* Dummy read was accepted: receive byte, but NAK it. */
Albert Aribaud04280c42010-08-27 18:26:05 +0200419 if (status == 0)
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200420 status = twsi_recv(adap, &dummy_byte, MVTWSI_READ_NAK);
Albert Aribaud04280c42010-08-27 18:26:05 +0200421 /* Stop transaction */
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200422 twsi_stop(adap);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200423 /* Return 0, or the status of the first failure */
Albert Aribaud04280c42010-08-27 18:26:05 +0200424 return status;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200425}
426
Albert Aribaud04280c42010-08-27 18:26:05 +0200427/*
Albert Aribaud04280c42010-08-27 18:26:05 +0200428 * Begin write, send address byte(s), begin read, receive data bytes, end.
429 *
mario.six@gdsys.cc7b0c4312016-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 Aribaud04280c42010-08-27 18:26:05 +0200434 */
Hans de Goede9830f1c2014-06-13 22:55:48 +0200435static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
436 int alen, uchar *data, int length)
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200437{
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200438 int status = 0;
439 int stop_status;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200440
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200441 /* Begin i2c write to send the address bytes */
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200442 status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200443 /* Send address bytes */
Albert Aribaud04280c42010-08-27 18:26:05 +0200444 while ((status == 0) && alen--)
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200445 status = twsi_send(adap, addr >> (8*alen),
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200446 MVTWSI_STATUS_DATA_W_ACK);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200447 /* Begin i2c read to receive data bytes */
Albert Aribaud04280c42010-08-27 18:26:05 +0200448 if (status == 0)
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200449 status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START,
mario.six@gdsys.cc1cc2c282016-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 Aribaud04280c42010-08-27 18:26:05 +0200457 /* Stop transaction */
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200458 stop_status = twsi_stop(adap);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200459 /* Return 0, or the status of the first failure */
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200460 return status != 0 ? status : stop_status;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200461}
462
Albert Aribaud04280c42010-08-27 18:26:05 +0200463/*
Albert Aribaud04280c42010-08-27 18:26:05 +0200464 * Begin write, send address byte(s), send data bytes, end.
465 */
Hans de Goede9830f1c2014-06-13 22:55:48 +0200466static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
467 int alen, uchar *data, int length)
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200468{
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200469 int status, stop_status;
Albert Aribaud04280c42010-08-27 18:26:05 +0200470
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200471 /* Begin i2c write to send first the address bytes, then the
472 * data bytes */
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200473 status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200474 /* Send address bytes */
Albert Aribaud04280c42010-08-27 18:26:05 +0200475 while ((status == 0) && alen--)
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200476 status = twsi_send(adap, addr >> (8*alen),
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200477 MVTWSI_STATUS_DATA_W_ACK);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200478 /* Send data bytes */
Albert Aribaud04280c42010-08-27 18:26:05 +0200479 while ((status == 0) && (length-- > 0))
mario.six@gdsys.cc1cc2c282016-07-21 11:57:04 +0200480 status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK);
Albert Aribaud04280c42010-08-27 18:26:05 +0200481 /* Stop transaction */
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200482 stop_status = twsi_stop(adap);
mario.six@gdsys.cc7b0c4312016-07-21 11:57:03 +0200483 /* Return 0, or the status of the first failure */
mario.six@gdsys.ccbdf0f662016-07-21 11:57:05 +0200484 return status != 0 ? status : stop_status;
Heiko Schocher5cd2a242009-07-20 09:59:37 +0200485}
486
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200487#ifdef CONFIG_I2C_MVTWSI_BASE0
Hans de Goede9830f1c2014-06-13 22:55:48 +0200488U_BOOT_I2C_ADAP_COMPLETE(twsi0, twsi_i2c_init, twsi_i2c_probe,
489 twsi_i2c_read, twsi_i2c_write,
490 twsi_i2c_set_bus_speed,
491 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 0)
Paul Kocialkowski2fae3e72015-04-10 23:09:51 +0200492#endif
493#ifdef CONFIG_I2C_MVTWSI_BASE1
494U_BOOT_I2C_ADAP_COMPLETE(twsi1, twsi_i2c_init, twsi_i2c_probe,
495 twsi_i2c_read, twsi_i2c_write,
496 twsi_i2c_set_bus_speed,
497 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 1)
498
499#endif
500#ifdef CONFIG_I2C_MVTWSI_BASE2
501U_BOOT_I2C_ADAP_COMPLETE(twsi2, twsi_i2c_init, twsi_i2c_probe,
502 twsi_i2c_read, twsi_i2c_write,
503 twsi_i2c_set_bus_speed,
504 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 2)
505
506#endif
507#ifdef CONFIG_I2C_MVTWSI_BASE3
508U_BOOT_I2C_ADAP_COMPLETE(twsi3, twsi_i2c_init, twsi_i2c_probe,
509 twsi_i2c_read, twsi_i2c_write,
510 twsi_i2c_set_bus_speed,
511 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 3)
512
513#endif
514#ifdef CONFIG_I2C_MVTWSI_BASE4
515U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe,
516 twsi_i2c_read, twsi_i2c_write,
517 twsi_i2c_set_bus_speed,
518 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4)
519
520#endif
Jelle van der Waa8d3d7c12016-01-14 14:06:26 +0100521#ifdef CONFIG_I2C_MVTWSI_BASE5
522U_BOOT_I2C_ADAP_COMPLETE(twsi5, twsi_i2c_init, twsi_i2c_probe,
523 twsi_i2c_read, twsi_i2c_write,
524 twsi_i2c_set_bus_speed,
525 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 5)
526
527#endif