xref: /rk3399_rockchip-uboot/drivers/i2c/muxes/max96745.c (revision 11f9ae3a9f57d1ecc3b8cc16cfbf5e4e599e5330)
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 	bool idle_disc;
17 };
18 
19 static int max96745_select(struct udevice *mux, struct udevice *bus,
20 			   uint channel)
21 {
22 	struct max96745_priv *priv = dev_get_priv(mux);
23 
24 	if (!priv->idle_disc)
25 		return 0;
26 
27 	if (channel == 1)
28 		dm_i2c_reg_clrset(mux, 0x0086, DIS_REM_CC,
29 				  FIELD_PREP(DIS_REM_CC, 0));
30 	else
31 		dm_i2c_reg_clrset(mux, 0x0076, DIS_REM_CC,
32 				  FIELD_PREP(DIS_REM_CC, 0));
33 
34 	return 0;
35 }
36 
37 static int max96745_deselect(struct udevice *mux, struct udevice *bus,
38 			     uint channel)
39 {
40 	struct max96745_priv *priv = dev_get_priv(mux);
41 
42 	if (!priv->idle_disc)
43 		return 0;
44 
45 	if (channel == 1)
46 		dm_i2c_reg_clrset(mux, 0x0086, DIS_REM_CC,
47 				  FIELD_PREP(DIS_REM_CC, 1));
48 	else
49 		dm_i2c_reg_clrset(mux, 0x0076, DIS_REM_CC,
50 				  FIELD_PREP(DIS_REM_CC, 1));
51 
52 	return 0;
53 }
54 
55 static const struct i2c_mux_ops max96745_ops = {
56 	.select = max96745_select,
57 	.deselect = max96745_deselect,
58 };
59 
60 static int max96745_power_on(struct max96745_priv *priv)
61 {
62 	int ret;
63 
64 	if (dm_gpio_is_valid(&priv->enable_gpio)) {
65 		dm_gpio_set_value(&priv->enable_gpio, 1);
66 		mdelay(200);
67 	}
68 
69 	/* Set for I2C Fast-mode speed */
70 	ret = dm_i2c_reg_write(priv->dev, 0x0070, 0x16);
71 	if (ret < 0)
72 		return ret;
73 
74 	if (priv->idle_disc) {
75 		ret = dm_i2c_reg_clrset(priv->dev, 0x0076, DIS_REM_CC,
76 					FIELD_PREP(DIS_REM_CC, 1));
77 		if (ret < 0)
78 			return ret;
79 
80 		ret = dm_i2c_reg_clrset(priv->dev, 0x0086, DIS_REM_CC,
81 					FIELD_PREP(DIS_REM_CC, 1));
82 		if (ret < 0)
83 			return ret;
84 	}
85 
86 	return 0;
87 }
88 
89 static int max96745_probe(struct udevice *dev)
90 {
91 	struct max96745_priv *priv = dev_get_priv(dev);
92 	int ret;
93 
94 	ret = i2c_set_chip_offset_len(dev, 2);
95 	if (ret)
96 		return ret;
97 
98 	priv->dev = dev;
99 	priv->idle_disc = dev_read_bool(dev, "i2c-mux-idle-disconnect");
100 
101 	ret = gpio_request_by_name(dev, "enable-gpios", 0,
102 				   &priv->enable_gpio, GPIOD_IS_OUT);
103 	if (ret && ret != -ENOENT) {
104 		dev_err(dev, "%s: failed to get enable GPIO: %d\n", __func__, ret);
105 		return ret;
106 	}
107 
108 	max96745_power_on(priv);
109 
110 	return 0;
111 }
112 
113 static const struct udevice_id max96745_of_match[] = {
114 	{ .compatible = "maxim,max96745" },
115 	{}
116 };
117 
118 U_BOOT_DRIVER(max96745) = {
119 	.name = "max96745",
120 	.id = UCLASS_I2C_MUX,
121 	.of_match = max96745_of_match,
122 	.bind = dm_scan_fdt_dev,
123 	.probe = max96745_probe,
124 	.ops = &max96745_ops,
125 	.priv_auto_alloc_size = sizeof(struct max96745_priv),
126 };
127