#define mV_to_regval(mV) v2r((mV) * 10, 4125, 125)
#define regval_to_mV(r) r2v(r, 4125, 125)
-static struct ltc3676_regs {
- u8 addr;
- u8 val;
- u8 mask;
-} ltc3676_regs[] = {
+static struct pmic_regs ltc3676_regs[] = {
{ LTC3676_MSKPG, ~LTC3676_MSKPG_BUCK1, },
{ LTC3676_DVB2B, VDD_SOC_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
{ LTC3676_DVB3B, VDD_DDR_VAL_LP, ~0x3f, },
{ LTC3676_CLIRQ, 0, }, /* clear interrupt status */
};
-static struct ltc3676_regs ltc3676_regs_1[] = {
+static struct pmic_regs ltc3676_regs_1[] = {
{ LTC3676_DVB1B, VDD_IO_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
{ LTC3676_DVB1A, VDD_IO_VAL, ~0x3f, },
};
-static struct ltc3676_regs ltc3676_regs_2[] = {
+static struct pmic_regs ltc3676_regs_2[] = {
{ LTC3676_DVB1B, VDD_IO_VAL_2_LP | LTC3676_PGOOD_MASK, ~0x3f, },
{ LTC3676_DVB1A, VDD_IO_VAL_2, ~0x3f, },
};
return pad_settings & 1;
}
-static int ltc3676_setup_regs(uchar slave_addr, struct ltc3676_regs *r,
+static int ltc3676_setup_regs(uchar slave_addr, struct pmic_regs *r,
size_t count)
{
int ret;
unsigned char value;
ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
- if ((value & ~r->mask) != r->val) {
- printf("Changing PMIC reg %02x from %02x to %02x\n",
- r->addr, value, r->val);
- }
if (ret) {
printf("%s: failed to read PMIC register %02x: %d\n",
__func__, r->addr, ret);
return ret;
}
+ if ((value & ~r->mask) != r->val) {
+ printf("Changing PMIC reg %02x from %02x to %02x\n",
+ r->addr, value, r->val);
+ }
#endif
ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
if (ret) {
__func__, r->addr, ret);
return ret;
}
+#ifdef DEBUG
+ ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
+ if (ret) {
+ printf("%s: failed to read PMIC register %02x: %d\n",
+ __func__, r->addr, ret);
+ return ret;
+ }
+ if (value != r->val) {
+ printf("Failed to set PMIC reg %02x to %02x; actual value: %02x\n",
+ r->addr, r->val, value);
+ }
+#endif
}
return 0;
}
-int ltc3676_pmic_setup(uchar slave_addr)
+int ltc3676_pmic_setup(uchar slave_addr, struct pmic_regs *regs,
+ size_t count)
{
int ret;
unsigned char value;
static struct {
uchar addr;
- int (*init)(uchar addr);
+ pmic_setup_func *init;
} i2c_addrs[] = {
#ifdef CONFIG_LTC3676
{ 0x3c, ltc3676_pmic_setup, },
#endif
};
-int tx6_pmic_init(int addr)
+int tx6_pmic_init(int addr, struct pmic_regs *regs, size_t num_regs)
{
int ret = -ENODEV;
int i;
ret = i2c_probe(i2c_addr);
if (ret == 0) {
debug("Initializing PMIC at I2C addr 0x%02x\n", i2c_addr);
- ret = i2c_addrs[i].init(i2c_addr);
+ ret = i2c_addrs[i].init(i2c_addr, regs, num_regs);
break;
}
}
*
*/
-int ltc3676_pmic_setup(uchar addr);
-int rn5t618_pmic_setup(uchar addr);
-int rn5t567_pmic_setup(uchar addr);
+#ifdef CONFIG_RN5T567
+#include "rn5t567.h"
+#endif
-int tx6_pmic_init(int addr);
+struct pmic_regs {
+ u8 addr;
+ u8 val;
+ u8 mask;
+};
+
+typedef int pmic_setup_func(uchar addr, struct pmic_regs *regs,
+ size_t num_regs);
+
+int ltc3676_pmic_setup(uchar addr, struct pmic_regs *regs, size_t num_regs);
+int rn5t618_pmic_setup(uchar addr, struct pmic_regs *regs, size_t num_regs);
+int rn5t567_pmic_setup(uchar addr, struct pmic_regs *regs, size_t num_regs);
+
+int tx6_pmic_init(int addr, struct pmic_regs *regs, size_t num_regs);
#include "../common/karo.h"
#include "pmic.h"
-#define RN5T567_NOETIMSET 0x11
-#define RN5T567_LDORTC1_SLOT 0x2a
-#define RN5T567_DC1CTL 0x2c
-#define RN5T567_DC1CTL2 0x2d
-#define RN5T567_DC2CTL 0x2e
-#define RN5T567_DC2CTL2 0x2f
-#define RN5T567_DC3CTL 0x30
-#define RN5T567_DC3CTL2 0x31
-#define RN5T567_DC1DAC 0x36 /* CORE */
-#define RN5T567_DC2DAC 0x37 /* SOC */
-#define RN5T567_DC3DAC 0x38 /* DDR */
-#define RN5T567_DC1DAC_SLP 0x3b
-#define RN5T567_DC2DAC_SLP 0x3c
-#define RN5T567_DC3DAC_SLP 0x3d
-#define RN5T567_LDOEN1 0x44
-#define RN5T567_LDODIS 0x46
-#define RN5T567_LDOEN2 0x48
-#define RN5T567_LDO3DAC 0x4e /* IO */
-#define RN5T567_LDORTC1DAC 0x56 /* VBACKUP */
-
-#define NOETIMSET_DIS_OFF_NOE_TIM (1 << 3)
-
-#define VDD_RTC_VAL mV_to_regval_rtc(3000)
-#define VDD_HIGH_VAL mV_to_regval3(3000)
-#define VDD_HIGH_VAL_LP mV_to_regval3(3000)
-#define VDD_CORE_VAL mV_to_regval(1350) /* DCDC1 */
-#define VDD_CORE_VAL_LP mV_to_regval(900)
-#define VDD_SOC_VAL mV_to_regval(1350) /* DCDC2 */
-#define VDD_SOC_VAL_LP mV_to_regval(900)
-#define VDD_DDR_VAL mV_to_regval(1350) /* DCDC3 */
-#define VDD_DDR_VAL_LP mV_to_regval(1350)
-
-/* calculate voltages in 10mV */
-#define v2r(v,n,m) DIV_ROUND(((((v) < (n)) ? (n) : (v)) - (n)), (m))
-#define r2v(r,n,m) (((r) * (m) + (n)) / 10)
-
-/* DCDC1-3 */
-#define mV_to_regval(mV) v2r((mV) * 10, 6000, 125)
-#define regval_to_mV(r) r2v(r, 6000, 125)
-
-/* LDO1-2 */
-#define mV_to_regval2(mV) v2r((mV) * 10, 9000, 250)
-#define regval2_to_mV(r) r2v(r, 9000, 250)
-
-/* LDO3 */
-#define mV_to_regval3(mV) v2r((mV) * 10, 6000, 250)
-#define regval3_to_mV(r) r2v(r, 6000, 250)
-
-/* LDORTC */
-#define mV_to_regval_rtc(mV) v2r((mV) * 10, 17000, 250)
-#define regval_rtc_to_mV(r) r2v(r, 17000, 250)
-
-static struct rn5t567_regs {
- u8 addr;
- u8 val;
- u8 mask;
-} rn5t567_regs[] = {
- { RN5T567_NOETIMSET, NOETIMSET_DIS_OFF_NOE_TIM | 0x5, },
- { RN5T567_DC1DAC, VDD_CORE_VAL, },
- { RN5T567_DC2DAC, VDD_SOC_VAL, },
- { RN5T567_DC3DAC, VDD_DDR_VAL, },
- { RN5T567_DC1DAC_SLP, VDD_CORE_VAL_LP, },
- { RN5T567_DC2DAC_SLP, VDD_SOC_VAL_LP, },
- { RN5T567_DC3DAC_SLP, VDD_DDR_VAL_LP, },
- { RN5T567_LDOEN1, 0x01f, ~0x1f, },
- { RN5T567_LDOEN2, 0x10, ~0x30, },
- { RN5T567_LDODIS, 0x00, },
- { RN5T567_LDO3DAC, VDD_HIGH_VAL, },
- { RN5T567_LDORTC1DAC, VDD_RTC_VAL, },
- { RN5T567_LDORTC1_SLOT, 0x0f, ~0x3f, },
-};
-
-static int rn5t567_setup_regs(uchar slave_addr, struct rn5t567_regs *r,
+static int rn5t567_setup_regs(uchar slave_addr, struct pmic_regs *r,
size_t count)
{
int ret;
unsigned char value;
ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
- if ((value & ~r->mask) != r->val) {
- printf("Changing PMIC reg %02x from %02x to %02x\n",
- r->addr, value, r->val);
- }
if (ret) {
printf("%s: failed to read PMIC register %02x: %d\n",
__func__, r->addr, ret);
return ret;
}
+ if ((value & ~r->mask) != r->val) {
+ printf("Changing PMIC reg %02x from %02x to %02x\n",
+ r->addr, value, r->val);
+ }
#endif
ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
if (ret) {
__func__, r->addr, ret);
return ret;
}
+#ifdef DEBUG
+ ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
+ if (ret) {
+ printf("%s: failed to read PMIC register %02x: %d\n",
+ __func__, r->addr, ret);
+ return ret;
+ }
+ if (value != r->val) {
+ printf("Failed to set PMIC reg %02x to %02x; actual value: %02x\n",
+ r->addr, r->val, value);
+ }
+#endif
}
return 0;
}
-int rn5t567_pmic_setup(uchar slave_addr)
+int rn5t567_pmic_setup(uchar slave_addr, struct pmic_regs *regs,
+ size_t count)
{
int ret;
unsigned char value;
return ret;
}
- ret = rn5t567_setup_regs(slave_addr, rn5t567_regs,
- ARRAY_SIZE(rn5t567_regs));
+ ret = rn5t567_setup_regs(slave_addr, regs, count);
if (ret)
return ret;
ret = i2c_read(slave_addr, RN5T567_DC1DAC, 1, &value, 1);
if (ret == 0) {
- printf("VDDCORE set to %umV\n", regval_to_mV(value));
+ printf("VDDCORE set to %umV\n", rn5t_regval_to_mV(value));
} else {
printf("Failed to read VDDCORE register setting\n");
}
-
+#ifndef CONFIG_SOC_MX6UL
ret = i2c_read(slave_addr, RN5T567_DC2DAC, 1, &value, 1);
if (ret == 0) {
- printf("VDDSOC set to %umV\n", regval_to_mV(value));
+ printf("VDDSOC set to %umV\n", rn5t_regval_to_mV(value));
} else {
printf("Failed to read VDDSOC register setting\n");
}
-
+#endif
return ret;
}
--- /dev/null
+/*
+ * Copyright (C) 2015 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define RN5T567_NOETIMSET 0x11
+#define RN5T567_LDORTC1_SLOT 0x2a
+#define RN5T567_DC1CTL 0x2c
+#define RN5T567_DC1CTL2 0x2d
+#define RN5T567_DC2CTL 0x2e
+#define RN5T567_DC2CTL2 0x2f
+#define RN5T567_DC3CTL 0x30
+#define RN5T567_DC3CTL2 0x31
+#define RN5T567_DC1DAC 0x36
+#define RN5T567_DC2DAC 0x37
+#define RN5T567_DC3DAC 0x38
+#define RN5T567_DC4DAC 0x39
+#define RN5T567_DC1DAC_SLP 0x3b
+#define RN5T567_DC2DAC_SLP 0x3c
+#define RN5T567_DC3DAC_SLP 0x3d
+#define RN5T567_DC4DAC_SLP 0x3e
+#define RN5T567_LDOEN1 0x44
+#define RN5T567_LDOEN2 0x45
+#define RN5T567_LDODIS 0x46
+#define RN5T567_LDO1DAC 0x4c
+#define RN5T567_LDO2DAC 0x4d
+#define RN5T567_LDO3DAC 0x4e
+#define RN5T567_LDO4DAC 0x4f
+#define RN5T567_LDO5DAC 0x50
+#define RN5T567_LDORTC1DAC 0x56 /* VBACKUP */
+
+#define NOETIMSET_DIS_OFF_NOE_TIM (1 << 3)
+
+#define DC2_DC2EN (1 << 0)
+#define DC2_DC2DIS (1 << 1)
+
+/* calculate voltages in 10mV */
+#define rn5t_v2r(v,n,m) DIV_ROUND(((((v) < (n)) ? (n) : (v)) - (n)), (m))
+#define rn5t_r2v(r,n,m) (((r) * (m) + (n)) / 10)
+
+/* DCDC1-4 */
+#define rn5t_mV_to_regval(mV) rn5t_v2r((mV) * 10, 6000, 125)
+#define rn5t_regval_to_mV(r) rn5t_r2v(r, 6000, 125)
+
+/* LDO1-2, 4-5 */
+#define rn5t_mV_to_regval2(mV) rn5t_v2r((mV) * 10, 9000, 250)
+#define rn5t_regval2_to_mV(r) rn5t_r2v(r, 9000, 250)
+
+/* LDO3 */
+#define rn5t_mV_to_regval3(mV) rn5t_v2r((mV) * 10, 6000, 250)
+#define rn5t_regval3_to_mV(r) rn5t_r2v(r, 6000, 250)
+
+/* LDORTC */
+#define rn5t_mV_to_regval_rtc(mV) rn5t_v2r((mV) * 10, 17000, 250)
+#define rn5t_regval_rtc_to_mV(r) rn5t_r2v(r, 17000, 250)
#define RN5T618_DC2DAC_SLP 0x3c
#define RN5T618_DC3DAC_SLP 0x3d
#define RN5T618_LDOEN1 0x44
+#define RN5T618_LDOEN2 0x45
#define RN5T618_LDODIS 0x46
-#define RN5T618_LDOEN2 0x48
#define RN5T618_LDO3DAC 0x4e /* IO */
#define RN5T618_LDORTCDAC 0x56 /* VBACKUP */
#define mV_to_regval_rtc(mV) v2r((mV) * 10, 17000, 250)
#define regval_rtc_to_mV(r) r2v(r, 17000, 250)
-static struct rn5t618_regs {
- u8 addr;
- u8 val;
- u8 mask;
-} rn5t618_regs[] = {
+static struct pmic_regs rn5t618_regs[] = {
{ RN5T618_NOETIMSET, 0, },
{ RN5T618_DC1DAC, VDD_CORE_VAL, },
{ RN5T618_DC2DAC, VDD_SOC_VAL, },
{ RN5T618_LDORTC1_SLOT, 0x0f, ~0x3f, },
};
-static int rn5t618_setup_regs(uchar slave_addr, struct rn5t618_regs *r,
+static int rn5t618_setup_regs(uchar slave_addr, struct pmic_regs *r,
size_t count)
{
int ret;
unsigned char value;
ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
- if ((value & ~r->mask) != r->val) {
- printf("Changing PMIC reg %02x from %02x to %02x\n",
- r->addr, value, r->val);
- }
if (ret) {
printf("%s: failed to read PMIC register %02x: %d\n",
__func__, r->addr, ret);
return ret;
}
+ if ((value & ~r->mask) != r->val) {
+ printf("Changing PMIC reg %02x from %02x to %02x\n",
+ r->addr, value, r->val);
+ }
#endif
ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
if (ret) {
__func__, r->addr, ret);
return ret;
}
+#ifdef DEBUG
+ ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
+ if (ret) {
+ printf("%s: failed to read PMIC register %02x: %d\n",
+ __func__, r->addr, ret);
+ return ret;
+ }
+ if (value != r->val) {
+ printf("Failed to set PMIC reg %02x to %02x; actual value: %02x\n",
+ r->addr, r->val, value);
+ }
+#endif
}
return 0;
}
-int rn5t618_pmic_setup(uchar slave_addr)
+int rn5t618_pmic_setup(uchar slave_addr, struct pmic_regs *regs,
+ size_t count)
{
int ret;
unsigned char value;
debug("%s@%d: \n", __func__, __LINE__);
-// i2c_init_all();
-
for (i = 0; i < ARRAY_SIZE(tx6_mod_revs); i++) {
u8 i2c_addr = tx6_mod_revs[i].addr;
int ret = i2c_probe(i2c_addr);
debug("%s@%d: \n", __func__, __LINE__);
pmic_id = tx6_pmic_probe();
- if (pmic_id >= 0)
+ if (pmic_id >= 0 && pmic_id < ARRAY_SIZE(tx6_mod_revs))
pmic_addr = tx6_mod_revs[pmic_id].addr;
printf("Board: Ka-Ro TX6%s-%d%d%d%c\n",
return 0;
}
- ret = tx6_pmic_init(pmic_addr);
+ ret = tx6_pmic_init(pmic_addr, NULL, 0);
if (ret) {
printf("Failed to setup PMIC voltages: %d\n", ret);
hang();
MX6_PAD_GPIO1_IO09__UART5_DCE_CTS,
#endif
/* internal I2C */
- MX6_PAD_SNVS_TAMPER1__GPIO5_IO01 | MUX_CFG_SION, /* I2C SCL */
- MX6_PAD_SNVS_TAMPER0__GPIO5_IO00 | MUX_CFG_SION, /* I2C SDA */
+ MX6_PAD_SNVS_TAMPER1__GPIO5_IO01 | MUX_CFG_SION |
+ MUX_PAD_CTRL(PAD_CTL_DSE_240ohm), /* I2C SCL */
+ MX6_PAD_SNVS_TAMPER0__GPIO5_IO00 | MUX_CFG_SION |
+ MUX_PAD_CTRL(PAD_CTL_DSE_240ohm | PAD_CTL_HYS |
+ PAD_CTL_ODE), /* I2C SDA */
/* FEC PHY GPIO functions */
MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_CFG_SION, /* PHY POWER */
{ TX6UL_FEC_INT_GPIO, GPIOFLAG_INPUT, "FEC PHY INT", },
};
-static int pmic_addr __maybe_unused __data = 0x3c;
-
#define GPIO_DR 0
#define GPIO_DIR 4
#define GPIO_PSR 8
SCL_BIT | SDA_BIT);
}
}
- debug("Setting up I2C Pads\n");
}
/* placed in section '.data' to prevent overwriting relocation info
#endif
}
+/* PMIC settings */
+#define VDD_RTC_VAL rn5t_mV_to_regval_rtc(3000)
+#define VDD_CORE_VAL rn5t_mV_to_regval(1300) /* DCDC1 */
+#define VDD_CORE_VAL_LP rn5t_mV_to_regval(900)
+#define VDD_DDR_VAL rn5t_mV_to_regval(1350) /* DCDC3 */
+#define VDD_DDR_VAL_LP rn5t_mV_to_regval(1350)
+#define VDD_HIGH_VAL rn5t_mV_to_regval(3300) /* DCDC4 */
+#define VDD_HIGH_VAL_LP rn5t_mV_to_regval(3300)
+#define VDD_CSI_VAL rn5t_mV_to_regval2(3300) /* LDO4 */
+#define VDD_CSI_VAL_LP rn5t_mV_to_regval2(3300)
+
+static struct pmic_regs rn5t567_regs[] = {
+ { RN5T567_NOETIMSET, NOETIMSET_DIS_OFF_NOE_TIM | 0x5, },
+ { RN5T567_DC2CTL, DC2_DC2DIS, },
+ { RN5T567_DC1DAC, VDD_CORE_VAL, },
+ { RN5T567_DC3DAC, VDD_DDR_VAL, },
+ { RN5T567_DC4DAC, VDD_HIGH_VAL, },
+ { RN5T567_DC1DAC_SLP, VDD_CORE_VAL_LP, },
+ { RN5T567_DC3DAC_SLP, VDD_DDR_VAL_LP, },
+ { RN5T567_DC4DAC_SLP, VDD_HIGH_VAL_LP, },
+ { RN5T567_LDOEN1, 0x01f, ~0x1f, },
+ { RN5T567_LDOEN2, 0x10, ~0x30, },
+ { RN5T567_LDODIS, 0x00, },
+ { RN5T567_LDO4DAC, VDD_CSI_VAL, },
+ { RN5T567_LDORTC1DAC, VDD_RTC_VAL, },
+ { RN5T567_LDORTC1_SLOT, 0x0f, ~0x3f, },
+};
+
+static int pmic_addr __maybe_unused = 0x33;
+
int board_init(void)
{
int ret;
#endif
return 0;
}
-#if 0
- ret = tx6_pmic_init(pmic_addr);
+
+ ret = tx6_pmic_init(pmic_addr, rn5t567_regs, ARRAY_SIZE(rn5t567_regs));
if (ret) {
printf("Failed to setup PMIC voltages: %d\n", ret);
hang();
}
-#endif
return 0;
}