xref: /OK3568_Linux_fs/u-boot/drivers/i2c/muxes/max96745.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2022 Rockchip Electronics Co., Ltd
4  */
5 
6 #include <asm-generic/gpio.h>
7 #include <common.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <i2c.h>
11 #include <max96745.h>
12 
13 struct max96745_priv {
14 	struct udevice *dev;
15 	struct gpio_desc enable_gpio;
16 	struct gpio_desc pwdnb_gpio;
17 	bool idle_disc;
18 };
19 
max96745_select(struct udevice * mux,struct udevice * bus,uint channel)20 static int max96745_select(struct udevice *mux, struct udevice *bus,
21 			   uint channel)
22 {
23 	struct max96745_priv *priv = dev_get_priv(mux);
24 
25 	if (!priv->idle_disc)
26 		return 0;
27 
28 	if (channel == 1)
29 		dm_i2c_reg_clrset(mux, 0x0086, DIS_REM_CC,
30 				  FIELD_PREP(DIS_REM_CC, 0));
31 	else
32 		dm_i2c_reg_clrset(mux, 0x0076, DIS_REM_CC,
33 				  FIELD_PREP(DIS_REM_CC, 0));
34 
35 	return 0;
36 }
37 
max96745_deselect(struct udevice * mux,struct udevice * bus,uint channel)38 static int max96745_deselect(struct udevice *mux, struct udevice *bus,
39 			     uint channel)
40 {
41 	struct max96745_priv *priv = dev_get_priv(mux);
42 
43 	if (!priv->idle_disc)
44 		return 0;
45 
46 	if (channel == 1)
47 		dm_i2c_reg_clrset(mux, 0x0086, DIS_REM_CC,
48 				  FIELD_PREP(DIS_REM_CC, 1));
49 	else
50 		dm_i2c_reg_clrset(mux, 0x0076, DIS_REM_CC,
51 				  FIELD_PREP(DIS_REM_CC, 1));
52 
53 	return 0;
54 }
55 
56 static const struct i2c_mux_ops max96745_ops = {
57 	.select = max96745_select,
58 	.deselect = max96745_deselect,
59 };
60 
max96745_power_on(struct max96745_priv * priv)61 static int max96745_power_on(struct max96745_priv *priv)
62 {
63 	int ret;
64 
65 	if (dm_gpio_is_valid(&priv->enable_gpio)) {
66 		dm_gpio_set_value(&priv->enable_gpio, 1);
67 		mdelay(200);
68 	}
69 
70 	if (dm_gpio_is_valid(&priv->pwdnb_gpio)) {
71 		dm_gpio_set_value(&priv->pwdnb_gpio, 0);
72 		mdelay(30);
73 	}
74 
75 	/* Set for I2C Fast-mode speed */
76 	ret = dm_i2c_reg_write(priv->dev, 0x0070, 0x16);
77 	if (ret < 0)
78 		return ret;
79 
80 	if (priv->idle_disc) {
81 		ret = dm_i2c_reg_clrset(priv->dev, 0x0076, DIS_REM_CC,
82 					FIELD_PREP(DIS_REM_CC, 1));
83 		if (ret < 0)
84 			return ret;
85 
86 		ret = dm_i2c_reg_clrset(priv->dev, 0x0086, DIS_REM_CC,
87 					FIELD_PREP(DIS_REM_CC, 1));
88 		if (ret < 0)
89 			return ret;
90 	}
91 
92 	return 0;
93 }
94 
max96745_probe(struct udevice * dev)95 static int max96745_probe(struct udevice *dev)
96 {
97 	struct max96745_priv *priv = dev_get_priv(dev);
98 	int ret;
99 
100 	ret = i2c_set_chip_offset_len(dev, 2);
101 	if (ret)
102 		return ret;
103 
104 	priv->dev = dev;
105 	priv->idle_disc = dev_read_bool(dev, "i2c-mux-idle-disconnect");
106 
107 	ret = gpio_request_by_name(dev, "enable-gpios", 0,
108 				   &priv->enable_gpio, GPIOD_IS_OUT);
109 	if (ret && ret != -ENOENT) {
110 		dev_err(dev, "%s: failed to get enable GPIO: %d\n", __func__, ret);
111 		return ret;
112 	}
113 
114 	ret = gpio_request_by_name(dev, "pwdnb-gpios", 0,
115 				   &priv->pwdnb_gpio, GPIOD_IS_OUT);
116 	if (ret && ret != -ENOENT) {
117 		dev_err(dev, "%s: failed to get pwdnb GPIO: %d\n", __func__, ret);
118 		return ret;
119 	}
120 
121 	max96745_power_on(priv);
122 
123 	return 0;
124 }
125 
126 static const struct udevice_id max96745_of_match[] = {
127 	{ .compatible = "maxim,max96745" },
128 	{}
129 };
130 
131 U_BOOT_DRIVER(max96745) = {
132 	.name = "max96745",
133 	.id = UCLASS_I2C_MUX,
134 	.of_match = max96745_of_match,
135 	.bind = dm_scan_fdt_dev,
136 	.probe = max96745_probe,
137 	.ops = &max96745_ops,
138 	.priv_auto_alloc_size = sizeof(struct max96745_priv),
139 };
140