summaryrefslogtreecommitdiff
path: root/board/toradex/apalis_imx6/pf0100.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/toradex/apalis_imx6/pf0100.c')
-rw-r--r--board/toradex/apalis_imx6/pf0100.c138
1 files changed, 125 insertions, 13 deletions
diff --git a/board/toradex/apalis_imx6/pf0100.c b/board/toradex/apalis_imx6/pf0100.c
index 5c9d7b0566..5e29ac89f0 100644
--- a/board/toradex/apalis_imx6/pf0100.c
+++ b/board/toradex/apalis_imx6/pf0100.c
@@ -19,15 +19,19 @@
#include "pf0100_otp.inc"
#include "pf0100.h"
+/* define for PMIC register dump */
+/*#define DEBUG */
+
/* 7-bit I2C bus slave address */
#define PFUZE100_I2C_ADDR (0x08)
-iomux_v3_cfg_t const pmic_prog_pads[] = {
+static iomux_v3_cfg_t const pmic_prog_pads[] = {
MX6_PAD_GPIO_2__GPIO_1_2 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
-void pmic_init(void)
+unsigned pmic_init(void)
{
+ unsigned programmed = 0;
uchar bus = 1;
uchar devid, revid, val;
@@ -35,27 +39,128 @@ void pmic_init(void)
if(!(0 == i2c_set_bus_num(bus) && (0 == i2c_probe(PFUZE100_I2C_ADDR))))
{
puts("i2c bus failed\n");
- return;
+ return 0;
}
/* get device ident */
if( i2c_read(PFUZE100_I2C_ADDR, PFUZE100_DEVICEID, 1, &devid, 1) < 0)
{
puts("i2c pmic devid read failed\n");
- return;
+ return 0;
}
if( i2c_read(PFUZE100_I2C_ADDR, PFUZE100_REVID, 1, &revid, 1) < 0)
{
puts("i2c pmic revid read failed\n");
- return;
+ return 0;
}
printf("device id: 0x%.2x, revision id: 0x%.2x\n", devid, revid);
+#ifdef DEBUG
+ {
+ unsigned i,j;
+
+ for(i=0; i<16; i++)
+ printf("\t%x",i);
+ for(j=0; j<0x80; )
+ {
+ printf("\n%2x",j);
+ for(i=0; i<16; i++)
+ {
+ i2c_read(PFUZE100_I2C_ADDR, j+i, 1, &val, 1);
+ printf("\t%2x", val);
+ }
+ j += 0x10;
+ }
+ printf("\nEXT Page 1");
+
+ val = PFUZE100_PAGE_REGISTER_PAGE1;
+ if( i2c_write(PFUZE100_I2C_ADDR, PFUZE100_PAGE_REGISTER, 1, &val, 1))
+ {
+ puts("i2c write failed\n");
+ return 0;
+ }
+
+ for(j=0x80; j<0x100; )
+ {
+ printf("\n%2x",j);
+ for(i=0; i<16; i++)
+ {
+ i2c_read(PFUZE100_I2C_ADDR, j+i, 1, &val, 1);
+ printf("\t%2x", val);
+ }
+ j += 0x10;
+ }
+ printf("\nEXT Page 2");
+
+ val = PFUZE100_PAGE_REGISTER_PAGE2;
+ if( i2c_write(PFUZE100_I2C_ADDR, PFUZE100_PAGE_REGISTER, 1, &val, 1))
+ {
+ puts("i2c write failed\n");
+ return 0;
+ }
+
+ for(j=0x80; j<0x100; )
+ {
+ printf("\n%2x",j);
+ for(i=0; i<16; i++)
+ {
+ i2c_read(PFUZE100_I2C_ADDR, j+i, 1, &val, 1);
+ printf("\t%2x", val);
+ }
+ j += 0x10;
+ }
+ printf("\n");
+ }
+#endif
+ /* get device programmed state */
+ val = PFUZE100_PAGE_REGISTER_PAGE1;
+ if( i2c_write(PFUZE100_I2C_ADDR, PFUZE100_PAGE_REGISTER, 1, &val, 1))
+ {
+ puts("i2c write failed\n");
+ return 0;
+ }
+ if( i2c_read(PFUZE100_I2C_ADDR, PFUZE100_FUSE_POR1, 1, &val, 1) < 0)
+ {
+ puts("i2c fuse_por read failed\n");
+ return 0;
+ }
+ if(val & PFUZE100_FUSE_POR_M)
+ programmed++;
+
+ if( i2c_read(PFUZE100_I2C_ADDR, PFUZE100_FUSE_POR2, 1, &val, 1) < 0)
+ {
+ puts("i2c fuse_por read failed\n");
+ return programmed;
+ }
+ if(val & PFUZE100_FUSE_POR_M)
+ programmed++;
+
+ if( i2c_read(PFUZE100_I2C_ADDR, PFUZE100_FUSE_POR3, 1, &val, 1) < 0)
+ {
+ puts("i2c fuse_por read failed\n");
+ return programmed;
+ }
+ if(val & PFUZE100_FUSE_POR_M)
+ programmed++;
+
+ switch (programmed) {
+ case 0:
+ printf("PMIC: not programmed\n");
+ break;
+ case 3:
+ printf("PMIC: programmed\n");
+ break;
+ default:
+ printf("PMIC: undefined progamming state\n");
+ break;
+ }
+
+ /* TODO the following should be removed for production */
/* set VGEN1 to 1.2V */
val = PFUZE100_VGEN1_VAL;
if( i2c_write(PFUZE100_I2C_ADDR, PFUZE100_VGEN1CTL, 1, &val, 1))
{
puts("i2c write failed\n");
- return;
+ return programmed;
}
/* set SWBST to 5.0V */
@@ -63,16 +168,20 @@ void pmic_init(void)
if( i2c_write(PFUZE100_I2C_ADDR, PFUZE100_SWBSTCTL, 1, &val, 1))
{
puts("i2c write failed\n");
- return;
}
+ return programmed;
}
-void pf0100_prog(void)
+int pf0100_prog(void)
{
unsigned char bus = 1;
unsigned char val;
unsigned i;
+ if(pmic_init() == 3) {
+ puts("PMIC already programmed, exiting\n");
+ return 1;
+ }
/* set up gpio to manipulate vprog, initially off */
imx_iomux_v3_setup_multiple_pads(pmic_prog_pads, ARRAY_SIZE(pmic_prog_pads));
gpio_direction_output(IMX_GPIO_NR(1, 2), 0);
@@ -80,7 +189,7 @@ void pf0100_prog(void)
if(!(0 == i2c_set_bus_num(bus) && (0 == i2c_probe(PFUZE100_I2C_ADDR))))
{
puts("i2c bus failed\n");
- return;
+ return 1;
}
for (i=0; i<ARRAY_SIZE(pmic_otp_prog); i++) {
@@ -92,7 +201,7 @@ void pf0100_prog(void)
{
printf("i2c write failed, reg 0x%2x, value0x%2x\n",
pmic_otp_prog[i].reg, val);
- return;
+ return 1;
}
break;
case pmic_delay:
@@ -106,15 +215,18 @@ void pf0100_prog(void)
break;
}
}
+ return 0;
}
-static int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc,
+int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
puts("Programming PMIC OTP...");
- pf0100_prog();
- puts("done. Power cycle the board\n");
+ if(!pf0100_prog())
+ puts("done.\n");
+ else
+ puts("failed.\n");
return 0;
}