Lines Matching +full:reg +full:- +full:data
1 // SPDX-License-Identifier: GPL-2.0-or-later
10 #include <linux/i2c-mux.h>
15 #include <linux/platform_data/i2c-mux-reg.h>
20 struct i2c_mux_reg_platform_data data; member
25 if (!mux->data.reg) in i2c_mux_reg_set()
26 return -EINVAL; in i2c_mux_reg_set()
31 * The endianness of reading doesn't matter and the return data in i2c_mux_reg_set()
34 switch (mux->data.reg_size) { in i2c_mux_reg_set()
36 if (mux->data.little_endian) in i2c_mux_reg_set()
37 iowrite32(chan_id, mux->data.reg); in i2c_mux_reg_set()
39 iowrite32be(chan_id, mux->data.reg); in i2c_mux_reg_set()
40 if (!mux->data.write_only) in i2c_mux_reg_set()
41 ioread32(mux->data.reg); in i2c_mux_reg_set()
44 if (mux->data.little_endian) in i2c_mux_reg_set()
45 iowrite16(chan_id, mux->data.reg); in i2c_mux_reg_set()
47 iowrite16be(chan_id, mux->data.reg); in i2c_mux_reg_set()
48 if (!mux->data.write_only) in i2c_mux_reg_set()
49 ioread16(mux->data.reg); in i2c_mux_reg_set()
52 iowrite8(chan_id, mux->data.reg); in i2c_mux_reg_set()
53 if (!mux->data.write_only) in i2c_mux_reg_set()
54 ioread8(mux->data.reg); in i2c_mux_reg_set()
72 if (mux->data.idle_in_use) in i2c_mux_reg_deselect()
73 return i2c_mux_reg_set(mux, mux->data.idle); in i2c_mux_reg_deselect()
82 struct device_node *np = pdev->dev.of_node; in i2c_mux_reg_probe_dt()
90 return -ENODEV; in i2c_mux_reg_probe_dt()
92 adapter_np = of_parse_phandle(np, "i2c-parent", 0); in i2c_mux_reg_probe_dt()
94 dev_err(&pdev->dev, "Cannot parse i2c-parent\n"); in i2c_mux_reg_probe_dt()
95 return -ENODEV; in i2c_mux_reg_probe_dt()
100 return -EPROBE_DEFER; in i2c_mux_reg_probe_dt()
102 mux->data.parent = i2c_adapter_id(adapter); in i2c_mux_reg_probe_dt()
103 put_device(&adapter->dev); in i2c_mux_reg_probe_dt()
105 mux->data.n_values = of_get_child_count(np); in i2c_mux_reg_probe_dt()
106 if (of_property_read_bool(np, "little-endian")) { in i2c_mux_reg_probe_dt()
107 mux->data.little_endian = true; in i2c_mux_reg_probe_dt()
108 } else if (of_property_read_bool(np, "big-endian")) { in i2c_mux_reg_probe_dt()
109 mux->data.little_endian = false; in i2c_mux_reg_probe_dt()
113 mux->data.little_endian = true; in i2c_mux_reg_probe_dt()
116 mux->data.little_endian = false; in i2c_mux_reg_probe_dt()
121 mux->data.write_only = of_property_read_bool(np, "write-only"); in i2c_mux_reg_probe_dt()
123 values = devm_kcalloc(&pdev->dev, in i2c_mux_reg_probe_dt()
124 mux->data.n_values, sizeof(*mux->data.values), in i2c_mux_reg_probe_dt()
127 return -ENOMEM; in i2c_mux_reg_probe_dt()
130 of_property_read_u32(child, "reg", values + i); in i2c_mux_reg_probe_dt()
133 mux->data.values = values; in i2c_mux_reg_probe_dt()
135 if (!of_property_read_u32(np, "idle-state", &mux->data.idle)) in i2c_mux_reg_probe_dt()
136 mux->data.idle_in_use = true; in i2c_mux_reg_probe_dt()
138 /* map address from "reg" if exists */ in i2c_mux_reg_probe_dt()
140 mux->data.reg_size = resource_size(&res); in i2c_mux_reg_probe_dt()
141 mux->data.reg = devm_ioremap_resource(&pdev->dev, &res); in i2c_mux_reg_probe_dt()
142 if (IS_ERR(mux->data.reg)) in i2c_mux_reg_probe_dt()
143 return PTR_ERR(mux->data.reg); in i2c_mux_reg_probe_dt()
165 mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL); in i2c_mux_reg_probe()
167 return -ENOMEM; in i2c_mux_reg_probe()
169 if (dev_get_platdata(&pdev->dev)) { in i2c_mux_reg_probe()
170 memcpy(&mux->data, dev_get_platdata(&pdev->dev), in i2c_mux_reg_probe()
171 sizeof(mux->data)); in i2c_mux_reg_probe()
175 return dev_err_probe(&pdev->dev, ret, in i2c_mux_reg_probe()
179 parent = i2c_get_adapter(mux->data.parent); in i2c_mux_reg_probe()
181 return -EPROBE_DEFER; in i2c_mux_reg_probe()
183 if (!mux->data.reg) { in i2c_mux_reg_probe()
184 dev_info(&pdev->dev, in i2c_mux_reg_probe()
186 mux->data.reg = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in i2c_mux_reg_probe()
187 if (IS_ERR(mux->data.reg)) { in i2c_mux_reg_probe()
188 ret = PTR_ERR(mux->data.reg); in i2c_mux_reg_probe()
191 mux->data.reg_size = resource_size(res); in i2c_mux_reg_probe()
194 if (mux->data.reg_size != 4 && mux->data.reg_size != 2 && in i2c_mux_reg_probe()
195 mux->data.reg_size != 1) { in i2c_mux_reg_probe()
196 dev_err(&pdev->dev, "Invalid register size\n"); in i2c_mux_reg_probe()
197 ret = -EINVAL; in i2c_mux_reg_probe()
201 muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, 0, 0, in i2c_mux_reg_probe()
204 ret = -ENOMEM; in i2c_mux_reg_probe()
207 muxc->priv = mux; in i2c_mux_reg_probe()
211 if (mux->data.idle_in_use) in i2c_mux_reg_probe()
212 muxc->deselect = i2c_mux_reg_deselect; in i2c_mux_reg_probe()
214 for (i = 0; i < mux->data.n_values; i++) { in i2c_mux_reg_probe()
215 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0; in i2c_mux_reg_probe()
216 class = mux->data.classes ? mux->data.classes[i] : 0; in i2c_mux_reg_probe()
218 ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class); in i2c_mux_reg_probe()
223 dev_dbg(&pdev->dev, "%d port mux on %s adapter\n", in i2c_mux_reg_probe()
224 mux->data.n_values, muxc->parent->name); in i2c_mux_reg_probe()
241 i2c_put_adapter(muxc->parent); in i2c_mux_reg_remove()
245 { .compatible = "i2c-mux-reg", },
254 .name = "i2c-mux-reg",
261 MODULE_DESCRIPTION("Register-based I2C multiplexer driver");
264 MODULE_ALIAS("platform:i2c-mux-reg");