• Home
  • Raw
  • Download

Lines Matching +full:i2c +full:- +full:mux

2  * I2C multiplexer using a single register
13 #include <linux/i2c.h>
14 #include <linux/i2c-mux.h>
19 #include <linux/platform_data/i2c-mux-reg.h>
27 static int i2c_mux_reg_set(const struct regmux *mux, unsigned int chan_id) in i2c_mux_reg_set() argument
29 if (!mux->data.reg) in i2c_mux_reg_set()
30 return -EINVAL; in i2c_mux_reg_set()
38 switch (mux->data.reg_size) { in i2c_mux_reg_set()
40 if (mux->data.little_endian) in i2c_mux_reg_set()
41 iowrite32(chan_id, mux->data.reg); in i2c_mux_reg_set()
43 iowrite32be(chan_id, mux->data.reg); in i2c_mux_reg_set()
44 if (!mux->data.write_only) in i2c_mux_reg_set()
45 ioread32(mux->data.reg); in i2c_mux_reg_set()
48 if (mux->data.little_endian) in i2c_mux_reg_set()
49 iowrite16(chan_id, mux->data.reg); in i2c_mux_reg_set()
51 iowrite16be(chan_id, mux->data.reg); in i2c_mux_reg_set()
52 if (!mux->data.write_only) in i2c_mux_reg_set()
53 ioread16(mux->data.reg); in i2c_mux_reg_set()
56 iowrite8(chan_id, mux->data.reg); in i2c_mux_reg_set()
57 if (!mux->data.write_only) in i2c_mux_reg_set()
58 ioread8(mux->data.reg); in i2c_mux_reg_set()
67 struct regmux *mux = i2c_mux_priv(muxc); in i2c_mux_reg_select() local
69 return i2c_mux_reg_set(mux, chan); in i2c_mux_reg_select()
74 struct regmux *mux = i2c_mux_priv(muxc); in i2c_mux_reg_deselect() local
76 if (mux->data.idle_in_use) in i2c_mux_reg_deselect()
77 return i2c_mux_reg_set(mux, mux->data.idle); in i2c_mux_reg_deselect()
83 static int i2c_mux_reg_probe_dt(struct regmux *mux, in i2c_mux_reg_probe_dt() argument
86 struct device_node *np = pdev->dev.of_node; in i2c_mux_reg_probe_dt()
94 return -ENODEV; in i2c_mux_reg_probe_dt()
96 adapter_np = of_parse_phandle(np, "i2c-parent", 0); in i2c_mux_reg_probe_dt()
98 dev_err(&pdev->dev, "Cannot parse i2c-parent\n"); in i2c_mux_reg_probe_dt()
99 return -ENODEV; in i2c_mux_reg_probe_dt()
104 return -EPROBE_DEFER; in i2c_mux_reg_probe_dt()
106 mux->data.parent = i2c_adapter_id(adapter); in i2c_mux_reg_probe_dt()
107 put_device(&adapter->dev); in i2c_mux_reg_probe_dt()
109 mux->data.n_values = of_get_child_count(np); in i2c_mux_reg_probe_dt()
110 if (of_property_read_bool(np, "little-endian")) { in i2c_mux_reg_probe_dt()
111 mux->data.little_endian = true; in i2c_mux_reg_probe_dt()
112 } else if (of_property_read_bool(np, "big-endian")) { in i2c_mux_reg_probe_dt()
113 mux->data.little_endian = false; in i2c_mux_reg_probe_dt()
117 mux->data.little_endian = true; in i2c_mux_reg_probe_dt()
120 mux->data.little_endian = false; in i2c_mux_reg_probe_dt()
125 mux->data.write_only = of_property_read_bool(np, "write-only"); in i2c_mux_reg_probe_dt()
127 values = devm_kcalloc(&pdev->dev, in i2c_mux_reg_probe_dt()
128 mux->data.n_values, sizeof(*mux->data.values), in i2c_mux_reg_probe_dt()
131 return -ENOMEM; in i2c_mux_reg_probe_dt()
137 mux->data.values = values; in i2c_mux_reg_probe_dt()
139 if (!of_property_read_u32(np, "idle-state", &mux->data.idle)) in i2c_mux_reg_probe_dt()
140 mux->data.idle_in_use = true; in i2c_mux_reg_probe_dt()
144 mux->data.reg_size = resource_size(&res); in i2c_mux_reg_probe_dt()
145 mux->data.reg = devm_ioremap_resource(&pdev->dev, &res); in i2c_mux_reg_probe_dt()
146 if (IS_ERR(mux->data.reg)) in i2c_mux_reg_probe_dt()
147 return PTR_ERR(mux->data.reg); in i2c_mux_reg_probe_dt()
153 static int i2c_mux_reg_probe_dt(struct regmux *mux, in i2c_mux_reg_probe_dt() argument
163 struct regmux *mux; in i2c_mux_reg_probe() local
169 mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL); in i2c_mux_reg_probe()
170 if (!mux) in i2c_mux_reg_probe()
171 return -ENOMEM; in i2c_mux_reg_probe()
173 if (dev_get_platdata(&pdev->dev)) { in i2c_mux_reg_probe()
174 memcpy(&mux->data, dev_get_platdata(&pdev->dev), in i2c_mux_reg_probe()
175 sizeof(mux->data)); in i2c_mux_reg_probe()
177 ret = i2c_mux_reg_probe_dt(mux, pdev); in i2c_mux_reg_probe()
178 if (ret == -EPROBE_DEFER) in i2c_mux_reg_probe()
182 dev_err(&pdev->dev, "Error parsing device tree"); in i2c_mux_reg_probe()
187 parent = i2c_get_adapter(mux->data.parent); in i2c_mux_reg_probe()
189 return -EPROBE_DEFER; in i2c_mux_reg_probe()
191 if (!mux->data.reg) { in i2c_mux_reg_probe()
192 dev_info(&pdev->dev, in i2c_mux_reg_probe()
195 mux->data.reg_size = resource_size(res); in i2c_mux_reg_probe()
196 mux->data.reg = devm_ioremap_resource(&pdev->dev, res); in i2c_mux_reg_probe()
197 if (IS_ERR(mux->data.reg)) { in i2c_mux_reg_probe()
198 ret = PTR_ERR(mux->data.reg); in i2c_mux_reg_probe()
203 if (mux->data.reg_size != 4 && mux->data.reg_size != 2 && in i2c_mux_reg_probe()
204 mux->data.reg_size != 1) { in i2c_mux_reg_probe()
205 dev_err(&pdev->dev, "Invalid register size\n"); in i2c_mux_reg_probe()
206 ret = -EINVAL; in i2c_mux_reg_probe()
210 muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, 0, 0, in i2c_mux_reg_probe()
213 ret = -ENOMEM; in i2c_mux_reg_probe()
216 muxc->priv = mux; in i2c_mux_reg_probe()
220 if (mux->data.idle_in_use) in i2c_mux_reg_probe()
221 muxc->deselect = i2c_mux_reg_deselect; in i2c_mux_reg_probe()
223 for (i = 0; i < mux->data.n_values; i++) { in i2c_mux_reg_probe()
224 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0; in i2c_mux_reg_probe()
225 class = mux->data.classes ? mux->data.classes[i] : 0; in i2c_mux_reg_probe()
227 ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class); in i2c_mux_reg_probe()
232 dev_dbg(&pdev->dev, "%d port mux on %s adapter\n", in i2c_mux_reg_probe()
233 mux->data.n_values, muxc->parent->name); in i2c_mux_reg_probe()
250 i2c_put_adapter(muxc->parent); in i2c_mux_reg_remove()
256 { .compatible = "i2c-mux-reg", },
265 .name = "i2c-mux-reg",
272 MODULE_DESCRIPTION("Register-based I2C multiplexer driver");
275 MODULE_ALIAS("platform:i2c-mux-reg");