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_power_off(struct max96755f_priv *priv) 86 { 87 if (dm_gpio_is_valid(&priv->enable_gpio)) 88 dm_gpio_set_value(&priv->enable_gpio, 0); 89 90 return 0; 91 } 92 93 static int max96755f_probe(struct udevice *dev) 94 { 95 struct max96755f_priv *priv = dev_get_priv(dev); 96 ofnode child; 97 u8 nr = 0; 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 106 ret = gpio_request_by_name(dev, "enable-gpios", 0, 107 &priv->enable_gpio, GPIOD_IS_OUT); 108 if (ret && ret != -ENOENT) { 109 dev_err(dev, "%s: failed to get enable GPIO: %d\n", __func__, ret); 110 return ret; 111 } 112 113 ret = max96755f_power_on(priv); 114 if (ret) { 115 dev_err(dev, "%s: failed to power on: %d\n", __func__, ret); 116 return ret; 117 } 118 119 ret = dm_i2c_reg_read(dev, 0x0013); 120 if (ret < 0 || !FIELD_GET(LOCKED, ret)) { 121 max96755f_power_off(priv); 122 dev_err(dev, "%s: GMSL link not locked\n", __func__); 123 return -ENODEV; 124 } 125 126 ofnode_for_each_subnode(child, dev_ofnode(dev)) { 127 if (!ofnode_is_available(child) || 128 !of_find_property(ofnode_to_np(child), "reg", NULL)) 129 continue; 130 131 nr++; 132 } 133 134 if (nr == 2) 135 priv->split_mode = true; 136 137 return 0; 138 } 139 140 static const struct udevice_id max96755f_of_match[] = { 141 { .compatible = "maxim,max96755f" }, 142 {} 143 }; 144 145 U_BOOT_DRIVER(max96755f) = { 146 .name = "max96755f", 147 .id = UCLASS_I2C_MUX, 148 .of_match = max96755f_of_match, 149 .bind = dm_scan_fdt_dev, 150 .probe = max96755f_probe, 151 .ops = &max96755f_ops, 152 .priv_auto_alloc_size = sizeof(struct max96755f_priv), 153 }; 154 155