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