xref: /rk3399_rockchip-uboot/drivers/i2c/muxes/max96745.c (revision a7a8e68169f79f6d0f9ec66f00b487f452fdfa54)
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