/* * ADI slave devices include RTC, ADC, regulator, charger, thermal and so on. * ADI supports 12/14bit address for r2p0, and additional 17bit for r3p0 or * later versions. Since bit[1:0] are zero, so the spec describe them as * 10/12/15bit address mode. * The 10bit mode supports sigle slave, 12/15bit mode supports 3 slave, the * high two bits is slave_id. * The slave devices address offset is 0x8000 for 10/12bit address mode, * and 0x20000 for 15bit mode.
*/ #define ADI_10BIT_SLAVE_ADDR_SIZE SZ_4K #define ADI_10BIT_SLAVE_OFFSET 0x8000 #define ADI_12BIT_SLAVE_ADDR_SIZE SZ_16K #define ADI_12BIT_SLAVE_OFFSET 0x8000 #define ADI_15BIT_SLAVE_ADDR_SIZE SZ_128K #define ADI_15BIT_SLAVE_OFFSET 0x20000
/* Timeout (ms) for the trylock of hardware spinlocks */ #define ADI_HWSPINLOCK_TIMEOUT 5000 /* * ADI controller has 50 channels including 2 software channels * and 48 hardware channels.
*/ #define ADI_HW_CHNS 50
staticint sprd_adi_read(struct sprd_adi *sadi, u32 reg, u32 *read_val)
{ int read_timeout = ADI_READ_TIMEOUT; unsignedlong flags;
u32 val; int ret = 0;
if (sadi->hwlock) {
ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
ADI_HWSPINLOCK_TIMEOUT,
&flags); if (ret) {
dev_err(sadi->dev, "get the hw lock failed\n"); return ret;
}
}
ret = sprd_adi_check_addr(sadi, reg); if (ret) goto out;
/* * Set the slave address offset need to read into RD_CMD register, * then ADI controller will start to transfer automatically.
*/
writel_relaxed(reg, sadi->base + REG_ADI_RD_CMD);
/* * Wait read operation complete, the BIT_RD_CMD_BUSY will be set * simultaneously when writing read command to register, and the * BIT_RD_CMD_BUSY will be cleared after the read operation is * completed.
*/ do {
val = readl_relaxed(sadi->base + REG_ADI_RD_DATA); if (!(val & BIT_RD_CMD_BUSY)) break;
cpu_relax();
} while (--read_timeout);
if (read_timeout == 0) {
dev_err(sadi->dev, "ADI read timeout\n");
ret = -EBUSY; goto out;
}
/* * The return value before adi r5p0 includes data and read register * address, from bit 0to bit 15 are data, and from bit 16 to bit 30 * are read register address. Then we can check the returned register * address to validate data.
*/ if (sadi->data->read_check) {
ret = sadi->data->read_check(val, reg); if (ret < 0) goto out;
}
*read_val = val & RD_VALUE_MASK;
out: if (sadi->hwlock)
hwspin_unlock_irqrestore(sadi->hwlock, &flags); return ret;
}
if (sadi->hwlock) {
ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
ADI_HWSPINLOCK_TIMEOUT,
&flags); if (ret) {
dev_err(sadi->dev, "get the hw lock failed\n"); return ret;
}
}
ret = sprd_adi_check_addr(sadi, reg); if (ret) goto out;
ret = sprd_adi_drain_fifo(sadi); if (ret < 0) goto out;
/* * we should wait for write fifo is empty before writing data to PMIC * registers.
*/ do { if (!sprd_adi_fifo_is_full(sadi)) { /* we need virtual register address to write. */
writel_relaxed(val, (void __iomem *)(sadi->slave_vbase + reg)); break;
}
cpu_relax();
} while (--timeout);
if (timeout == 0) {
dev_err(sadi->dev, "write fifo is full\n");
ret = -EBUSY;
}
out: if (sadi->hwlock)
hwspin_unlock_irqrestore(sadi->hwlock, &flags); return ret;
}
/* Record the reboot mode */
sprd_adi_read(sadi, wdg->rst_sts, &val);
val &= ~HWRST_STATUS_WATCHDOG;
val |= reboot_mode;
sprd_adi_write(sadi, wdg->rst_sts, val);
/* Enable the interface clock of the watchdog */
sprd_adi_read(sadi, wdg->wdg_en, &val);
val |= BIT_WDG_EN;
sprd_adi_write(sadi, wdg->wdg_en, val);
/* Enable the work clock of the watchdog */
sprd_adi_read(sadi, wdg->wdg_clk, &val);
val |= BIT_WDG_EN;
sprd_adi_write(sadi, wdg->wdg_clk, val);
/* Unlock the watchdog */
sprd_adi_write(sadi, wdg->base + REG_WDG_LOCK, WDG_UNLOCK_KEY);
staticvoid sprd_adi_hw_init(struct sprd_adi *sadi)
{ struct device_node *np = sadi->dev->of_node; int i, size, chn_cnt; const __be32 *list;
u32 tmp;
/* Set all channels as default priority */
writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIL);
writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIH);
/* Set clock auto gate mode */
tmp = readl_relaxed(sadi->base + REG_ADI_GSSI_CFG0);
tmp &= ~BIT_CLK_ALL_ON;
writel_relaxed(tmp, sadi->base + REG_ADI_GSSI_CFG0);
/* Set hardware channels setting */
list = of_get_property(np, "sprd,hw-channels", &size); if (!list || !size) {
dev_info(sadi->dev, "no hw channels setting in node\n"); return;
}
chn_cnt = size / 8; for (i = 0; i < chn_cnt; i++) {
u32 value;
u32 chn_id = be32_to_cpu(*list++);
u32 chn_config = be32_to_cpu(*list++);
/* Channel 0 and 1 are software channels */ if (chn_id < 2) continue;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.