2 * Copyright (C) 2014-2016, Toradex AG
4 * SPDX-License-Identifier: GPL-2.0+
8 * Helpers for Freescale PMIC PF0100
13 #include <asm/arch/imx-regs.h>
14 #include <asm/arch/iomux.h>
15 #include <asm/arch/mx6-pins.h>
17 #include <asm/mach-imx/iomux-v3.h>
19 #include "pf0100_otp.inc"
22 /* define for PMIC register dump */
25 /* use GPIO: EXT_IO1 to switch on VPGM, ON: 1 */
26 static iomux_v3_cfg_t
const pmic_prog_pads
[] = {
27 MX6_PAD_NANDF_D3__GPIO2_IO03
| MUX_PAD_CTRL(NO_PAD_CTRL
),
28 # define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 3)
31 unsigned pmic_init(void)
33 unsigned programmed
= 0;
35 uchar devid
, revid
, val
;
38 if (!((0 == i2c_set_bus_num(bus
)) &&
39 (0 == i2c_probe(PFUZE100_I2C_ADDR
)))) {
40 puts("i2c bus failed\n");
43 /* get device ident */
44 if (i2c_read(PFUZE100_I2C_ADDR
, PFUZE100_DEVICEID
, 1, &devid
, 1) < 0) {
45 puts("i2c pmic devid read failed\n");
48 if (i2c_read(PFUZE100_I2C_ADDR
, PFUZE100_REVID
, 1, &revid
, 1) < 0) {
49 puts("i2c pmic revid read failed\n");
52 printf("device id: 0x%.2x, revision id: 0x%.2x\n", devid
, revid
);
58 for (i
= 0; i
< 16; i
++)
60 for (j
= 0; j
< 0x80; ) {
62 for (i
= 0; i
< 16; i
++) {
63 i2c_read(PFUZE100_I2C_ADDR
, j
+i
, 1, &val
, 1);
68 printf("\nEXT Page 1");
70 val
= PFUZE100_PAGE_REGISTER_PAGE1
;
71 if (i2c_write(PFUZE100_I2C_ADDR
, PFUZE100_PAGE_REGISTER
, 1,
73 puts("i2c write failed\n");
77 for (j
= 0x80; j
< 0x100; ) {
79 for (i
= 0; i
< 16; i
++) {
80 i2c_read(PFUZE100_I2C_ADDR
, j
+i
, 1, &val
, 1);
85 printf("\nEXT Page 2");
87 val
= PFUZE100_PAGE_REGISTER_PAGE2
;
88 if (i2c_write(PFUZE100_I2C_ADDR
, PFUZE100_PAGE_REGISTER
, 1,
90 puts("i2c write failed\n");
94 for (j
= 0x80; j
< 0x100; ) {
96 for (i
= 0; i
< 16; i
++) {
97 i2c_read(PFUZE100_I2C_ADDR
, j
+i
, 1, &val
, 1);
105 /* get device programmed state */
106 val
= PFUZE100_PAGE_REGISTER_PAGE1
;
107 if (i2c_write(PFUZE100_I2C_ADDR
, PFUZE100_PAGE_REGISTER
, 1, &val
, 1)) {
108 puts("i2c write failed\n");
111 if (i2c_read(PFUZE100_I2C_ADDR
, PFUZE100_FUSE_POR1
, 1, &val
, 1) < 0) {
112 puts("i2c fuse_por read failed\n");
115 if (val
& PFUZE100_FUSE_POR_M
)
118 if (i2c_read(PFUZE100_I2C_ADDR
, PFUZE100_FUSE_POR2
, 1, &val
, 1) < 0) {
119 puts("i2c fuse_por read failed\n");
122 if (val
& PFUZE100_FUSE_POR_M
)
125 if (i2c_read(PFUZE100_I2C_ADDR
, PFUZE100_FUSE_POR3
, 1, &val
, 1) < 0) {
126 puts("i2c fuse_por read failed\n");
129 if (val
& PFUZE100_FUSE_POR_M
)
132 switch (programmed
) {
134 printf("PMIC: not programmed\n");
137 printf("PMIC: programmed\n");
140 printf("PMIC: undefined programming state\n");
147 int pf0100_prog(void)
149 unsigned char bus
= 1;
153 if (pmic_init() == 3) {
154 puts("PMIC already programmed, exiting\n");
155 return CMD_RET_FAILURE
;
157 /* set up gpio to manipulate vprog, initially off */
158 imx_iomux_v3_setup_multiple_pads(pmic_prog_pads
,
159 ARRAY_SIZE(pmic_prog_pads
));
160 gpio_direction_output(PMIC_PROG_VOLTAGE
, 0);
162 if (!((0 == i2c_set_bus_num(bus
)) &&
163 (0 == i2c_probe(PFUZE100_I2C_ADDR
)))) {
164 puts("i2c bus failed\n");
165 return CMD_RET_FAILURE
;
168 for (i
= 0; i
< ARRAY_SIZE(pmic_otp_prog
); i
++) {
169 switch (pmic_otp_prog
[i
].cmd
) {
171 val
= (unsigned char) (pmic_otp_prog
[i
].value
& 0xff);
172 if (i2c_write(PFUZE100_I2C_ADDR
, pmic_otp_prog
[i
].reg
,
174 printf("i2c write failed, reg 0x%2x, value 0x%2x\n",
175 pmic_otp_prog
[i
].reg
, val
);
176 return CMD_RET_FAILURE
;
180 udelay(pmic_otp_prog
[i
].value
* 1000);
183 gpio_direction_output(PMIC_PROG_VOLTAGE
,
184 pmic_otp_prog
[i
].value
);
191 return CMD_RET_SUCCESS
;
194 int do_pf0100_prog(cmd_tbl_t
*cmdtp
, int flag
, int argc
,
198 puts("Programming PMIC OTP...");
200 if (ret
== CMD_RET_SUCCESS
)
208 pf0100_otp_prog
, 1, 0, do_pf0100_prog
,
209 "Program the OTP fuses on the PMIC PF0100",