Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 167267
b: refs/heads/master
c: 9e6eba6
h: refs/heads/master
i:
  167265: a17e754
  167263: eff3a43
v: v3
  • Loading branch information
Luca Tettamanti authored and Jean Delvare committed Oct 9, 2009
1 parent 3496ef6 commit 5739c3c
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 18e255558574c5663c9d72fe82c099d2115aee55
refs/heads/master: 9e6eba610c2eb68b05841a15ece1cf929c44aea3
185 changes: 184 additions & 1 deletion trunk/drivers/hwmon/asus_atk0110.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,22 @@
#define METHOD_OLD_ENUM_FAN "FSIF"

#define ATK_MUX_HWMON 0x00000006ULL
#define ATK_MUX_MGMT 0x00000011ULL

#define ATK_CLASS_MASK 0xff000000ULL
#define ATK_CLASS_FREQ_CTL 0x03000000ULL
#define ATK_CLASS_FAN_CTL 0x04000000ULL
#define ATK_CLASS_HWMON 0x06000000ULL
#define ATK_CLASS_MGMT 0x11000000ULL

#define ATK_TYPE_MASK 0x00ff0000ULL
#define HWMON_TYPE_VOLT 0x00020000ULL
#define HWMON_TYPE_TEMP 0x00030000ULL
#define HWMON_TYPE_FAN 0x00040000ULL

#define HWMON_SENSOR_ID_MASK 0x0000ffffULL
#define ATK_ELEMENT_ID_MASK 0x0000ffffULL

#define ATK_EC_ID 0x11060004ULL

