.. | .. |
---|
18 | 18 | #include <linux/delay.h> |
---|
19 | 19 | #include <linux/err.h> |
---|
20 | 20 | #include <linux/i2c.h> |
---|
| 21 | +#include <linux/i2c-smbus.h> |
---|
21 | 22 | #include <linux/interrupt.h> |
---|
22 | 23 | #include <linux/io.h> |
---|
23 | 24 | #include <linux/iopoll.h> |
---|
| 25 | +#include <linux/mfd/syscon.h> |
---|
24 | 26 | #include <linux/module.h> |
---|
25 | 27 | #include <linux/of.h> |
---|
26 | 28 | #include <linux/of_address.h> |
---|
27 | 29 | #include <linux/of_platform.h> |
---|
28 | 30 | #include <linux/platform_device.h> |
---|
| 31 | +#include <linux/pinctrl/consumer.h> |
---|
| 32 | +#include <linux/pm_runtime.h> |
---|
| 33 | +#include <linux/pm_wakeirq.h> |
---|
| 34 | +#include <linux/regmap.h> |
---|
29 | 35 | #include <linux/reset.h> |
---|
30 | 36 | #include <linux/slab.h> |
---|
31 | 37 | |
---|
.. | .. |
---|
45 | 51 | |
---|
46 | 52 | /* STM32F7 I2C control 1 */ |
---|
47 | 53 | #define STM32F7_I2C_CR1_PECEN BIT(23) |
---|
| 54 | +#define STM32F7_I2C_CR1_SMBHEN BIT(20) |
---|
| 55 | +#define STM32F7_I2C_CR1_WUPEN BIT(18) |
---|
48 | 56 | #define STM32F7_I2C_CR1_SBC BIT(16) |
---|
49 | 57 | #define STM32F7_I2C_CR1_RXDMAEN BIT(15) |
---|
50 | 58 | #define STM32F7_I2C_CR1_TXDMAEN BIT(14) |
---|
.. | .. |
---|
146 | 154 | |
---|
147 | 155 | #define STM32F7_I2C_MAX_LEN 0xff |
---|
148 | 156 | #define STM32F7_I2C_DMA_LEN_MIN 0x16 |
---|
149 | | -#define STM32F7_I2C_MAX_SLAVE 0x2 |
---|
| 157 | +enum { |
---|
| 158 | + STM32F7_SLAVE_HOSTNOTIFY, |
---|
| 159 | + STM32F7_SLAVE_7_10_BITS_ADDR, |
---|
| 160 | + STM32F7_SLAVE_7_BITS_ADDR, |
---|
| 161 | + STM32F7_I2C_MAX_SLAVE |
---|
| 162 | +}; |
---|
150 | 163 | |
---|
151 | 164 | #define STM32F7_I2C_DNF_DEFAULT 0 |
---|
152 | 165 | #define STM32F7_I2C_DNF_MAX 15 |
---|
.. | .. |
---|
164 | 177 | #define STM32F7_SCLH_MAX BIT(8) |
---|
165 | 178 | #define STM32F7_SCLL_MAX BIT(8) |
---|
166 | 179 | |
---|
| 180 | +#define STM32F7_AUTOSUSPEND_DELAY (HZ / 100) |
---|
| 181 | + |
---|
| 182 | +/** |
---|
| 183 | + * struct stm32f7_i2c_regs - i2c f7 registers backup |
---|
| 184 | + * @cr1: Control register 1 |
---|
| 185 | + * @cr2: Control register 2 |
---|
| 186 | + * @oar1: Own address 1 register |
---|
| 187 | + * @oar2: Own address 2 register |
---|
| 188 | + * @tmgr: Timing register |
---|
| 189 | + */ |
---|
| 190 | +struct stm32f7_i2c_regs { |
---|
| 191 | + u32 cr1; |
---|
| 192 | + u32 cr2; |
---|
| 193 | + u32 oar1; |
---|
| 194 | + u32 oar2; |
---|
| 195 | + u32 tmgr; |
---|
| 196 | +}; |
---|
| 197 | + |
---|
167 | 198 | /** |
---|
168 | 199 | * struct stm32f7_i2c_spec - private i2c specification timing |
---|
169 | 200 | * @rate: I2C bus speed (Hz) |
---|
170 | | - * @rate_min: 80% of I2C bus speed (Hz) |
---|
171 | | - * @rate_max: 100% of I2C bus speed (Hz) |
---|
172 | 201 | * @fall_max: Max fall time of both SDA and SCL signals (ns) |
---|
173 | 202 | * @rise_max: Max rise time of both SDA and SCL signals (ns) |
---|
174 | 203 | * @hddat_min: Min data hold time (ns) |
---|
.. | .. |
---|
179 | 208 | */ |
---|
180 | 209 | struct stm32f7_i2c_spec { |
---|
181 | 210 | u32 rate; |
---|
182 | | - u32 rate_min; |
---|
183 | | - u32 rate_max; |
---|
184 | 211 | u32 fall_max; |
---|
185 | 212 | u32 rise_max; |
---|
186 | 213 | u32 hddat_min; |
---|
.. | .. |
---|
192 | 219 | |
---|
193 | 220 | /** |
---|
194 | 221 | * struct stm32f7_i2c_setup - private I2C timing setup parameters |
---|
195 | | - * @speed: I2C speed mode (standard, Fast Plus) |
---|
196 | 222 | * @speed_freq: I2C speed frequency (Hz) |
---|
197 | 223 | * @clock_src: I2C clock source frequency (Hz) |
---|
198 | 224 | * @rise_time: Rise time (ns) |
---|
199 | 225 | * @fall_time: Fall time (ns) |
---|
200 | 226 | * @dnf: Digital filter coefficient (0-16) |
---|
201 | 227 | * @analog_filter: Analog filter delay (On/Off) |
---|
| 228 | + * @fmp_clr_offset: Fast Mode Plus clear register offset from set register |
---|
202 | 229 | */ |
---|
203 | 230 | struct stm32f7_i2c_setup { |
---|
204 | | - enum stm32_i2c_speed speed; |
---|
205 | 231 | u32 speed_freq; |
---|
206 | 232 | u32 clock_src; |
---|
207 | 233 | u32 rise_time; |
---|
208 | 234 | u32 fall_time; |
---|
209 | 235 | u8 dnf; |
---|
210 | 236 | bool analog_filter; |
---|
| 237 | + u32 fmp_clr_offset; |
---|
211 | 238 | }; |
---|
212 | 239 | |
---|
213 | 240 | /** |
---|
.. | .. |
---|
263 | 290 | * @base: virtual memory area |
---|
264 | 291 | * @complete: completion of I2C message |
---|
265 | 292 | * @clk: hw i2c clock |
---|
266 | | - * @speed: I2C clock frequency of the controller. Standard, Fast or Fast+ |
---|
| 293 | + * @bus_rate: I2C clock frequency of the controller |
---|
267 | 294 | * @msg: Pointer to data to be written |
---|
268 | 295 | * @msg_num: number of I2C messages to be executed |
---|
269 | 296 | * @msg_id: message identifiant |
---|
.. | .. |
---|
272 | 299 | * @timing: I2C computed timings |
---|
273 | 300 | * @slave: list of slave devices registered on the I2C bus |
---|
274 | 301 | * @slave_running: slave device currently used |
---|
| 302 | + * @backup_regs: backup of i2c controller registers (for suspend/resume) |
---|
275 | 303 | * @slave_dir: transfer direction for the current slave device |
---|
276 | 304 | * @master_mode: boolean to know in which mode the I2C is running (master or |
---|
277 | 305 | * slave) |
---|
278 | 306 | * @dma: dma data |
---|
279 | 307 | * @use_dma: boolean to know if dma is used in the current transfer |
---|
| 308 | + * @regmap: holds SYSCFG phandle for Fast Mode Plus bits |
---|
| 309 | + * @fmp_sreg: register address for setting Fast Mode Plus bits |
---|
| 310 | + * @fmp_creg: register address for clearing Fast Mode Plus bits |
---|
| 311 | + * @fmp_mask: mask for Fast Mode Plus bits in set register |
---|
| 312 | + * @wakeup_src: boolean to know if the device is a wakeup source |
---|
| 313 | + * @smbus_mode: states that the controller is configured in SMBus mode |
---|
| 314 | + * @host_notify_client: SMBus host-notify client |
---|
280 | 315 | */ |
---|
281 | 316 | struct stm32f7_i2c_dev { |
---|
282 | 317 | struct i2c_adapter adap; |
---|
.. | .. |
---|
284 | 319 | void __iomem *base; |
---|
285 | 320 | struct completion complete; |
---|
286 | 321 | struct clk *clk; |
---|
287 | | - int speed; |
---|
| 322 | + unsigned int bus_rate; |
---|
288 | 323 | struct i2c_msg *msg; |
---|
289 | 324 | unsigned int msg_num; |
---|
290 | 325 | unsigned int msg_id; |
---|
.. | .. |
---|
293 | 328 | struct stm32f7_i2c_timings timing; |
---|
294 | 329 | struct i2c_client *slave[STM32F7_I2C_MAX_SLAVE]; |
---|
295 | 330 | struct i2c_client *slave_running; |
---|
| 331 | + struct stm32f7_i2c_regs backup_regs; |
---|
296 | 332 | u32 slave_dir; |
---|
297 | 333 | bool master_mode; |
---|
298 | 334 | struct stm32_i2c_dma *dma; |
---|
299 | 335 | bool use_dma; |
---|
| 336 | + struct regmap *regmap; |
---|
| 337 | + u32 fmp_sreg; |
---|
| 338 | + u32 fmp_creg; |
---|
| 339 | + u32 fmp_mask; |
---|
| 340 | + bool wakeup_src; |
---|
| 341 | + bool smbus_mode; |
---|
| 342 | + struct i2c_client *host_notify_client; |
---|
300 | 343 | }; |
---|
301 | 344 | |
---|
302 | 345 | /* |
---|
.. | .. |
---|
306 | 349 | * Table10. Characteristics of the SDA and SCL bus lines for Standard, Fast, |
---|
307 | 350 | * and Fast-mode Plus I2C-bus devices |
---|
308 | 351 | */ |
---|
309 | | -static struct stm32f7_i2c_spec i2c_specs[] = { |
---|
310 | | - [STM32_I2C_SPEED_STANDARD] = { |
---|
311 | | - .rate = 100000, |
---|
312 | | - .rate_min = 80000, |
---|
313 | | - .rate_max = 100000, |
---|
| 352 | +static struct stm32f7_i2c_spec stm32f7_i2c_specs[] = { |
---|
| 353 | + { |
---|
| 354 | + .rate = I2C_MAX_STANDARD_MODE_FREQ, |
---|
314 | 355 | .fall_max = 300, |
---|
315 | 356 | .rise_max = 1000, |
---|
316 | 357 | .hddat_min = 0, |
---|
.. | .. |
---|
319 | 360 | .l_min = 4700, |
---|
320 | 361 | .h_min = 4000, |
---|
321 | 362 | }, |
---|
322 | | - [STM32_I2C_SPEED_FAST] = { |
---|
323 | | - .rate = 400000, |
---|
324 | | - .rate_min = 320000, |
---|
325 | | - .rate_max = 400000, |
---|
| 363 | + { |
---|
| 364 | + .rate = I2C_MAX_FAST_MODE_FREQ, |
---|
326 | 365 | .fall_max = 300, |
---|
327 | 366 | .rise_max = 300, |
---|
328 | 367 | .hddat_min = 0, |
---|
.. | .. |
---|
331 | 370 | .l_min = 1300, |
---|
332 | 371 | .h_min = 600, |
---|
333 | 372 | }, |
---|
334 | | - [STM32_I2C_SPEED_FAST_PLUS] = { |
---|
335 | | - .rate = 1000000, |
---|
336 | | - .rate_min = 800000, |
---|
337 | | - .rate_max = 1000000, |
---|
| 373 | + { |
---|
| 374 | + .rate = I2C_MAX_FAST_MODE_PLUS_FREQ, |
---|
338 | 375 | .fall_max = 100, |
---|
339 | 376 | .rise_max = 120, |
---|
340 | 377 | .hddat_min = 0, |
---|
.. | .. |
---|
352 | 389 | .analog_filter = STM32F7_I2C_ANALOG_FILTER_ENABLE, |
---|
353 | 390 | }; |
---|
354 | 391 | |
---|
| 392 | +static const struct stm32f7_i2c_setup stm32mp15_setup = { |
---|
| 393 | + .rise_time = STM32F7_I2C_RISE_TIME_DEFAULT, |
---|
| 394 | + .fall_time = STM32F7_I2C_FALL_TIME_DEFAULT, |
---|
| 395 | + .dnf = STM32F7_I2C_DNF_DEFAULT, |
---|
| 396 | + .analog_filter = STM32F7_I2C_ANALOG_FILTER_ENABLE, |
---|
| 397 | + .fmp_clr_offset = 0x40, |
---|
| 398 | +}; |
---|
| 399 | + |
---|
355 | 400 | static inline void stm32f7_i2c_set_bits(void __iomem *reg, u32 mask) |
---|
356 | 401 | { |
---|
357 | 402 | writel_relaxed(readl_relaxed(reg) | mask, reg); |
---|
.. | .. |
---|
367 | 412 | stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, mask); |
---|
368 | 413 | } |
---|
369 | 414 | |
---|
| 415 | +static struct stm32f7_i2c_spec *stm32f7_get_specs(u32 rate) |
---|
| 416 | +{ |
---|
| 417 | + int i; |
---|
| 418 | + |
---|
| 419 | + for (i = 0; i < ARRAY_SIZE(stm32f7_i2c_specs); i++) |
---|
| 420 | + if (rate <= stm32f7_i2c_specs[i].rate) |
---|
| 421 | + return &stm32f7_i2c_specs[i]; |
---|
| 422 | + |
---|
| 423 | + return ERR_PTR(-EINVAL); |
---|
| 424 | +} |
---|
| 425 | + |
---|
| 426 | +#define RATE_MIN(rate) ((rate) * 8 / 10) |
---|
370 | 427 | static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev, |
---|
371 | 428 | struct stm32f7_i2c_setup *setup, |
---|
372 | 429 | struct stm32f7_i2c_timings *output) |
---|
373 | 430 | { |
---|
| 431 | + struct stm32f7_i2c_spec *specs; |
---|
374 | 432 | u32 p_prev = STM32F7_PRESC_MAX; |
---|
375 | 433 | u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC, |
---|
376 | 434 | setup->clock_src); |
---|
.. | .. |
---|
388 | 446 | u16 p, l, a, h; |
---|
389 | 447 | int ret = 0; |
---|
390 | 448 | |
---|
391 | | - if (setup->speed >= STM32_I2C_SPEED_END) { |
---|
392 | | - dev_err(i2c_dev->dev, "speed out of bound {%d/%d}\n", |
---|
393 | | - setup->speed, STM32_I2C_SPEED_END - 1); |
---|
| 449 | + specs = stm32f7_get_specs(setup->speed_freq); |
---|
| 450 | + if (specs == ERR_PTR(-EINVAL)) { |
---|
| 451 | + dev_err(i2c_dev->dev, "speed out of bound {%d}\n", |
---|
| 452 | + setup->speed_freq); |
---|
394 | 453 | return -EINVAL; |
---|
395 | 454 | } |
---|
396 | 455 | |
---|
397 | | - if ((setup->rise_time > i2c_specs[setup->speed].rise_max) || |
---|
398 | | - (setup->fall_time > i2c_specs[setup->speed].fall_max)) { |
---|
| 456 | + if ((setup->rise_time > specs->rise_max) || |
---|
| 457 | + (setup->fall_time > specs->fall_max)) { |
---|
399 | 458 | dev_err(i2c_dev->dev, |
---|
400 | 459 | "timings out of bound Rise{%d>%d}/Fall{%d>%d}\n", |
---|
401 | | - setup->rise_time, i2c_specs[setup->speed].rise_max, |
---|
402 | | - setup->fall_time, i2c_specs[setup->speed].fall_max); |
---|
| 460 | + setup->rise_time, specs->rise_max, |
---|
| 461 | + setup->fall_time, specs->fall_max); |
---|
403 | 462 | return -EINVAL; |
---|
404 | 463 | } |
---|
405 | 464 | |
---|
.. | .. |
---|
407 | 466 | dev_err(i2c_dev->dev, |
---|
408 | 467 | "DNF out of bound %d/%d\n", |
---|
409 | 468 | setup->dnf, STM32F7_I2C_DNF_MAX); |
---|
410 | | - return -EINVAL; |
---|
411 | | - } |
---|
412 | | - |
---|
413 | | - if (setup->speed_freq > i2c_specs[setup->speed].rate) { |
---|
414 | | - dev_err(i2c_dev->dev, "ERROR: Freq {%d/%d}\n", |
---|
415 | | - setup->speed_freq, i2c_specs[setup->speed].rate); |
---|
416 | 469 | return -EINVAL; |
---|
417 | 470 | } |
---|
418 | 471 | |
---|
.. | .. |
---|
425 | 478 | STM32F7_I2C_ANALOG_FILTER_DELAY_MAX : 0); |
---|
426 | 479 | dnf_delay = setup->dnf * i2cclk; |
---|
427 | 480 | |
---|
428 | | - sdadel_min = i2c_specs[setup->speed].hddat_min + setup->fall_time - |
---|
| 481 | + sdadel_min = specs->hddat_min + setup->fall_time - |
---|
429 | 482 | af_delay_min - (setup->dnf + 3) * i2cclk; |
---|
430 | 483 | |
---|
431 | | - sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time - |
---|
| 484 | + sdadel_max = specs->vddat_max - setup->rise_time - |
---|
432 | 485 | af_delay_max - (setup->dnf + 4) * i2cclk; |
---|
433 | 486 | |
---|
434 | | - scldel_min = setup->rise_time + i2c_specs[setup->speed].sudat_min; |
---|
| 487 | + scldel_min = setup->rise_time + specs->sudat_min; |
---|
435 | 488 | |
---|
436 | 489 | if (sdadel_min < 0) |
---|
437 | 490 | sdadel_min = 0; |
---|
.. | .. |
---|
469 | 522 | |
---|
470 | 523 | list_add_tail(&v->node, |
---|
471 | 524 | &solutions); |
---|
| 525 | + break; |
---|
472 | 526 | } |
---|
473 | 527 | } |
---|
| 528 | + |
---|
| 529 | + if (p_prev == p) |
---|
| 530 | + break; |
---|
474 | 531 | } |
---|
475 | 532 | } |
---|
476 | 533 | |
---|
.. | .. |
---|
482 | 539 | |
---|
483 | 540 | tsync = af_delay_min + dnf_delay + (2 * i2cclk); |
---|
484 | 541 | s = NULL; |
---|
485 | | - clk_max = NSEC_PER_SEC / i2c_specs[setup->speed].rate_min; |
---|
486 | | - clk_min = NSEC_PER_SEC / i2c_specs[setup->speed].rate_max; |
---|
| 542 | + clk_max = NSEC_PER_SEC / RATE_MIN(setup->speed_freq); |
---|
| 543 | + clk_min = NSEC_PER_SEC / setup->speed_freq; |
---|
487 | 544 | |
---|
488 | 545 | /* |
---|
489 | 546 | * Among Prescaler possibilities discovered above figures out SCL Low |
---|
.. | .. |
---|
501 | 558 | for (l = 0; l < STM32F7_SCLL_MAX; l++) { |
---|
502 | 559 | u32 tscl_l = (l + 1) * prescaler + tsync; |
---|
503 | 560 | |
---|
504 | | - if ((tscl_l < i2c_specs[setup->speed].l_min) || |
---|
| 561 | + if ((tscl_l < specs->l_min) || |
---|
505 | 562 | (i2cclk >= |
---|
506 | 563 | ((tscl_l - af_delay_min - dnf_delay) / 4))) { |
---|
507 | 564 | continue; |
---|
.. | .. |
---|
513 | 570 | setup->rise_time + setup->fall_time; |
---|
514 | 571 | |
---|
515 | 572 | if ((tscl >= clk_min) && (tscl <= clk_max) && |
---|
516 | | - (tscl_h >= i2c_specs[setup->speed].h_min) && |
---|
| 573 | + (tscl_h >= specs->h_min) && |
---|
517 | 574 | (i2cclk < tscl_h)) { |
---|
518 | 575 | int clk_error = tscl - i2cbus; |
---|
519 | 576 | |
---|
.. | .. |
---|
559 | 616 | return ret; |
---|
560 | 617 | } |
---|
561 | 618 | |
---|
| 619 | +static u32 stm32f7_get_lower_rate(u32 rate) |
---|
| 620 | +{ |
---|
| 621 | + int i = ARRAY_SIZE(stm32f7_i2c_specs); |
---|
| 622 | + |
---|
| 623 | + while (--i) |
---|
| 624 | + if (stm32f7_i2c_specs[i].rate < rate) |
---|
| 625 | + break; |
---|
| 626 | + |
---|
| 627 | + return stm32f7_i2c_specs[i].rate; |
---|
| 628 | +} |
---|
| 629 | + |
---|
562 | 630 | static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev, |
---|
563 | 631 | struct stm32f7_i2c_setup *setup) |
---|
564 | 632 | { |
---|
| 633 | + struct i2c_timings timings, *t = &timings; |
---|
565 | 634 | int ret = 0; |
---|
566 | 635 | |
---|
567 | | - setup->speed = i2c_dev->speed; |
---|
568 | | - setup->speed_freq = i2c_specs[setup->speed].rate; |
---|
| 636 | + t->bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ; |
---|
| 637 | + t->scl_rise_ns = i2c_dev->setup.rise_time; |
---|
| 638 | + t->scl_fall_ns = i2c_dev->setup.fall_time; |
---|
| 639 | + |
---|
| 640 | + i2c_parse_fw_timings(i2c_dev->dev, t, false); |
---|
| 641 | + |
---|
| 642 | + if (t->bus_freq_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) { |
---|
| 643 | + dev_err(i2c_dev->dev, "Invalid bus speed (%i>%i)\n", |
---|
| 644 | + t->bus_freq_hz, I2C_MAX_FAST_MODE_PLUS_FREQ); |
---|
| 645 | + return -EINVAL; |
---|
| 646 | + } |
---|
| 647 | + |
---|
| 648 | + setup->speed_freq = t->bus_freq_hz; |
---|
| 649 | + i2c_dev->setup.rise_time = t->scl_rise_ns; |
---|
| 650 | + i2c_dev->setup.fall_time = t->scl_fall_ns; |
---|
569 | 651 | setup->clock_src = clk_get_rate(i2c_dev->clk); |
---|
570 | 652 | |
---|
571 | 653 | if (!setup->clock_src) { |
---|
.. | .. |
---|
579 | 661 | if (ret) { |
---|
580 | 662 | dev_err(i2c_dev->dev, |
---|
581 | 663 | "failed to compute I2C timings.\n"); |
---|
582 | | - if (i2c_dev->speed > STM32_I2C_SPEED_STANDARD) { |
---|
583 | | - i2c_dev->speed--; |
---|
584 | | - setup->speed = i2c_dev->speed; |
---|
585 | | - setup->speed_freq = |
---|
586 | | - i2c_specs[setup->speed].rate; |
---|
587 | | - dev_warn(i2c_dev->dev, |
---|
588 | | - "downgrade I2C Speed Freq to (%i)\n", |
---|
589 | | - i2c_specs[setup->speed].rate); |
---|
590 | | - } else { |
---|
| 664 | + if (setup->speed_freq <= I2C_MAX_STANDARD_MODE_FREQ) |
---|
591 | 665 | break; |
---|
592 | | - } |
---|
| 666 | + setup->speed_freq = |
---|
| 667 | + stm32f7_get_lower_rate(setup->speed_freq); |
---|
| 668 | + dev_warn(i2c_dev->dev, |
---|
| 669 | + "downgrade I2C Speed Freq to (%i)\n", |
---|
| 670 | + setup->speed_freq); |
---|
593 | 671 | } |
---|
594 | 672 | } while (ret); |
---|
595 | 673 | |
---|
.. | .. |
---|
598 | 676 | return ret; |
---|
599 | 677 | } |
---|
600 | 678 | |
---|
601 | | - dev_dbg(i2c_dev->dev, "I2C Speed(%i), Freq(%i), Clk Source(%i)\n", |
---|
602 | | - setup->speed, setup->speed_freq, setup->clock_src); |
---|
| 679 | + dev_dbg(i2c_dev->dev, "I2C Speed(%i), Clk Source(%i)\n", |
---|
| 680 | + setup->speed_freq, setup->clock_src); |
---|
603 | 681 | dev_dbg(i2c_dev->dev, "I2C Rise(%i) and Fall(%i) Time\n", |
---|
604 | 682 | setup->rise_time, setup->fall_time); |
---|
605 | 683 | dev_dbg(i2c_dev->dev, "I2C Analog Filter(%s), DNF(%i)\n", |
---|
606 | 684 | (setup->analog_filter ? "On" : "Off"), setup->dnf); |
---|
| 685 | + |
---|
| 686 | + i2c_dev->bus_rate = setup->speed_freq; |
---|
607 | 687 | |
---|
608 | 688 | return 0; |
---|
609 | 689 | } |
---|
.. | .. |
---|
949 | 1029 | cr2 &= ~STM32F7_I2C_CR2_RD_WRN; |
---|
950 | 1030 | f7_msg->read_write = I2C_SMBUS_READ; |
---|
951 | 1031 | break; |
---|
| 1032 | + case I2C_SMBUS_I2C_BLOCK_DATA: |
---|
| 1033 | + /* Rely on emulated i2c transfer (through master_xfer) */ |
---|
| 1034 | + return -EOPNOTSUPP; |
---|
952 | 1035 | default: |
---|
953 | 1036 | dev_err(dev, "Unsupported smbus protocol %d\n", f7_msg->size); |
---|
954 | 1037 | return -EOPNOTSUPP; |
---|
.. | .. |
---|
1258 | 1341 | int i; |
---|
1259 | 1342 | |
---|
1260 | 1343 | /* |
---|
1261 | | - * slave[0] supports 7-bit and 10-bit slave address |
---|
1262 | | - * slave[1] supports 7-bit slave address only |
---|
| 1344 | + * slave[STM32F7_SLAVE_HOSTNOTIFY] support only SMBus Host address (0x8) |
---|
| 1345 | + * slave[STM32F7_SLAVE_7_10_BITS_ADDR] supports 7-bit and 10-bit slave address |
---|
| 1346 | + * slave[STM32F7_SLAVE_7_BITS_ADDR] supports 7-bit slave address only |
---|
1263 | 1347 | */ |
---|
1264 | | - for (i = STM32F7_I2C_MAX_SLAVE - 1; i >= 0; i--) { |
---|
1265 | | - if (i == 1 && (slave->flags & I2C_CLIENT_TEN)) |
---|
| 1348 | + if (i2c_dev->smbus_mode && (slave->addr == 0x08)) { |
---|
| 1349 | + if (i2c_dev->slave[STM32F7_SLAVE_HOSTNOTIFY]) |
---|
| 1350 | + goto fail; |
---|
| 1351 | + *id = STM32F7_SLAVE_HOSTNOTIFY; |
---|
| 1352 | + return 0; |
---|
| 1353 | + } |
---|
| 1354 | + |
---|
| 1355 | + for (i = STM32F7_I2C_MAX_SLAVE - 1; i > STM32F7_SLAVE_HOSTNOTIFY; i--) { |
---|
| 1356 | + if ((i == STM32F7_SLAVE_7_BITS_ADDR) && |
---|
| 1357 | + (slave->flags & I2C_CLIENT_TEN)) |
---|
1266 | 1358 | continue; |
---|
1267 | 1359 | if (!i2c_dev->slave[i]) { |
---|
1268 | 1360 | *id = i; |
---|
.. | .. |
---|
1270 | 1362 | } |
---|
1271 | 1363 | } |
---|
1272 | 1364 | |
---|
| 1365 | +fail: |
---|
1273 | 1366 | dev_err(dev, "Slave 0x%x could not be registered\n", slave->addr); |
---|
1274 | 1367 | |
---|
1275 | 1368 | return -EINVAL; |
---|
.. | .. |
---|
1402 | 1495 | |
---|
1403 | 1496 | /* NACK received */ |
---|
1404 | 1497 | if (status & STM32F7_I2C_ISR_NACKF) { |
---|
1405 | | - dev_dbg(i2c_dev->dev, "<%s>: Receive NACK\n", __func__); |
---|
| 1498 | + dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n", |
---|
| 1499 | + __func__, f7_msg->addr); |
---|
1406 | 1500 | writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR); |
---|
1407 | 1501 | if (i2c_dev->use_dma) { |
---|
1408 | 1502 | stm32f7_i2c_disable_dma_req(i2c_dev); |
---|
.. | .. |
---|
1563 | 1657 | i2c_dev->msg_id = 0; |
---|
1564 | 1658 | f7_msg->smbus = false; |
---|
1565 | 1659 | |
---|
1566 | | - ret = clk_enable(i2c_dev->clk); |
---|
1567 | | - if (ret) { |
---|
1568 | | - dev_err(i2c_dev->dev, "Failed to enable clock\n"); |
---|
| 1660 | + ret = pm_runtime_resume_and_get(i2c_dev->dev); |
---|
| 1661 | + if (ret < 0) |
---|
1569 | 1662 | return ret; |
---|
1570 | | - } |
---|
1571 | 1663 | |
---|
1572 | 1664 | ret = stm32f7_i2c_wait_free_bus(i2c_dev); |
---|
1573 | 1665 | if (ret) |
---|
1574 | | - goto clk_free; |
---|
| 1666 | + goto pm_free; |
---|
1575 | 1667 | |
---|
1576 | 1668 | stm32f7_i2c_xfer_msg(i2c_dev, msgs); |
---|
1577 | 1669 | |
---|
1578 | 1670 | time_left = wait_for_completion_timeout(&i2c_dev->complete, |
---|
1579 | 1671 | i2c_dev->adap.timeout); |
---|
1580 | 1672 | ret = f7_msg->result; |
---|
| 1673 | + if (ret) { |
---|
| 1674 | + /* |
---|
| 1675 | + * It is possible that some unsent data have already been |
---|
| 1676 | + * written into TXDR. To avoid sending old data in a |
---|
| 1677 | + * further transfer, flush TXDR in case of any error |
---|
| 1678 | + */ |
---|
| 1679 | + writel_relaxed(STM32F7_I2C_ISR_TXE, |
---|
| 1680 | + i2c_dev->base + STM32F7_I2C_ISR); |
---|
| 1681 | + goto pm_free; |
---|
| 1682 | + } |
---|
1581 | 1683 | |
---|
1582 | 1684 | if (!time_left) { |
---|
1583 | 1685 | dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n", |
---|
.. | .. |
---|
1588 | 1690 | ret = -ETIMEDOUT; |
---|
1589 | 1691 | } |
---|
1590 | 1692 | |
---|
1591 | | -clk_free: |
---|
1592 | | - clk_disable(i2c_dev->clk); |
---|
| 1693 | +pm_free: |
---|
| 1694 | + pm_runtime_mark_last_busy(i2c_dev->dev); |
---|
| 1695 | + pm_runtime_put_autosuspend(i2c_dev->dev); |
---|
1593 | 1696 | |
---|
1594 | 1697 | return (ret < 0) ? ret : num; |
---|
1595 | 1698 | } |
---|
.. | .. |
---|
1611 | 1714 | f7_msg->read_write = read_write; |
---|
1612 | 1715 | f7_msg->smbus = true; |
---|
1613 | 1716 | |
---|
1614 | | - ret = clk_enable(i2c_dev->clk); |
---|
1615 | | - if (ret) { |
---|
1616 | | - dev_err(i2c_dev->dev, "Failed to enable clock\n"); |
---|
| 1717 | + ret = pm_runtime_resume_and_get(dev); |
---|
| 1718 | + if (ret < 0) |
---|
1617 | 1719 | return ret; |
---|
1618 | | - } |
---|
1619 | 1720 | |
---|
1620 | 1721 | ret = stm32f7_i2c_wait_free_bus(i2c_dev); |
---|
1621 | 1722 | if (ret) |
---|
1622 | | - goto clk_free; |
---|
| 1723 | + goto pm_free; |
---|
1623 | 1724 | |
---|
1624 | 1725 | ret = stm32f7_i2c_smbus_xfer_msg(i2c_dev, flags, command, data); |
---|
1625 | 1726 | if (ret) |
---|
1626 | | - goto clk_free; |
---|
| 1727 | + goto pm_free; |
---|
1627 | 1728 | |
---|
1628 | 1729 | timeout = wait_for_completion_timeout(&i2c_dev->complete, |
---|
1629 | 1730 | i2c_dev->adap.timeout); |
---|
1630 | 1731 | ret = f7_msg->result; |
---|
1631 | | - if (ret) |
---|
1632 | | - goto clk_free; |
---|
| 1732 | + if (ret) { |
---|
| 1733 | + /* |
---|
| 1734 | + * It is possible that some unsent data have already been |
---|
| 1735 | + * written into TXDR. To avoid sending old data in a |
---|
| 1736 | + * further transfer, flush TXDR in case of any error |
---|
| 1737 | + */ |
---|
| 1738 | + writel_relaxed(STM32F7_I2C_ISR_TXE, |
---|
| 1739 | + i2c_dev->base + STM32F7_I2C_ISR); |
---|
| 1740 | + goto pm_free; |
---|
| 1741 | + } |
---|
1633 | 1742 | |
---|
1634 | 1743 | if (!timeout) { |
---|
1635 | 1744 | dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr); |
---|
.. | .. |
---|
1637 | 1746 | dmaengine_terminate_all(dma->chan_using); |
---|
1638 | 1747 | stm32f7_i2c_wait_free_bus(i2c_dev); |
---|
1639 | 1748 | ret = -ETIMEDOUT; |
---|
1640 | | - goto clk_free; |
---|
| 1749 | + goto pm_free; |
---|
1641 | 1750 | } |
---|
1642 | 1751 | |
---|
1643 | 1752 | /* Check PEC */ |
---|
1644 | 1753 | if ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK && read_write) { |
---|
1645 | 1754 | ret = stm32f7_i2c_smbus_check_pec(i2c_dev); |
---|
1646 | 1755 | if (ret) |
---|
1647 | | - goto clk_free; |
---|
| 1756 | + goto pm_free; |
---|
1648 | 1757 | } |
---|
1649 | 1758 | |
---|
1650 | 1759 | if (read_write && size != I2C_SMBUS_QUICK) { |
---|
.. | .. |
---|
1669 | 1778 | } |
---|
1670 | 1779 | } |
---|
1671 | 1780 | |
---|
1672 | | -clk_free: |
---|
1673 | | - clk_disable(i2c_dev->clk); |
---|
| 1781 | +pm_free: |
---|
| 1782 | + pm_runtime_mark_last_busy(dev); |
---|
| 1783 | + pm_runtime_put_autosuspend(dev); |
---|
1674 | 1784 | return ret; |
---|
| 1785 | +} |
---|
| 1786 | + |
---|
| 1787 | +static void stm32f7_i2c_enable_wakeup(struct stm32f7_i2c_dev *i2c_dev, |
---|
| 1788 | + bool enable) |
---|
| 1789 | +{ |
---|
| 1790 | + void __iomem *base = i2c_dev->base; |
---|
| 1791 | + u32 mask = STM32F7_I2C_CR1_WUPEN; |
---|
| 1792 | + |
---|
| 1793 | + if (!i2c_dev->wakeup_src) |
---|
| 1794 | + return; |
---|
| 1795 | + |
---|
| 1796 | + if (enable) { |
---|
| 1797 | + device_set_wakeup_enable(i2c_dev->dev, true); |
---|
| 1798 | + stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask); |
---|
| 1799 | + } else { |
---|
| 1800 | + device_set_wakeup_enable(i2c_dev->dev, false); |
---|
| 1801 | + stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1, mask); |
---|
| 1802 | + } |
---|
1675 | 1803 | } |
---|
1676 | 1804 | |
---|
1677 | 1805 | static int stm32f7_i2c_reg_slave(struct i2c_client *slave) |
---|
.. | .. |
---|
1696 | 1824 | if (ret) |
---|
1697 | 1825 | return ret; |
---|
1698 | 1826 | |
---|
1699 | | - if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) { |
---|
1700 | | - ret = clk_enable(i2c_dev->clk); |
---|
1701 | | - if (ret) { |
---|
1702 | | - dev_err(dev, "Failed to enable clock\n"); |
---|
1703 | | - return ret; |
---|
1704 | | - } |
---|
1705 | | - } |
---|
| 1827 | + ret = pm_runtime_resume_and_get(dev); |
---|
| 1828 | + if (ret < 0) |
---|
| 1829 | + return ret; |
---|
1706 | 1830 | |
---|
1707 | | - if (id == 0) { |
---|
| 1831 | + if (!stm32f7_i2c_is_slave_registered(i2c_dev)) |
---|
| 1832 | + stm32f7_i2c_enable_wakeup(i2c_dev, true); |
---|
| 1833 | + |
---|
| 1834 | + switch (id) { |
---|
| 1835 | + case 0: |
---|
| 1836 | + /* Slave SMBus Host */ |
---|
| 1837 | + i2c_dev->slave[id] = slave; |
---|
| 1838 | + break; |
---|
| 1839 | + |
---|
| 1840 | + case 1: |
---|
1708 | 1841 | /* Configure Own Address 1 */ |
---|
1709 | 1842 | oar1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR1); |
---|
1710 | 1843 | oar1 &= ~STM32F7_I2C_OAR1_MASK; |
---|
.. | .. |
---|
1717 | 1850 | oar1 |= STM32F7_I2C_OAR1_OA1EN; |
---|
1718 | 1851 | i2c_dev->slave[id] = slave; |
---|
1719 | 1852 | writel_relaxed(oar1, i2c_dev->base + STM32F7_I2C_OAR1); |
---|
1720 | | - } else if (id == 1) { |
---|
| 1853 | + break; |
---|
| 1854 | + |
---|
| 1855 | + case 2: |
---|
1721 | 1856 | /* Configure Own Address 2 */ |
---|
1722 | 1857 | oar2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR2); |
---|
1723 | 1858 | oar2 &= ~STM32F7_I2C_OAR2_MASK; |
---|
1724 | 1859 | if (slave->flags & I2C_CLIENT_TEN) { |
---|
1725 | 1860 | ret = -EOPNOTSUPP; |
---|
1726 | | - goto exit; |
---|
| 1861 | + goto pm_free; |
---|
1727 | 1862 | } |
---|
1728 | 1863 | |
---|
1729 | 1864 | oar2 |= STM32F7_I2C_OAR2_OA2_7(slave->addr); |
---|
1730 | 1865 | oar2 |= STM32F7_I2C_OAR2_OA2EN; |
---|
1731 | 1866 | i2c_dev->slave[id] = slave; |
---|
1732 | 1867 | writel_relaxed(oar2, i2c_dev->base + STM32F7_I2C_OAR2); |
---|
1733 | | - } else { |
---|
| 1868 | + break; |
---|
| 1869 | + |
---|
| 1870 | + default: |
---|
| 1871 | + dev_err(dev, "I2C slave id not supported\n"); |
---|
1734 | 1872 | ret = -ENODEV; |
---|
1735 | | - goto exit; |
---|
| 1873 | + goto pm_free; |
---|
1736 | 1874 | } |
---|
1737 | 1875 | |
---|
1738 | 1876 | /* Enable ACK */ |
---|
.. | .. |
---|
1743 | 1881 | STM32F7_I2C_CR1_PE; |
---|
1744 | 1882 | stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask); |
---|
1745 | 1883 | |
---|
1746 | | - return 0; |
---|
| 1884 | + ret = 0; |
---|
| 1885 | +pm_free: |
---|
| 1886 | + if (!stm32f7_i2c_is_slave_registered(i2c_dev)) |
---|
| 1887 | + stm32f7_i2c_enable_wakeup(i2c_dev, false); |
---|
1747 | 1888 | |
---|
1748 | | -exit: |
---|
1749 | | - if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) |
---|
1750 | | - clk_disable(i2c_dev->clk); |
---|
| 1889 | + pm_runtime_mark_last_busy(dev); |
---|
| 1890 | + pm_runtime_put_autosuspend(dev); |
---|
1751 | 1891 | |
---|
1752 | 1892 | return ret; |
---|
1753 | 1893 | } |
---|
.. | .. |
---|
1765 | 1905 | |
---|
1766 | 1906 | WARN_ON(!i2c_dev->slave[id]); |
---|
1767 | 1907 | |
---|
1768 | | - if (id == 0) { |
---|
| 1908 | + ret = pm_runtime_resume_and_get(i2c_dev->dev); |
---|
| 1909 | + if (ret < 0) |
---|
| 1910 | + return ret; |
---|
| 1911 | + |
---|
| 1912 | + if (id == 1) { |
---|
1769 | 1913 | mask = STM32F7_I2C_OAR1_OA1EN; |
---|
1770 | 1914 | stm32f7_i2c_clr_bits(base + STM32F7_I2C_OAR1, mask); |
---|
1771 | | - } else { |
---|
| 1915 | + } else if (id == 2) { |
---|
1772 | 1916 | mask = STM32F7_I2C_OAR2_OA2EN; |
---|
1773 | 1917 | stm32f7_i2c_clr_bits(base + STM32F7_I2C_OAR2, mask); |
---|
1774 | 1918 | } |
---|
1775 | 1919 | |
---|
1776 | 1920 | i2c_dev->slave[id] = NULL; |
---|
1777 | 1921 | |
---|
1778 | | - if (!(stm32f7_i2c_is_slave_registered(i2c_dev))) { |
---|
| 1922 | + if (!stm32f7_i2c_is_slave_registered(i2c_dev)) { |
---|
1779 | 1923 | stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK); |
---|
1780 | | - clk_disable(i2c_dev->clk); |
---|
| 1924 | + stm32f7_i2c_enable_wakeup(i2c_dev, false); |
---|
1781 | 1925 | } |
---|
| 1926 | + |
---|
| 1927 | + pm_runtime_mark_last_busy(i2c_dev->dev); |
---|
| 1928 | + pm_runtime_put_autosuspend(i2c_dev->dev); |
---|
1782 | 1929 | |
---|
1783 | 1930 | return 0; |
---|
1784 | 1931 | } |
---|
1785 | 1932 | |
---|
1786 | | -static u32 stm32f7_i2c_func(struct i2c_adapter *adap) |
---|
| 1933 | +static int stm32f7_i2c_write_fm_plus_bits(struct stm32f7_i2c_dev *i2c_dev, |
---|
| 1934 | + bool enable) |
---|
1787 | 1935 | { |
---|
1788 | | - return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SLAVE | |
---|
1789 | | - I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | |
---|
1790 | | - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | |
---|
1791 | | - I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | |
---|
1792 | | - I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_PEC; |
---|
| 1936 | + int ret; |
---|
| 1937 | + |
---|
| 1938 | + if (i2c_dev->bus_rate <= I2C_MAX_FAST_MODE_FREQ || |
---|
| 1939 | + IS_ERR_OR_NULL(i2c_dev->regmap)) |
---|
| 1940 | + /* Optional */ |
---|
| 1941 | + return 0; |
---|
| 1942 | + |
---|
| 1943 | + if (i2c_dev->fmp_sreg == i2c_dev->fmp_creg) |
---|
| 1944 | + ret = regmap_update_bits(i2c_dev->regmap, |
---|
| 1945 | + i2c_dev->fmp_sreg, |
---|
| 1946 | + i2c_dev->fmp_mask, |
---|
| 1947 | + enable ? i2c_dev->fmp_mask : 0); |
---|
| 1948 | + else |
---|
| 1949 | + ret = regmap_write(i2c_dev->regmap, |
---|
| 1950 | + enable ? i2c_dev->fmp_sreg : |
---|
| 1951 | + i2c_dev->fmp_creg, |
---|
| 1952 | + i2c_dev->fmp_mask); |
---|
| 1953 | + |
---|
| 1954 | + return ret; |
---|
1793 | 1955 | } |
---|
1794 | 1956 | |
---|
1795 | | -static struct i2c_algorithm stm32f7_i2c_algo = { |
---|
| 1957 | +static int stm32f7_i2c_setup_fm_plus_bits(struct platform_device *pdev, |
---|
| 1958 | + struct stm32f7_i2c_dev *i2c_dev) |
---|
| 1959 | +{ |
---|
| 1960 | + struct device_node *np = pdev->dev.of_node; |
---|
| 1961 | + int ret; |
---|
| 1962 | + |
---|
| 1963 | + i2c_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg-fmp"); |
---|
| 1964 | + if (IS_ERR(i2c_dev->regmap)) |
---|
| 1965 | + /* Optional */ |
---|
| 1966 | + return 0; |
---|
| 1967 | + |
---|
| 1968 | + ret = of_property_read_u32_index(np, "st,syscfg-fmp", 1, |
---|
| 1969 | + &i2c_dev->fmp_sreg); |
---|
| 1970 | + if (ret) |
---|
| 1971 | + return ret; |
---|
| 1972 | + |
---|
| 1973 | + i2c_dev->fmp_creg = i2c_dev->fmp_sreg + |
---|
| 1974 | + i2c_dev->setup.fmp_clr_offset; |
---|
| 1975 | + |
---|
| 1976 | + return of_property_read_u32_index(np, "st,syscfg-fmp", 2, |
---|
| 1977 | + &i2c_dev->fmp_mask); |
---|
| 1978 | +} |
---|
| 1979 | + |
---|
| 1980 | +static int stm32f7_i2c_enable_smbus_host(struct stm32f7_i2c_dev *i2c_dev) |
---|
| 1981 | +{ |
---|
| 1982 | + struct i2c_adapter *adap = &i2c_dev->adap; |
---|
| 1983 | + void __iomem *base = i2c_dev->base; |
---|
| 1984 | + struct i2c_client *client; |
---|
| 1985 | + |
---|
| 1986 | + client = i2c_new_slave_host_notify_device(adap); |
---|
| 1987 | + if (IS_ERR(client)) |
---|
| 1988 | + return PTR_ERR(client); |
---|
| 1989 | + |
---|
| 1990 | + i2c_dev->host_notify_client = client; |
---|
| 1991 | + |
---|
| 1992 | + /* Enable SMBus Host address */ |
---|
| 1993 | + stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, STM32F7_I2C_CR1_SMBHEN); |
---|
| 1994 | + |
---|
| 1995 | + return 0; |
---|
| 1996 | +} |
---|
| 1997 | + |
---|
| 1998 | +static void stm32f7_i2c_disable_smbus_host(struct stm32f7_i2c_dev *i2c_dev) |
---|
| 1999 | +{ |
---|
| 2000 | + void __iomem *base = i2c_dev->base; |
---|
| 2001 | + |
---|
| 2002 | + if (i2c_dev->host_notify_client) { |
---|
| 2003 | + /* Disable SMBus Host address */ |
---|
| 2004 | + stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1, |
---|
| 2005 | + STM32F7_I2C_CR1_SMBHEN); |
---|
| 2006 | + i2c_free_slave_host_notify_device(i2c_dev->host_notify_client); |
---|
| 2007 | + } |
---|
| 2008 | +} |
---|
| 2009 | + |
---|
| 2010 | +static u32 stm32f7_i2c_func(struct i2c_adapter *adap) |
---|
| 2011 | +{ |
---|
| 2012 | + struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(adap); |
---|
| 2013 | + |
---|
| 2014 | + u32 func = I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SLAVE | |
---|
| 2015 | + I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | |
---|
| 2016 | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | |
---|
| 2017 | + I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | |
---|
| 2018 | + I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_PEC | |
---|
| 2019 | + I2C_FUNC_SMBUS_I2C_BLOCK; |
---|
| 2020 | + |
---|
| 2021 | + if (i2c_dev->smbus_mode) |
---|
| 2022 | + func |= I2C_FUNC_SMBUS_HOST_NOTIFY; |
---|
| 2023 | + |
---|
| 2024 | + return func; |
---|
| 2025 | +} |
---|
| 2026 | + |
---|
| 2027 | +static const struct i2c_algorithm stm32f7_i2c_algo = { |
---|
1796 | 2028 | .master_xfer = stm32f7_i2c_xfer, |
---|
1797 | 2029 | .smbus_xfer = stm32f7_i2c_smbus_xfer, |
---|
1798 | 2030 | .functionality = stm32f7_i2c_func, |
---|
.. | .. |
---|
1805 | 2037 | struct stm32f7_i2c_dev *i2c_dev; |
---|
1806 | 2038 | const struct stm32f7_i2c_setup *setup; |
---|
1807 | 2039 | struct resource *res; |
---|
1808 | | - u32 clk_rate, rise_time, fall_time; |
---|
1809 | 2040 | struct i2c_adapter *adap; |
---|
1810 | 2041 | struct reset_control *rst; |
---|
1811 | 2042 | dma_addr_t phy_addr; |
---|
.. | .. |
---|
1815 | 2046 | if (!i2c_dev) |
---|
1816 | 2047 | return -ENOMEM; |
---|
1817 | 2048 | |
---|
1818 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1819 | | - i2c_dev->base = devm_ioremap_resource(&pdev->dev, res); |
---|
| 2049 | + i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); |
---|
1820 | 2050 | if (IS_ERR(i2c_dev->base)) |
---|
1821 | 2051 | return PTR_ERR(i2c_dev->base); |
---|
1822 | 2052 | phy_addr = (dma_addr_t)res->start; |
---|
.. | .. |
---|
1837 | 2067 | return irq_error ? : -ENOENT; |
---|
1838 | 2068 | } |
---|
1839 | 2069 | |
---|
| 2070 | + i2c_dev->wakeup_src = of_property_read_bool(pdev->dev.of_node, |
---|
| 2071 | + "wakeup-source"); |
---|
| 2072 | + |
---|
1840 | 2073 | i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); |
---|
1841 | | - if (IS_ERR(i2c_dev->clk)) { |
---|
1842 | | - dev_err(&pdev->dev, "Error: Missing controller clock\n"); |
---|
1843 | | - return PTR_ERR(i2c_dev->clk); |
---|
1844 | | - } |
---|
| 2074 | + if (IS_ERR(i2c_dev->clk)) |
---|
| 2075 | + return dev_err_probe(&pdev->dev, PTR_ERR(i2c_dev->clk), |
---|
| 2076 | + "Failed to get controller clock\n"); |
---|
| 2077 | + |
---|
1845 | 2078 | ret = clk_prepare_enable(i2c_dev->clk); |
---|
1846 | 2079 | if (ret) { |
---|
1847 | 2080 | dev_err(&pdev->dev, "Failed to prepare_enable clock\n"); |
---|
1848 | 2081 | return ret; |
---|
1849 | 2082 | } |
---|
1850 | 2083 | |
---|
1851 | | - i2c_dev->speed = STM32_I2C_SPEED_STANDARD; |
---|
1852 | | - ret = device_property_read_u32(&pdev->dev, "clock-frequency", |
---|
1853 | | - &clk_rate); |
---|
1854 | | - if (!ret && clk_rate >= 1000000) |
---|
1855 | | - i2c_dev->speed = STM32_I2C_SPEED_FAST_PLUS; |
---|
1856 | | - else if (!ret && clk_rate >= 400000) |
---|
1857 | | - i2c_dev->speed = STM32_I2C_SPEED_FAST; |
---|
1858 | | - else if (!ret && clk_rate >= 100000) |
---|
1859 | | - i2c_dev->speed = STM32_I2C_SPEED_STANDARD; |
---|
1860 | | - |
---|
1861 | 2084 | rst = devm_reset_control_get(&pdev->dev, NULL); |
---|
1862 | 2085 | if (IS_ERR(rst)) { |
---|
1863 | | - dev_err(&pdev->dev, "Error: Missing controller reset\n"); |
---|
1864 | | - ret = PTR_ERR(rst); |
---|
| 2086 | + ret = dev_err_probe(&pdev->dev, PTR_ERR(rst), |
---|
| 2087 | + "Error: Missing reset ctrl\n"); |
---|
1865 | 2088 | goto clk_free; |
---|
1866 | 2089 | } |
---|
1867 | 2090 | reset_control_assert(rst); |
---|
.. | .. |
---|
1897 | 2120 | } |
---|
1898 | 2121 | i2c_dev->setup = *setup; |
---|
1899 | 2122 | |
---|
1900 | | - ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-rising-time-ns", |
---|
1901 | | - &rise_time); |
---|
1902 | | - if (!ret) |
---|
1903 | | - i2c_dev->setup.rise_time = rise_time; |
---|
1904 | | - |
---|
1905 | | - ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-falling-time-ns", |
---|
1906 | | - &fall_time); |
---|
1907 | | - if (!ret) |
---|
1908 | | - i2c_dev->setup.fall_time = fall_time; |
---|
1909 | | - |
---|
1910 | 2123 | ret = stm32f7_i2c_setup_timing(i2c_dev, &i2c_dev->setup); |
---|
1911 | 2124 | if (ret) |
---|
1912 | 2125 | goto clk_free; |
---|
1913 | 2126 | |
---|
1914 | | - stm32f7_i2c_hw_config(i2c_dev); |
---|
| 2127 | + /* Setup Fast mode plus if necessary */ |
---|
| 2128 | + if (i2c_dev->bus_rate > I2C_MAX_FAST_MODE_FREQ) { |
---|
| 2129 | + ret = stm32f7_i2c_setup_fm_plus_bits(pdev, i2c_dev); |
---|
| 2130 | + if (ret) |
---|
| 2131 | + goto clk_free; |
---|
| 2132 | + ret = stm32f7_i2c_write_fm_plus_bits(i2c_dev, true); |
---|
| 2133 | + if (ret) |
---|
| 2134 | + goto clk_free; |
---|
| 2135 | + } |
---|
1915 | 2136 | |
---|
1916 | 2137 | adap = &i2c_dev->adap; |
---|
1917 | 2138 | i2c_set_adapdata(adap, i2c_dev); |
---|
.. | .. |
---|
1930 | 2151 | i2c_dev->dma = stm32_i2c_dma_request(i2c_dev->dev, phy_addr, |
---|
1931 | 2152 | STM32F7_I2C_TXDR, |
---|
1932 | 2153 | STM32F7_I2C_RXDR); |
---|
1933 | | - if (PTR_ERR(i2c_dev->dma) == -ENODEV) |
---|
1934 | | - i2c_dev->dma = NULL; |
---|
1935 | | - else if (IS_ERR(i2c_dev->dma)) { |
---|
| 2154 | + if (IS_ERR(i2c_dev->dma)) { |
---|
1936 | 2155 | ret = PTR_ERR(i2c_dev->dma); |
---|
1937 | | - if (ret != -EPROBE_DEFER) |
---|
1938 | | - dev_err(&pdev->dev, |
---|
1939 | | - "Failed to request dma error %i\n", ret); |
---|
1940 | | - goto clk_free; |
---|
| 2156 | + /* DMA support is optional, only report other errors */ |
---|
| 2157 | + if (ret != -ENODEV) |
---|
| 2158 | + goto fmp_clear; |
---|
| 2159 | + dev_dbg(i2c_dev->dev, "No DMA option: fallback using interrupts\n"); |
---|
| 2160 | + i2c_dev->dma = NULL; |
---|
1941 | 2161 | } |
---|
1942 | 2162 | |
---|
1943 | | - ret = i2c_add_adapter(adap); |
---|
1944 | | - if (ret) |
---|
1945 | | - goto clk_free; |
---|
| 2163 | + if (i2c_dev->wakeup_src) { |
---|
| 2164 | + device_set_wakeup_capable(i2c_dev->dev, true); |
---|
| 2165 | + |
---|
| 2166 | + ret = dev_pm_set_wake_irq(i2c_dev->dev, irq_event); |
---|
| 2167 | + if (ret) { |
---|
| 2168 | + dev_err(i2c_dev->dev, "Failed to set wake up irq\n"); |
---|
| 2169 | + goto clr_wakeup_capable; |
---|
| 2170 | + } |
---|
| 2171 | + } |
---|
1946 | 2172 | |
---|
1947 | 2173 | platform_set_drvdata(pdev, i2c_dev); |
---|
1948 | 2174 | |
---|
1949 | | - clk_disable(i2c_dev->clk); |
---|
| 2175 | + pm_runtime_set_autosuspend_delay(i2c_dev->dev, |
---|
| 2176 | + STM32F7_AUTOSUSPEND_DELAY); |
---|
| 2177 | + pm_runtime_use_autosuspend(i2c_dev->dev); |
---|
| 2178 | + pm_runtime_set_active(i2c_dev->dev); |
---|
| 2179 | + pm_runtime_enable(i2c_dev->dev); |
---|
| 2180 | + |
---|
| 2181 | + pm_runtime_get_noresume(&pdev->dev); |
---|
| 2182 | + |
---|
| 2183 | + stm32f7_i2c_hw_config(i2c_dev); |
---|
| 2184 | + |
---|
| 2185 | + i2c_dev->smbus_mode = of_property_read_bool(pdev->dev.of_node, "smbus"); |
---|
| 2186 | + |
---|
| 2187 | + ret = i2c_add_adapter(adap); |
---|
| 2188 | + if (ret) |
---|
| 2189 | + goto pm_disable; |
---|
| 2190 | + |
---|
| 2191 | + if (i2c_dev->smbus_mode) { |
---|
| 2192 | + ret = stm32f7_i2c_enable_smbus_host(i2c_dev); |
---|
| 2193 | + if (ret) { |
---|
| 2194 | + dev_err(i2c_dev->dev, |
---|
| 2195 | + "failed to enable SMBus Host-Notify protocol (%d)\n", |
---|
| 2196 | + ret); |
---|
| 2197 | + goto i2c_adapter_remove; |
---|
| 2198 | + } |
---|
| 2199 | + } |
---|
1950 | 2200 | |
---|
1951 | 2201 | dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr); |
---|
1952 | 2202 | |
---|
| 2203 | + pm_runtime_mark_last_busy(i2c_dev->dev); |
---|
| 2204 | + pm_runtime_put_autosuspend(i2c_dev->dev); |
---|
| 2205 | + |
---|
1953 | 2206 | return 0; |
---|
| 2207 | + |
---|
| 2208 | +i2c_adapter_remove: |
---|
| 2209 | + i2c_del_adapter(adap); |
---|
| 2210 | + |
---|
| 2211 | +pm_disable: |
---|
| 2212 | + pm_runtime_put_noidle(i2c_dev->dev); |
---|
| 2213 | + pm_runtime_disable(i2c_dev->dev); |
---|
| 2214 | + pm_runtime_set_suspended(i2c_dev->dev); |
---|
| 2215 | + pm_runtime_dont_use_autosuspend(i2c_dev->dev); |
---|
| 2216 | + |
---|
| 2217 | + if (i2c_dev->wakeup_src) |
---|
| 2218 | + dev_pm_clear_wake_irq(i2c_dev->dev); |
---|
| 2219 | + |
---|
| 2220 | +clr_wakeup_capable: |
---|
| 2221 | + if (i2c_dev->wakeup_src) |
---|
| 2222 | + device_set_wakeup_capable(i2c_dev->dev, false); |
---|
| 2223 | + |
---|
| 2224 | + if (i2c_dev->dma) { |
---|
| 2225 | + stm32_i2c_dma_free(i2c_dev->dma); |
---|
| 2226 | + i2c_dev->dma = NULL; |
---|
| 2227 | + } |
---|
| 2228 | + |
---|
| 2229 | +fmp_clear: |
---|
| 2230 | + stm32f7_i2c_write_fm_plus_bits(i2c_dev, false); |
---|
1954 | 2231 | |
---|
1955 | 2232 | clk_free: |
---|
1956 | 2233 | clk_disable_unprepare(i2c_dev->clk); |
---|
.. | .. |
---|
1962 | 2239 | { |
---|
1963 | 2240 | struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev); |
---|
1964 | 2241 | |
---|
| 2242 | + stm32f7_i2c_disable_smbus_host(i2c_dev); |
---|
| 2243 | + |
---|
| 2244 | + i2c_del_adapter(&i2c_dev->adap); |
---|
| 2245 | + pm_runtime_get_sync(i2c_dev->dev); |
---|
| 2246 | + |
---|
| 2247 | + if (i2c_dev->wakeup_src) { |
---|
| 2248 | + dev_pm_clear_wake_irq(i2c_dev->dev); |
---|
| 2249 | + /* |
---|
| 2250 | + * enforce that wakeup is disabled and that the device |
---|
| 2251 | + * is marked as non wakeup capable |
---|
| 2252 | + */ |
---|
| 2253 | + device_init_wakeup(i2c_dev->dev, false); |
---|
| 2254 | + } |
---|
| 2255 | + |
---|
| 2256 | + pm_runtime_put_noidle(i2c_dev->dev); |
---|
| 2257 | + pm_runtime_disable(i2c_dev->dev); |
---|
| 2258 | + pm_runtime_set_suspended(i2c_dev->dev); |
---|
| 2259 | + pm_runtime_dont_use_autosuspend(i2c_dev->dev); |
---|
| 2260 | + |
---|
1965 | 2261 | if (i2c_dev->dma) { |
---|
1966 | 2262 | stm32_i2c_dma_free(i2c_dev->dma); |
---|
1967 | 2263 | i2c_dev->dma = NULL; |
---|
1968 | 2264 | } |
---|
1969 | 2265 | |
---|
1970 | | - i2c_del_adapter(&i2c_dev->adap); |
---|
| 2266 | + stm32f7_i2c_write_fm_plus_bits(i2c_dev, false); |
---|
1971 | 2267 | |
---|
1972 | | - clk_unprepare(i2c_dev->clk); |
---|
| 2268 | + clk_disable_unprepare(i2c_dev->clk); |
---|
1973 | 2269 | |
---|
1974 | 2270 | return 0; |
---|
1975 | 2271 | } |
---|
1976 | 2272 | |
---|
| 2273 | +static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev) |
---|
| 2274 | +{ |
---|
| 2275 | + struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); |
---|
| 2276 | + |
---|
| 2277 | + if (!stm32f7_i2c_is_slave_registered(i2c_dev)) |
---|
| 2278 | + clk_disable_unprepare(i2c_dev->clk); |
---|
| 2279 | + |
---|
| 2280 | + return 0; |
---|
| 2281 | +} |
---|
| 2282 | + |
---|
| 2283 | +static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev) |
---|
| 2284 | +{ |
---|
| 2285 | + struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); |
---|
| 2286 | + int ret; |
---|
| 2287 | + |
---|
| 2288 | + if (!stm32f7_i2c_is_slave_registered(i2c_dev)) { |
---|
| 2289 | + ret = clk_prepare_enable(i2c_dev->clk); |
---|
| 2290 | + if (ret) { |
---|
| 2291 | + dev_err(dev, "failed to prepare_enable clock\n"); |
---|
| 2292 | + return ret; |
---|
| 2293 | + } |
---|
| 2294 | + } |
---|
| 2295 | + |
---|
| 2296 | + return 0; |
---|
| 2297 | +} |
---|
| 2298 | + |
---|
| 2299 | +#ifdef CONFIG_PM_SLEEP |
---|
| 2300 | +static int stm32f7_i2c_regs_backup(struct stm32f7_i2c_dev *i2c_dev) |
---|
| 2301 | +{ |
---|
| 2302 | + int ret; |
---|
| 2303 | + struct stm32f7_i2c_regs *backup_regs = &i2c_dev->backup_regs; |
---|
| 2304 | + |
---|
| 2305 | + ret = pm_runtime_resume_and_get(i2c_dev->dev); |
---|
| 2306 | + if (ret < 0) |
---|
| 2307 | + return ret; |
---|
| 2308 | + |
---|
| 2309 | + backup_regs->cr1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR1); |
---|
| 2310 | + backup_regs->cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2); |
---|
| 2311 | + backup_regs->oar1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR1); |
---|
| 2312 | + backup_regs->oar2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR2); |
---|
| 2313 | + backup_regs->tmgr = readl_relaxed(i2c_dev->base + STM32F7_I2C_TIMINGR); |
---|
| 2314 | + stm32f7_i2c_write_fm_plus_bits(i2c_dev, false); |
---|
| 2315 | + |
---|
| 2316 | + pm_runtime_put_sync(i2c_dev->dev); |
---|
| 2317 | + |
---|
| 2318 | + return ret; |
---|
| 2319 | +} |
---|
| 2320 | + |
---|
| 2321 | +static int stm32f7_i2c_regs_restore(struct stm32f7_i2c_dev *i2c_dev) |
---|
| 2322 | +{ |
---|
| 2323 | + u32 cr1; |
---|
| 2324 | + int ret; |
---|
| 2325 | + struct stm32f7_i2c_regs *backup_regs = &i2c_dev->backup_regs; |
---|
| 2326 | + |
---|
| 2327 | + ret = pm_runtime_resume_and_get(i2c_dev->dev); |
---|
| 2328 | + if (ret < 0) |
---|
| 2329 | + return ret; |
---|
| 2330 | + |
---|
| 2331 | + cr1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR1); |
---|
| 2332 | + if (cr1 & STM32F7_I2C_CR1_PE) |
---|
| 2333 | + stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, |
---|
| 2334 | + STM32F7_I2C_CR1_PE); |
---|
| 2335 | + |
---|
| 2336 | + writel_relaxed(backup_regs->tmgr, i2c_dev->base + STM32F7_I2C_TIMINGR); |
---|
| 2337 | + writel_relaxed(backup_regs->cr1 & ~STM32F7_I2C_CR1_PE, |
---|
| 2338 | + i2c_dev->base + STM32F7_I2C_CR1); |
---|
| 2339 | + if (backup_regs->cr1 & STM32F7_I2C_CR1_PE) |
---|
| 2340 | + stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1, |
---|
| 2341 | + STM32F7_I2C_CR1_PE); |
---|
| 2342 | + writel_relaxed(backup_regs->cr2, i2c_dev->base + STM32F7_I2C_CR2); |
---|
| 2343 | + writel_relaxed(backup_regs->oar1, i2c_dev->base + STM32F7_I2C_OAR1); |
---|
| 2344 | + writel_relaxed(backup_regs->oar2, i2c_dev->base + STM32F7_I2C_OAR2); |
---|
| 2345 | + stm32f7_i2c_write_fm_plus_bits(i2c_dev, true); |
---|
| 2346 | + |
---|
| 2347 | + pm_runtime_put_sync(i2c_dev->dev); |
---|
| 2348 | + |
---|
| 2349 | + return ret; |
---|
| 2350 | +} |
---|
| 2351 | + |
---|
| 2352 | +static int stm32f7_i2c_suspend(struct device *dev) |
---|
| 2353 | +{ |
---|
| 2354 | + struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); |
---|
| 2355 | + int ret; |
---|
| 2356 | + |
---|
| 2357 | + i2c_mark_adapter_suspended(&i2c_dev->adap); |
---|
| 2358 | + |
---|
| 2359 | + if (!device_may_wakeup(dev) && !dev->power.wakeup_path) { |
---|
| 2360 | + ret = stm32f7_i2c_regs_backup(i2c_dev); |
---|
| 2361 | + if (ret < 0) { |
---|
| 2362 | + i2c_mark_adapter_resumed(&i2c_dev->adap); |
---|
| 2363 | + return ret; |
---|
| 2364 | + } |
---|
| 2365 | + |
---|
| 2366 | + pinctrl_pm_select_sleep_state(dev); |
---|
| 2367 | + pm_runtime_force_suspend(dev); |
---|
| 2368 | + } |
---|
| 2369 | + |
---|
| 2370 | + return 0; |
---|
| 2371 | +} |
---|
| 2372 | + |
---|
| 2373 | +static int stm32f7_i2c_resume(struct device *dev) |
---|
| 2374 | +{ |
---|
| 2375 | + struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); |
---|
| 2376 | + int ret; |
---|
| 2377 | + |
---|
| 2378 | + if (!device_may_wakeup(dev) && !dev->power.wakeup_path) { |
---|
| 2379 | + ret = pm_runtime_force_resume(dev); |
---|
| 2380 | + if (ret < 0) |
---|
| 2381 | + return ret; |
---|
| 2382 | + pinctrl_pm_select_default_state(dev); |
---|
| 2383 | + |
---|
| 2384 | + ret = stm32f7_i2c_regs_restore(i2c_dev); |
---|
| 2385 | + if (ret < 0) |
---|
| 2386 | + return ret; |
---|
| 2387 | + } |
---|
| 2388 | + |
---|
| 2389 | + i2c_mark_adapter_resumed(&i2c_dev->adap); |
---|
| 2390 | + |
---|
| 2391 | + return 0; |
---|
| 2392 | +} |
---|
| 2393 | +#endif |
---|
| 2394 | + |
---|
| 2395 | +static const struct dev_pm_ops stm32f7_i2c_pm_ops = { |
---|
| 2396 | + SET_RUNTIME_PM_OPS(stm32f7_i2c_runtime_suspend, |
---|
| 2397 | + stm32f7_i2c_runtime_resume, NULL) |
---|
| 2398 | + SET_SYSTEM_SLEEP_PM_OPS(stm32f7_i2c_suspend, stm32f7_i2c_resume) |
---|
| 2399 | +}; |
---|
| 2400 | + |
---|
1977 | 2401 | static const struct of_device_id stm32f7_i2c_match[] = { |
---|
1978 | 2402 | { .compatible = "st,stm32f7-i2c", .data = &stm32f7_setup}, |
---|
| 2403 | + { .compatible = "st,stm32mp15-i2c", .data = &stm32mp15_setup}, |
---|
1979 | 2404 | {}, |
---|
1980 | 2405 | }; |
---|
1981 | 2406 | MODULE_DEVICE_TABLE(of, stm32f7_i2c_match); |
---|
.. | .. |
---|
1984 | 2409 | .driver = { |
---|
1985 | 2410 | .name = "stm32f7-i2c", |
---|
1986 | 2411 | .of_match_table = stm32f7_i2c_match, |
---|
| 2412 | + .pm = &stm32f7_i2c_pm_ops, |
---|
1987 | 2413 | }, |
---|
1988 | 2414 | .probe = stm32f7_i2c_probe, |
---|
1989 | 2415 | .remove = stm32f7_i2c_remove, |
---|