uboot/post/board/lwmon5/sysmon.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
   3 *
   4 * Developed for DENX Software Engineering GmbH
   5 *
   6 * See file CREDITS for list of people who contributed to this
   7 * project.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of
  12 * the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22 * MA 02111-1307 USA
  23 */
  24
  25#include <post.h>
  26#include <common.h>
  27
  28/*
  29 * SYSMON test
  30 *
  31 * This test performs the system hardware monitoring.
  32 * The test passes when all the following voltages and temperatures
  33 * are within allowed ranges:
  34 *
  35 * Temperature            -40 .. +90 C
  36 * +5V                  +4.50 .. +5.50 V
  37 * +5V standby          +3.50 .. +5.50 V
  38 *
  39 * LCD backlight is not enabled if temperature values are not within
  40 * allowed ranges (-30 .. + 80). The brightness of backlite can be
  41 * controlled by setting "brightness" enviroment variable. Default value is 50%
  42 *
  43 * See the list of all parameters in the sysmon_table below
  44 */
  45
  46#include <post.h>
  47#include <watchdog.h>
  48#include <i2c.h>
  49
  50#if defined(CONFIG_VIDEO)
  51#include <mb862xx.h>
  52#endif
  53
  54#if CONFIG_POST & CONFIG_SYS_POST_SYSMON
  55
  56DECLARE_GLOBAL_DATA_PTR;
  57
  58/* from dspic.c */
  59extern int dspic_read(ushort reg);
  60
  61#define REG_TEMPERATURE                 0x12BC
  62#define REG_VOLTAGE_5V                  0x12CA
  63#define REG_VOLTAGE_5V_STANDBY          0x12C6
  64
  65#define TEMPERATURE_MIN                 (-40)   /* degr. C */
  66#define TEMPERATURE_MAX                 (+90)   /* degr. C */
  67#define TEMPERATURE_DISPLAY_MIN         (-35)   /* degr. C */
  68#define TEMPERATURE_DISPLAY_MAX         (+85)   /* degr. C */
  69
  70#define VOLTAGE_5V_MIN                  (+4500) /* mV */
  71#define VOLTAGE_5V_MAX                  (+5500) /* mV */
  72
  73#define VOLTAGE_5V_STANDBY_MIN          (+3500) /* mV */
  74#define VOLTAGE_5V_STANDBY_MAX          (+5500) /* mV */
  75
  76typedef struct sysmon_s sysmon_t;
  77typedef struct sysmon_table_s sysmon_table_t;
  78
  79static void sysmon_dspic_init (sysmon_t * this);
  80static int sysmon_dspic_read (sysmon_t * this, uint addr);
  81static void sysmon_backlight_disable (sysmon_table_t * this);
  82
  83struct sysmon_s
  84{
  85        uchar   chip;
  86        void    (*init)(sysmon_t *);
  87        int     (*read)(sysmon_t *, uint);
  88};
  89
  90static sysmon_t sysmon_dspic =
  91        {CONFIG_SYS_I2C_DSPIC_IO_ADDR, sysmon_dspic_init, sysmon_dspic_read};
  92
  93static sysmon_t * sysmon_list[] =
  94{
  95        &sysmon_dspic,
  96        NULL
  97};
  98
  99struct sysmon_table_s
 100{
 101        char *          name;
 102        char *          unit_name;
 103        sysmon_t *      sysmon;
 104        void            (*exec_before)(sysmon_table_t *);
 105        void            (*exec_after)(sysmon_table_t *);
 106
 107        int             unit_precision;
 108        int             unit_div;
 109        int             unit_min;
 110        int             unit_max;
 111        uint            val_mask;
 112        uint            val_min;
 113        uint            val_max;
 114        int             val_valid;
 115        uint            val_min_alt;
 116        uint            val_max_alt;
 117        int             val_valid_alt;
 118        uint            addr;
 119};
 120
 121static sysmon_table_t sysmon_table[] =
 122{
 123        {
 124        "Temperature", " C", &sysmon_dspic, NULL, sysmon_backlight_disable,
 125        1, 1, -32768, 32767, 0xFFFF,
 126        0x8000 + TEMPERATURE_MIN,         0x8000 + TEMPERATURE_MAX,         0,
 127        0x8000 + TEMPERATURE_DISPLAY_MIN, 0x8000 + TEMPERATURE_DISPLAY_MAX, 0,
 128        REG_TEMPERATURE,
 129        },
 130
 131        {
 132        "+ 5 V", "V", &sysmon_dspic, NULL, NULL,
 133        100, 1000, -0x8000, 0x7FFF, 0xFFFF,
 134        0x8000 + VOLTAGE_5V_MIN, 0x8000 + VOLTAGE_5V_MAX, 0,
 135        0x8000 + VOLTAGE_5V_MIN, 0x8000 + VOLTAGE_5V_MAX, 0,
 136        REG_VOLTAGE_5V,
 137        },
 138
 139        {
 140        "+ 5 V standby", "V", &sysmon_dspic, NULL, NULL,
 141        100, 1000, -0x8000, 0x7FFF, 0xFFFF,
 142        0x8000 + VOLTAGE_5V_STANDBY_MIN, 0x8000 + VOLTAGE_5V_STANDBY_MAX, 0,
 143        0x8000 + VOLTAGE_5V_STANDBY_MIN, 0x8000 + VOLTAGE_5V_STANDBY_MAX, 0,
 144        REG_VOLTAGE_5V_STANDBY,
 145        },
 146};
 147static int sysmon_table_size = sizeof(sysmon_table) / sizeof(sysmon_table[0]);
 148
 149int sysmon_init_f (void)
 150{
 151        sysmon_t ** l;
 152
 153        for (l = sysmon_list; *l; l++)
 154                (*l)->init(*l);
 155
 156        return 0;
 157}
 158
 159void sysmon_reloc (void)
 160{
 161        /* Do nothing for now, sysmon_reloc() is required by the sysmon post */
 162}
 163
 164static char *sysmon_unit_value (sysmon_table_t *s, uint val)
 165{
 166        static char buf[32];
 167        char *p, sign;
 168        int decimal, frac;
 169        int unit_val;
 170
 171        unit_val = s->unit_min + (s->unit_max - s->unit_min) * val / s->val_mask;
 172
 173        if (val == -1)
 174                return "I/O ERROR";
 175
 176        if (unit_val < 0) {
 177                sign = '-';
 178                unit_val = -unit_val;
 179        } else
 180                sign = '+';
 181
 182        p = buf + sprintf(buf, "%c%2d", sign, unit_val / s->unit_div);
 183
 184
 185        frac = unit_val % s->unit_div;
 186
 187        frac /= (s->unit_div / s->unit_precision);
 188
 189        decimal = s->unit_precision;
 190
 191        if (decimal != 1)
 192                *p++ = '.';
 193        for (decimal /= 10; decimal != 0; decimal /= 10)
 194                *p++ = '0' + (frac / decimal) % 10;
 195        strcpy(p, s->unit_name);
 196
 197        return buf;
 198}
 199
 200static void sysmon_dspic_init (sysmon_t * this)
 201{
 202}
 203
 204static int sysmon_dspic_read (sysmon_t * this, uint addr)
 205{
 206        int res = dspic_read(addr);
 207
 208        /* To fit into the table range we should add 0x8000 */
 209        return (res == -1) ? -1 : (res + 0x8000);
 210}
 211
 212static void sysmon_backlight_disable (sysmon_table_t * this)
 213{
 214#if defined(CONFIG_VIDEO)
 215        board_backlight_switch(this->val_valid_alt);
 216#endif
 217}
 218
 219int sysmon_post_test (int flags)
 220{
 221        int res = 0;
 222        sysmon_table_t * t;
 223        int val;
 224
 225        for (t = sysmon_table; t < sysmon_table + sysmon_table_size; t ++) {
 226                if (t->exec_before)
 227                        t->exec_before(t);
 228
 229                val = t->sysmon->read(t->sysmon, t->addr);
 230                if (val != -1) {
 231                        t->val_valid = val >= t->val_min && val <= t->val_max;
 232                        t->val_valid_alt = val >= t->val_min_alt && val <= t->val_max_alt;
 233                } else {
 234                        t->val_valid = 0;
 235                        t->val_valid_alt = 0;
 236                }
 237
 238                if (t->exec_after)
 239                        t->exec_after(t);
 240
 241                if ((!t->val_valid) || (flags & POST_MANUAL)) {
 242                        printf("%-17s = %-10s ", t->name, sysmon_unit_value(t, val));
 243                        printf("allowed range");
 244                        printf(" %-8s ..", sysmon_unit_value(t, t->val_min));
 245                        printf(" %-8s", sysmon_unit_value(t, t->val_max));
 246                        printf("     %s\n", t->val_valid ? "OK" : "FAIL");
 247                }
 248
 249                if (!t->val_valid)
 250                        res = 1;
 251        }
 252
 253        return res;
 254}
 255#endif /* CONFIG_POST & CONFIG_SYS_POST_SYSMON */
 256