aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2012-10-25 12:23:53 -0400
committerWolfram Sang <w.sang@pengutronix.de>2012-11-16 03:28:27 -0500
commit9b7a0c40de6c5c04371f8cdb9153a0a5a0af5243 (patch)
tree02a02f2c3b38e8504d58a2eb4e4fa815804faf78 /drivers/i2c
parent29fb08c300b5cb626b8a803440aab25d0983cab7 (diff)
i2c: mux: Add dt support to i2c-mux-gpio driver
Allow the i2c-mux-gpio to be used by a device tree enabled device. The bindings are inspired by the one found in the i2c-mux-pinctrl driver. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Reviewed-by: Stephen Warren <swarren@nvidia.com> Acked-by: Peter Korsgaard <peter.korsgaard@barco.com> [wsa: fixed some whitespace] Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/muxes/i2c-mux-gpio.c145
1 files changed, 114 insertions, 31 deletions
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index 566a6757a33d..3b7bc06fe8a6 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -16,6 +16,8 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/gpio.h> 18#include <linux/gpio.h>
19#include <linux/of_i2c.h>
20#include <linux/of_gpio.h>
19 21
20struct gpiomux { 22struct gpiomux {
21 struct i2c_adapter *parent; 23 struct i2c_adapter *parent;
@@ -57,29 +59,110 @@ static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip,
57 return !strcmp(chip->label, data); 59 return !strcmp(chip->label, data);
58} 60}
59 61
62#ifdef CONFIG_OF
63static int __devinit i2c_mux_gpio_probe_dt(struct gpiomux *mux,
64 struct platform_device *pdev)
65{
66 struct device_node *np = pdev->dev.of_node;
67 struct device_node *adapter_np, *child;
68 struct i2c_adapter *adapter;
69 unsigned *values, *gpios;
70 int i = 0;
71
72 if (!np)
73 return -ENODEV;
74
75 adapter_np = of_parse_phandle(np, "i2c-parent", 0);
76 if (!adapter_np) {
77 dev_err(&pdev->dev, "Cannot parse i2c-parent\n");
78 return -ENODEV;
79 }
80 adapter = of_find_i2c_adapter_by_node(adapter_np);
81 if (!adapter) {
82 dev_err(&pdev->dev, "Cannot find parent bus\n");
83 return -ENODEV;
84 }
85 mux->data.parent = i2c_adapter_id(adapter);
86 put_device(&adapter->dev);
87
88 mux->data.n_values = of_get_child_count(np);
89
90 values = devm_kzalloc(&pdev->dev,
91 sizeof(*mux->data.values) * mux->data.n_values,
92 GFP_KERNEL);
93 if (!values) {
94 dev_err(&pdev->dev, "Cannot allocate values array");
95 return -ENOMEM;
96 }
97
98 for_each_child_of_node(np, child) {
99 of_property_read_u32(child, "reg", values + i);
100 i++;
101 }
102 mux->data.values = values;
103
104 if (of_property_read_u32(np, "idle-state", &mux->data.idle))
105 mux->data.idle = I2C_MUX_GPIO_NO_IDLE;
106
107 mux->data.n_gpios = of_gpio_named_count(np, "mux-gpios");
108 if (mux->data.n_gpios < 0) {
109 dev_err(&pdev->dev, "Missing mux-gpios property in the DT.\n");
110 return -EINVAL;
111 }
112
113 gpios = devm_kzalloc(&pdev->dev,
114 sizeof(*mux->data.gpios) * mux->data.n_gpios, GFP_KERNEL);
115 if (!gpios) {
116 dev_err(&pdev->dev, "Cannot allocate gpios array");
117 return -ENOMEM;
118 }
119
120 for (i = 0; i < mux->data.n_gpios; i++)
121 gpios[i] = of_get_named_gpio(np, "mux-gpios", i);
122
123 mux->data.gpios = gpios;
124
125 return 0;
126}
127#else
128static int __devinit i2c_mux_gpio_probe_dt(struct gpiomux *mux,
129 struct platform_device *pdev)
130{
131 return 0;
132}
133#endif
134
60static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev) 135static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
61{ 136{
62 struct gpiomux *mux; 137 struct gpiomux *mux;
63 struct i2c_mux_gpio_platform_data *pdata;
64 struct i2c_adapter *parent; 138 struct i2c_adapter *parent;
65 int (*deselect) (struct i2c_adapter *, void *, u32); 139 int (*deselect) (struct i2c_adapter *, void *, u32);
66 unsigned initial_state, gpio_base; 140 unsigned initial_state, gpio_base;
67 int i, ret; 141 int i, ret;
68 142
69 pdata = pdev->dev.platform_data; 143 mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
70 if (!pdata) { 144 if (!mux) {
71 dev_err(&pdev->dev, "Missing platform data\n"); 145 dev_err(&pdev->dev, "Cannot allocate gpiomux structure");
72 return -ENODEV; 146 return -ENOMEM;
73 } 147 }
74 148
149 platform_set_drvdata(pdev, mux);
150
151 if (!pdev->dev.platform_data) {
152 ret = i2c_mux_gpio_probe_dt(mux, pdev);
153 if (ret < 0)
154 return ret;
155 } else
156 memcpy(&mux->data, pdev->dev.platform_data, sizeof(mux->data));
157
75 /* 158 /*
76 * If a GPIO chip name is provided, the GPIO pin numbers provided are 159 * If a GPIO chip name is provided, the GPIO pin numbers provided are
77 * relative to its base GPIO number. Otherwise they are absolute. 160 * relative to its base GPIO number. Otherwise they are absolute.
78 */ 161 */
79 if (pdata->gpio_chip) { 162 if (mux->data.gpio_chip) {
80 struct gpio_chip *gpio; 163 struct gpio_chip *gpio;
81 164
82 gpio = gpiochip_find(pdata->gpio_chip, 165 gpio = gpiochip_find(mux->data.gpio_chip,
83 match_gpio_chip_by_label); 166 match_gpio_chip_by_label);
84 if (!gpio) 167 if (!gpio)
85 return -EPROBE_DEFER; 168 return -EPROBE_DEFER;
@@ -89,49 +172,44 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
89 gpio_base = 0; 172 gpio_base = 0;
90 } 173 }
91 174
92 parent = i2c_get_adapter(pdata->parent); 175 parent = i2c_get_adapter(mux->data.parent);
93 if (!parent) { 176 if (!parent) {
94 dev_err(&pdev->dev, "Parent adapter (%d) not found\n", 177 dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
95 pdata->parent); 178 mux->data.parent);
96 return -ENODEV; 179 return -ENODEV;
97 } 180 }
98 181
99 mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
100 if (!mux) {
101 ret = -ENOMEM;
102 goto alloc_failed;
103 }
104
105 mux->parent = parent; 182 mux->parent = parent;
106 mux->data = *pdata;
107 mux->gpio_base = gpio_base; 183 mux->gpio_base = gpio_base;
184
108 mux->adap = devm_kzalloc(&pdev->dev, 185 mux->adap = devm_kzalloc(&pdev->dev,
109 sizeof(*mux->adap) * pdata->n_values, 186 sizeof(*mux->adap) * mux->data.n_values,
110 GFP_KERNEL); 187 GFP_KERNEL);
111 if (!mux->adap) { 188 if (!mux->adap) {
189 dev_err(&pdev->dev, "Cannot allocate i2c_adapter structure");
112 ret = -ENOMEM; 190 ret = -ENOMEM;
113 goto alloc_failed; 191 goto alloc_failed;
114 } 192 }
115 193
116 if (pdata->idle != I2C_MUX_GPIO_NO_IDLE) { 194 if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) {
117 initial_state = pdata->idle; 195 initial_state = mux->data.idle;
118 deselect = i2c_mux_gpio_deselect; 196 deselect = i2c_mux_gpio_deselect;
119 } else { 197 } else {
120 initial_state = pdata->values[0]; 198 initial_state = mux->data.values[0];
121 deselect = NULL; 199 deselect = NULL;
122 } 200 }
123 201
124 for (i = 0; i < pdata->n_gpios; i++) { 202 for (i = 0; i < mux->data.n_gpios; i++) {
125 ret = gpio_request(gpio_base + pdata->gpios[i], "i2c-mux-gpio"); 203 ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio");
126 if (ret) 204 if (ret)
127 goto err_request_gpio; 205 goto err_request_gpio;
128 gpio_direction_output(gpio_base + pdata->gpios[i], 206 gpio_direction_output(gpio_base + mux->data.gpios[i],
129 initial_state & (1 << i)); 207 initial_state & (1 << i));
130 } 208 }
131 209
132 for (i = 0; i < pdata->n_values; i++) { 210 for (i = 0; i < mux->data.n_values; i++) {
133 u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0; 211 u32 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0;
134 unsigned int class = pdata->classes ? pdata->classes[i] : 0; 212 unsigned int class = mux->data.classes ? mux->data.classes[i] : 0;
135 213
136 mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr, 214 mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr,
137 i, class, 215 i, class,
@@ -144,19 +222,17 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
144 } 222 }
145 223
146 dev_info(&pdev->dev, "%d port mux on %s adapter\n", 224 dev_info(&pdev->dev, "%d port mux on %s adapter\n",
147 pdata->n_values, parent->name); 225 mux->data.n_values, parent->name);
148
149 platform_set_drvdata(pdev, mux);
150 226
151 return 0; 227 return 0;
152 228
153add_adapter_failed: 229add_adapter_failed:
154 for (; i > 0; i--) 230 for (; i > 0; i--)
155 i2c_del_mux_adapter(mux->adap[i - 1]); 231 i2c_del_mux_adapter(mux->adap[i - 1]);
156 i = pdata->n_gpios; 232 i = mux->data.n_gpios;
157err_request_gpio: 233err_request_gpio:
158 for (; i > 0; i--) 234 for (; i > 0; i--)
159 gpio_free(gpio_base + pdata->gpios[i - 1]); 235 gpio_free(gpio_base + mux->data.gpios[i - 1]);
160alloc_failed: 236alloc_failed:
161 i2c_put_adapter(parent); 237 i2c_put_adapter(parent);
162 238
@@ -180,12 +256,19 @@ static int __devexit i2c_mux_gpio_remove(struct platform_device *pdev)
180 return 0; 256 return 0;
181} 257}
182 258
259static const struct of_device_id i2c_mux_gpio_of_match[] __devinitconst = {
260 { .compatible = "i2c-mux-gpio", },
261 {},
262};
263MODULE_DEVICE_TABLE(of, i2c_mux_gpio_of_match);
264
183static struct platform_driver i2c_mux_gpio_driver = { 265static struct platform_driver i2c_mux_gpio_driver = {
184 .probe = i2c_mux_gpio_probe, 266 .probe = i2c_mux_gpio_probe,
185 .remove = __devexit_p(i2c_mux_gpio_remove), 267 .remove = __devexit_p(i2c_mux_gpio_remove),
186 .driver = { 268 .driver = {
187 .owner = THIS_MODULE, 269 .owner = THIS_MODULE,
188 .name = "i2c-mux-gpio", 270 .name = "i2c-mux-gpio",
271 .of_match_table = of_match_ptr(i2c_mux_gpio_of_match),
189 }, 272 },
190}; 273};
191 274