Merge tag 'for-v2021.04' of https://gitlab.denx.de/u-boot/custodians/u-boot-i2c
[platform/kernel/u-boot.git] / board / freescale / common / vid.c
index b37f3bf..20f5421 100644 (file)
@@ -1,12 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2020 NXP
  */
 
 #include <common.h>
 #include <command.h>
 #include <env.h>
 #include <i2c.h>
+#include <irq_func.h>
+#include <log.h>
 #include <asm/io.h>
 #ifdef CONFIG_FSL_LSCH2
 #include <asm/arch/immap_lsch2.h>
@@ -15,6 +18,7 @@
 #else
 #include <asm/immap_85xx.h>
 #endif
+#include <linux/delay.h>
 #include "vid.h"
 
 int __weak i2c_multiplexer_select_vid_channel(u8 channel)
@@ -61,14 +65,14 @@ static int find_ir_chip_on_i2c(void)
        u8 byte;
        int i;
        const int ir_i2c_addr[] = {0x38, 0x08, 0x09};
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
        struct udevice *dev;
 #endif
 
        /* Check all the address */
        for (i = 0; i < (sizeof(ir_i2c_addr)/sizeof(ir_i2c_addr[0])); i++) {
                i2caddress = ir_i2c_addr[i];
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
                ret = i2c_read(i2caddress,
                               IR36021_MFR_ID_OFFSET, 1, (void *)&byte,
                               sizeof(byte));
@@ -113,12 +117,12 @@ static int read_voltage_from_INA220(int i2caddress)
        int i, ret, voltage_read = 0;
        u16 vol_mon;
        u8 buf[2];
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
        struct udevice *dev;
 #endif
 
        for (i = 0; i < NUM_READINGS; i++) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
                ret = i2c_read(I2C_VOL_MONITOR_ADDR,
                               I2C_VOL_MONITOR_BUS_V_OFFSET, 1,
                               (void *)&buf, 2);
@@ -156,12 +160,12 @@ static int read_voltage_from_IR(int i2caddress)
        int i, ret, voltage_read = 0;
        u16 vol_mon;
        u8 buf;
-#ifdef CONFIG_DM_I2C
+#if CONFIG_IS_ENABLED(DM_I2C)
        struct udevice *dev;
 #endif
 
        for (i = 0; i < NUM_READINGS; i++) {
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
                ret = i2c_read(i2caddress,
                               IR36021_LOOP1_VOUT_OFFSET,
                               1, (void *)&buf, 1);
@@ -209,7 +213,7 @@ static int read_voltage_from_LTC(int i2caddress)
        int  ret, vcode = 0;
        u8 chan = PWM_CHANNEL0;
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
        /* select the PAGE 0 using PMBus commands PAGE for VDD*/
        ret = i2c_write(I2C_VOL_MONITOR_ADDR,
                        PMBUS_CMD_PAGE, 1, &chan, 1);
@@ -225,7 +229,7 @@ static int read_voltage_from_LTC(int i2caddress)
                return ret;
        }
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
        /*read the output voltage using PMBus command READ_VOUT*/
        ret = i2c_read(I2C_VOL_MONITOR_ADDR,
                       PMBUS_CMD_READ_VOUT, 1, (void *)&vcode, 2);
@@ -340,7 +344,7 @@ static int set_voltage_to_IR(int i2caddress, int vdd)
        vid = DIV_ROUND_UP(vdd - 245, 5);
 #endif
 
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
        ret = i2c_write(i2caddress, IR36021_LOOP1_MANUAL_ID_OFFSET,
                        1, (void *)&vid, sizeof(vid));
 #else
@@ -376,6 +380,7 @@ static int set_voltage_to_LTC(int i2caddress, int vdd)
 {
        int ret, vdd_last, vdd_target = vdd;
        int count = 100, temp = 0;
+       unsigned char value;
 
        /* Scale up to the LTC resolution is 1/4096V */
        vdd = (vdd * 4096) / 1000;
@@ -387,17 +392,52 @@ static int set_voltage_to_LTC(int i2caddress, int vdd)
                        vdd & 0xFF, (vdd & 0xFF00) >> 8};
 
        /* Write the desired voltage code to the regulator */
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
+       /* Check write protect state */
+       ret = i2c_read(I2C_VOL_MONITOR_ADDR,
+                      PMBUS_CMD_WRITE_PROTECT, 1,
+                      (void *)&value, sizeof(value));
+       if (ret)
+               goto exit;
+
+       if (value != EN_WRITE_ALL_CMD) {
+               value = EN_WRITE_ALL_CMD;
+               ret = i2c_write(I2C_VOL_MONITOR_ADDR,
+                               PMBUS_CMD_WRITE_PROTECT, 1,
+                               (void *)&value, sizeof(value));
+               if (ret)
+                       goto exit;
+       }
+
        ret = i2c_write(I2C_VOL_MONITOR_ADDR,
-                       PMBUS_CMD_PAGE_PLUS_WRITE, 1, (void *)&buff, 5);
+                       PMBUS_CMD_PAGE_PLUS_WRITE, 1,
+                       (void *)&buff, sizeof(buff));
 #else
        struct udevice *dev;
 
        ret = i2c_get_chip_for_busnum(0, I2C_VOL_MONITOR_ADDR, 1, &dev);
