.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License as published by |
---|
6 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
7 | | - * (at your option) any later version. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, |
---|
10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | | - * GNU General Public License for more details. |
---|
13 | 4 | */ |
---|
14 | 5 | |
---|
15 | 6 | #include <linux/clk.h> |
---|
.. | .. |
---|
82 | 73 | #define UNIPHIER_FI2C_BYTE_WISE BIT(3) |
---|
83 | 74 | #define UNIPHIER_FI2C_DEFER_STOP_COMP BIT(4) |
---|
84 | 75 | |
---|
85 | | -#define UNIPHIER_FI2C_DEFAULT_SPEED 100000 |
---|
86 | | -#define UNIPHIER_FI2C_MAX_SPEED 400000 |
---|
87 | 76 | #define UNIPHIER_FI2C_FIFO_SIZE 8 |
---|
88 | 77 | |
---|
89 | 78 | struct uniphier_fi2c_priv { |
---|
.. | .. |
---|
117 | 106 | if (fifo_space-- <= 0) |
---|
118 | 107 | break; |
---|
119 | 108 | |
---|
120 | | - dev_dbg(&priv->adap.dev, "write data: %02x\n", *priv->buf); |
---|
121 | 109 | writel(*priv->buf++, priv->membase + UNIPHIER_FI2C_DTTX); |
---|
122 | 110 | priv->len--; |
---|
123 | 111 | } |
---|
.. | .. |
---|
133 | 121 | break; |
---|
134 | 122 | |
---|
135 | 123 | *priv->buf++ = readl(priv->membase + UNIPHIER_FI2C_DTRX); |
---|
136 | | - dev_dbg(&priv->adap.dev, "read data: %02x\n", priv->buf[-1]); |
---|
137 | 124 | priv->len--; |
---|
138 | 125 | } |
---|
139 | 126 | } |
---|
.. | .. |
---|
151 | 138 | |
---|
152 | 139 | static void uniphier_fi2c_stop(struct uniphier_fi2c_priv *priv) |
---|
153 | 140 | { |
---|
154 | | - dev_dbg(&priv->adap.dev, "stop condition\n"); |
---|
155 | | - |
---|
156 | 141 | priv->enabled_irqs |= UNIPHIER_FI2C_INT_STOP; |
---|
157 | 142 | uniphier_fi2c_set_irqs(priv); |
---|
158 | 143 | writel(UNIPHIER_FI2C_CR_MST | UNIPHIER_FI2C_CR_STO, |
---|
.. | .. |
---|
169 | 154 | irq_status = readl(priv->membase + UNIPHIER_FI2C_INT); |
---|
170 | 155 | irq_status &= priv->enabled_irqs; |
---|
171 | 156 | |
---|
172 | | - dev_dbg(&priv->adap.dev, |
---|
173 | | - "interrupt: enabled_irqs=%04x, irq_status=%04x\n", |
---|
174 | | - priv->enabled_irqs, irq_status); |
---|
175 | | - |
---|
176 | 157 | if (irq_status & UNIPHIER_FI2C_INT_STOP) |
---|
177 | 158 | goto complete; |
---|
178 | 159 | |
---|
179 | 160 | if (unlikely(irq_status & UNIPHIER_FI2C_INT_AL)) { |
---|
180 | | - dev_dbg(&priv->adap.dev, "arbitration lost\n"); |
---|
181 | 161 | priv->error = -EAGAIN; |
---|
182 | 162 | goto complete; |
---|
183 | 163 | } |
---|
184 | 164 | |
---|
185 | 165 | if (unlikely(irq_status & UNIPHIER_FI2C_INT_NA)) { |
---|
186 | | - dev_dbg(&priv->adap.dev, "could not get ACK\n"); |
---|
187 | 166 | priv->error = -ENXIO; |
---|
188 | 167 | if (priv->flags & UNIPHIER_FI2C_RD) { |
---|
189 | 168 | /* |
---|
.. | .. |
---|
224 | 203 | if (unlikely(priv->flags & UNIPHIER_FI2C_MANUAL_NACK)) { |
---|
225 | 204 | if (priv->len <= UNIPHIER_FI2C_FIFO_SIZE && |
---|
226 | 205 | !(priv->flags & UNIPHIER_FI2C_BYTE_WISE)) { |
---|
227 | | - dev_dbg(&priv->adap.dev, |
---|
228 | | - "enable read byte count IRQ\n"); |
---|
229 | 206 | priv->enabled_irqs |= UNIPHIER_FI2C_INT_RB; |
---|
230 | 207 | uniphier_fi2c_set_irqs(priv); |
---|
231 | 208 | priv->flags |= UNIPHIER_FI2C_BYTE_WISE; |
---|
232 | 209 | } |
---|
233 | | - if (priv->len <= 1) { |
---|
234 | | - dev_dbg(&priv->adap.dev, "set NACK\n"); |
---|
| 210 | + if (priv->len <= 1) |
---|
235 | 211 | writel(UNIPHIER_FI2C_CR_MST | |
---|
236 | 212 | UNIPHIER_FI2C_CR_NACK, |
---|
237 | 213 | priv->membase + UNIPHIER_FI2C_CR); |
---|
238 | | - } |
---|
239 | 214 | } |
---|
240 | 215 | |
---|
241 | 216 | goto handled; |
---|
.. | .. |
---|
269 | 244 | return IRQ_HANDLED; |
---|
270 | 245 | } |
---|
271 | 246 | |
---|
272 | | -static void uniphier_fi2c_tx_init(struct uniphier_fi2c_priv *priv, u16 addr) |
---|
| 247 | +static void uniphier_fi2c_tx_init(struct uniphier_fi2c_priv *priv, u16 addr, |
---|
| 248 | + bool repeat) |
---|
273 | 249 | { |
---|
274 | 250 | priv->enabled_irqs |= UNIPHIER_FI2C_INT_TE; |
---|
275 | 251 | uniphier_fi2c_set_irqs(priv); |
---|
.. | .. |
---|
279 | 255 | /* set slave address */ |
---|
280 | 256 | writel(UNIPHIER_FI2C_DTTX_CMD | addr << 1, |
---|
281 | 257 | priv->membase + UNIPHIER_FI2C_DTTX); |
---|
282 | | - /* first chunk of data */ |
---|
283 | | - uniphier_fi2c_fill_txfifo(priv, true); |
---|
| 258 | + /* |
---|
| 259 | + * First chunk of data. For a repeated START condition, do not write |
---|
| 260 | + * data to the TX fifo here to avoid the timing issue. |
---|
| 261 | + */ |
---|
| 262 | + if (!repeat) |
---|
| 263 | + uniphier_fi2c_fill_txfifo(priv, true); |
---|
284 | 264 | } |
---|
285 | 265 | |
---|
286 | 266 | static void uniphier_fi2c_rx_init(struct uniphier_fi2c_priv *priv, u16 addr) |
---|
.. | .. |
---|
338 | 318 | bool is_read = msg->flags & I2C_M_RD; |
---|
339 | 319 | unsigned long time_left, flags; |
---|
340 | 320 | |
---|
341 | | - dev_dbg(&adap->dev, "%s: addr=0x%02x, len=%d, repeat=%d, stop=%d\n", |
---|
342 | | - is_read ? "receive" : "transmit", msg->addr, msg->len, |
---|
343 | | - repeat, stop); |
---|
344 | | - |
---|
345 | 321 | priv->len = msg->len; |
---|
346 | 322 | priv->buf = msg->buf; |
---|
347 | 323 | priv->enabled_irqs = UNIPHIER_FI2C_INT_FAULTS; |
---|
.. | .. |
---|
361 | 337 | if (is_read) |
---|
362 | 338 | uniphier_fi2c_rx_init(priv, msg->addr); |
---|
363 | 339 | else |
---|
364 | | - uniphier_fi2c_tx_init(priv, msg->addr); |
---|
| 340 | + uniphier_fi2c_tx_init(priv, msg->addr, repeat); |
---|
365 | 341 | |
---|
366 | | - dev_dbg(&adap->dev, "start condition\n"); |
---|
367 | 342 | /* |
---|
368 | 343 | * For a repeated START condition, writing a slave address to the FIFO |
---|
369 | 344 | * kicks the controller. So, the UNIPHIER_FI2C_CR register should be |
---|
.. | .. |
---|
387 | 362 | uniphier_fi2c_recover(priv); |
---|
388 | 363 | return -ETIMEDOUT; |
---|
389 | 364 | } |
---|
390 | | - dev_dbg(&adap->dev, "complete\n"); |
---|
391 | 365 | |
---|
392 | 366 | if (unlikely(priv->flags & UNIPHIER_FI2C_DEFER_STOP_COMP)) { |
---|
393 | 367 | u32 status; |
---|
.. | .. |
---|
542 | 516 | { |
---|
543 | 517 | struct device *dev = &pdev->dev; |
---|
544 | 518 | struct uniphier_fi2c_priv *priv; |
---|
545 | | - struct resource *regs; |
---|
546 | 519 | u32 bus_speed; |
---|
547 | 520 | unsigned long clk_rate; |
---|
548 | 521 | int irq, ret; |
---|
.. | .. |
---|
551 | 524 | if (!priv) |
---|
552 | 525 | return -ENOMEM; |
---|
553 | 526 | |
---|
554 | | - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
555 | | - priv->membase = devm_ioremap_resource(dev, regs); |
---|
| 527 | + priv->membase = devm_platform_ioremap_resource(pdev, 0); |
---|
556 | 528 | if (IS_ERR(priv->membase)) |
---|
557 | 529 | return PTR_ERR(priv->membase); |
---|
558 | 530 | |
---|
559 | 531 | irq = platform_get_irq(pdev, 0); |
---|
560 | | - if (irq < 0) { |
---|
561 | | - dev_err(dev, "failed to get IRQ number\n"); |
---|
| 532 | + if (irq < 0) |
---|
562 | 533 | return irq; |
---|
563 | | - } |
---|
564 | 534 | |
---|
565 | 535 | if (of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed)) |
---|
566 | | - bus_speed = UNIPHIER_FI2C_DEFAULT_SPEED; |
---|
| 536 | + bus_speed = I2C_MAX_STANDARD_MODE_FREQ; |
---|
567 | 537 | |
---|
568 | | - if (!bus_speed || bus_speed > UNIPHIER_FI2C_MAX_SPEED) { |
---|
| 538 | + if (!bus_speed || bus_speed > I2C_MAX_FAST_MODE_FREQ) { |
---|
569 | 539 | dev_err(dev, "invalid clock-frequency %d\n", bus_speed); |
---|
570 | 540 | return -EINVAL; |
---|
571 | 541 | } |
---|