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