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 }; 17 18 static int max96745_select(struct udevice *mux, struct udevice *bus, 19 uint channel) 20 { 21 if (channel == 1) 22 dm_i2c_reg_clrset(mux, 0x0086, DIS_REM_CC, 23 FIELD_PREP(DIS_REM_CC, 0)); 24 else 25 dm_i2c_reg_clrset(mux, 0x0076, DIS_REM_CC, 26 FIELD_PREP(DIS_REM_CC, 0)); 27 28 return 0; 29 } 30 31 static int max96745_deselect(struct udevice *mux, struct udevice *bus, 32 uint channel) 33 { 34 if (channel == 1) 35 dm_i2c_reg_clrset(mux, 0x0086, DIS_REM_CC, 36 FIELD_PREP(DIS_REM_CC, 1)); 37 else 38 dm_i2c_reg_clrset(mux, 0x0076, DIS_REM_CC, 39 FIELD_PREP(DIS_REM_CC, 1)); 40 41 return 0; 42 } 43 44 static const struct i2c_mux_ops max96745_ops = { 45 .select = max96745_select, 46 .deselect = max96745_deselect, 47 }; 48 49 static int max96745_power_on(struct max96745_priv *priv) 50 { 51 int ret; 52 53 if (dm_gpio_is_valid(&priv->enable_gpio)) { 54 dm_gpio_set_value(&priv->enable_gpio, 1); 55 mdelay(100); 56 } 57 58 ret = dm_i2c_reg_clrset(priv->dev, 0x0010, RESET_ALL, 59 FIELD_PREP(RESET_ALL, 1)); 60 if (ret < 0) 61 return ret; 62 63 mdelay(100); 64 65 return 0; 66 } 67 68 static int max96745_power_off(struct max96745_priv *priv) 69 { 70 if (dm_gpio_is_valid(&priv->enable_gpio)) 71 dm_gpio_set_value(&priv->enable_gpio, 0); 72 73 return 0; 74 } 75 76 static int max96745_probe(struct udevice *dev) 77 { 78 struct max96745_priv *priv = dev_get_priv(dev); 79 int ret; 80 81 ret = i2c_set_chip_offset_len(dev, 2); 82 if (ret) 83 return ret; 84 85 priv->dev = dev; 86 87 ret = gpio_request_by_name(dev, "enable-gpios", 0, 88 &priv->enable_gpio, GPIOD_IS_OUT); 89 if (ret && ret != -ENOENT) { 90 dev_err(dev, "%s: failed to get enable GPIO: %d\n", __func__, ret); 91 return ret; 92 } 93 94 ret = max96745_power_on(priv); 95 if (ret) { 96 dev_err(dev, "%s: failed to power on: %d\n", __func__, ret); 97 return ret; 98 } 99 100 ret = dm_i2c_reg_read(dev, 0x002a); 101 if (ret < 0 || !FIELD_GET(LINK_LOCKED, ret)) { 102 max96745_power_off(priv); 103 dev_err(dev, "%s: GMSL link not locked\n", __func__); 104 return -ENODEV; 105 } 106 107 dm_i2c_reg_clrset(dev, 0x0076, DIS_REM_CC, FIELD_PREP(DIS_REM_CC, 1)); 108 dm_i2c_reg_clrset(dev, 0x0086, DIS_REM_CC, FIELD_PREP(DIS_REM_CC, 1)); 109 110 return 0; 111 } 112 113 static const struct udevice_id max96745_of_match[] = { 114 { .compatible = "maxim,max96745" }, 115 {} 116 }; 117 118 U_BOOT_DRIVER(max96745) = { 119 .name = "max96745", 120 .id = UCLASS_I2C_MUX, 121 .of_match = max96745_of_match, 122 .bind = dm_scan_fdt_dev, 123 .probe = max96745_probe, 124 .ops = &max96745_ops, 125 .priv_auto_alloc_size = sizeof(struct max96745_priv), 126 }; 127