1*a430556eSPeng Fan /*
2*a430556eSPeng Fan * I2C multiplexer using GPIO API
3*a430556eSPeng Fan *
4*a430556eSPeng Fan * Copyright 2017 NXP
5*a430556eSPeng Fan *
6*a430556eSPeng Fan * Peng Fan <peng.fan@nxp.com>
7*a430556eSPeng Fan *
8*a430556eSPeng Fan * SPDX-License-Identifier: GPL-2.0+
9*a430556eSPeng Fan */
10*a430556eSPeng Fan
11*a430556eSPeng Fan #include <asm/io.h>
12*a430556eSPeng Fan #include <asm-generic/gpio.h>
13*a430556eSPeng Fan #include <common.h>
14*a430556eSPeng Fan #include <dm.h>
15*a430556eSPeng Fan #include <dm/pinctrl.h>
16*a430556eSPeng Fan #include <fdtdec.h>
17*a430556eSPeng Fan #include <i2c.h>
18*a430556eSPeng Fan #include <linux/errno.h>
19*a430556eSPeng Fan
20*a430556eSPeng Fan DECLARE_GLOBAL_DATA_PTR;
21*a430556eSPeng Fan
22*a430556eSPeng Fan /**
23*a430556eSPeng Fan * struct i2c_mux_gpio_priv - private data for i2c mux gpio
24*a430556eSPeng Fan *
25*a430556eSPeng Fan * @values: the reg value of each child node
26*a430556eSPeng Fan * @n_values: num of regs
27*a430556eSPeng Fan * @gpios: the mux-gpios array
28*a430556eSPeng Fan * @n_gpios: num of gpios in mux-gpios
29*a430556eSPeng Fan * @idle: the value of idle-state
30*a430556eSPeng Fan */
31*a430556eSPeng Fan struct i2c_mux_gpio_priv {
32*a430556eSPeng Fan u32 *values;
33*a430556eSPeng Fan int n_values;
34*a430556eSPeng Fan struct gpio_desc *gpios;
35*a430556eSPeng Fan int n_gpios;
36*a430556eSPeng Fan u32 idle;
37*a430556eSPeng Fan };
38*a430556eSPeng Fan
39*a430556eSPeng Fan
i2c_mux_gpio_select(struct udevice * dev,struct udevice * bus,uint channel)40*a430556eSPeng Fan static int i2c_mux_gpio_select(struct udevice *dev, struct udevice *bus,
41*a430556eSPeng Fan uint channel)
42*a430556eSPeng Fan {
43*a430556eSPeng Fan struct i2c_mux_gpio_priv *priv = dev_get_priv(dev);
44*a430556eSPeng Fan int i, ret;
45*a430556eSPeng Fan
46*a430556eSPeng Fan for (i = 0; i < priv->n_gpios; i++) {
47*a430556eSPeng Fan ret = dm_gpio_set_value(&priv->gpios[i], (channel >> i) & 1);
48*a430556eSPeng Fan if (ret)
49*a430556eSPeng Fan return ret;
50*a430556eSPeng Fan }
51*a430556eSPeng Fan
52*a430556eSPeng Fan return 0;
53*a430556eSPeng Fan }
54*a430556eSPeng Fan
i2c_mux_gpio_deselect(struct udevice * dev,struct udevice * bus,uint channel)55*a430556eSPeng Fan static int i2c_mux_gpio_deselect(struct udevice *dev, struct udevice *bus,
56*a430556eSPeng Fan uint channel)
57*a430556eSPeng Fan {
58*a430556eSPeng Fan struct i2c_mux_gpio_priv *priv = dev_get_priv(dev);
59*a430556eSPeng Fan int i, ret;
60*a430556eSPeng Fan
61*a430556eSPeng Fan for (i = 0; i < priv->n_gpios; i++) {
62*a430556eSPeng Fan ret = dm_gpio_set_value(&priv->gpios[i], (priv->idle >> i) & 1);
63*a430556eSPeng Fan if (ret)
64*a430556eSPeng Fan return ret;
65*a430556eSPeng Fan }
66*a430556eSPeng Fan
67*a430556eSPeng Fan return 0;
68*a430556eSPeng Fan }
69*a430556eSPeng Fan
i2c_mux_gpio_probe(struct udevice * dev)70*a430556eSPeng Fan static int i2c_mux_gpio_probe(struct udevice *dev)
71*a430556eSPeng Fan {
72*a430556eSPeng Fan const void *fdt = gd->fdt_blob;
73*a430556eSPeng Fan int node = dev_of_offset(dev);
74*a430556eSPeng Fan struct i2c_mux_gpio_priv *mux = dev_get_priv(dev);
75*a430556eSPeng Fan struct gpio_desc *gpios;
76*a430556eSPeng Fan u32 *values;
77*a430556eSPeng Fan int i = 0, subnode, ret;
78*a430556eSPeng Fan
79*a430556eSPeng Fan mux->n_values = fdtdec_get_child_count(fdt, node);
80*a430556eSPeng Fan values = devm_kzalloc(dev, sizeof(*mux->values) * mux->n_values,
81*a430556eSPeng Fan GFP_KERNEL);
82*a430556eSPeng Fan if (!values) {
83*a430556eSPeng Fan dev_err(dev, "Cannot alloc values array");
84*a430556eSPeng Fan return -ENOMEM;
85*a430556eSPeng Fan }
86*a430556eSPeng Fan
87*a430556eSPeng Fan fdt_for_each_subnode(subnode, fdt, node) {
88*a430556eSPeng Fan *(values + i) = fdtdec_get_uint(fdt, subnode, "reg", -1);
89*a430556eSPeng Fan i++;
90*a430556eSPeng Fan }
91*a430556eSPeng Fan
92*a430556eSPeng Fan mux->values = values;
93*a430556eSPeng Fan
94*a430556eSPeng Fan mux->idle = fdtdec_get_uint(fdt, node, "idle-state", -1);
95*a430556eSPeng Fan
96*a430556eSPeng Fan mux->n_gpios = gpio_get_list_count(dev, "mux-gpios");
97*a430556eSPeng Fan if (mux->n_gpios < 0) {
98*a430556eSPeng Fan dev_err(dev, "Missing mux-gpios property\n");
99*a430556eSPeng Fan return -EINVAL;
100*a430556eSPeng Fan }
101*a430556eSPeng Fan
102*a430556eSPeng Fan gpios = devm_kzalloc(dev, sizeof(struct gpio_desc) * mux->n_gpios,
103*a430556eSPeng Fan GFP_KERNEL);
104*a430556eSPeng Fan if (!gpios) {
105*a430556eSPeng Fan dev_err(dev, "Cannot allocate gpios array\n");
106*a430556eSPeng Fan return -ENOMEM;
107*a430556eSPeng Fan }
108*a430556eSPeng Fan
109*a430556eSPeng Fan ret = gpio_request_list_by_name(dev, "mux-gpios", gpios, mux->n_gpios,
110*a430556eSPeng Fan GPIOD_IS_OUT_ACTIVE);
111*a430556eSPeng Fan if (ret <= 0) {
112*a430556eSPeng Fan dev_err(dev, "Failed to request mux-gpios\n");
113*a430556eSPeng Fan return ret;
114*a430556eSPeng Fan }
115*a430556eSPeng Fan
116*a430556eSPeng Fan mux->gpios = gpios;
117*a430556eSPeng Fan
118*a430556eSPeng Fan return 0;
119*a430556eSPeng Fan }
120*a430556eSPeng Fan
121*a430556eSPeng Fan static const struct i2c_mux_ops i2c_mux_gpio_ops = {
122*a430556eSPeng Fan .select = i2c_mux_gpio_select,
123*a430556eSPeng Fan .deselect = i2c_mux_gpio_deselect,
124*a430556eSPeng Fan };
125*a430556eSPeng Fan
126*a430556eSPeng Fan static const struct udevice_id i2c_mux_gpio_ids[] = {
127*a430556eSPeng Fan { .compatible = "i2c-mux-gpio", },
128*a430556eSPeng Fan {}
129*a430556eSPeng Fan };
130*a430556eSPeng Fan
131*a430556eSPeng Fan U_BOOT_DRIVER(i2c_mux_gpio) = {
132*a430556eSPeng Fan .name = "i2c_mux_gpio",
133*a430556eSPeng Fan .id = UCLASS_I2C_MUX,
134*a430556eSPeng Fan .of_match = i2c_mux_gpio_ids,
135*a430556eSPeng Fan .ops = &i2c_mux_gpio_ops,
136*a430556eSPeng Fan .probe = i2c_mux_gpio_probe,
137*a430556eSPeng Fan .priv_auto_alloc_size = sizeof(struct i2c_mux_gpio_priv),
138*a430556eSPeng Fan };
139