159189a8bSTim Harvey /* 259189a8bSTim Harvey * Copyright (C) 2013 Gateworks Corporation 359189a8bSTim Harvey * 459189a8bSTim Harvey * Author: Tim Harvey <tharvey@gateworks.com> 559189a8bSTim Harvey * 659189a8bSTim Harvey * SPDX-License-Identifier: GPL-2.0+ 759189a8bSTim Harvey */ 859189a8bSTim Harvey 959189a8bSTim Harvey #include <asm/errno.h> 1059189a8bSTim Harvey #include <common.h> 1159189a8bSTim Harvey #include <i2c.h> 1259189a8bSTim Harvey #include <linux/ctype.h> 1359189a8bSTim Harvey 1459189a8bSTim Harvey #include "gsc.h" 1559189a8bSTim Harvey 1659189a8bSTim Harvey /* 1759189a8bSTim Harvey * The Gateworks System Controller will fail to ACK a master transaction if 1859189a8bSTim Harvey * it is busy, which can occur during its 1HZ timer tick while reading ADC's. 1959189a8bSTim Harvey * When this does occur, it will never be busy long enough to fail more than 2059189a8bSTim Harvey * 2 back-to-back transfers. Thus we wrap i2c_read and i2c_write with 2159189a8bSTim Harvey * 3 retries. 2259189a8bSTim Harvey */ 2359189a8bSTim Harvey int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) 2459189a8bSTim Harvey { 2559189a8bSTim Harvey int retry = 3; 2659189a8bSTim Harvey int n = 0; 2759189a8bSTim Harvey int ret; 2859189a8bSTim Harvey 2959189a8bSTim Harvey while (n++ < retry) { 3059189a8bSTim Harvey ret = i2c_read(chip, addr, alen, buf, len); 3159189a8bSTim Harvey if (!ret) 3259189a8bSTim Harvey break; 3359189a8bSTim Harvey debug("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr, 3459189a8bSTim Harvey n, ret); 3559189a8bSTim Harvey if (ret != -ENODEV) 3659189a8bSTim Harvey break; 3759189a8bSTim Harvey mdelay(10); 3859189a8bSTim Harvey } 3959189a8bSTim Harvey return ret; 4059189a8bSTim Harvey } 4159189a8bSTim Harvey 4259189a8bSTim Harvey int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) 4359189a8bSTim Harvey { 4459189a8bSTim Harvey int retry = 3; 4559189a8bSTim Harvey int n = 0; 4659189a8bSTim Harvey int ret; 4759189a8bSTim Harvey 4859189a8bSTim Harvey while (n++ < retry) { 4959189a8bSTim Harvey ret = i2c_write(chip, addr, alen, buf, len); 5059189a8bSTim Harvey if (!ret) 5159189a8bSTim Harvey break; 5259189a8bSTim Harvey debug("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr, 5359189a8bSTim Harvey n, ret); 5459189a8bSTim Harvey if (ret != -ENODEV) 5559189a8bSTim Harvey break; 5659189a8bSTim Harvey mdelay(10); 5759189a8bSTim Harvey } 58e5131d53STim Harvey mdelay(100); 5959189a8bSTim Harvey return ret; 6059189a8bSTim Harvey } 6159189a8bSTim Harvey 6259189a8bSTim Harvey #ifdef CONFIG_CMD_GSC 63*16e369f5STim Harvey static void read_hwmon(const char *name, uint reg, uint size) 6459189a8bSTim Harvey { 6559189a8bSTim Harvey unsigned char buf[3]; 6659189a8bSTim Harvey uint ui; 6759189a8bSTim Harvey 6859189a8bSTim Harvey printf("%-8s:", name); 6959189a8bSTim Harvey memset(buf, 0, sizeof(buf)); 7059189a8bSTim Harvey if (gsc_i2c_read(GSC_HWMON_ADDR, reg, 1, buf, size)) { 7159189a8bSTim Harvey puts("fRD\n"); 7259189a8bSTim Harvey } else { 7359189a8bSTim Harvey ui = buf[0] | (buf[1]<<8) | (buf[2]<<16); 7459189a8bSTim Harvey if (ui == 0xffffff) 75*16e369f5STim Harvey puts("invalid\n"); 7659189a8bSTim Harvey else 77*16e369f5STim Harvey printf("%d\n", ui); 7859189a8bSTim Harvey } 7959189a8bSTim Harvey } 8059189a8bSTim Harvey 8159189a8bSTim Harvey int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 8259189a8bSTim Harvey { 8359189a8bSTim Harvey const char *model = getenv("model"); 8459189a8bSTim Harvey 8559189a8bSTim Harvey i2c_set_bus_num(0); 86*16e369f5STim Harvey read_hwmon("Temp", GSC_HWMON_TEMP, 2); 87*16e369f5STim Harvey read_hwmon("VIN", GSC_HWMON_VIN, 3); 88*16e369f5STim Harvey read_hwmon("VBATT", GSC_HWMON_VBATT, 3); 89*16e369f5STim Harvey read_hwmon("VDD_3P3", GSC_HWMON_VDD_3P3, 3); 90*16e369f5STim Harvey read_hwmon("VDD_HIGH", GSC_HWMON_VDD_HIGH, 3); 91*16e369f5STim Harvey read_hwmon("VDD_DDR", GSC_HWMON_VDD_DDR, 3); 92*16e369f5STim Harvey read_hwmon("VDD_5P0", GSC_HWMON_VDD_5P0, 3); 93*16e369f5STim Harvey read_hwmon("VDD_2P5", GSC_HWMON_VDD_2P5, 3); 94*16e369f5STim Harvey read_hwmon("VDD_1P8", GSC_HWMON_VDD_1P8, 3); 9559189a8bSTim Harvey switch (model[3]) { 9659189a8bSTim Harvey case '1': /* GW51xx */ 97*16e369f5STim Harvey read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3); 98*16e369f5STim Harvey read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3); 9959189a8bSTim Harvey break; 10059189a8bSTim Harvey case '2': /* GW52xx */ 10159189a8bSTim Harvey case '3': /* GW53xx */ 102*16e369f5STim Harvey read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3); 103*16e369f5STim Harvey read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3); 104*16e369f5STim Harvey read_hwmon("VDD_1P0", GSC_HWMON_VDD_1P0, 3); 10559189a8bSTim Harvey break; 10659189a8bSTim Harvey case '4': /* GW54xx */ 107*16e369f5STim Harvey read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3); 108*16e369f5STim Harvey read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3); 109*16e369f5STim Harvey read_hwmon("VDD_1P0", GSC_HWMON_VDD_1P0, 3); 11059189a8bSTim Harvey break; 1113aa22674STim Harvey case '5': /* GW55xx */ 112*16e369f5STim Harvey read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3); 113*16e369f5STim Harvey read_hwmon("VDD_SOC", GSC_HWMON_VDD_SOC, 3); 1143aa22674STim Harvey break; 11559189a8bSTim Harvey } 11659189a8bSTim Harvey return 0; 11759189a8bSTim Harvey } 11859189a8bSTim Harvey 11959189a8bSTim Harvey U_BOOT_CMD(gsc, 1, 1, do_gsc, 12059189a8bSTim Harvey "GSC test", 12159189a8bSTim Harvey "" 12259189a8bSTim Harvey ); 12359189a8bSTim Harvey 12459189a8bSTim Harvey #endif /* CONFIG_CMD_GSC */ 125