1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2022 Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <errno.h> 9 #include <i2c.h> 10 #include <max96755f.h> 11 #include <dm/of_access.h> 12 #include <dm/ofnode.h> 13 14 static int max96755f_select(struct udevice *mux, struct udevice *bus, 15 uint channel) 16 { 17 struct max96755f_priv *priv = dev_get_priv(mux); 18 int link_cfg; 19 20 dm_i2c_reg_clrset(priv->dev, 0x0001, DIS_REM_CC, 21 FIELD_PREP(DIS_REM_CC, 0)); 22 23 if (!priv->split_mode) 24 return 0; 25 26 link_cfg = dm_i2c_reg_read(priv->dev, 0x0010); 27 if ((link_cfg & LINK_CFG) == SPLITTER_MODE) 28 return 0; 29 30 if (channel == 0 && (link_cfg & LINK_CFG) != LINKA) { 31 dm_i2c_reg_clrset(priv->dev, 0x0010, 32 RESET_ONESHOT | AUTO_LINK | LINK_CFG, 33 FIELD_PREP(RESET_ONESHOT, 1) | 34 FIELD_PREP(AUTO_LINK, 0) | 35 FIELD_PREP(LINK_CFG, LINKA)); 36 mdelay(50); 37 } else if (channel == 1 && (link_cfg & LINK_CFG) != LINKB) { 38 dm_i2c_reg_clrset(priv->dev, 0x0010, 39 RESET_ONESHOT | AUTO_LINK | LINK_CFG, 40 FIELD_PREP(RESET_ONESHOT, 1) | 41 FIELD_PREP(AUTO_LINK, 0) | 42 FIELD_PREP(LINK_CFG, LINKB)); 43 mdelay(50); 44 } 45 46 return 0; 47 } 48 49 static int max96755f_deselect(struct udevice *mux, struct udevice *bus, 50 uint channel) 51 { 52 struct max96755f_priv *priv = dev_get_priv(mux); 53 54 dm_i2c_reg_clrset(priv->dev, 0x0001, DIS_REM_CC, 55 FIELD_PREP(DIS_REM_CC, 1)); 56 return 0; 57 } 58 59 static const struct i2c_mux_ops max96755f_ops = { 60 .select = max96755f_select, 61 .deselect = max96755f_deselect, 62 }; 63 64 static int max96755f_power_on(struct max96755f_priv *priv) 65 { 66 int ret; 67 68 if (dm_gpio_is_valid(&priv->enable_gpio)) { 69 dm_gpio_set_value(&priv->enable_gpio, 1); 70 mdelay(100); 71 } 72 73 ret = dm_i2c_reg_clrset(priv->dev, 0x0010, RESET_ALL, 74 FIELD_PREP(RESET_ALL, 1)); 75 if (ret < 0) 76 return ret; 77 78 mdelay(100); 79 80 dm_i2c_reg_clrset(priv->dev, 0x0001, DIS_REM_CC, 81 FIELD_PREP(DIS_REM_CC, 1)); 82 return 0; 83 } 84 85 static int max96755f_probe(struct udevice *dev) 86 { 87 struct max96755f_priv *priv = dev_get_priv(dev); 88 ofnode child; 89 u8 nr = 0; 90 int ret; 91 92 ret = i2c_set_chip_offset_len(dev, 2); 93 if (ret) 94 return ret; 95 96 priv->dev = dev; 97 98 ret = gpio_request_by_name(dev, "enable-gpios", 0, 99 &priv->enable_gpio, GPIOD_IS_OUT); 100 if (ret && ret != -ENOENT) { 101 dev_err(dev, "%s: failed to get enable GPIO: %d\n", __func__, ret); 102 return ret; 103 } 104 105 ret = max96755f_power_on(priv); 106 if (ret) { 107 dev_err(dev, "%s: failed to power on: %d\n", __func__, ret); 108 return ret; 109 } 110 111 ofnode_for_each_subnode(child, dev_ofnode(dev)) { 112 if (!ofnode_is_available(child) || 113 !of_find_property(ofnode_to_np(child), "reg", NULL)) 114 continue; 115 116 nr++; 117 } 118 119 if (nr == 2) 120 priv->split_mode = true; 121 122 return 0; 123 } 124 125 static const struct udevice_id max96755f_of_match[] = { 126 { .compatible = "maxim,max96755f" }, 127 {} 128 }; 129 130 U_BOOT_DRIVER(max96755f) = { 131 .name = "max96755f", 132 .id = UCLASS_I2C_MUX, 133 .of_match = max96755f_of_match, 134 .bind = dm_scan_fdt_dev, 135 .probe = max96755f_probe, 136 .ops = &max96755f_ops, 137 .priv_auto_alloc_size = sizeof(struct max96755f_priv), 138 }; 139 140