| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* linux/drivers/i2c/busses/i2c-s3c2410.c |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2004,2005,2009 Simtec Electronics |
|---|
| 4 | 5 | * Ben Dooks <ben@simtec.co.uk> |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * S3C2410 I2C Controller |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | 8 | */ |
|---|
| 18 | 9 | |
|---|
| 19 | 10 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 33 | 24 | #include <linux/slab.h> |
|---|
| 34 | 25 | #include <linux/io.h> |
|---|
| 35 | 26 | #include <linux/of.h> |
|---|
| 36 | | -#include <linux/of_gpio.h> |
|---|
| 27 | +#include <linux/gpio/consumer.h> |
|---|
| 37 | 28 | #include <linux/pinctrl/consumer.h> |
|---|
| 38 | 29 | #include <linux/mfd/syscon.h> |
|---|
| 39 | 30 | #include <linux/regmap.h> |
|---|
| .. | .. |
|---|
| 104 | 95 | struct s3c24xx_i2c { |
|---|
| 105 | 96 | wait_queue_head_t wait; |
|---|
| 106 | 97 | kernel_ulong_t quirks; |
|---|
| 107 | | - unsigned int suspended:1; |
|---|
| 108 | 98 | |
|---|
| 109 | 99 | struct i2c_msg *msg; |
|---|
| 110 | 100 | unsigned int msg_num; |
|---|
| .. | .. |
|---|
| 123 | 113 | struct i2c_adapter adap; |
|---|
| 124 | 114 | |
|---|
| 125 | 115 | struct s3c2410_platform_i2c *pdata; |
|---|
| 126 | | - int gpios[2]; |
|---|
| 116 | + struct gpio_desc *gpios[2]; |
|---|
| 127 | 117 | struct pinctrl *pctrl; |
|---|
| 128 | 118 | #if defined(CONFIG_ARM_S3C24XX_CPUFREQ) |
|---|
| 129 | 119 | struct notifier_block freq_transition; |
|---|
| .. | .. |
|---|
| 445 | 435 | * fall through to the write state, as we will need to |
|---|
| 446 | 436 | * send a byte as well |
|---|
| 447 | 437 | */ |
|---|
| 448 | | - |
|---|
| 438 | + fallthrough; |
|---|
| 449 | 439 | case STATE_WRITE: |
|---|
| 450 | 440 | /* |
|---|
| 451 | 441 | * we are writing data to the device... check for the |
|---|
| .. | .. |
|---|
| 706 | 696 | unsigned long timeout; |
|---|
| 707 | 697 | int ret; |
|---|
| 708 | 698 | |
|---|
| 709 | | - if (i2c->suspended) |
|---|
| 710 | | - return -EIO; |
|---|
| 711 | | - |
|---|
| 712 | 699 | ret = s3c24xx_i2c_set_master(i2c); |
|---|
| 713 | 700 | if (ret != 0) { |
|---|
| 714 | 701 | dev_err(i2c->dev, "cannot get bus (error %d)\n", ret); |
|---|
| .. | .. |
|---|
| 850 | 837 | int freq; |
|---|
| 851 | 838 | |
|---|
| 852 | 839 | i2c->clkrate = clkin; |
|---|
| 853 | | - clkin /= 1000; /* clkin now in KHz */ |
|---|
| 840 | + clkin /= 1000; /* clkin now in KHz */ |
|---|
| 854 | 841 | |
|---|
| 855 | 842 | dev_dbg(i2c->dev, "pdata desired frequency %lu\n", pdata->frequency); |
|---|
| 856 | 843 | |
|---|
| 857 | | - target_frequency = pdata->frequency ? pdata->frequency : 100000; |
|---|
| 844 | + target_frequency = pdata->frequency ?: I2C_MAX_STANDARD_MODE_FREQ; |
|---|
| 858 | 845 | |
|---|
| 859 | 846 | target_frequency /= 1000; /* Target frequency now in KHz */ |
|---|
| 860 | 847 | |
|---|
| .. | .. |
|---|
| 963 | 950 | #ifdef CONFIG_OF |
|---|
| 964 | 951 | static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) |
|---|
| 965 | 952 | { |
|---|
| 966 | | - int idx, gpio, ret; |
|---|
| 953 | + int i; |
|---|
| 967 | 954 | |
|---|
| 968 | 955 | if (i2c->quirks & QUIRK_NO_GPIO) |
|---|
| 969 | 956 | return 0; |
|---|
| 970 | 957 | |
|---|
| 971 | | - for (idx = 0; idx < 2; idx++) { |
|---|
| 972 | | - gpio = of_get_gpio(i2c->dev->of_node, idx); |
|---|
| 973 | | - if (!gpio_is_valid(gpio)) { |
|---|
| 974 | | - dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio); |
|---|
| 975 | | - goto free_gpio; |
|---|
| 976 | | - } |
|---|
| 977 | | - i2c->gpios[idx] = gpio; |
|---|
| 978 | | - |
|---|
| 979 | | - ret = gpio_request(gpio, "i2c-bus"); |
|---|
| 980 | | - if (ret) { |
|---|
| 981 | | - dev_err(i2c->dev, "gpio [%d] request failed (%d)\n", |
|---|
| 982 | | - gpio, ret); |
|---|
| 983 | | - goto free_gpio; |
|---|
| 958 | + for (i = 0; i < 2; i++) { |
|---|
| 959 | + i2c->gpios[i] = devm_gpiod_get_index(i2c->dev, NULL, |
|---|
| 960 | + i, GPIOD_ASIS); |
|---|
| 961 | + if (IS_ERR(i2c->gpios[i])) { |
|---|
| 962 | + dev_err(i2c->dev, "i2c gpio invalid at index %d\n", i); |
|---|
| 963 | + return -EINVAL; |
|---|
| 984 | 964 | } |
|---|
| 985 | 965 | } |
|---|
| 986 | 966 | return 0; |
|---|
| 987 | | - |
|---|
| 988 | | -free_gpio: |
|---|
| 989 | | - while (--idx >= 0) |
|---|
| 990 | | - gpio_free(i2c->gpios[idx]); |
|---|
| 991 | | - return -EINVAL; |
|---|
| 992 | 967 | } |
|---|
| 993 | 968 | |
|---|
| 994 | | -static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c) |
|---|
| 995 | | -{ |
|---|
| 996 | | - unsigned int idx; |
|---|
| 997 | | - |
|---|
| 998 | | - if (i2c->quirks & QUIRK_NO_GPIO) |
|---|
| 999 | | - return; |
|---|
| 1000 | | - |
|---|
| 1001 | | - for (idx = 0; idx < 2; idx++) |
|---|
| 1002 | | - gpio_free(i2c->gpios[idx]); |
|---|
| 1003 | | -} |
|---|
| 1004 | 969 | #else |
|---|
| 1005 | 970 | static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) |
|---|
| 1006 | 971 | { |
|---|
| 1007 | 972 | return 0; |
|---|
| 1008 | | -} |
|---|
| 1009 | | - |
|---|
| 1010 | | -static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c) |
|---|
| 1011 | | -{ |
|---|
| 1012 | 973 | } |
|---|
| 1013 | 974 | #endif |
|---|
| 1014 | 975 | |
|---|
| .. | .. |
|---|
| 1238 | 1199 | |
|---|
| 1239 | 1200 | i2c_del_adapter(&i2c->adap); |
|---|
| 1240 | 1201 | |
|---|
| 1241 | | - if (pdev->dev.of_node && IS_ERR(i2c->pctrl)) |
|---|
| 1242 | | - s3c24xx_i2c_dt_gpio_free(i2c); |
|---|
| 1243 | | - |
|---|
| 1244 | 1202 | return 0; |
|---|
| 1245 | 1203 | } |
|---|
| 1246 | 1204 | |
|---|
| .. | .. |
|---|
| 1249 | 1207 | { |
|---|
| 1250 | 1208 | struct s3c24xx_i2c *i2c = dev_get_drvdata(dev); |
|---|
| 1251 | 1209 | |
|---|
| 1252 | | - i2c->suspended = 1; |
|---|
| 1210 | + i2c_mark_adapter_suspended(&i2c->adap); |
|---|
| 1253 | 1211 | |
|---|
| 1254 | 1212 | if (!IS_ERR(i2c->sysreg)) |
|---|
| 1255 | 1213 | regmap_read(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, &i2c->sys_i2c_cfg); |
|---|
| .. | .. |
|---|
| 1270 | 1228 | return ret; |
|---|
| 1271 | 1229 | s3c24xx_i2c_init(i2c); |
|---|
| 1272 | 1230 | clk_disable(i2c->clk); |
|---|
| 1273 | | - i2c->suspended = 0; |
|---|
| 1231 | + i2c_mark_adapter_resumed(&i2c->adap); |
|---|
| 1274 | 1232 | |
|---|
| 1275 | 1233 | return 0; |
|---|
| 1276 | 1234 | } |
|---|
| .. | .. |
|---|
| 1311 | 1269 | module_exit(i2c_adap_s3c_exit); |
|---|
| 1312 | 1270 | |
|---|
| 1313 | 1271 | MODULE_DESCRIPTION("S3C24XX I2C Bus driver"); |
|---|
| 1314 | | -MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); |
|---|
| 1272 | +MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
|---|
| 1315 | 1273 | MODULE_LICENSE("GPL"); |
|---|