diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-gpio.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-gpio.c | 98 |
1 files changed, 76 insertions, 22 deletions
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index a651779d9ff7..c0330a41db03 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c | |||
| @@ -14,8 +14,15 @@ | |||
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 17 | 17 | #include <linux/gpio.h> | |
| 18 | #include <asm/gpio.h> | 18 | #include <linux/of_gpio.h> |
| 19 | #include <linux/of_i2c.h> | ||
| 20 | |||
| 21 | struct i2c_gpio_private_data { | ||
| 22 | struct i2c_adapter adap; | ||
| 23 | struct i2c_algo_bit_data bit_data; | ||
| 24 | struct i2c_gpio_platform_data pdata; | ||
| 25 | }; | ||
| 19 | 26 | ||
| 20 | /* Toggle SDA by changing the direction of the pin */ | 27 | /* Toggle SDA by changing the direction of the pin */ |
| 21 | static void i2c_gpio_setsda_dir(void *data, int state) | 28 | static void i2c_gpio_setsda_dir(void *data, int state) |
| @@ -78,24 +85,62 @@ static int i2c_gpio_getscl(void *data) | |||
| 78 | return gpio_get_value(pdata->scl_pin); | 85 | return gpio_get_value(pdata->scl_pin); |
| 79 | } | 86 | } |
| 80 | 87 | ||
| 88 | static int __devinit of_i2c_gpio_probe(struct device_node *np, | ||
| 89 | struct i2c_gpio_platform_data *pdata) | ||
| 90 | { | ||
| 91 | u32 reg; | ||
| 92 | |||
| 93 | if (of_gpio_count(np) < 2) | ||
| 94 | return -ENODEV; | ||
| 95 | |||
| 96 | pdata->sda_pin = of_get_gpio(np, 0); | ||
| 97 | pdata->scl_pin = of_get_gpio(np, 1); | ||
| 98 | |||
| 99 | if (!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin)) { | ||
| 100 | pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n", | ||
| 101 | np->full_name, pdata->sda_pin, pdata->scl_pin); | ||
| 102 | return -ENODEV; | ||
| 103 | } | ||
| 104 | |||
| 105 | of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay); | ||
| 106 | |||
| 107 | if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", ®)) | ||
| 108 | pdata->timeout = msecs_to_jiffies(reg); | ||
| 109 | |||
| 110 | pdata->sda_is_open_drain = | ||
| 111 | of_property_read_bool(np, "i2c-gpio,sda-open-drain"); | ||
| 112 | pdata->scl_is_open_drain = | ||
| 113 | of_property_read_bool(np, "i2c-gpio,scl-open-drain"); | ||
| 114 | pdata->scl_is_output_only = | ||
| 115 | of_property_read_bool(np, "i2c-gpio,scl-output-only"); | ||
| 116 | |||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 81 | static int __devinit i2c_gpio_probe(struct platform_device *pdev) | 120 | static int __devinit i2c_gpio_probe(struct platform_device *pdev) |
| 82 | { | 121 | { |
| 122 | struct i2c_gpio_private_data *priv; | ||
| 83 | struct i2c_gpio_platform_data *pdata; | 123 | struct i2c_gpio_platform_data *pdata; |
| 84 | struct i2c_algo_bit_data *bit_data; | 124 | struct i2c_algo_bit_data *bit_data; |
| 85 | struct i2c_adapter *adap; | 125 | struct i2c_adapter *adap; |
| 86 | int ret; | 126 | int ret; |
| 87 | 127 | ||
| 88 | pdata = pdev->dev.platform_data; | 128 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 89 | if (!pdata) | 129 | if (!priv) |
| 90 | return -ENXIO; | 130 | return -ENOMEM; |
| 91 | 131 | adap = &priv->adap; | |
| 92 | ret = -ENOMEM; | 132 | bit_data = &priv->bit_data; |
| 93 | adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); | 133 | pdata = &priv->pdata; |
| 94 | if (!adap) | 134 | |
| 95 | goto err_alloc_adap; | 135 | if (pdev->dev.of_node) { |
| 96 | bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL); | 136 | ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata); |
| 97 | if (!bit_data) | 137 | if (ret) |
| 98 | goto err_alloc_bit_data; | 138 | return ret; |
| 139 | } else { | ||
| 140 | if (!pdev->dev.platform_data) | ||
| 141 | return -ENXIO; | ||
| 142 | memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); | ||
| 143 | } | ||
| 99 | 144 | ||
| 100 | ret = gpio_request(pdata->sda_pin, "sda"); | 145 | ret = gpio_request(pdata->sda_pin, "sda"); |
| 101 | if (ret) | 146 | if (ret) |
| @@ -143,6 +188,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev) | |||
| 143 | adap->algo_data = bit_data; | 188 | adap->algo_data = bit_data; |
| 144 | adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; | 189 | adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; |
| 145 | adap->dev.parent = &pdev->dev; | 190 | adap->dev.parent = &pdev->dev; |
| 191 | adap->dev.of_node = pdev->dev.of_node; | ||
| 146 | 192 | ||
| 147 | /* | 193 | /* |
| 148 | * If "dev->id" is negative we consider it as zero. | 194 | * If "dev->id" is negative we consider it as zero. |
| @@ -154,7 +200,9 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev) | |||
| 154 | if (ret) | 200 | if (ret) |
| 155 | goto err_add_bus; | 201 | goto err_add_bus; |
| 156 | 202 | ||
| 157 | platform_set_drvdata(pdev, adap); | 203 | of_i2c_register_devices(adap); |
| 204 | |||
| 205 | platform_set_drvdata(pdev, priv); | ||
| 158 | 206 | ||
| 159 | dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n", | 207 | dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n", |
| 160 | pdata->sda_pin, pdata->scl_pin, | 208 | pdata->sda_pin, pdata->scl_pin, |
| @@ -168,34 +216,40 @@ err_add_bus: | |||
| 168 | err_request_scl: | 216 | err_request_scl: |
| 169 | gpio_free(pdata->sda_pin); | 217 | gpio_free(pdata->sda_pin); |
| 170 | err_request_sda: | 218 | err_request_sda: |
| 171 | kfree(bit_data); | ||
| 172 | err_alloc_bit_data: | ||
| 173 | kfree(adap); | ||
| 174 | err_alloc_adap: | ||
| 175 | return ret; | 219 | return ret; |
| 176 | } | 220 | } |
| 177 | 221 | ||
| 178 | static int __devexit i2c_gpio_remove(struct platform_device *pdev) | 222 | static int __devexit i2c_gpio_remove(struct platform_device *pdev) |
| 179 | { | 223 | { |
| 224 | struct i2c_gpio_private_data *priv; | ||
| 180 | struct i2c_gpio_platform_data *pdata; | 225 | struct i2c_gpio_platform_data *pdata; |
| 181 | struct i2c_adapter *adap; | 226 | struct i2c_adapter *adap; |
| 182 | 227 | ||
| 183 | adap = platform_get_drvdata(pdev); | 228 | priv = platform_get_drvdata(pdev); |
| 184 | pdata = pdev->dev.platform_data; | 229 | adap = &priv->adap; |
| 230 | pdata = &priv->pdata; | ||
| 185 | 231 | ||
| 186 | i2c_del_adapter(adap); | 232 | i2c_del_adapter(adap); |
| 187 | gpio_free(pdata->scl_pin); | 233 | gpio_free(pdata->scl_pin); |
| 188 | gpio_free(pdata->sda_pin); | 234 | gpio_free(pdata->sda_pin); |
| 189 | kfree(adap->algo_data); | ||
| 190 | kfree(adap); | ||
| 191 | 235 | ||
| 192 | return 0; | 236 | return 0; |
| 193 | } | 237 | } |
| 194 | 238 | ||
| 239 | #if defined(CONFIG_OF) | ||
| 240 | static const struct of_device_id i2c_gpio_dt_ids[] = { | ||
| 241 | { .compatible = "i2c-gpio", }, | ||
| 242 | { /* sentinel */ } | ||
| 243 | }; | ||
| 244 | |||
| 245 | MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids); | ||
| 246 | #endif | ||
| 247 | |||
| 195 | static struct platform_driver i2c_gpio_driver = { | 248 | static struct platform_driver i2c_gpio_driver = { |
| 196 | .driver = { | 249 | .driver = { |
| 197 | .name = "i2c-gpio", | 250 | .name = "i2c-gpio", |
| 198 | .owner = THIS_MODULE, | 251 | .owner = THIS_MODULE, |
| 252 | .of_match_table = of_match_ptr(i2c_gpio_dt_ids), | ||
| 199 | }, | 253 | }, |
| 200 | .probe = i2c_gpio_probe, | 254 | .probe = i2c_gpio_probe, |
| 201 | .remove = __devexit_p(i2c_gpio_remove), | 255 | .remove = __devexit_p(i2c_gpio_remove), |
