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