allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / cfe / cfe / arch / mips / cpu / sb1250 / src / ui_tempsensor.c
blobe9f3fa82f5d15de99a574c9cb23fbd756c1c7f38
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 (mpl@broadcom.com)
9 *
10 *********************************************************************
12 * Copyright 2000,2001,2002,2003
13 * Broadcom Corporation. All rights reserved.
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.
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.
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.
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 ********************************************************************* */
48 #include "lib_types.h"
49 #include "lib_string.h"
50 #include "lib_queue.h"
51 #include "lib_malloc.h"
52 #include "lib_printf.h"
54 #include "cfe_console.h"
55 #include "cfe_timer.h"
57 #include "cfe_error.h"
59 #include "ui_command.h"
60 #include "cfe.h"
62 #include "bsp_config.h"
64 #include "sbmips.h"
65 #include "sb1250_regs.h"
66 #include "sb1250_smbus.h"
69 /* *********************************************************************
70 * Configuration
71 ********************************************************************* */
73 #define _MAX6654_ /* Support Maxim 6654 temperature chip w/parasitic mode */
75 /* *********************************************************************
76 * prototypes
77 ********************************************************************* */
79 int ui_init_tempsensorcmds(void);
81 #if (defined(TEMPSENSOR_SMBUS_DEV) && defined(TEMPSENSOR_SMBUS_CHAN))
82 static int ui_cmd_showtemp(ui_cmdline_t *cmd,int argc,char *argv[]);
83 static void temp_timer_proc(void *);
84 #endif
86 /* *********************************************************************
87 * Data
88 ********************************************************************* */
90 #if (defined(TEMPSENSOR_SMBUS_DEV) && defined(TEMPSENSOR_SMBUS_CHAN))
91 static int64_t temp_timer = 0;
92 static int temp_prev_local = 0;
93 static int temp_prev_remote = 0;
94 #endif
96 /* *********************************************************************
97 * ui_init_swarmcmds()
99 * Add SWARM-specific commands to the command table
101 * Input parameters:
102 * nothing
104 * Return value:
106 ********************************************************************* */
109 int ui_init_tempsensorcmds(void)
112 #if (defined(TEMPSENSOR_SMBUS_DEV) && defined(TEMPSENSOR_SMBUS_CHAN))
113 cmd_addcmd("show temp",
114 ui_cmd_showtemp,
115 NULL,
116 "Display CPU temperature",
117 "show temp",
118 "-continuous;Poll for temperature changes|"
119 "-stop;Stop polling for temperature changes");
121 cfe_bg_add(temp_timer_proc,NULL);
122 #endif
124 return 0;
129 #if (defined(TEMPSENSOR_SMBUS_DEV) && defined(TEMPSENSOR_SMBUS_CHAN))
130 /* *********************************************************************
131 * temp_smbus_init(chan)
133 * Initialize the specified SMBus channel for the temp sensor
135 * Input parameters:
136 * chan - channel # (0 or 1)
138 * Return value:
139 * nothing
140 ********************************************************************* */
142 static void temp_smbus_init(int chan)
144 uintptr_t reg;
146 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_FREQ));
148 SBWRITECSR(reg,K_SMB_FREQ_100KHZ); /* 400Khz clock */
150 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CONTROL));
152 SBWRITECSR(reg,0); /* not in direct mode, no interrupts, will poll */
156 /* *********************************************************************
157 * temp_smbus_waitready(chan)
159 * Wait until the SMBus channel is ready. We simply poll
160 * the busy bit until it clears.
162 * Input parameters:
163 * chan - channel (0 or 1)
165 * Return value:
166 * nothing
167 ********************************************************************* */
168 static int temp_smbus_waitready(int chan)
170 uintptr_t reg;
171 uint64_t status;
173 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_STATUS));
175 for (;;) {
176 status = SBREADCSR(reg);
177 if (status & M_SMB_BUSY) continue;
178 break;
181 if (status & M_SMB_ERROR) {
182 SBWRITECSR(reg,(status & M_SMB_ERROR));
183 return -1;
185 return 0;
188 /* *********************************************************************
189 * temp_smbus_read(chan,slaveaddr,devaddr)
191 * Read a byte from the temperature sensor chip
193 * Input parameters:
194 * chan - SMBus channel
195 * slaveaddr - SMBus slave address
196 * devaddr - byte with in the sensor device to read
198 * Return value:
199 * 0 if ok
200 * else -1
201 ********************************************************************* */
203 static int temp_smbus_read(int chan,int slaveaddr,int devaddr)
205 uintptr_t reg;
206 int err;
209 * Make sure the bus is idle (probably should
210 * ignore error here)
213 if (temp_smbus_waitready(chan) < 0) return -1;
216 * Write the device address to the controller. There are two
217 * parts, the high part goes in the "CMD" field, and the
218 * low part is the data field.
221 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CMD));
222 SBWRITECSR(reg,devaddr);
225 * Read the data byte
228 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_START));
229 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_CMD_RD1BYTE) | slaveaddr);
231 err = temp_smbus_waitready(chan);
232 if (err < 0) return err;
234 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA));
235 err = SBREADCSR(reg);
237 return (err & 0xFF);
240 #ifdef _MAX6654_
241 /* *********************************************************************
242 * temp_smbus_write(chan,slaveaddr,devaddr,data)
244 * write a byte to the temperature sensor chip
246 * Input parameters:
247 * chan - SMBus channel
248 * slaveaddr - SMBus slave address
249 * devaddr - byte with in the sensor device to read
251 * Return value:
252 * 0 if ok
253 * else -1
254 ********************************************************************* */
256 static int temp_smbus_write(int chan,int slaveaddr,int devaddr,int data)
258 uintptr_t reg;
259 int err;
262 * Make sure the bus is idle (probably should
263 * ignore error here)
266 if (temp_smbus_waitready(chan) < 0) return -1;
269 * Write the device address to the controller. There are two
270 * parts, the high part goes in the "CMD" field, and the
271 * low part is the data field.
274 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CMD));
275 SBWRITECSR(reg,devaddr);
278 * Write the data byte
281 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA));
282 SBWRITECSR(reg,data);
285 * Do the write command.
288 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_START));
289 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_WR2BYTE) | slaveaddr);
291 err = temp_smbus_waitready(chan);
293 return err;
295 #endif
298 /* *********************************************************************
299 * temp_showtemp(noisy)
301 * Display the temperature. If 'noisy' is true, display it
302 * regardless of whether it has changed, otherwise only display
303 * when it has changed.
305 * Input parameters:
306 * noisy - display whether or not changed
308 * Return value:
309 * nothing
310 ********************************************************************* */
312 static int temp_showtemp(int noisy)
314 int local,remote,status;
315 char statstr[50];
317 local = temp_smbus_read(TEMPSENSOR_SMBUS_CHAN,TEMPSENSOR_SMBUS_DEV,0);
318 remote = temp_smbus_read(TEMPSENSOR_SMBUS_CHAN,TEMPSENSOR_SMBUS_DEV,1);
319 status = temp_smbus_read(TEMPSENSOR_SMBUS_CHAN,TEMPSENSOR_SMBUS_DEV,2);
321 if ((local < 0) || (remote < 0) || (status < 0)) {
322 if (noisy) printf("Temperature sensor device did not respond\n");
323 return -1;
326 if (noisy || (local != temp_prev_local) || (remote != temp_prev_remote)) {
327 statstr[0] = 0;
328 if (status & 0x80) strcat(statstr,"Busy ");
329 if (status & 0x40) strcat(statstr,"HiTempLcl ");
330 if (status & 0x20) strcat(statstr,"LoTempLcl ");
331 if (status & 0x10) strcat(statstr,"HiTempRem ");
332 if (status & 0x08) strcat(statstr,"LoTempRem ");
333 if (status & 0x04) strcat(statstr,"Fault ");
335 if (noisy || !(status & 0x80)) {
336 /* don't display if busy, always display if noisy */
337 console_log("Temperature: CPU: %dC Board: %dC Status:%02X [ %s]",
338 remote,local,status,statstr);
342 temp_prev_local = local;
343 temp_prev_remote = remote;
345 return 0;
351 /* *********************************************************************
352 * ui_cmd_showtemp(cmd,argc,argv)
354 * Show temperature
356 * Input parameters:
357 * cmd - command structure
358 * argc,argv - parameters
360 * Return value:
361 * -1 if error occured. Does not return otherwise
362 ********************************************************************* */
364 static int ui_cmd_showtemp(ui_cmdline_t *cmd,int argc,char *argv[])
367 temp_smbus_init(TEMPSENSOR_SMBUS_CHAN);
369 #ifdef _MAX6654_
370 do {
371 int dev,rev;
372 static int didinit = 0;
374 if (!didinit) {
375 didinit = 1;
376 dev = temp_smbus_read(TEMPSENSOR_SMBUS_CHAN,TEMPSENSOR_SMBUS_DEV,0xFE);
377 rev = temp_smbus_read(TEMPSENSOR_SMBUS_CHAN,TEMPSENSOR_SMBUS_DEV,0xFF);
378 printf("Temperature Sensor Device ID %02X rev %02X\n",dev,rev);
380 if (dev == 0x4D) { /* MAX6654 */
381 printf("Switching MAX6654 to parasitic mode\n");
382 /* Switch to 1hz conversion rate (1 seconds per conversion) */
383 temp_smbus_write(TEMPSENSOR_SMBUS_CHAN,TEMPSENSOR_SMBUS_DEV,0x0A,0x04);
384 /* Switch to parasitic mode */
385 temp_smbus_write(TEMPSENSOR_SMBUS_CHAN,TEMPSENSOR_SMBUS_DEV,9,0x10);
388 } while (0);
389 #endif
391 if (temp_showtemp(1) < 0) {
392 TIMER_CLEAR(temp_timer);
393 return -1;
396 if (cmd_sw_isset(cmd,"-continuous")) {
397 TIMER_SET(temp_timer,2*CFE_HZ);
399 if (cmd_sw_isset(cmd,"-stop")) {
400 TIMER_CLEAR(temp_timer);
403 return 0;
406 /* *********************************************************************
407 * temp_timer_proc()
409 * So we can be fancy and log temperature changes as they happen.
411 * Input parameters:
412 * nothing
414 * Return value:
415 * nothing
416 ********************************************************************* */
418 void temp_timer_proc(void *arg)
420 if (!TIMER_RUNNING(temp_timer)) return;
422 if (TIMER_EXPIRED(temp_timer)) {
423 temp_showtemp(0);
424 TIMER_SET(temp_timer,2*CFE_HZ);
427 #endif