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 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 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 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 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