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