Subject: [PATCH] [acpi ec] Add interface for reading from device - Add acpi_ec_read() for reading from EC device - Add common __read() that does the same low-level access no matter whether we're using the interrupt or polling method (depends on ->e_wait() method) - Note that this uses ->e_sem for both access methods - Add ec_read() function that is exported to other users (to be compatible) Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/ec/Makefile | 2 - drivers/acpi/drivers/ec/read.c | 83 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletions(-) create mode 100644 drivers/acpi/drivers/ec/read.c applies-to: 6bf691e3603a4db64df31fffb2c8f08d60ce36ee dc17eabe4e5d91f5e3e55f88bd7eff34f0c4c0ef diff --git a/drivers/acpi/drivers/ec/Makefile b/drivers/acpi/drivers/ec/Makefile index c2ee992..26f3b7b 100644 --- a/drivers/acpi/drivers/ec/Makefile +++ b/drivers/acpi/drivers/ec/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_ACPI_EC) += ec.o ec-y := driver.o device.o event.o poll.o intr.o ec-y += setup.o -ec-y += resource.o gpe.o +ec-y += resource.o gpe.o read.o ec-$(CONFIG_ACPI_DM_PROC) += proc.o ec-$(CONFIG_ACPI_DM_SYSFS) += sysfs.o diff --git a/drivers/acpi/drivers/ec/read.c b/drivers/acpi/drivers/ec/read.c new file mode 100644 index 0000000..afda8a5 --- /dev/null +++ b/drivers/acpi/drivers/ec/read.c @@ -0,0 +1,83 @@ +/*** + * drivers/acpi/drivers/ec/intr.c - Interrupt-driven EC driver + * + * Copyright (C) 2006 Patrick Mochel + * + * Based on drivers/acpi/ec.c, which was + * + * Copyright (C) 2004 Luming Yu + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * This file is released under the GPLv2. + */ + +#include "ec.h" + + +static int __read(struct acpi_ec * ec, u8 addr, u32 * data) +{ + int ret; + + ret = ec->e_wait(ec, ACPI_EC_EVENT_IBE); + if (ret) { + dbg("EC Read, IB not empty"); + return ret; + } + + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->e_command); + ret = ec->e_wait(ec, ACPI_EC_EVENT_IBE); + if (ret) + dbg("EC Read, IB not empty"); + + acpi_hw_low_level_write(8, addr, &ec->e_data); + ret = ec->e_wait(ec, ACPI_EC_EVENT_OBF); + if (ret) { + dbg("EC Read, OB not full"); + return ret; + } + acpi_hw_low_level_read(8, data, &ec->e_data); + dbg("Read [%#02x] from address [%#02x]", *data, address); + return 0; +} + + +int acpi_ec_read(struct acpi_ec * ec, u8 addr, u32 * data) +{ + acpi_status status; + u32 glk; + int ret; + + if (ec->e_global_lock) { + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) + return -ENODEV; + } + + down(&ec->e_sem); + ret = __read(ec, addr, data); + up(&ec->e_sem); + + if (ec->e_global_lock) + acpi_release_global_lock(glk); + return ret; +} + +/* + * Externally callable EC access functions. For now, assume 1 EC only + */ +int ec_read(u8 addr, u8 * val) +{ + int ret; + u32 data; + + if (!first_ec) + return -ENODEV; + + ret = acpi_ec_read(first_ec, addr, &data); + if (!ret) + *val = data; + return ret; +} + +EXPORT_SYMBOL(ec_read); --- 0.99.9.GIT