1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Temperature sensor commands: File: ui_tempsensor.c 5 * 6 * Temperature sensor commands 7 * 8 * Author: Mitch Lichtenberg 9 * 10 ********************************************************************* 11 * 12 * Copyright 2000,2001,2002,2003 13 * Broadcom Corporation. All rights reserved. 14 * 15 * This software is furnished under license and may be used and 16 * copied only in accordance with the following terms and 17 * conditions. Subject to these conditions, you may download, 18 * copy, install, use, modify and distribute modified or unmodified 19 * copies of this software in source and/or binary form. No title 20 * or ownership is transferred hereby. 21 * 22 * 1) Any source code used, modified or distributed must reproduce 23 * and retain this copyright notice and list of conditions 24 * as they appear in the source file. 25 * 26 * 2) No right is granted to use any trade name, trademark, or 27 * logo of Broadcom Corporation. The "Broadcom Corporation" 28 * name may not be used to endorse or promote products derived 29 * from this software without the prior written permission of 30 * Broadcom Corporation. 31 * 32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 44 * THE POSSIBILITY OF SUCH DAMAGE. 45 ********************************************************************* */ 46 47 48#include "cfe.h" 49#include "cfe_smbus.h" 50#include "ui_command.h" 51 52 53/* ********************************************************************* 54 * Supported chips 55 * chip vendor id (at 0xFE) rev ID (at 0xFF) 56 * 57 * ADT7461 0x41 0x51 58 * MAX1617 0x4D 0x01 59 * MAX6654 0x4D 0x08 60 * 61 ********************************************************************* */ 62 63/* ********************************************************************* 64 * Configuration 65 ********************************************************************* */ 66 67#define _MAX6654_ /* Support Maxim 6654 temperature chip w/parasitic mode */ 68 69/* ********************************************************************* 70 * prototypes 71 ********************************************************************* */ 72 73int ui_init_tempsensorcmds(void); 74 75#if (defined(TEMPSENSOR_SMBUS_DEV) && defined(TEMPSENSOR_SMBUS_CHAN)) 76static int ui_cmd_showtemp(ui_cmdline_t *cmd,int argc,char *argv[]); 77static void temp_timer_proc(void *); 78#endif 79 80/* ********************************************************************* 81 * Data 82 ********************************************************************* */ 83 84#if (defined(TEMPSENSOR_SMBUS_DEV) && defined(TEMPSENSOR_SMBUS_CHAN)) 85static int64_t temp_timer = 0; 86static int temp_prev_local = 0; 87static int temp_prev_remote = 0; 88#endif 89 90/* ********************************************************************* 91 * ui_init_swarmcmds() 92 * 93 * Add SWARM-specific commands to the command table 94 * 95 * Input parameters: 96 * nothing 97 * 98 * Return value: 99 * 0 100 ********************************************************************* */ 101 102 103int ui_init_tempsensorcmds(void) 104{ 105 106#if (defined(TEMPSENSOR_SMBUS_DEV) && defined(TEMPSENSOR_SMBUS_CHAN)) 107 cmd_addcmd("show temp", 108 ui_cmd_showtemp, 109 NULL, 110 "Display CPU temperature", 111 "show temp", 112 "-continuous;Poll for temperature changes|" 113 "-stop;Stop polling for temperature changes"); 114 115 cfe_bg_add(temp_timer_proc,NULL); 116#endif 117 118 return 0; 119} 120 121 122 123#if (defined(TEMPSENSOR_SMBUS_DEV) && defined(TEMPSENSOR_SMBUS_CHAN)) 124/* ********************************************************************* 125 * temp_smbus_read(chan,slaveaddr,devaddr) 126 * 127 * Read a byte from the temperature sensor chip 128 * 129 * Input parameters: 130 * chan - SMBus channel 131 * slaveaddr - SMBus slave address 132 * devaddr - byte with in the sensor device to read 133 * 134 * Return value: 135 * 0 if ok 136 * else -1 137 ********************************************************************* */ 138 139static int temp_smbus_read(cfe_smbus_channel_t *chan,int slaveaddr,int devaddr) 140{ 141 uint8_t buf[1]; 142 int err; 143 144 /* 145 * Read the data byte 146 */ 147 148 err = SMBUS_XACT(chan,slaveaddr,devaddr,buf,1); 149 if (err < 0) return err; 150 151 return buf[0]; 152} 153 154#ifdef _MAX6654_ 155/* ********************************************************************* 156 * temp_smbus_write(chan,slaveaddr,devaddr,data) 157 * 158 * write a byte to the temperature sensor chip 159 * 160 * Input parameters: 161 * chan - SMBus channel 162 * slaveaddr - SMBus slave address 163 * devaddr - byte with in the sensor device to read 164 * 165 * Return value: 166 * 0 if ok 167 * else -1 168 ********************************************************************* */ 169 170static int temp_smbus_write(cfe_smbus_channel_t *chan,int slaveaddr,int devaddr,int data) 171{ 172 uint8_t buf[2]; 173 int err; 174 175 /* 176 * Write the data byte 177 */ 178 179 buf[0] = devaddr; 180 buf[1] = data; 181 182 err = SMBUS_WRITE(chan,slaveaddr,buf,2); 183 return err; 184} 185#endif 186 187 188/* ********************************************************************* 189 * temp_showtemp(noisy) 190 * 191 * Display the temperature. If 'noisy' is true, display it 192 * regardless of whether it has changed, otherwise only display 193 * when it has changed. 194 * 195 * Input parameters: 196 * noisy - display whether or not changed 197 * 198 * Return value: 199 * nothing 200 ********************************************************************* */ 201 202static int temp_showtemp(int noisy) 203{ 204 int local,remote,status; 205 char statstr[50]; 206 cfe_smbus_channel_t *chan = SMBUS_CHANNEL(TEMPSENSOR_SMBUS_CHAN); 207 208 local = temp_smbus_read(chan,TEMPSENSOR_SMBUS_DEV,0); 209 remote = temp_smbus_read(chan,TEMPSENSOR_SMBUS_DEV,1); 210 status = temp_smbus_read(chan,TEMPSENSOR_SMBUS_DEV,2); 211 212 if ((local < 0) || (remote < 0) || (status < 0)) { 213 if (noisy) printf("Temperature sensor device did not respond\n"); 214 return -1; 215 } 216 217 if (noisy || (local != temp_prev_local) || (remote != temp_prev_remote)) { 218 statstr[0] = 0; 219 if (status & 0x80) strcat(statstr,"Busy "); 220 if (status & 0x40) strcat(statstr,"HiTempLcl "); 221 if (status & 0x20) strcat(statstr,"LoTempLcl "); 222 if (status & 0x10) strcat(statstr,"HiTempRem "); 223 if (status & 0x08) strcat(statstr,"LoTempRem "); 224 if (status & 0x04) strcat(statstr,"Fault "); 225 226 if (noisy || !(status & 0x80)) { 227 /* don't display if busy, always display if noisy */ 228 console_log("Temperature: CPU: %dC Board: %dC Status:%02X [ %s]", 229 remote,local,status,statstr); 230 } 231 } 232 233 temp_prev_local = local; 234 temp_prev_remote = remote; 235 236 return 0; 237} 238 239 240 241 242/* ********************************************************************* 243 * ui_cmd_showtemp(cmd,argc,argv) 244 * 245 * Show temperature 246 * 247 * Input parameters: 248 * cmd - command structure 249 * argc,argv - parameters 250 * 251 * Return value: 252 * -1 if error occured. Does not return otherwise 253 ********************************************************************* */ 254 255static int ui_cmd_showtemp(ui_cmdline_t *cmd,int argc,char *argv[]) 256{ 257 258 do { 259 int dev,rev; 260 static int didinit = 0; 261 cfe_smbus_channel_t *chan = SMBUS_CHANNEL(TEMPSENSOR_SMBUS_CHAN); 262 263 if (!didinit) { 264 didinit = 1; 265 dev = temp_smbus_read(chan,TEMPSENSOR_SMBUS_DEV,0xFE); 266 rev = temp_smbus_read(chan,TEMPSENSOR_SMBUS_DEV,0xFF); 267 printf("Temperature Sensor Device ID %02X rev %02X\n",dev,rev); 268 269#ifdef _MAX6654_ 270 if (dev == 0x4D && rev == 0x08) { /* MAX6654 */ 271 printf("Switching MAX6654 to parasitic mode\n"); 272 /* Switch to 1hz conversion rate (1 seconds per conversion) */ 273 temp_smbus_write(chan,TEMPSENSOR_SMBUS_DEV,0x0A,0x04); 274 /* Switch to parasitic mode */ 275 temp_smbus_write(chan,TEMPSENSOR_SMBUS_DEV,9,0x10); 276 } 277#endif 278 } 279 } while (0); 280 281 if (temp_showtemp(1) < 0) { 282 TIMER_CLEAR(temp_timer); 283 return -1; 284 } 285 286 if (cmd_sw_isset(cmd,"-continuous")) { 287 TIMER_SET(temp_timer,2*CFE_HZ); 288 } 289 if (cmd_sw_isset(cmd,"-stop")) { 290 TIMER_CLEAR(temp_timer); 291 } 292 293 return 0; 294} 295 296/* ********************************************************************* 297 * temp_timer_proc() 298 * 299 * So we can be fancy and log temperature changes as they happen. 300 * 301 * Input parameters: 302 * nothing 303 * 304 * Return value: 305 * nothing 306 ********************************************************************* */ 307 308void temp_timer_proc(void *arg) 309{ 310 if (!TIMER_RUNNING(temp_timer)) return; 311 312 if (TIMER_EXPIRED(temp_timer)) { 313 temp_showtemp(0); 314 TIMER_SET(temp_timer,2*CFE_HZ); 315 } 316} 317#endif 318