1 // SPDX-License-Identifier: GPL-2.0+
3 * I2C multiplexer using GPIO API
7 * Peng Fan <peng.fan@nxp.com>
11 #include <asm-generic/gpio.h>
14 #include <dm/pinctrl.h>
17 #include <linux/errno.h>
19 DECLARE_GLOBAL_DATA_PTR
;
22 * struct i2c_mux_gpio_priv - private data for i2c mux gpio
24 * @values: the reg value of each child node
25 * @n_values: num of regs
26 * @gpios: the mux-gpios array
27 * @n_gpios: num of gpios in mux-gpios
28 * @idle: the value of idle-state
30 struct i2c_mux_gpio_priv
{
33 struct gpio_desc
*gpios
;
39 static int i2c_mux_gpio_select(struct udevice
*dev
, struct udevice
*bus
,
42 struct i2c_mux_gpio_priv
*priv
= dev_get_priv(dev
);
45 for (i
= 0; i
< priv
->n_gpios
; i
++) {
46 ret
= dm_gpio_set_value(&priv
->gpios
[i
], (channel
>> i
) & 1);
54 static int i2c_mux_gpio_deselect(struct udevice
*dev
, struct udevice
*bus
,
57 struct i2c_mux_gpio_priv
*priv
= dev_get_priv(dev
);
60 for (i
= 0; i
< priv
->n_gpios
; i
++) {
61 ret
= dm_gpio_set_value(&priv
->gpios
[i
], (priv
->idle
>> i
) & 1);
69 static int i2c_mux_gpio_probe(struct udevice
*dev
)
71 const void *fdt
= gd
->fdt_blob
;
72 int node
= dev_of_offset(dev
);
73 struct i2c_mux_gpio_priv
*mux
= dev_get_priv(dev
);
74 struct gpio_desc
*gpios
;
76 int i
= 0, subnode
, ret
;
78 mux
->n_values
= fdtdec_get_child_count(fdt
, node
);
79 values
= devm_kzalloc(dev
, sizeof(*mux
->values
) * mux
->n_values
,
82 dev_err(dev
, "Cannot alloc values array");
86 fdt_for_each_subnode(subnode
, fdt
, node
) {
87 *(values
+ i
) = fdtdec_get_uint(fdt
, subnode
, "reg", -1);
93 mux
->idle
= fdtdec_get_uint(fdt
, node
, "idle-state", -1);
95 mux
->n_gpios
= gpio_get_list_count(dev
, "mux-gpios");
96 if (mux
->n_gpios
< 0) {
97 dev_err(dev
, "Missing mux-gpios property\n");
101 gpios
= devm_kzalloc(dev
, sizeof(struct gpio_desc
) * mux
->n_gpios
,
104 dev_err(dev
, "Cannot allocate gpios array\n");
108 ret
= gpio_request_list_by_name(dev
, "mux-gpios", gpios
, mux
->n_gpios
,
109 GPIOD_IS_OUT_ACTIVE
);
111 dev_err(dev
, "Failed to request mux-gpios\n");
120 static const struct i2c_mux_ops i2c_mux_gpio_ops
= {
121 .select
= i2c_mux_gpio_select
,
122 .deselect
= i2c_mux_gpio_deselect
,
125 static const struct udevice_id i2c_mux_gpio_ids
[] = {
126 { .compatible
= "i2c-mux-gpio", },
130 U_BOOT_DRIVER(i2c_mux_gpio
) = {
131 .name
= "i2c_mux_gpio",
132 .id
= UCLASS_I2C_MUX
,
133 .of_match
= i2c_mux_gpio_ids
,
134 .ops
= &i2c_mux_gpio_ops
,
135 .probe
= i2c_mux_gpio_probe
,
136 .priv_auto_alloc_size
= sizeof(struct i2c_mux_gpio_priv
),