enum atk_pack_member {
HWMON_PACK_FLAGS,
Expand Down Expand Up @@ -89,6 +93,9 @@ struct atk_data {
/* new inteface */
acpi_handle enumerate_handle;
acpi_handle read_handle;
acpi_handle write_handle;

bool disable_ec;

int voltage_count;
int temperature_count;
Expand Down Expand Up @@ -529,6 +536,43 @@ static union acpi_object *atk_gitm(struct atk_data *data, u64 id)
return obj;
}

static union acpi_object *atk_sitm(struct atk_data *data,
struct atk_acpi_input_buf *buf)
{
struct device *dev = &data->acpi_dev->dev;
struct acpi_object_list params;
union acpi_object tmp;
struct acpi_buffer ret;
union acpi_object *obj;
acpi_status status;

tmp.type = ACPI_TYPE_BUFFER;
tmp.buffer.pointer = (u8 *)buf;
tmp.buffer.length = sizeof(*buf);

params.count = 1;
params.pointer = &tmp;

ret.length = ACPI_ALLOCATE_BUFFER;
status = acpi_evaluate_object_typed(data->write_handle, NULL, &params,
&ret, ACPI_TYPE_BUFFER);
if (status != AE_OK) {
dev_warn(dev, "SITM[%#x] ACPI exception: %s\n", buf->id,
acpi_format_exception(status));
return ERR_PTR(-EIO);
}
obj = ret.pointer;

/* Sanity check */
if (obj->buffer.length < 8) {
dev_warn(dev, "Unexpected ASBF length: %u\n",
obj->buffer.length);
ACPI_FREE(obj);
return ERR_PTR(-EIO);
}
return obj;
}

static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
{
struct atk_data *data = sensor->data;
Expand Down Expand Up @@ -784,13 +828,135 @@ static int atk_enumerate_old_hwmon(struct atk_data *data)
return ret;
}

static int atk_ec_present(struct atk_data *data)
{
struct device *dev = &data->acpi_dev->dev;
union acpi_object *pack;
union acpi_object *ec;
int ret;
int i;

pack = atk_ggrp(data, ATK_MUX_MGMT);
if (IS_ERR(pack)) {
if (PTR_ERR(pack) == -ENOENT) {
/* The MGMT class does not exists - that's ok */
dev_dbg(dev, "Class %#llx not found\n", ATK_MUX_MGMT);
return 0;
}
return PTR_ERR(pack);
}

/* Search the EC */
ec = NULL;
for (i = 0; i < pack->package.count; i++) {
union acpi_object *obj = &pack->package.elements[i];
union acpi_object *id;

if (obj->type != ACPI_TYPE_PACKAGE)
continue;

id = &obj->package.elements[0];
if (id->type != ACPI_TYPE_INTEGER)
continue;

if (id->integer.value == ATK_EC_ID) {
ec = obj;
break;
}
}

ret = (ec != NULL);
if (!ret)
/* The system has no EC */
dev_dbg(dev, "EC not found\n");

ACPI_FREE(pack);
return ret;
}

static int atk_ec_enabled(struct atk_data *data)
{
struct device *dev = &data->acpi_dev->dev;
union acpi_object *obj;
struct atk_acpi_ret_buffer *buf;
int err;

obj = atk_gitm(data, ATK_EC_ID);
if (IS_ERR(obj)) {
dev_err(dev, "Unable to query EC status\n");
return PTR_ERR(obj);
}
buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;

if (buf->flags == 0) {
dev_err(dev, "Unable to query EC status\n");
err = -EIO;
} else {
err = (buf->value != 0);
dev_dbg(dev, "EC is %sabled\n",
err ? "en" : "dis");
}

ACPI_FREE(obj);
return err;
}

static int atk_ec_ctl(struct atk_data *data, int enable)
{
struct device *dev = &data->acpi_dev->dev;
union acpi_object *obj;
struct atk_acpi_input_buf sitm;
struct atk_acpi_ret_buffer *ec_ret;
int err = 0;

sitm.id = ATK_EC_ID;
sitm.param1 = enable;
sitm.param2 = 0;

obj = atk_sitm(data, &sitm);
if (IS_ERR(obj)) {
dev_err(dev, "Failed to %sable the EC\n",
enable ? "en" : "dis");
return PTR_ERR(obj);
}
ec_ret = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
if (ec_ret->flags == 0) {
dev_err(dev, "Failed to %sable the EC\n",
enable ? "en" : "dis");
err = -EIO;
} else {
dev_info(dev, "EC %sabled\n",
enable ? "en" : "dis");
}

ACPI_FREE(obj);
return err;
}

static int atk_enumerate_new_hwmon(struct atk_data *data)
{
struct device *dev = &data->acpi_dev->dev;
union acpi_object *pack;
int err;
int i;

err = atk_ec_present(data);
if (err < 0)
return err;
if (err) {
err = atk_ec_enabled(data);
if (err < 0)
return err;
/* If the EC was disabled we will disable it again on unload */
data->disable_ec = err;

err = atk_ec_ctl(data, 1);
if (err) {
data->disable_ec = false;
return err;
}
}

dev_dbg(dev, "Enumerating hwmon sensors\n");

pack = atk_ggrp(data, ATK_MUX_HWMON);
Expand Down Expand Up @@ -941,6 +1107,15 @@ static int atk_check_new_if(struct atk_data *data)
}
data->read_handle = ret;

/* De-multiplexer (write) */
status = acpi_get_handle(data->atk_handle, METHOD_WRITE, &ret);
if (status != AE_OK) {
dev_dbg(dev, "method " METHOD_READ " not found: %s\n",
acpi_format_exception(status));
return -ENODEV;
}
data->write_handle = ret;

return 0;
}

Expand All @@ -961,6 +1136,7 @@ static int atk_add(struct acpi_device *device)
data->acpi_dev = device;
data->atk_handle = device->handle;
INIT_LIST_HEAD(&data->sensor_list);
data->disable_ec = false;

buf.length = ACPI_ALLOCATE_BUFFER;
ret = acpi_evaluate_object_typed(data->atk_handle, BOARD_ID, NULL,
Expand Down Expand Up @@ -1019,6 +1195,8 @@ static int atk_add(struct acpi_device *device)
cleanup:
atk_free_sensors(data);
out:
if (data->disable_ec)
atk_ec_ctl(data, 0);
kfree(data);
return err;
}
Expand All @@ -1034,6 +1212,11 @@ static int atk_remove(struct acpi_device *device, int type)
atk_free_sensors(data);
hwmon_device_unregister(data->hwmon_dev);

if (data->disable_ec) {
if (atk_ec_ctl(data, 0))
dev_err(&device->dev, "Failed to disable EC\n");
}

kfree(data);

return 0;
Expand Down

0 comments on commit 5739c3c

Please sign in to comment.