static int as3722_check_device_id(struct as3722 *as3722) { u32 val; int ret; /* Check that this is actually a AS3722 */ ret = as3722_read(as3722, AS3722_ASIC_ID1_REG, &val); if (ret < 0) { dev_err(as3722->dev, "ASIC_ID1 read failed: %d\n", ret); return ret; } if (val != AS3722_DEVICE_ID) { dev_err(as3722->dev, "Device is not AS3722, ID is 0x%x\n", val); return -ENODEV; } ret = as3722_read(as3722, AS3722_ASIC_ID2_REG, &val); if (ret < 0) { dev_err(as3722->dev, "ASIC_ID2 read failed: %d\n", ret); return ret; } dev_info(as3722->dev, "AS3722 with revision 0x%x found\n", val); return 0; }
static int as3722_gpio_set(struct udevice *pmic, unsigned int gpio, unsigned int level) { const char *l; u8 value; int err; if (gpio > 7) return -EINVAL; err = as3722_read(pmic, AS3722_GPIO_SIGNAL_OUT, &value); if (err < 0) { error("failed to read GPIO signal out register: %d", err); return err; } if (level == 0) { value &= ~(1 << gpio); l = "low"; } else { value |= 1 << gpio; l = "high"; } err = as3722_write(pmic, AS3722_GPIO_SIGNAL_OUT, value); if (err) { error("failed to set GPIO#%u %s: %d", gpio, l, err); return err; } return 0; }
static void as3722_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct as3722_pctrl_info *as_pci = to_as_pci(chip); struct as3722 *as3722 = as_pci->as3722; int en_invert; u32 val; int ret; ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &val); if (ret < 0) { dev_err(as_pci->dev, "GPIO_CONTROL%d_REG read failed: %d\n", offset, ret); return; } en_invert = !!(val & AS3722_GPIO_INV); if (value) val = (en_invert) ? 0 : AS3722_GPIOn_SIGNAL(offset); else val = (en_invert) ? AS3722_GPIOn_SIGNAL(offset) : 0; ret = as3722_update_bits(as3722, AS3722_GPIO_SIGNAL_OUT_REG, AS3722_GPIOn_SIGNAL(offset), val); if (ret < 0) dev_err(as_pci->dev, "GPIO_SIGNAL_OUT_REG update failed: %d\n", ret); }
static int as3722_gpio_get(struct gpio_chip *chip, unsigned offset) { struct as3722_pctrl_info *as_pci = to_as_pci(chip); struct as3722 *as3722 = as_pci->as3722; int ret; u32 reg; u32 control; u32 val; int mode; int invert_enable; ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &control); if (ret < 0) { dev_err(as_pci->dev, "GPIO_CONTROL%d_REG read failed: %d\n", offset, ret); return ret; } invert_enable = !!(control & AS3722_GPIO_INV); mode = control & AS3722_GPIO_MODE_MASK; switch (mode) { case AS3722_GPIO_MODE_INPUT: case AS3722_GPIO_MODE_INPUT_PULL_UP: case AS3722_GPIO_MODE_INPUT_PULL_DOWN: case AS3722_GPIO_MODE_IO_OPEN_DRAIN: case AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP: reg = AS3722_GPIO_SIGNAL_IN_REG; break; case AS3722_GPIO_MODE_OUTPUT_VDDH: case AS3722_GPIO_MODE_OUTPUT_VDDL: reg = AS3722_GPIO_SIGNAL_OUT_REG; break; default: return -EINVAL; } ret = as3722_read(as3722, reg, &val); if (ret < 0) { dev_err(as_pci->dev, "GPIO_SIGNAL_IN_REG read failed: %d\n", ret); return ret; } val = !!(val & AS3722_GPIOn_SIGNAL(offset)); return (invert_enable) ? !val : val; }
static int as3722_read_id(struct udevice *pmic, u8 *id, u8 *revision) { int err; err = as3722_read(pmic, AS3722_ASIC_ID1, id); if (err) { error("failed to read ID1 register: %d", err); return err; } err = as3722_read(pmic, AS3722_ASIC_ID2, revision); if (err) { error("failed to read ID2 register: %d", err); return err; } return 0; }
static void as3722rtc_init(void) { static int initialized; if (initialized) return; uint8_t control = as3722_read(AS3722_RTC_CONTROL); as3722_write(AS3722_RTC_CONTROL, control | AS3722_RTC_CONTROL_ON); initialized = 1; }
int rtc_get(struct rtc_time *time) { as3722rtc_init(); time->sec = bcd2bin(as3722_read(AS3722_RTC_SECOND) & 0x7f); time->min = bcd2bin(as3722_read(AS3722_RTC_MINUTE) & 0x7f); time->hour = bcd2bin(as3722_read(AS3722_RTC_HOUR) & 0x3f); time->mday = bcd2bin(as3722_read(AS3722_RTC_DAY) & 0x3f); time->mon = bcd2bin(as3722_read(AS3722_RTC_MONTH) & 0x1f); time->year = bcd2bin(as3722_read(AS3722_RTC_YEAR) & 0x7f); return 0; }
int as3722_sd_enable(struct udevice *pmic, unsigned int sd) { u8 value; int err; if (sd > 6) return -EINVAL; err = as3722_read(pmic, AS3722_SD_CONTROL, &value); if (err) { error("failed to read SD control register: %d", err); return err; } value |= 1 << sd; err = as3722_write(pmic, AS3722_SD_CONTROL, value); if (err < 0) { error("failed to write SD control register: %d", err); return err; } return 0; }
int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo) { u8 value; int err; if (ldo > 11) return -EINVAL; err = as3722_read(pmic, AS3722_LDO_CONTROL, &value); if (err) { error("failed to read LDO control register: %d", err); return err; } value |= 1 << ldo; err = as3722_write(pmic, AS3722_LDO_CONTROL, value); if (err < 0) { error("failed to write LDO control register: %d", err); return err; } return 0; }
static int as3722_write(struct as3722_softc *sc, uint8_t reg, uint8_t val, int flags) { uint8_t buf[2] = { reg, val }; return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0, buf, 2, flags); } static int as3722_set_clear(struct as3722_softc *sc, uint8_t reg, uint8_t set, uint8_t clr, int flags) { uint8_t old, new; int error; error = as3722_read(sc, reg, &old, flags); if (error) { return error; } new = set | (old & ~clr); return as3722_write(sc, reg, new, flags); } static int as3722_wdt_setmode(struct sysmon_wdog *smw) { struct as3722_softc * const sc = smw->smw_cookie; int error; const int flags = (cold ? I2C_F_POLL : 0);