xref: /OK3568_Linux_fs/u-boot/drivers/i2c/muxes/max96755f.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2022 Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <i2c.h>
10 #include <max96755f.h>
11 #include <dm/of_access.h>
12 #include <dm/ofnode.h>
13 
max96755f_select(struct udevice * mux,struct udevice * bus,uint channel)14 static int max96755f_select(struct udevice *mux, struct udevice *bus,
15 			    uint channel)
16 {
17 	struct max96755f_priv *priv = dev_get_priv(mux);
18 	int link_cfg;
19 
20 	dm_i2c_reg_clrset(priv->dev, 0x0001, DIS_REM_CC,
21 			  FIELD_PREP(DIS_REM_CC, 0));
22 
23 	if (!priv->split_mode)
24 		return 0;
25 
26 	link_cfg = dm_i2c_reg_read(priv->dev, 0x0010);
27 	if ((link_cfg & LINK_CFG) == SPLITTER_MODE)
28 		return 0;
29 
30 	if (channel == 0 && (link_cfg & LINK_CFG) != LINKA) {
31 		dm_i2c_reg_clrset(priv->dev, 0x0010,
32 				  RESET_ONESHOT | AUTO_LINK | LINK_CFG,
33 				  FIELD_PREP(RESET_ONESHOT, 1) |
34 				  FIELD_PREP(AUTO_LINK, 0) |
35 				  FIELD_PREP(LINK_CFG, LINKA));
36 		mdelay(50);
37 	} else if (channel == 1 && (link_cfg & LINK_CFG) != LINKB) {
38 		dm_i2c_reg_clrset(priv->dev, 0x0010,
39 				  RESET_ONESHOT | AUTO_LINK | LINK_CFG,
40 				  FIELD_PREP(RESET_ONESHOT, 1) |
41 				  FIELD_PREP(AUTO_LINK, 0) |
42 				  FIELD_PREP(LINK_CFG, LINKB));
43 		mdelay(50);
44 	}
45 
46 	return 0;
47 }
48 
max96755f_deselect(struct udevice * mux,struct udevice * bus,uint channel)49 static int max96755f_deselect(struct udevice *mux, struct udevice *bus,
50 			      uint channel)
51 {
52 	struct max96755f_priv *priv = dev_get_priv(mux);
53 
54 	dm_i2c_reg_clrset(priv->dev, 0x0001, DIS_REM_CC,
55 			  FIELD_PREP(DIS_REM_CC, 1));
56 	return 0;
57 }
58 
59 static const struct i2c_mux_ops max96755f_ops = {
60 	.select = max96755f_select,
61 	.deselect = max96755f_deselect,
62 };
63 
max96755f_power_on(struct max96755f_priv * priv)64 static int max96755f_power_on(struct max96755f_priv *priv)
65 {
66 	int ret;
67 
68 	if (dm_gpio_is_valid(&priv->enable_gpio)) {
69 		dm_gpio_set_value(&priv->enable_gpio, 1);
70 		mdelay(100);
71 	}
72 
73 	ret = dm_i2c_reg_clrset(priv->dev, 0x0010, RESET_ALL,
74 				FIELD_PREP(RESET_ALL, 1));
75 	if (ret < 0)
76 		return ret;
77 
78 	mdelay(100);
79 
80 	dm_i2c_reg_clrset(priv->dev, 0x0001, DIS_REM_CC,
81 			  FIELD_PREP(DIS_REM_CC, 1));
82 	return 0;
83 }
84 
max96755f_probe(struct udevice * dev)85 static int max96755f_probe(struct udevice *dev)
86 {
87 	struct max96755f_priv *priv = dev_get_priv(dev);
88 	ofnode child;
89 	u8 nr = 0;
90 	int ret;
91 
92 	ret = i2c_set_chip_offset_len(dev, 2);
93 	if (ret)
94 		return ret;
95 
96 	priv->dev = dev;
97 
98 	ret = gpio_request_by_name(dev, "enable-gpios", 0,
99 				   &priv->enable_gpio, GPIOD_IS_OUT);
100 	if (ret && ret != -ENOENT) {
101 		dev_err(dev, "%s: failed to get enable GPIO: %d\n", __func__, ret);
102 		return ret;
103 	}
104 
105 	ret = max96755f_power_on(priv);
106 	if (ret) {
107 		dev_err(dev, "%s: failed to power on: %d\n", __func__, ret);
108 		return ret;
109 	}
110 
111 	ofnode_for_each_subnode(child, dev_ofnode(dev)) {
112 		if (!ofnode_is_available(child) ||
113 		    !of_find_property(ofnode_to_np(child), "reg", NULL))
114 			continue;
115 
116 		nr++;
117 	}
118 
119 	if (nr == 2)
120 		priv->split_mode = true;
121 
122 	return 0;
123 }
124 
125 static const struct udevice_id max96755f_of_match[] = {
126 	{ .compatible = "maxim,max96755f" },
127 	{}
128 };
129 
130 U_BOOT_DRIVER(max96755f) = {
131 	.name = "max96755f",
132 	.id = UCLASS_I2C_MUX,
133 	.of_match = max96755f_of_match,
134 	.bind = dm_scan_fdt_dev,
135 	.probe = max96755f_probe,
136 	.ops = &max96755f_ops,
137 	.priv_auto_alloc_size = sizeof(struct max96755f_priv),
138 };
139 
140