-       if (!ret)
+       if (!ret) {
+               /* Check write protect state */
+               ret = dm_i2c_read(dev,
+                                 PMBUS_CMD_WRITE_PROTECT,
+                                 (void *)&value, sizeof(value));
+               if (ret)
+                       goto exit;
+
+               if (value != EN_WRITE_ALL_CMD) {
+                       value = EN_WRITE_ALL_CMD;
+                       ret = dm_i2c_write(dev,
+                                          PMBUS_CMD_WRITE_PROTECT,
+                                          (void *)&value, sizeof(value));
+                       if (ret)
+                               goto exit;
+               }
+
                ret = dm_i2c_write(dev, PMBUS_CMD_PAGE_PLUS_WRITE,
-                                  (void *)&buff, 5);
+                                  (void *)&buff, sizeof(buff));
+       }
 #endif
+exit:
        if (ret) {
                printf("VID: I2C failed to write to the volatge regulator\n");
                return -1;
@@ -445,10 +485,10 @@ int adjust_vdd(ulong vdd_override)
        u8 vid;
 #endif
        int vdd_target, vdd_current, vdd_last;
-       int ret, i2caddress;
+       int ret, i2caddress = 0;
        unsigned long vdd_string_override;
        char *vdd_string;
-#ifdef CONFIG_ARCH_LX2160A
+#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LX2162A)
        static const u16 vdd[32] = {
                8250,
                7875,
@@ -530,10 +570,10 @@ int adjust_vdd(ulong vdd_override)
                0,      /* reserved */
                0,      /* reserved */
                0,      /* reserved */
+               9000,      /* reserved */
                0,      /* reserved */
                0,      /* reserved */
                0,      /* reserved */
-               9000,      /* reserved */
                0,      /* reserved */
                0,      /* reserved */
                0,      /* reserved */
@@ -581,7 +621,7 @@ int adjust_vdd(ulong vdd_override)
        }
 
        /* check IR chip work on Intel mode*/
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
        ret = i2c_read(i2caddress,
                       IR36021_INTEL_MODE_OOFSET,
                       1, (void *)&buf, 1);
@@ -763,7 +803,7 @@ int adjust_vdd(ulong vdd_override)
        }
 
        /* check IR chip work on Intel mode*/
-#ifndef CONFIG_DM_I2C
+#if !CONFIG_IS_ENABLED(DM_I2C)
        ret = i2c_read(i2caddress,
                       IR36021_INTEL_MODE_OOFSET,
                       1, (void *)&buf, 1);
@@ -889,7 +929,7 @@ exit:
 
 static int print_vdd(void)
 {
-       int vdd_last, ret, i2caddress;
+       int vdd_last, ret, i2caddress = 0;
 
        ret = i2c_multiplexer_select_vid_channel(I2C_MUX_CH_VOL_MONITOR);
        if (ret) {
@@ -924,9 +964,9 @@ exit:
 
 }
 
-static int do_vdd_override(cmd_tbl_t *cmdtp,
+static int do_vdd_override(struct cmd_tbl *cmdtp,
                           int flag, int argc,
-                          char * const argv[])
+                          char *const argv[])
 {
        ulong override;
 
@@ -940,9 +980,8 @@ static int do_vdd_override(cmd_tbl_t *cmdtp,
        return 0;
 }
 
-static int do_vdd_read(cmd_tbl_t *cmdtp,
-                        int flag, int argc,
-                        char * const argv[])
+static int do_vdd_read(struct cmd_tbl *cmdtp, int flag, int argc,
+                      char *const argv[])
 {
        if (argc < 1)
                return CMD_RET_USAGE;