| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* ------------------------------------------------------------------------- */ |
|---|
| 2 | 3 | /* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx & IXP46x */ |
|---|
| 3 | 4 | /* ------------------------------------------------------------------------- */ |
|---|
| .. | .. |
|---|
| 23 | 24 | * |
|---|
| 24 | 25 | * - writing to slave address causes latchup on iop331. |
|---|
| 25 | 26 | * fix: driver refuses to address self. |
|---|
| 26 | | - * |
|---|
| 27 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 28 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 29 | | - * the Free Software Foundation, version 2. |
|---|
| 30 | 27 | */ |
|---|
| 31 | 28 | |
|---|
| 32 | 29 | #include <linux/interrupt.h> |
|---|
| .. | .. |
|---|
| 38 | 35 | #include <linux/platform_device.h> |
|---|
| 39 | 36 | #include <linux/i2c.h> |
|---|
| 40 | 37 | #include <linux/io.h> |
|---|
| 41 | | -#include <linux/gpio.h> |
|---|
| 38 | +#include <linux/gpio/consumer.h> |
|---|
| 42 | 39 | |
|---|
| 43 | 40 | #include "i2c-iop3xx.h" |
|---|
| 44 | 41 | |
|---|
| .. | .. |
|---|
| 71 | 68 | |
|---|
| 72 | 69 | /* |
|---|
| 73 | 70 | * Every time unit enable is asserted, GPOD needs to be cleared |
|---|
| 74 | | - * on IOP3XX to avoid data corruption on the bus. |
|---|
| 71 | + * on IOP3XX to avoid data corruption on the bus. We use the |
|---|
| 72 | + * gpiod_set_raw_value() to make sure the 0 hits the hardware |
|---|
| 73 | + * GPOD register. These descriptors are only passed along to |
|---|
| 74 | + * the device if this is necessary. |
|---|
| 75 | 75 | */ |
|---|
| 76 | | -#if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X) |
|---|
| 77 | | - if (iop3xx_adap->id == 0) { |
|---|
| 78 | | - gpio_set_value(7, 0); |
|---|
| 79 | | - gpio_set_value(6, 0); |
|---|
| 80 | | - } else { |
|---|
| 81 | | - gpio_set_value(5, 0); |
|---|
| 82 | | - gpio_set_value(4, 0); |
|---|
| 83 | | - } |
|---|
| 84 | | -#endif |
|---|
| 76 | + if (iop3xx_adap->gpio_scl) |
|---|
| 77 | + gpiod_set_raw_value(iop3xx_adap->gpio_scl, 0); |
|---|
| 78 | + if (iop3xx_adap->gpio_sda) |
|---|
| 79 | + gpiod_set_raw_value(iop3xx_adap->gpio_sda, 0); |
|---|
| 80 | + |
|---|
| 85 | 81 | /* NB SR bits not same position as CR IE bits :-( */ |
|---|
| 86 | 82 | iop3xx_adap->SR_enabled = |
|---|
| 87 | 83 | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD | |
|---|
| .. | .. |
|---|
| 434 | 430 | goto free_adapter; |
|---|
| 435 | 431 | } |
|---|
| 436 | 432 | |
|---|
| 433 | + adapter_data->gpio_scl = devm_gpiod_get_optional(&pdev->dev, |
|---|
| 434 | + "scl", |
|---|
| 435 | + GPIOD_ASIS); |
|---|
| 436 | + if (IS_ERR(adapter_data->gpio_scl)) { |
|---|
| 437 | + ret = PTR_ERR(adapter_data->gpio_scl); |
|---|
| 438 | + goto free_both; |
|---|
| 439 | + } |
|---|
| 440 | + adapter_data->gpio_sda = devm_gpiod_get_optional(&pdev->dev, |
|---|
| 441 | + "sda", |
|---|
| 442 | + GPIOD_ASIS); |
|---|
| 443 | + if (IS_ERR(adapter_data->gpio_sda)) { |
|---|
| 444 | + ret = PTR_ERR(adapter_data->gpio_sda); |
|---|
| 445 | + goto free_both; |
|---|
| 446 | + } |
|---|
| 447 | + |
|---|
| 437 | 448 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 438 | 449 | if (!res) { |
|---|
| 439 | 450 | ret = -ENODEV; |
|---|
| .. | .. |
|---|
| 469 | 480 | new_adapter->owner = THIS_MODULE; |
|---|
| 470 | 481 | new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; |
|---|
| 471 | 482 | new_adapter->dev.parent = &pdev->dev; |
|---|
| 483 | + new_adapter->dev.of_node = pdev->dev.of_node; |
|---|
| 472 | 484 | new_adapter->nr = pdev->id; |
|---|
| 473 | 485 | |
|---|
| 474 | 486 | /* |
|---|
| .. | .. |
|---|
| 506 | 518 | return ret; |
|---|
| 507 | 519 | } |
|---|
| 508 | 520 | |
|---|
| 521 | +static const struct of_device_id i2c_iop3xx_match[] = { |
|---|
| 522 | + { .compatible = "intel,iop3xx-i2c", }, |
|---|
| 523 | + { .compatible = "intel,ixp4xx-i2c", }, |
|---|
| 524 | + {}, |
|---|
| 525 | +}; |
|---|
| 526 | +MODULE_DEVICE_TABLE(of, i2c_iop3xx_match); |
|---|
| 509 | 527 | |
|---|
| 510 | 528 | static struct platform_driver iop3xx_i2c_driver = { |
|---|
| 511 | 529 | .probe = iop3xx_i2c_probe, |
|---|
| 512 | 530 | .remove = iop3xx_i2c_remove, |
|---|
| 513 | 531 | .driver = { |
|---|
| 514 | 532 | .name = "IOP3xx-I2C", |
|---|
| 533 | + .of_match_table = i2c_iop3xx_match, |
|---|
| 515 | 534 | }, |
|---|
| 516 | 535 | }; |
|---|
| 517 | 536 | |
|---|