/* * Do I2C/PMU writes to bring up SD card bus power * */ void board_sdmmc_voltage_init(void) { struct udevice *dev; uchar reg, data_buffer[1]; int ret; int i; ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (ret) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return; } /* TPS659110: LDO5_REG = 3.3v, ACTIVE to SDMMC1 */ data_buffer[0] = 0x65; reg = 0x32; for (i = 0; i < MAX_I2C_RETRY; ++i) { if (dm_i2c_write(dev, reg, data_buffer, 1)) udelay(100); } /* TPS659110: GPIO7_REG = PDEN, output a 1 to EN_3V3_SYS */ data_buffer[0] = 0x09; reg = 0x67; for (i = 0; i < MAX_I2C_RETRY; ++i) { if (dm_i2c_write(dev, reg, data_buffer, 1)) udelay(100); } }
/* * Set USB VBUS signals (via I2C IO expander/GPIO) as output and set * output value as disabled * * Set USB Current Limit signals (via I2C IO expander/GPIO) as output * and set output value as enabled */ int board_xhci_config(void) { struct udevice *dev; int ret; u8 buf[8]; if (of_machine_is_compatible("marvell,armada7040-db")) { /* Configure IO exander PCA9555: 7bit address 0x21 */ ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); if (ret) { printf("Cannot find PCA9555: %d\n", ret); return 0; } /* * Read configuration (direction) and set VBUS pin as output * (reset pin = output) */ ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1); if (ret) { printf("Failed to read IO expander value via I2C\n"); return -EIO; } buf[0] &= ~I2C_IO_REG_VBUS; buf[0] &= ~I2C_IO_REG_CL; ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1); if (ret) { printf("Failed to set IO expander via I2C\n"); return -EIO; } /* Read output value and configure it */ ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); if (ret) { printf("Failed to read IO expander value via I2C\n"); return -EIO; } buf[0] &= ~I2C_IO_REG_VBUS; buf[0] |= I2C_IO_REG_CL; ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); if (ret) { printf("Failed to set IO expander via I2C\n"); return -EIO; } mdelay(500); /* required delay to let output value settle */ } return 0; }
static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm) { uchar buf[8]; int i = 0, ret; /* start register address */ buf[i++] = PCF2127_REG_SC; /* hours, minutes and seconds */ buf[i++] = bin2bcd(tm->tm_sec); buf[i++] = bin2bcd(tm->tm_min); buf[i++] = bin2bcd(tm->tm_hour); buf[i++] = bin2bcd(tm->tm_mday); buf[i++] = tm->tm_wday & 0x07; /* month, 1 - 12 */ buf[i++] = bin2bcd(tm->tm_mon + 1); /* year */ buf[i++] = bin2bcd(tm->tm_year % 100); /* write register's data */ ret = dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)); return ret; }
static int pcf2127_rtc_get(struct udevice *dev, struct rtc_time *tm) { int ret = 0; uchar buf[10] = { PCF2127_REG_CTRL1 }; ret = dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, 1); if (ret < 0) return ret; ret = dm_i2c_read(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)); if (ret < 0) return ret; if (buf[PCF2127_REG_CTRL3] & 0x04) puts("### Warning: RTC Low Voltage - date/time not reliable\n"); tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F); tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F); tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F); tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F); tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]) + 1900; if (tm->tm_year < 1970) tm->tm_year += 100; /* assume we are in 1970...2069 */ tm->tm_wday = buf[PCF2127_REG_DW] & 0x07; tm->tm_yday = 0; tm->tm_isdst = 0; debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec); return ret; }
static bool disable_mcu_watchdog(void) { struct udevice *bus, *dev; int ret, retry = 3; uchar buf[1] = {0x0}; if (uclass_get_device_by_name(UCLASS_I2C, OMNIA_I2C_MCU_DM_NAME, &bus)) { puts("Cannot find MCU bus! Can not disable MCU WDT.\n"); return false; } ret = i2c_get_chip(bus, OMNIA_I2C_MCU, 1, &dev); if (ret) { puts("Cannot get MCU chip! Can not disable MCU WDT.\n"); return false; } for (; retry > 0; --retry) if (!dm_i2c_write(dev, OMNIA_I2C_MCU_WDT_ADDR, (uchar *) buf, 1)) break; if (retry <= 0) { puts("I2C MCU watchdog failed to disable!\n"); return false; } return true; }
static int tpm_tis_i2c_write_generic(struct udevice *dev, u8 addr, const u8 *buffer, size_t len, unsigned int sleep_time_us, u8 max_count) { struct tpm_chip_priv *priv = dev_get_uclass_priv(dev); struct tpm_chip *chip = dev_get_priv(dev); int rc = 0; int count; if (chip->chip_type == SLB9635) { /* Prepare send buffer to include the address */ priv->buf[0] = addr; memcpy(&(priv->buf[1]), buffer, len); buffer = priv->buf; len++; addr = 0; } for (count = 0; count < max_count; count++) { rc = dm_i2c_write(dev, addr, buffer, len); if (rc == 0) break; /* Success, break to skip sleep */ udelay(sleep_time_us); } /* take care of 'guard time' */ udelay(sleep_time_us); if (rc) return rc; return 0; }
/* * Do I2C/PMU writes to bring up SD card bus power * */ void board_sdmmc_voltage_init(void) { struct udevice *dev; uchar reg, data_buffer[1]; int ret; ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (ret) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return; } /* TPS65913: LDO9_VOLTAGE = 3.3V */ data_buffer[0] = 0x31; reg = 0x61; ret = dm_i2c_write(dev, reg, data_buffer, 1); if (ret) printf("%s: PMU i2c_write %02X<-%02X returned %d\n", __func__, reg, data_buffer[0], ret); /* TPS65913: LDO9_CTRL = Active */ data_buffer[0] = 0x01; reg = 0x60; ret = dm_i2c_write(dev, reg, data_buffer, 1); if (ret) printf("%s: PMU i2c_write %02X<-%02X returned %d\n", __func__, reg, data_buffer[0], ret); /* TPS65090: FET6_CTRL = enable output auto discharge, enable FET6 */ data_buffer[0] = 0x03; reg = 0x14; ret = i2c_get_chip_for_busnum(0, BAT_I2C_ADDRESS, 1, &dev); if (ret) { debug("%s: Cannot find charger I2C chip\n", __func__); return; } ret = dm_i2c_write(dev, reg, data_buffer, 1); if (ret) printf("%s: BAT i2c_write %02X<-%02X returned %d\n", __func__, reg, data_buffer[0], ret); }
int tegra_pcie_board_init(void) { struct udevice *dev; u8 addr, data[1]; int err; err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (err) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return err; } /* TPS659110: VDD2_OP_REG = 1.05V */ data[0] = 0x27; addr = 0x25; err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set VDD supply\n"); return err; } /* TPS659110: VDD2_REG 7.5 mV/us, ACTIVE */ data[0] = 0x0D; addr = 0x24; err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to enable VDD supply\n"); return err; } /* TPS659110: LDO6_REG = 1.1V, ACTIVE */ data[0] = 0x0D; addr = 0x35; err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set AVDD supply\n"); return err; } return 0; }
static int act8846_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { if (dm_i2c_write(dev, reg, buff, len)) { debug("write error to device: %p register: %#x!\n", dev, reg); return -EIO; } return 0; }
static int lp873x_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { if (dm_i2c_write(dev, reg, buff, len)) { error("write error to device: %p register: %#x!", dev, reg); return -EIO; } return 0; }
/* * st33zp24_i2c_write8_reg * Send byte to the TIS register according to the ST33ZP24 I2C protocol. * @param: tpm_register, the tpm tis register where the data should be written * @param: tpm_data, the tpm_data to write inside the tpm_register * @param: tpm_size, The length of the data * @return: Number of byte written successfully else an error code. */ static int st33zp24_i2c_write8_reg(struct udevice *dev, u8 tpm_register, const u8 *tpm_data, size_t tpm_size) { struct tpm_chip_priv *chip_priv = dev_get_uclass_priv(dev); chip_priv->buf[0] = tpm_register; memcpy(chip_priv->buf + 1, tpm_data, tpm_size); return dm_i2c_write(dev, 0, chip_priv->buf, tpm_size + 1); }
static int max8997_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { int ret; ret = dm_i2c_write(dev, reg, buff, len); if (ret) pr_err("write error to device: %p register: %#x!", dev, reg); return ret; }
static int pmic_tps65910_write(struct udevice *dev, uint reg, const u8 *buffer, int len) { int ret; ret = dm_i2c_write(dev, reg, buffer, len); if (ret) pr_err("%s write error on register %02x\n", dev->name, reg); return ret; }
int tegra_pcie_board_init(void) { struct udevice *dev; u8 addr, data[1]; int err; err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (err) { debug("failed to find PMU bus\n"); return err; } /* TPS659110: LDO1_REG = 1.05V, ACTIVE */ data[0] = 0x15; addr = 0x30; err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set VDD supply\n"); return err; } /* GPIO: PEX = 3.3V */ err = gpio_request(TEGRA_GPIO(L, 7), "PEX"); if (err < 0) return err; gpio_direction_output(TEGRA_GPIO(L, 7), 1); /* TPS659110: LDO2_REG = 1.05V, ACTIVE */ data[0] = 0x15; addr = 0x31; err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set AVDD supply\n"); return err; } return 0; }
int i2c_write(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer, int len) { struct udevice *dev; int ret; ret = i2c_compat_get_device(chip_addr, alen, &dev); if (ret) return ret; return dm_i2c_write(dev, addr, buffer, len); }
void pmu_write(uchar reg, uchar data) { struct udevice *dev; int ret; ret = i2c_get_chip_for_busnum(4, PMU_I2C_ADDRESS, 1, &dev); if (ret) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return; } dm_i2c_write(dev, reg, &data, 1); }
static int stpmu1_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { int ret; ret = dm_i2c_write(dev, reg, buff, len); if (ret) dev_err(dev, "%s: failed to write register %#x :%d", __func__, reg, ret); return ret; }
/* * tpm_tis_i2c_read() - read from TPM register * @addr: register address to read from * @buffer: provided by caller * @len: number of bytes to read * * Read len bytes from TPM register and put them into * buffer (little-endian format, i.e. first byte is put into buffer[0]). * * NOTE: TPM is big-endian for multi-byte values. Multi-byte * values have to be swapped. * * Return -EIO on error, 0 on success. */ static int tpm_tis_i2c_read(struct udevice *dev, u8 addr, u8 *buffer, size_t len) { struct tpm_chip *chip = dev_get_priv(dev); int rc; int count; uint32_t addrbuf = addr; if ((chip->chip_type == SLB9635) || (chip->chip_type == UNKNOWN)) { /* slb9635 protocol should work in both cases */ for (count = 0; count < MAX_COUNT; count++) { rc = dm_i2c_write(dev, 0, (uchar *)&addrbuf, 1); if (rc == 0) break; /* Success, break to skip sleep */ udelay(SLEEP_DURATION_US); } if (rc) return rc; /* After the TPM has successfully received the register address * it needs some time, thus we're sleeping here again, before * retrieving the data */ for (count = 0; count < MAX_COUNT; count++) { udelay(SLEEP_DURATION_US); rc = dm_i2c_read(dev, 0, buffer, len); if (rc == 0) break; /* success, break to skip sleep */ } } else { /* * Use a combined read for newer chips. * Unfortunately the smbus functions are not suitable due to * the 32 byte limit of the smbus. * Retries should usually not be needed, but are kept just to * be safe on the safe side. */ for (count = 0; count < MAX_COUNT; count++) { rc = dm_i2c_read(dev, addr, buffer, len); if (rc == 0) break; /* break here to skip sleep */ udelay(SLEEP_DURATION_US); } } /* Take care of 'guard time' */ udelay(SLEEP_DURATION_US); if (rc) return rc; return 0; }
int board_late_init(void) { struct udevice *dev; u8 buf[8]; int ret; /* Configure SMSC USB2513 USB Hub: 7bit address 0x2c */ ret = i2c_get_chip_for_busnum(0, 0x2c, 1, &dev); if (ret) { printf("Cannot find USB2513: %d\n", ret); return 0; } /* * The first access to the USB Hub fails sometimes, so lets read * a dummy byte to be sure here */ dm_i2c_read(dev, 0x00, buf, 1); /* * The SMSC hub is not visible on the I2C bus after the first * configuration at power-up. The following code deliberately * does not report upon failure of these I2C write calls. */ buf[0] = 0x93; dm_i2c_write(dev, 0x06, buf, 1); buf[0] = 0xaa; dm_i2c_write(dev, 0xf8, buf, 1); buf[0] = 0x0f; dm_i2c_write(dev, 0xfa, buf, 1); buf[0] = 0x01; dm_i2c_write(dev, 0xff, buf, 1); return 0; }
static int pca953x_write_single(struct udevice *dev, int reg, u8 val, int offset) { struct pca953x_info *info = dev_get_platdata(dev); int bank_shift = fls((info->gpio_count - 1) / BANK_SZ); int off = offset / BANK_SZ; int ret = 0; ret = dm_i2c_write(dev, (reg << bank_shift) + off, &val, 1); if (ret) { dev_err(dev, "%s error\n", __func__); return ret; } return 0; }
void pin_mux_mmc(void) { struct udevice *dev; uchar val; int ret; /* Turn on MAX77620 LDO2 to 3.3V for SD card power */ debug("%s: Set LDO2 for VDDIO_SDMMC_AP power to 3.3V\n", __func__); ret = i2c_get_chip_for_busnum(0, MAX77620_I2C_ADDR_7BIT, 1, &dev); if (ret) { printf("%s: Cannot find MAX77620 I2C chip\n", __func__); return; } /* 0xF2 for 3.3v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ val = 0xF2; ret = dm_i2c_write(dev, MAX77620_CNFG1_L2_REG, &val, 1); if (ret) printf("i2c_write 0 0x3c 0x27 failed: %d\n", ret); }
int board_xhci_enable(void) { struct udevice *dev; int ret; u8 buf[8]; if (of_machine_is_compatible("marvell,armada7040-db")) { /* * This function enables all USB ports simultaniously, * it only needs to get called once */ if (usb_enabled) return 0; /* Configure IO exander PCA9555: 7bit address 0x21 */ ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); if (ret) { printf("Cannot find PCA9555: %d\n", ret); return 0; } /* Read VBUS output value */ ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); if (ret) { printf("Failed to read IO expander value via I2C\n"); return -EIO; } /* Enable VBUS power: Set output value of VBUS pin as enabled */ buf[0] |= I2C_IO_REG_VBUS; ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); if (ret) { printf("Failed to set IO expander via I2C\n"); return -EIO; } mdelay(500); /* required delay to let output value settle */ usb_enabled = 1; } return 0; }
void reset_cpu(ulong addr) { struct udevice *dev; const u8 pmic_bus = 6; const u8 pmic_addr = 0x5a; u8 data; int ret; ret = i2c_get_chip_for_busnum(pmic_bus, pmic_addr, 1, &dev); if (ret) hang(); ret = dm_i2c_read(dev, 0x13, &data, 1); if (ret) hang(); data |= BIT(1); ret = dm_i2c_write(dev, 0x13, &data, 1); if (ret) hang(); }
int arch_misc_init(void) { /* Disable PMIC sleep mode on low supply voltage */ struct udevice *dev; u8 addr, data[1]; int err; err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); if (err) { debug("%s: Cannot find PMIC I2C chip\n", __func__); return err; } addr = PMU_SUPPLYENE; err = dm_i2c_read(dev, addr, data, 1); if (err) { debug("failed to get PMU_SUPPLYENE\n"); return err; } data[0] &= ~PMU_SUPPLYENE_SYSINEN; data[0] |= PMU_SUPPLYENE_EXITSLREQ; err = dm_i2c_write(dev, addr, data, 1); if (err) { debug("failed to set PMU_SUPPLYENE\n"); return err; } /* make sure SODIMM pin 87 nRESET_OUT is released properly */ pinmux_set_func(PMUX_PINGRP_ATA, PMUX_FUNC_GMI); if (readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BOOTTYPE) == NVBOOTTYPE_RECOVERY) printf("USB recovery mode\n"); return 0; }
int dm_i2c_reg_write(struct udevice *dev, uint offset, uint value) { uint8_t val = value; return dm_i2c_write(dev, offset, &val, 1); }
static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd, int cmd_version, const uint8_t *dout, int dout_len, uint8_t **dinp, int din_len) { struct cros_ec_dev *dev = dev_get_uclass_priv(udev); /* version8, cmd8, arglen8, out8[dout_len], csum8 */ int out_bytes = dout_len + 4; /* response8, arglen8, in8[din_len], checksum8 */ int in_bytes = din_len + 3; uint8_t *ptr; /* Receive input data, so that args will be dword aligned */ uint8_t *in_ptr; int len, csum, ret; /* * Sanity-check I/O sizes given transaction overhead in internal * buffers. */ if (out_bytes > sizeof(dev->dout)) { debug("%s: Cannot send %d bytes\n", __func__, dout_len); return -1; } if (in_bytes > sizeof(dev->din)) { debug("%s: Cannot receive %d bytes\n", __func__, din_len); return -1; } assert(dout_len >= 0); assert(dinp); /* * Copy command and data into output buffer so we can do a single I2C * burst transaction. */ ptr = dev->dout; /* * in_ptr starts of pointing to a dword-aligned input data buffer. * We decrement it back by the number of header bytes we expect to * receive, so that the first parameter of the resulting input data * will be dword aligned. */ in_ptr = dev->din + sizeof(int64_t); if (dev->protocol_version != 2) { /* Something we don't support */ debug("%s: Protocol version %d unsupported\n", __func__, dev->protocol_version); return -1; } *ptr++ = EC_CMD_VERSION0 + cmd_version; *ptr++ = cmd; *ptr++ = dout_len; in_ptr -= 2; /* Expect status, length bytes */ memcpy(ptr, dout, dout_len); ptr += dout_len; *ptr++ = (uint8_t) cros_ec_calc_checksum(dev->dout, dout_len + 3); /* Send output data */ cros_ec_dump_data("out", -1, dev->dout, out_bytes); ret = dm_i2c_write(udev, 0, dev->dout, out_bytes); if (ret) { debug("%s: Cannot complete I2C write to %s\n", __func__, udev->name); ret = -1; } if (!ret) { ret = dm_i2c_read(udev, 0, in_ptr, in_bytes); if (ret) { debug("%s: Cannot complete I2C read from %s\n", __func__, udev->name); ret = -1; } } if (*in_ptr != EC_RES_SUCCESS) { debug("%s: Received bad result code %d\n", __func__, *in_ptr); return -(int)*in_ptr; } len = in_ptr[1]; if (len + 3 > sizeof(dev->din)) { debug("%s: Received length %#02x too large\n", __func__, len); return -1; } csum = cros_ec_calc_checksum(in_ptr, 2 + len); if (csum != in_ptr[2 + len]) { debug("%s: Invalid checksum rx %#02x, calced %#02x\n", __func__, in_ptr[2 + din_len], csum); return -1; } din_len = min(din_len, len); cros_ec_dump_data("in", -1, in_ptr, din_len + 3); /* Return pointer to dword-aligned input data, if any */ *dinp = dev->din + sizeof(int64_t); return din_len; }