From: Harald Welte <laforge@gnumonks.org>
To: linuxppc-dev@lists.linuxppc.org
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: Re: [PATCH] ugly hack to make therm_pm72 work on XServe G5
Date: Fri, 6 Aug 2004 10:04:06 +0200 [thread overview]
Message-ID: <20040806080406.GB11638@sunbeam2> (raw)
In-Reply-To: <20040805114348.GD7112@sunbeam2>
[-- Attachment #1: Type: text/plain, Size: 575 bytes --]
I actually forgot that small userspace program ;)
It is a total ripoff of the kernel driver and was implemented because
it's easier to play with i2c from userspace during development.
benh: Any reason why you implemented your own byte+word read/write
routines? Apparently the i2c_smbus routines work quite fine, even from
userspace...
--
- Harald Welte <laforge@gnumonks.org> http://www.gnumonks.org/
============================================================================
Programming is like sex: One mistake and you have to support it your lifetime
[-- Attachment #2: rackmac-fans.c --]
[-- Type: text/x-csrc, Size: 4722 bytes --]
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>
static int fd;
#ifdef RAW_I2C
static int fan_read_reg(int reg, unsigned char *buf, int nb)
{
int tries, nr, nw;
buf[0] = reg;
tries = 0;
for (;;) {
nw = write(fd, buf, 1);
if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100)
break;
usleep(10);
++tries;
}
if (nw < 0) {
fprintf(stderr, "Failure writing address to FCU: %d\n", nw);
return -EIO;
}
tries = 0;
for (;;) {
nr = read(fd, buf, nb);
if (nr > 0 || (nr < 0 && nr != ENODEV) || tries >= 100)
break;
usleep(10);
++tries;
}
if (nr <= 0)
fprintf(stderr, "Failure reading data from FCU: %d\n", nw);
return nr;
}
static int fan_write_reg(int reg, const unsigned char *ptr, int nb)
{
int tries, nw;
unsigned char buf[16];
buf[0] = reg;
memcpy(buf+1, ptr, nb);
++nb;
tries = 0;
for (;;) {
nw = write(fd, buf, nb);
if (nw > 0 || (nw < 0 && nw != EIO) || tries >= 100)
break;
usleep(1);
++tries;
}
if (nw < 0)
fprintf(stderr, "Failure writing to FCU: %d", nw);
return nw;
}
#else
static int fan_read_reg(int reg, unsigned char *ptr, int nb)
{
int ret;
if (nb == 1) {
ret = i2c_smbus_read_byte_data(fd, reg);
if (ret < 0) {
fprintf(stderr,"error during read_word_data\n");
return ret;
}
*ptr = (unsigned char) ret;
return nb;
} else if (nb == 2) {
ret = i2c_smbus_read_word_data(fd, reg);
if (ret < 0) {
fprintf(stderr,"error during read_word_data\n");
return ret;
}
*ptr = (u_int16_t) ret;
return nb;
} else {
fprintf(stderr, "%u bytes not inplemented\n", nb);
return -EINVAL;
}
}
static int fan_write_reg(int reg, const unsigned char *ptr, int nb)
{
int ret;
if (nb == 1) {
ret = i2c_smbus_write_byte_data(fd, reg, *ptr);
if (ret < 0) {
fprintf(stderr, "error during write_byte_data\n");
return ret;
}
return nb;
} else if (nb == 2) {
ret = i2c_smbus_write_word_data(fd, reg, *ptr);
if (ret < 0) {
fprintf(stderr, "error during write_word_data\n");
return ret;
}
return nb;
} else {
fprintf(stderr, "%u bytes not implemented\n", nb);
return -EINVAL;
}
}
#endif
static int set_rpm_fan(int fan, int rpm)
{
unsigned char buf[2];
int rc;
if (rpm < 300)
rpm = 300;
else if (rpm > 8191)
rpm = 8191;
buf[0] = rpm >> 5;
buf[1] = rpm << 3;
rc = fan_write_reg(0x10 + (fan *2), buf, 2);
if (rc < 0)
return -EIO;
return 0;
}
static int get_rpm_fan(int fan, int programmed)
{
unsigned char failure;
unsigned char active;
unsigned char buf[2];
int rc, reg_base;
rc = fan_read_reg(0xb, &failure, 1);
if (rc != 1) {
fprintf(stderr, "unable to reada 0xb register\n");
return -EIO;
}
if ((failure & (1 << fan)) != 0)
return -EFAULT;
rc = fan_read_reg(0xd, &active, 1);
if (rc != 1) {
fprintf(stderr, "unable to read 0xd register\n");
return -EIO;
}
if ((active & (1 << fan)) == 0)
return -ENXIO;
reg_base = programmed ? 0x10 : 0x11;
rc = fan_read_reg(reg_base + (fan * 2), buf, 2);
if (rc != 2) {
fprintf(stderr, "unable to read fan register 0x%x\n",=20
reg_base+(fan*2));
return -EIO;
}
return (buf[0] << 5 | buf[1] >> 3);
}
static int set_pwm_fan(int fan, int pwm)
{
unsigned char buf[2];
int rc;
if (pwm < 10)
pwm = 10;
else if (pwm > 100)
pwm = 100;
pwm = (pwm * 2559) / 1000;
buf[0] = pwm;
rc = fan_write_reg(0x30 + (fan*2), buf, 1);
if (rc < 0)
return rc;
return 0;
}
static int get_pwm_fan(int fan)
{
unsigned char failure;
unsigned char active;
unsigned char buf[2];
int rc;
rc = fan_read_reg(0x2b, &failure, 1);
if (rc != 1)
return -EIO;
if ((failure & (1 << fan)) != 0)
return -EFAULT;
rc = fan_read_reg(0x2d, &active, 1);
if (rc != 1)
return -EIO;
if ((active & (1 << fan)) == 0)
return -ENXIO;
=09
rc = fan_read_reg(0x30 + (fan *2), buf, 1);
if (rc != 1)
return -EIO;
return (buf[0] * 1000) / 2559;
}
int main(int argc, char **argv)
{
int ret;
int fan_num;
fd = open("/dev/i2c-2", O_RDWR);
if (fd < 0)
exit(1);
ret = ioctl(fd, I2C_SLAVE_FORCE, 0x2f);
if (ret < 0) {
fprintf(stderr, "Unable to access device 0x2f\n");
exit(1);
}
for (fan_num = 1; fan_num <= 6; fan_num++) {
int rpm;
set_rpm_fan(fan_num, 3000);
rpm = get_rpm_fan(fan_num, 0);
if (rpm < 0)
printf("Fan %d: %s\n", fan_num, strerror(-rpm));
else
printf("Fan %d: %d rpm\n", fan_num, rpm);
}
=09
for (fan_num = 1; fan_num <= 2; fan_num++) {
int pwm;
set_pwm_fan(fan_num, 30);
pwm = get_pwm_fan(fan_num);
if (pwm < 0)
printf("PWM-Fan %d: %s\n", fan_num, strerror(-pwm));
else
printf("PWM-Fan %d: %d\n", fan_num, pwm);
}
}
next prev parent reply other threads:[~2004-08-06 8:04 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-05 11:43 [PATCH] ugly hack to make therm_pm72 work on XServe G5 Harald Welte
2004-08-06 8:04 ` Harald Welte [this message]
2004-08-06 8:09 ` Benjamin Herrenschmidt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040806080406.GB11638@sunbeam2 \
--to=laforge@gnumonks.org \
--cc=benh@kernel.crashing.org \
--cc=linuxppc-dev@lists.linuxppc.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).