Commit e605dc6c authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.5

into kroah.com:/home/greg/linux/BK/i2c-2.5
parents 75b08514 7481987d
......@@ -66,7 +66,8 @@ config SENSORS_W83781D
config I2C_SENSOR
tristate
depends on SENSORS_ADM1021 || SENSORS_LM75 || SENSORS_VIA686A || SENSORS_W83781D
default m
default y if SENSORS_ADM1021=y || SENSORS_LM75=y || SENSORS_VIA686A=y || SENSORS_W83781D=y
default m if SENSORS_ADM1021=m || SENSORS_LM75=m || SENSORS_VIA686A=m || SENSORS_W83781D=m
default n
endmenu
......@@ -87,9 +87,9 @@ static const u8 regover[] = { 0x39, 0x3d, 0x1d };
static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e };
/* temps numbered 1-3 */
#define VIA686A_REG_TEMP(nr) (regtemp[(nr) - 1])
#define VIA686A_REG_TEMP_OVER(nr) (regover[(nr) - 1])
#define VIA686A_REG_TEMP_HYST(nr) (reghyst[(nr) - 1])
#define VIA686A_REG_TEMP(nr) (regtemp[nr])
#define VIA686A_REG_TEMP_OVER(nr) (regover[nr])
#define VIA686A_REG_TEMP_HYST(nr) (reghyst[nr])
#define VIA686A_REG_TEMP_LOW1 0x4b // bits 7-6
#define VIA686A_REG_TEMP_LOW23 0x49 // 2 = bits 5-4, 3 = bits 7-6
......@@ -369,6 +369,8 @@ static inline long TEMP_FROM_REG10(u16 val)
dynamically allocated, at the same time when a new via686a client is
allocated. */
struct via686a_data {
int sysctl_id;
struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
......@@ -391,13 +393,258 @@ static int via686a_attach_adapter(struct i2c_adapter *adapter);
static int via686a_detect(struct i2c_adapter *adapter, int address, int kind);
static int via686a_detach_client(struct i2c_client *client);
static int via686a_read_value(struct i2c_client *client, u8 register);
static void via686a_write_value(struct i2c_client *client, u8 register,
u8 value);
static inline int via686a_read_value(struct i2c_client *client, u8 reg)
{
return (inb_p(client->addr + reg));
}
static inline void via686a_write_value(struct i2c_client *client, u8 reg,
u8 value)
{
outb_p(value, client->addr + reg);
}
static void via686a_update_client(struct i2c_client *client);
static void via686a_init_client(struct i2c_client *client);
static int via686a_id = 0;
/* following are the sysfs callback functions */
/* 7 voltage sensors */
static ssize_t show_in(struct device *dev, char *buf, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)*10 );
}
static ssize_t show_in_min(struct device *dev, char *buf, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)*10 );
}
static ssize_t show_in_max(struct device *dev, char *buf, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)*10 );
}
static ssize_t set_in_min(struct device *dev, const char *buf,
size_t count, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10)/10;
data->in_min[nr] = IN_TO_REG(val,nr);
via686a_write_value(client, VIA686A_REG_IN_MIN(nr),
data->in_min[nr]);
return count;
}
static ssize_t set_in_max(struct device *dev, const char *buf,
size_t count, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10)/10;
data->in_max[nr] = IN_TO_REG(val,nr);
via686a_write_value(client, VIA686A_REG_IN_MAX(nr),
data->in_max[nr]);
return count;
}
#define show_in_offset(offset) \
static ssize_t \
show_in##offset (struct device *dev, char *buf) \
{ \
return show_in(dev, buf, 0x##offset); \
} \
static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \
{ \
return show_in_min(dev, buf, 0x##offset); \
} \
static ssize_t \
show_in##offset##_max (struct device *dev, char *buf) \
{ \
return show_in_max(dev, buf, 0x##offset); \
} \
static ssize_t set_in##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
return set_in_min(dev, buf, count, 0x##offset); \
} \
static ssize_t set_in##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
return set_in_max(dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(in_input##offset, S_IRUGO, show_in##offset, NULL) \
static DEVICE_ATTR(in_min##offset, S_IRUGO | S_IWUSR, \
show_in##offset##_min, set_in##offset##_min) \
static DEVICE_ATTR(in_max##offset, S_IRUGO | S_IWUSR, \
show_in##offset##_max, set_in##offset##_max)
show_in_offset(0);
show_in_offset(1);
show_in_offset(2);
show_in_offset(3);
show_in_offset(4);
/* 3 temperatures */
static ssize_t show_temp(struct device *dev, char *buf, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])*10 );
}
/* more like overshoot temperature */
static ssize_t show_temp_max(struct device *dev, char *buf, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])*10);
}
/* more like hysteresis temperature */
static ssize_t show_temp_min(struct device *dev, char *buf, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])*10);
}
static ssize_t set_temp_max(struct device *dev, const char *buf,
size_t count, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10)/10;
data->temp_over[nr] = TEMP_TO_REG(val);
via686a_write_value(client, VIA686A_REG_TEMP_OVER(nr), data->temp_over[nr]);
return count;
}
static ssize_t set_temp_min(struct device *dev, const char *buf,
size_t count, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10)/10;
data->temp_hyst[nr] = TEMP_TO_REG(val);
via686a_write_value(client, VIA686A_REG_TEMP_HYST(nr), data->temp_hyst[nr]);
return count;
}
#define show_temp_offset(offset) \
static ssize_t show_temp_##offset (struct device *dev, char *buf) \
{ \
return show_temp(dev, buf, 0x##offset - 1); \
} \
static ssize_t \
show_temp_##offset##_max (struct device *dev, char *buf) \
{ \
return show_temp_max(dev, buf, 0x##offset - 1); \
} \
static ssize_t \
show_temp_##offset##_min (struct device *dev, char *buf) \
{ \
return show_temp_min(dev, buf, 0x##offset - 1); \
} \
static ssize_t set_temp_##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
return set_temp_max(dev, buf, count, 0x##offset - 1); \
} \
static ssize_t set_temp_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
return set_temp_min(dev, buf, count, 0x##offset - 1); \
} \
static DEVICE_ATTR(temp_input##offset, S_IRUGO, show_temp_##offset, NULL) \
static DEVICE_ATTR(temp_max##offset, S_IRUGO | S_IWUSR, \
show_temp_##offset##_max, set_temp_##offset##_max) \
static DEVICE_ATTR(temp_min##offset, S_IRUGO | S_IWUSR, \
show_temp_##offset##_min, set_temp_##offset##_min)
show_temp_offset(1);
show_temp_offset(2);
show_temp_offset(3);
/* 2 Fans */
static ssize_t show_fan(struct device *dev, char *buf, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr],
DIV_FROM_REG(data->fan_div[nr])) );
}
static ssize_t show_fan_min(struct device *dev, char *buf, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf,"%d\n",
FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
}
static ssize_t show_fan_div(struct device *dev, char *buf, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf,"%d\n", DIV_FROM_REG(data->fan_div[nr]) );
}
static ssize_t set_fan_min(struct device *dev, const char *buf,
size_t count, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
via686a_write_value(client, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]);
return count;
}
static ssize_t set_fan_div(struct device *dev, const char *buf,
size_t count, int nr) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
int old = via686a_read_value(client, VIA686A_REG_FANDIV);
data->fan_div[nr] = DIV_TO_REG(val);
old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
via686a_write_value(client, VIA686A_REG_FANDIV, old);
return count;
}
#define show_fan_offset(offset) \
static ssize_t show_fan_##offset (struct device *dev, char *buf) \
{ \
return show_fan(dev, buf, 0x##offset - 1); \
} \
static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
{ \
return show_fan_min(dev, buf, 0x##offset - 1); \
} \
static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
{ \
return show_fan_div(dev, buf, 0x##offset - 1); \
} \
static ssize_t set_fan_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
return set_fan_min(dev, buf, count, 0x##offset - 1); \
} \
static ssize_t set_fan_##offset##_div (struct device *dev, \
const char *buf, size_t count) \
{ \
return set_fan_div(dev, buf, count, 0x##offset - 1); \
} \
static DEVICE_ATTR(fan_input##offset, S_IRUGO, show_fan_##offset, NULL) \
static DEVICE_ATTR(fan_min##offset, S_IRUGO | S_IWUSR, \
show_fan_##offset##_min, set_fan_##offset##_min) \
static DEVICE_ATTR(fan_div##offset, S_IRUGO | S_IWUSR, \
show_fan_##offset##_div, set_fan_##offset##_div)
show_fan_offset(1);
show_fan_offset(2);
/* Alarm */
static ssize_t show_alarm(struct device *dev, char *buf) {
struct i2c_client *client = to_i2c_client(dev);
struct via686a_data *data = i2c_get_clientdata(client);
via686a_update_client(client);
return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms));
}
static DEVICE_ATTR(alarm, S_IRUGO | S_IWUSR, show_alarm, NULL);
/* The driver. I choose to use type i2c_driver, as at is identical to both
smbus_driver and isa_driver, and clients could be of either kind */
......@@ -411,83 +658,6 @@ static struct i2c_driver via686a_driver = {
};
/* The /proc/sys entries */
/* -- SENSORS SYSCTL START -- */
#define VIA686A_SYSCTL_IN0 1000
#define VIA686A_SYSCTL_IN1 1001
#define VIA686A_SYSCTL_IN2 1002
#define VIA686A_SYSCTL_IN3 1003
#define VIA686A_SYSCTL_IN4 1004
#define VIA686A_SYSCTL_FAN1 1101
#define VIA686A_SYSCTL_FAN2 1102
#define VIA686A_SYSCTL_TEMP 1200
#define VIA686A_SYSCTL_TEMP2 1201
#define VIA686A_SYSCTL_TEMP3 1202
#define VIA686A_SYSCTL_FAN_DIV 2000
#define VIA686A_SYSCTL_ALARMS 2001
#define VIA686A_ALARM_IN0 0x01
#define VIA686A_ALARM_IN1 0x02
#define VIA686A_ALARM_IN2 0x04
#define VIA686A_ALARM_IN3 0x08
#define VIA686A_ALARM_TEMP 0x10
#define VIA686A_ALARM_FAN1 0x40
#define VIA686A_ALARM_FAN2 0x80
#define VIA686A_ALARM_IN4 0x100
#define VIA686A_ALARM_TEMP2 0x800
#define VIA686A_ALARM_CHAS 0x1000
#define VIA686A_ALARM_TEMP3 0x8000
/* -- SENSORS SYSCTL END -- */
#if 0
/* These files are created for each detected VIA686A. This is just a template;
though at first sight, you might think we could use a statically
allocated list, we need some way to get back to the parent - which
is done through one of the 'extra' fields which are initialized
when a new copy is allocated. */
static ctl_table via686a_dir_table_template[] = {
{VIA686A_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &via686a_in},
{VIA686A_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &via686a_in},
{VIA686A_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &via686a_in},
{VIA686A_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &via686a_in},
{VIA686A_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &via686a_in},
{VIA686A_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &via686a_fan},
{VIA686A_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &via686a_fan},
{VIA686A_SYSCTL_TEMP, "temp1", NULL, 0, 0644, NULL, &i2c_proc_real,
&i2c_sysctl_real, NULL, &via686a_temp},
{VIA686A_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_temp},
{VIA686A_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_temp},
{VIA686A_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_fan_div},
{VIA686A_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL,
&i2c_proc_real, &i2c_sysctl_real, NULL, &via686a_alarms},
{0}
};
#endif
static inline int via686a_read_value(struct i2c_client *client, u8 reg)
{
return (inb_p(client->addr + reg));
}
static inline void via686a_write_value(struct i2c_client *client, u8 reg,
u8 value)
{
outb_p(value, client->addr + reg);
}
/* This is called when the module is loaded */
static int via686a_attach_adapter(struct i2c_adapter *adapter)
{
......@@ -499,7 +669,7 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
struct i2c_client *new_client;
struct via686a_data *data;
int err = 0;
const char *name = "via686a";
const char client_name[] = "via686a chip";
u16 val;
/* Make sure we are probing the ISA bus!! */
......@@ -552,17 +722,50 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
new_client->adapter = adapter;
new_client->driver = &via686a_driver;
new_client->flags = 0;
new_client->dev.parent = &adapter->dev;
/* Fill in the remaining client fields and put into the global list */
snprintf(new_client->dev.name, DEVICE_NAME_SIZE, name);
snprintf(new_client->dev.name, DEVICE_NAME_SIZE, client_name);
new_client->id = via686a_id++;
data->valid = 0;
init_MUTEX(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto ERROR3;
/* register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_in_input0);
device_create_file(&new_client->dev, &dev_attr_in_input1);
device_create_file(&new_client->dev, &dev_attr_in_input2);
device_create_file(&new_client->dev, &dev_attr_in_input3);
device_create_file(&new_client->dev, &dev_attr_in_input4);
device_create_file(&new_client->dev, &dev_attr_in_min0);
device_create_file(&new_client->dev, &dev_attr_in_min1);
device_create_file(&new_client->dev, &dev_attr_in_min2);
device_create_file(&new_client->dev, &dev_attr_in_min3);
device_create_file(&new_client->dev, &dev_attr_in_min4);
device_create_file(&new_client->dev, &dev_attr_in_max0);
device_create_file(&new_client->dev, &dev_attr_in_max1);
device_create_file(&new_client->dev, &dev_attr_in_max2);
device_create_file(&new_client->dev, &dev_attr_in_max3);
device_create_file(&new_client->dev, &dev_attr_in_max4);
device_create_file(&new_client->dev, &dev_attr_temp_input1);
device_create_file(&new_client->dev, &dev_attr_temp_input2);
device_create_file(&new_client->dev, &dev_attr_temp_input3);
device_create_file(&new_client->dev, &dev_attr_temp_max1);
device_create_file(&new_client->dev, &dev_attr_temp_max2);
device_create_file(&new_client->dev, &dev_attr_temp_max3);
device_create_file(&new_client->dev, &dev_attr_temp_min1);
device_create_file(&new_client->dev, &dev_attr_temp_min2);
device_create_file(&new_client->dev, &dev_attr_temp_min3);
device_create_file(&new_client->dev, &dev_attr_fan_input1);
device_create_file(&new_client->dev, &dev_attr_fan_input2);
device_create_file(&new_client->dev, &dev_attr_fan_min1);
device_create_file(&new_client->dev, &dev_attr_fan_min2);
device_create_file(&new_client->dev, &dev_attr_fan_div1);
device_create_file(&new_client->dev, &dev_attr_fan_div2);
device_create_file(&new_client->dev, &dev_attr_alarm);
/* Initialize the VIA686A chip */
via686a_init_client(new_client);
return 0;
......@@ -629,7 +832,7 @@ static void via686a_init_client(struct i2c_client *client)
FAN_TO_REG(VIA686A_INIT_FAN_MIN, 2));
via686a_write_value(client, VIA686A_REG_FAN_MIN(2),
FAN_TO_REG(VIA686A_INIT_FAN_MIN, 2));
for (i = 1; i <= 3; i++) {
for (i = 0; i <= 2; i++) {
via686a_write_value(client, VIA686A_REG_TEMP_OVER(i),
TEMP_TO_REG(VIA686A_INIT_TEMP_OVER));
via686a_write_value(client, VIA686A_REG_TEMP_HYST(i),
......@@ -670,13 +873,13 @@ static void via686a_update_client(struct i2c_client *client)
data->fan_min[i - 1] = via686a_read_value(client,
VIA686A_REG_FAN_MIN(i));
}
for (i = 1; i <= 3; i++) {
data->temp[i - 1] = via686a_read_value(client,
for (i = 0; i <= 2; i++) {
data->temp[i] = via686a_read_value(client,
VIA686A_REG_TEMP(i)) << 2;
data->temp_over[i - 1] =
data->temp_over[i] =
via686a_read_value(client,
VIA686A_REG_TEMP_OVER(i));
data->temp_hyst[i - 1] =
data->temp_hyst[i] =
via686a_read_value(client,
VIA686A_REG_TEMP_HYST(i));
}
......@@ -709,164 +912,12 @@ static void via686a_update_client(struct i2c_client *client)
up(&data->update_lock);
}
/* The next few functions are the call-back functions of the /proc/sys and
sysctl files. Which function is used is defined in the ctl_table in
the extra1 field.
Each function must return the magnitude (power of 10 to divide the date
with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
put a maximum of *nrels elements in results reflecting the data of this
file, and set *nrels to the number it actually put in it, if operation==
SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
large enough (by checking the incoming value of *nrels). This is not very
good practice, but as long as you put less than about 5 values in results,
you can assume it is large enough. */
/* FIXME, remove these functions, they are here to verify the sysfs conversion
* is correct, or not */
__attribute__((unused))
static void via686a_in(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct via686a_data *data = i2c_get_clientdata(client);
int nr = ctl_name - VIA686A_SYSCTL_IN0;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 2;
else if (operation == SENSORS_PROC_REAL_READ) {
via686a_update_client(client);
results[0] = IN_FROM_REG(data->in_min[nr], nr);
results[1] = IN_FROM_REG(data->in_max[nr], nr);
results[2] = IN_FROM_REG(data->in[nr], nr);
*nrels_mag = 3;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1) {
data->in_min[nr] = IN_TO_REG(results[0], nr);
via686a_write_value(client, VIA686A_REG_IN_MIN(nr),
data->in_min[nr]);
}
if (*nrels_mag >= 2) {
data->in_max[nr] = IN_TO_REG(results[1], nr);
via686a_write_value(client, VIA686A_REG_IN_MAX(nr),
data->in_max[nr]);
}
}
}
__attribute__((unused))
static void via686a_fan(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct via686a_data *data = i2c_get_clientdata(client);
int nr = ctl_name - VIA686A_SYSCTL_FAN1 + 1;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
via686a_update_client(client);
results[0] = FAN_FROM_REG(data->fan_min[nr - 1],
DIV_FROM_REG(data->fan_div
[nr - 1]));
results[1] = FAN_FROM_REG(data->fan[nr - 1],
DIV_FROM_REG(data->fan_div[nr - 1]));
*nrels_mag = 2;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1) {
data->fan_min[nr - 1] = FAN_TO_REG(results[0],
DIV_FROM_REG(data->
fan_div[nr -1]));
via686a_write_value(client,
VIA686A_REG_FAN_MIN(nr),
data->fan_min[nr - 1]);
}
}
}
__attribute__((unused))
static void via686a_temp(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct via686a_data *data = i2c_get_clientdata(client);
int nr = ctl_name - VIA686A_SYSCTL_TEMP;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 1;
else if (operation == SENSORS_PROC_REAL_READ) {
via686a_update_client(client);
results[0] = TEMP_FROM_REG(data->temp_over[nr]);
results[1] = TEMP_FROM_REG(data->temp_hyst[nr]);
results[2] = TEMP_FROM_REG10(data->temp[nr]);
*nrels_mag = 3;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1) {
data->temp_over[nr] = TEMP_TO_REG(results[0]);
via686a_write_value(client,
VIA686A_REG_TEMP_OVER(nr + 1),
data->temp_over[nr]);
}
if (*nrels_mag >= 2) {
data->temp_hyst[nr] = TEMP_TO_REG(results[1]);
via686a_write_value(client,
VIA686A_REG_TEMP_HYST(nr + 1),
data->temp_hyst[nr]);
}
}
}
__attribute__((unused))
static void via686a_alarms(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct via686a_data *data = i2c_get_clientdata(client);
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
via686a_update_client(client);
results[0] = ALARMS_FROM_REG(data->alarms);
*nrels_mag = 1;
}
}
__attribute__((unused))
static void via686a_fan_div(struct i2c_client *client, int operation,
int ctl_name, int *nrels_mag, long *results)
{
struct via686a_data *data = i2c_get_clientdata(client);
int old;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
via686a_update_client(client);
results[0] = DIV_FROM_REG(data->fan_div[0]);
results[1] = DIV_FROM_REG(data->fan_div[1]);
*nrels_mag = 2;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
old = via686a_read_value(client, VIA686A_REG_FANDIV);
if (*nrels_mag >= 2) {
data->fan_div[1] = DIV_TO_REG(results[1]);
old = (old & 0x3f) | (data->fan_div[1] << 6);
}
if (*nrels_mag >= 1) {
data->fan_div[0] = DIV_TO_REG(results[0]);
old = (old & 0xcf) | (data->fan_div[0] << 4);
via686a_write_value(client, VIA686A_REG_FANDIV,
old);
}
}
}
static struct pci_device_id via686a_pci_ids[] __devinitdata = {
{
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_82C686_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.class = 0,
.class_mask = 0,
.driver_data = 0,
},
{ 0, }
};
......
......@@ -364,7 +364,7 @@ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
\
w83781d_update_client(client); \
\
return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr])); \
return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr] * 10)); \
}
show_in_reg(in);
show_in_reg(in_min);
......@@ -378,7 +378,7 @@ static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count
u32 val; \
\
val = simple_strtoul(buf, NULL, 10); \
data->in_##reg[nr] = IN_TO_REG(val); \
data->in_##reg[nr] = (IN_TO_REG(val) / 10); \
w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
\
return count; \
......@@ -712,7 +712,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct w83781d_data *data = i2c_get_clientdata(client);
u32 val, old, old2, old3;
u32 val, old, old2, old3 = 0;
val = simple_strtoul(buf, NULL, 10);
old = w83781d_read_value(client, W83781D_REG_VID_FANDIV);
......
......@@ -196,9 +196,11 @@ static struct i2c_algo_iic_data iic_ite_data = {
static struct i2c_adapter iic_ite_ops = {
.owner = THIS_MODULE,
.name = "ITE IIC adapter",
.id = I2C_HW_I_IIC,
.algo_data = &iic_ite_data,
.dev = {
.name = "ITE IIC adapter",
},
};
/* Called when the module is loaded. This function starts the
......
......@@ -77,7 +77,7 @@ static struct i2c_adapter *i2cdev_adaps[I2CDEV_ADAPS_MAX];
static struct i2c_driver i2cdev_driver = {
.owner = THIS_MODULE,
.name = "i2c-dev dummy driver",
.name = "dev driver",
.id = I2C_DRIVERID_I2CDEV,
.flags = I2C_DF_DUMMY,
.attach_adapter = i2cdev_attach_adapter,
......@@ -100,10 +100,6 @@ static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
char *tmp;
int ret;
#ifdef DEBUG
struct inode *inode = file->f_dentry->d_inode;
#endif /* DEBUG */
struct i2c_client *client = (struct i2c_client *)file->private_data;
if (count > 8192)
......@@ -114,10 +110,8 @@ static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
if (tmp==NULL)
return -ENOMEM;
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: i2c-%d reading %d bytes.\n",minor(inode->i_rdev),
count);
#endif
pr_debug("i2c-dev.o: i2c-%d reading %d bytes.\n",
minor(file->f_dentry->d_inode->i_rdev), count);
ret = i2c_master_recv(client,tmp,count);
if (ret >= 0)
......@@ -133,10 +127,6 @@ static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
char *tmp;
struct i2c_client *client = (struct i2c_client *)file->private_data;
#ifdef DEBUG
struct inode *inode = file->f_dentry->d_inode;
#endif /* DEBUG */
if (count > 8192)
count = 8192;
......@@ -149,10 +139,9 @@ static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
return -EFAULT;
}
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: i2c-%d writing %d bytes.\n",minor(inode->i_rdev),
count);
#endif
pr_debug("i2c-dev.o: i2c-%d writing %d bytes.\n",
minor(file->f_dentry->d_inode->i_rdev), count);
ret = i2c_master_send(client,tmp,count);
kfree(tmp);
return ret;
......@@ -169,10 +158,8 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
int i,datasize,res;
unsigned long funcs;
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
pr_debug("i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
minor(inode->i_rdev),cmd, arg);
#endif /* DEBUG */
switch ( cmd ) {
case I2C_SLAVE:
......@@ -207,6 +194,11 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
sizeof(rdwr_arg)))
return -EFAULT;
/* Put an arbritrary limit on the number of messages that can
* be sent at once */
if (rdwr_arg.nmsgs > 42)
return -EINVAL;
rdwr_pa = (struct i2c_msg *)
kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
GFP_KERNEL);
......@@ -214,38 +206,43 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
if (rdwr_pa == NULL) return -ENOMEM;
res = 0;
for( i=0; i<rdwr_arg.nmsgs; i++ )
{
for( i=0; i<rdwr_arg.nmsgs; i++ ) {
if(copy_from_user(&(rdwr_pa[i]),
&(rdwr_arg.msgs[i]),
sizeof(rdwr_pa[i])))
{
sizeof(rdwr_pa[i]))) {
res = -EFAULT;
break;
}
/* Limit the size of the message to a sane amount */
if (rdwr_pa[i].len > 8192) {
res = -EINVAL;
break;
}
rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
if(rdwr_pa[i].buf == NULL)
{
if(rdwr_pa[i].buf == NULL) {
res = -ENOMEM;
break;
}
if(copy_from_user(rdwr_pa[i].buf,
rdwr_arg.msgs[i].buf,
rdwr_pa[i].len))
{
kfree(rdwr_pa[i].buf);
rdwr_pa[i].len)) {
res = -EFAULT;
break;
}
}
if (!res)
{
if (res < 0) {
int j;
for (j = 0; j < i; ++j)
kfree(rdwr_pa[j].buf);
kfree(rdwr_pa);
return res;
}
if (!res) {
res = i2c_transfer(client->adapter,
rdwr_pa,
rdwr_arg.nmsgs);
}
while(i-- > 0)
{
while(i-- > 0) {
if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD))
{
if(copy_to_user(
......@@ -274,20 +271,18 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
(data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
(data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
(data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n",
dev_dbg(&client->dev,
"size out of range (%x) in ioctl I2C_SMBUS.\n",
data_arg.size);
#endif
return -EINVAL;
}
/* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
so the check is valid if size==I2C_SMBUS_QUICK too. */
if ((data_arg.read_write != I2C_SMBUS_READ) &&
(data_arg.read_write != I2C_SMBUS_WRITE)) {
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n",
dev_dbg(&client->dev,
"read_write out of range (%x) in ioctl I2C_SMBUS.\n",
data_arg.read_write);
#endif
return -EINVAL;
}
......@@ -304,9 +299,8 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
data_arg.size, NULL);
if (data_arg.data == NULL) {
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n");
#endif
dev_dbg(&client->dev,
"data is NULL pointer in ioctl I2C_SMBUS.\n");
return -EINVAL;
}
......@@ -365,7 +359,7 @@ static int i2cdev_open(struct inode *inode, struct file *file)
return 0;
out_kfree:
out_kfree:
kfree(client);
return -ENODEV;
}
......@@ -428,7 +422,8 @@ int __init i2c_dev_init(void)
{
int res;
printk(KERN_INFO "i2c-dev.o: i2c /dev entries driver module version %s (%s)\n", I2C_VERSION, I2C_DATE);
printk(KERN_INFO "i2c /dev entries driver module version %s (%s)\n",
I2C_VERSION, I2C_DATE);
if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) {
printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n",
......
......@@ -59,9 +59,11 @@ static struct i2c_algo_bit_data bit_frodo_data = {
static struct i2c_adapter frodo_ops = {
.owner = THIS_MODULE,
.name = "Frodo adapter driver",
.id = I2C_HW_B_FRODO,
.algo_data = &bit_frodo_data,
.dev = {
.name = "Frodo adapter driver",
},
};
static int __init i2c_frodo_init (void)
......
......@@ -82,9 +82,11 @@ static struct i2c_algo_bit_data scx200_i2c_data = {
static struct i2c_adapter scx200_i2c_ops = {
.owner = THIS_MODULE,
.name = "NatSemi SCx200 I2C",
.id = I2C_HW_B_VELLE,
.algo_data = &scx200_i2c_data,
.dev = {
.name = "NatSemi SCx200 I2C",
},
};
int scx200_i2c_init(void)
......@@ -110,7 +112,7 @@ int scx200_i2c_init(void)
if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
printk(KERN_ERR NAME ": adapter %s registration failed\n",
scx200_i2c_ops.name);
scx200_i2c_ops.dev.name);
return -ENODEV;
}
......
......@@ -31,16 +31,16 @@
/* This is the structure as used in the I2C_SMBUS ioctl call */
struct i2c_smbus_ioctl_data {
char read_write;
__u8 read_write;
__u8 command;
int size;
__u32 size;
union i2c_smbus_data *data;
};
/* This is the structure as used in the I2C_RDWR ioctl call */
struct i2c_rdwr_ioctl_data {
struct i2c_msg *msgs; /* pointers to i2c_msgs */
int nmsgs; /* number of i2c_msgs */
__u32 nmsgs; /* number of i2c_msgs */
};
#endif /* _LINUX_I2C_DEV_H */
......@@ -182,6 +182,13 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data)
return dev_set_drvdata (&dev->dev, data);
}
#define I2C_DEVNAME(str) .dev = { .name = str }
static inline char *i2c_clientname(struct i2c_client *c)
{
return c->dev.name;
}
/*
* The following structs are for those who like to implement new bus drivers:
* i2c_algorithm is the interface to a class of hardware solutions which can
......@@ -360,15 +367,15 @@ extern int i2c_check_functionality (struct i2c_adapter *adap, u32 func);
*/
struct i2c_msg {
__u16 addr; /* slave address */
unsigned short flags;
__u16 flags;
#define I2C_M_TEN 0x10 /* we have a ten bit chip address */
#define I2C_M_RD 0x01
#define I2C_M_NOSTART 0x4000
#define I2C_M_REV_DIR_ADDR 0x2000
#define I2C_M_IGNORE_NAK 0x1000
#define I2C_M_NO_RD_ACK 0x0800
short len; /* msg length */
char *buf; /* pointer to msg data */
__u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */
};
/* To determine what functionality is present */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment