public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: Hiroshi Miura <miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
To: David Bronaugh
	<dbronaugh-Jp3n8lUXroSX6QiC4yPwbg@public.gmane.org>,
	acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: letsnote-tech-eXqGM+LsbTTAqL8d+zIrHngSJqDPrsil@public.gmane.org,
	Hiroshi Miura <miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>,
	Ryuta NAKANISHI <ryuta-rkWIgeFJRjg@public.gmane.org>
Subject: [PATCH]Panasonic Hotkey Driver v0.7
Date: Wed, 15 Sep 2004 09:42:00 +0900	[thread overview]
Message-ID: <878ybc8isn.wl%miura@da-cha.org> (raw)
In-Reply-To: <87pt5e5lu3.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1694 bytes --]

Hi, 

I'm update panasonic hotkey driver to follow the discussion about
common hotkey driver.
I correct a driver name of acpi event message from 'HKEY' to 'pcc'.
now it generate event like 'pcc HKEY 00000080 00000001'.

I also update it to enlarge mentainanceability.
I use seq_file in-kernel functions to implement proc interface as same as 
standard methods (button/ec/ac/battery).

I'm also fix bugs and update hotkey-handler originally written by David Bronaugh.
On my debian platform, original hotkey-handler don't work because of message from 
acpid is quoted by '"'. It makes bios version check and select proper method to
'mute'. It also detect swsusp version whether vanilla one, Nigel's swsusp2(before ver 2.0.0.103)
or Nigel's swsusp2(after ver 2.0.0.104).

Patch generated by bkexport and new version of hotkey-handler is attatched.
It is against v0.6.4.

You can download whole and incremental patches from http://www.da-cha.org/letsnote/


future plan: 
1. generate both keyboard input and acpid event as configurable.
  Pavel>If those are keys, you should just treat them as keys... 
  Pavel>That is hook it into input subsystem.

  This is already implemented in yet another panasonic hotkey driver
  written by Ryuta Nakanishi. I want to merge his code.

2. gui. It may be made by other volunteers.

-- 
Hiroshi Miura  --- http://www.da-cha.org/  --- miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org
NTTDATA Corp. OpenSource Software Center. --- miurahr-3MafRgGXt7BL9jVzuh4AOg@public.gmane.org 
NTTDATA Intellilink Corp. OpenSource Engineering Dev. -- miurahr-w0OK63jvRlAuJ+9fw/WgBHgSJqDPrsil@public.gmane.org
Key fingerprint = 9117 9407 5684 FBF1 4063  15B4 401D D077 04AB 8617


[-- Attachment #2: pcc-acpi-0.7.patch --]
[-- Type: application/octet-stream, Size: 25528 bytes --]

#### AUTHOR miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org
#### COMMENT START
### Comments for ChangeSet
[ACPI] pcc_acpi: rewrite pcc_acpi driver proc functions.
  change event driver name from HKEY to pcc.
### Comments for drivers/acpi/pcc_acpi.c
Change proc interface functions and relative functions using seq_file 
facisity as same as other acpi drivers.
Change hotkey event message as  'pcc HKEY 0000080 00000001'
These changes are to prepare share code.
#### COMMENT END

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/09/14 02:20:14+09:00 miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org 
#   [ACPI] pcc_acpi: rewrite pcc_acpi driver proc functions.
#     change event driver name from HKEY to pcc.
# 
# drivers/acpi/pcc_acpi.c
#   2004/09/14 02:19:55+09:00 miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org +299 -182
#   Change proc interface functions and relative functions using seq_file 
#   facisity as same as other acpi drivers.
#   Change hotkey event message as  'pcc HKEY 0000080 00000001'
#   These changes are to prepare share code.
# 
diff -Nru a/drivers/acpi/pcc_acpi.c b/drivers/acpi/pcc_acpi.c
--- a/drivers/acpi/pcc_acpi.c	2004-09-14 02:21:10 +09:00
+++ b/drivers/acpi/pcc_acpi.c	2004-09-14 02:21:10 +09:00
@@ -21,6 +21,10 @@
  *---------------------------------------------------------------------------
  *
  * ChangeLog:
+ *	Sep.10, 2004	Hiroshi Miura <miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
+ *		-v0.7	Change proc interface functions using seq_file
+ *			fasility as same as other ACPI drivers.
+ *
  *	Aug.28, 2004	Hiroshi Miura <miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
  *		-v0.6.4 Fix a silly error with status checking
  *
@@ -62,15 +66,16 @@
  *
  */
 
-#define ACPI_PCC_VERSION	"0.6.3"
+#define ACPI_PCC_VERSION	"0.7"
 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
+#include <linux/ctype.h>
+#include <linux/seq_file.h>
 #include <asm/uaccess.h>
-
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -103,9 +108,9 @@
  *******************************************************************/
 #define PROC_PCC		"pcc"
 
-#define ACPI_PCC_DRIVER_NAME "PCC HotKey Driver"
-#define ACPI_HOTKEY_DEVICE_NAME "HotKey"
-#define ACPI_HOTKEY_CLASS "HKEY"
+#define ACPI_PCC_DRIVER_NAME "PCC Extra Driver"
+#define ACPI_PCC_DEVICE_NAME "PCCExtra"
+#define ACPI_PCC_CLASS "pcc"
 
 /* LCD_TYPEs: 0 = Normal, 1 = Semi-transparent
    ENV_STATEs: Normal temp=0x01, High temp=0x81, N/A=0x00 
@@ -119,9 +124,9 @@
 static int acpi_pcc_hotkey_add (struct acpi_device *device);
 static int acpi_pcc_hotkey_remove (struct acpi_device *device, int type);
 
-static struct acpi_driver acpi_hotkey_driver = {
+static struct acpi_driver acpi_pcc_driver = {
 	.name =		ACPI_PCC_DRIVER_NAME,
-	.class =	ACPI_HOTKEY_CLASS,
+	.class =	ACPI_PCC_CLASS,
 	.ids =		HKEY_HID,
 	.ops =		{
 				.add =		acpi_pcc_hotkey_add,
@@ -132,78 +137,97 @@
 struct acpi_hotkey {
 	acpi_handle		handle;
 	struct acpi_device	*device;
+	struct proc_dir_entry   *proc_dir_entry;
 	unsigned long		num_sifr;
 	unsigned long		status;
 };
 
-typedef struct _ProcItem
-{
-	const char* name;
-	char* (*read_func)(char*, struct acpi_hotkey*);
-	unsigned long (*write_func)(const char*, unsigned long, struct acpi_hotkey*);
-	struct acpi_hotkey *hotkey;
-} ProcItem;
-
-static struct proc_dir_entry* acpi_pcc_dir;
-
-/* register utils for proc handler */
-static int dispatch_read(char* page, char** start, off_t off, int count, 
-			 int* eof, ProcItem* item)
-{
-	char* p = page;
-	int len;
-
-	if (off == 0 && item->read_func) {
-		p = item->read_func(p, item->hotkey);
-	}
-
-	/* ISSUE: I don't understand this code */
-	len = (p - page);
-	if (len <= off+count) {
-		*eof = 1;
-	}
-	*start = page + off;
-	len -= off;
-	if (len > count) {
-		len = count;
-	}
-	if (len < 0) {
-		len = 0;
-	}
-	return len;
-}
-
-static int dispatch_write(struct file* file, __user const char* buffer,
-	unsigned long count, ProcItem* item)
-{
-	int result;
-	char* tmp_buffer;
-
-	/* Arg buffer points to userspace memory, which can't be accessed
-	 * directly.  Since we're making a copy, zero-terminate the
-	 * destination so that sscanf can be used on it safely.
-	 */
-	tmp_buffer = kmalloc(count + 1, GFP_KERNEL);
-	if (!tmp_buffer) {
-		printk(KERN_INFO LOGPREFIX "dispatch_write: Couldn't allocate buffer");
-		return -EFAULT;
-	}
-
-	if (copy_from_user(tmp_buffer, buffer, count)) {
-		printk(KERN_INFO LOGPREFIX "dispatch_write: Couldn't copy data from userspace");
-		result = -EFAULT;
-		goto end;
-	}
+/* --------------------------------------------------------------------------
+                              FS Interface (/proc)
+   -------------------------------------------------------------------------- */
+static int acpi_pcc_version_open_fs(struct inode*,struct file*);
+static int acpi_pcc_numbatteries_open_fs(struct inode*,struct file*);
+static int acpi_pcc_lcdtype_open_fs(struct inode*,struct file*);
+static int acpi_pcc_mute_open_fs(struct inode*,struct file*);
+static int acpi_pcc_ac_brightness_max_open_fs(struct inode*,struct file*);
+static int acpi_pcc_ac_brightness_min_open_fs(struct inode*,struct file*);
+static int acpi_pcc_dc_brightness_max_open_fs(struct inode*,struct file*);
+static int acpi_pcc_dc_brightness_min_open_fs(struct inode*,struct file*);
+static int acpi_pcc_ac_brightness_open_fs(struct inode*,struct file*);
+static int acpi_pcc_dc_brightness_open_fs(struct inode*,struct file*);
+static ssize_t acpi_pcc_write_mute (struct file*,const char __user *,size_t,loff_t *);
+static ssize_t acpi_pcc_write_ac_brightness (struct file*,const char __user *,size_t,loff_t *);
+static ssize_t acpi_pcc_write_dc_brightness (struct file*,const char __user *,size_t,loff_t *);
+
+static struct file_operations acpi_pcc_version_fops = {
+	.open		= acpi_pcc_version_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
-	tmp_buffer[count] = 0;
-	result = item->write_func(tmp_buffer, count, item->hotkey);
-		
-end:
-	kfree(tmp_buffer);
-	return result;
-}
+static struct file_operations acpi_pcc_numbatteries_fops = {
+	.open		= acpi_pcc_numbatteries_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+static struct file_operations acpi_pcc_lcdtype_fops = {
+	.open		= acpi_pcc_lcdtype_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+static struct file_operations acpi_pcc_mute_fops = {
+	.open		= acpi_pcc_mute_open_fs,
+	.read		= seq_read,
+	.write		= acpi_pcc_write_mute,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+static struct file_operations acpi_pcc_ac_brightness_fops = {
+	.open		= acpi_pcc_ac_brightness_open_fs,
+	.read		= seq_read,
+	.write		= acpi_pcc_write_ac_brightness,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+static struct file_operations acpi_pcc_ac_brightness_max_fops = {
+	.open		= acpi_pcc_ac_brightness_max_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+static struct file_operations acpi_pcc_ac_brightness_min_fops = {
+	.open		= acpi_pcc_ac_brightness_min_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+static struct file_operations acpi_pcc_dc_brightness_fops = {
+	.open		= acpi_pcc_dc_brightness_open_fs,
+	.read		= seq_read,
+	.write		= acpi_pcc_write_dc_brightness,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+static struct file_operations acpi_pcc_dc_brightness_max_fops = {
+	.open		= acpi_pcc_dc_brightness_max_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+static struct file_operations acpi_pcc_dc_brightness_min_fops = {
+	.open		= acpi_pcc_dc_brightness_min_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
-static int write_sset(int func, int val, struct acpi_hotkey *hotkey)
+/* --------------------------------------------------------------------------
+                           method access functions
+   -------------------------------------------------------------------------- */
+static int acpi_pcc_write_sset(int func, int val, struct acpi_hotkey *hotkey)
 {
 	struct acpi_object_list params;
 	union acpi_object in_objs[2];
@@ -249,7 +273,7 @@
 
 	ACPI_FUNCTION_TRACE("acpi_pcc_retrieve_biosdata");
 
-	status = acpi_evaluate_object(hotkey->handle,METHOD_HKEY_SINF, 0 , &buffer);
+	status = acpi_evaluate_object(hotkey->handle, METHOD_HKEY_SINF, 0 , &buffer);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "evaluation error HKEY.SINF\n"));
 		return_VALUE(0);
@@ -282,8 +306,9 @@
 	return_VALUE(status == AE_OK);
 }
 
-static char* acpi_pcc_read_sinf_field(char* p, int field, struct acpi_hotkey *hotkey) 
+static int acpi_pcc_read_sinf_field(struct seq_file *seq, int field)
 {
+	struct acpi_hotkey *hotkey = (struct acpi_hotkey *) seq->private;
 	u32* sinf = kmalloc(sizeof(u32) * (hotkey->num_sifr + 1), GFP_KERNEL);
 
 	ACPI_FUNCTION_TRACE("acpi_pcc_read_sinf_field");
@@ -291,145 +316,223 @@
 	if (!sinf) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate %li bytes\n", 
 		       sizeof(u32) * hotkey->num_sifr));
-		return p;
+		return_VALUE(0);
 	}
 
 	if (acpi_pcc_retrieve_biosdata(sinf, hotkey)) {
-		p += sprintf(p, "%u\n",	sinf[field]);
+		seq_printf(seq, "%u\n",	sinf[field]);
 	} else {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't retrieve BIOS data\n"));
 	}
 
 	kfree(sinf);
-	return p;
+	return_VALUE(0);
 }
 
-/* Sinf read methods */
-static char* acpi_pcc_read_num_batteries(char* p, struct acpi_hotkey *hotkey) 
-{
-	return acpi_pcc_read_sinf_field(p, SINF_NUM_BATTERIES, hotkey);
-}
 
-static char* acpi_pcc_read_lcd_type(char* p, struct acpi_hotkey *hotkey) 
+/* --------------------------------------------------------------------------
+                       user interface functions
+   -------------------------------------------------------------------------- */
+
+/* Sinf read methods */
+static int acpi_pcc_numbatteries_show(struct seq_file *seq, void *offset)
 {
-	return acpi_pcc_read_sinf_field(p, SINF_LCD_TYPE, hotkey);
+	return acpi_pcc_read_sinf_field(seq, SINF_NUM_BATTERIES);
 }
 
-static char* acpi_pcc_read_ac_max_brightness(char* p, struct acpi_hotkey *hotkey) 
+static int acpi_pcc_lcdtype_show(struct seq_file *seq, void *offset)
 {
-	return acpi_pcc_read_sinf_field(p, SINF_AC_MAX_BRIGHT, hotkey);
+	return acpi_pcc_read_sinf_field(seq, SINF_LCD_TYPE);
 }
 
-static char* acpi_pcc_read_ac_min_brightness(char* p, struct acpi_hotkey *hotkey) 
+static int acpi_pcc_ac_max_brightness_show(struct seq_file *seq, void *offset)
 {
-	return acpi_pcc_read_sinf_field(p, SINF_AC_MIN_BRIGHT, hotkey);
+	return acpi_pcc_read_sinf_field(seq, SINF_AC_MAX_BRIGHT);
 }
 
-static char* acpi_pcc_read_ac_brightness(char* p, struct acpi_hotkey *hotkey) 
+static int acpi_pcc_ac_min_brightness_show(struct seq_file *seq, void *offset)
 {
-	return acpi_pcc_read_sinf_field(p, SINF_AC_CUR_BRIGHT, hotkey);
+	return acpi_pcc_read_sinf_field(seq, SINF_AC_MIN_BRIGHT);
 }
 
-static char* acpi_pcc_read_dc_max_brightness(char* p, struct acpi_hotkey *hotkey) 
+static int acpi_pcc_ac_brightness_show(struct seq_file *seq, void *offset)
 {
-	return acpi_pcc_read_sinf_field(p, SINF_DC_MAX_BRIGHT, hotkey);
+	return acpi_pcc_read_sinf_field(seq, SINF_AC_CUR_BRIGHT);
 }
 
-static char* acpi_pcc_read_dc_min_brightness(char* p, struct acpi_hotkey *hotkey) 
+static int acpi_pcc_dc_max_brightness_show(struct seq_file *seq, void *offset)
 {
-	return acpi_pcc_read_sinf_field(p, SINF_DC_MIN_BRIGHT, hotkey);
+	return acpi_pcc_read_sinf_field(seq, SINF_DC_MAX_BRIGHT);
 }
 
-static char* acpi_pcc_read_dc_brightness(char* p, struct acpi_hotkey *hotkey) 
+static int acpi_pcc_dc_min_brightness_show(struct seq_file *seq, void *offset)
 {
-	return acpi_pcc_read_sinf_field(p, SINF_DC_CUR_BRIGHT, hotkey);
+	return acpi_pcc_read_sinf_field(seq, SINF_DC_MIN_BRIGHT);
 }
 
-static char* acpi_pcc_read_mute(char* p, struct acpi_hotkey *hotkey) 
+static int acpi_pcc_dc_brightness_show(struct seq_file *seq, void *offset)
 {
-	return acpi_pcc_read_sinf_field(p, SINF_MUTE, hotkey);
+	return acpi_pcc_read_sinf_field(seq, SINF_DC_CUR_BRIGHT);
 }
 
-static char* acpi_pcc_read_env_state(char* p, struct acpi_hotkey *hotkey) 
+static int acpi_pcc_mute_show(struct seq_file *seq, void *offset)
 {
-	return acpi_pcc_read_sinf_field(p, SINF_ENV_STATE, hotkey);
+	return acpi_pcc_read_sinf_field(seq, SINF_MUTE);
 }
 
-static unsigned long acpi_pcc_write_mute(const char* buffer, 
-					 unsigned long count, struct acpi_hotkey *hotkey)
+/* write methods */
+static ssize_t acpi_pcc_write_mute (struct file *file,	const char __user *buffer,
+		     size_t count, loff_t *ppos)
 {
-	u32 value;
+	struct seq_file		*seq = (struct seq_file *)file->private_data;
+	struct acpi_hotkey	*hotkey = (struct acpi_hotkey *)seq->private;
+	char			write_string[4]= {'\0'};
+	u32 mute;
 
 	ACPI_FUNCTION_TRACE("acpi_pcc_write_mute");
 
-	if (sscanf(buffer, "%i", &value) == 1 && value >= 0 && value <= 1) {
-		write_sset(SINF_MUTE, value, hotkey);
+	if (!hotkey || (count > sizeof(write_string) - 1))
+		return_VALUE(-EINVAL);
+
+	if (copy_from_user(write_string, buffer, count))
+		return_VALUE(-EFAULT);
+	write_string[count] = '\0';
+
+	if (sscanf(write_string, "%i", &mute) == 1 && (mute == 0 || mute == 1)) {
+		acpi_pcc_write_sset(SINF_MUTE, mute, hotkey);
 	}
 
-	return count;
+	return_VALUE(count);
 }
 
-static unsigned long acpi_pcc_write_brightness(const char* buffer,
-					       unsigned long count,
+static unsigned long acpi_pcc_write_brightness(struct file *file, const char __user *buffer,
+					       size_t count,
 					       int min_index, int max_index,
-					       int cur_index, struct acpi_hotkey *hotkey)
+					       int cur_index)
 {
+	struct seq_file		*seq = (struct seq_file *)file->private_data;
+	struct acpi_hotkey	*hotkey = (struct acpi_hotkey *)seq->private;
+	char			write_string[8] = {'\0'};
 	u32 bright;
 	u32* sinf = kmalloc(sizeof(u32) * (hotkey->num_sifr + 1), GFP_KERNEL);
 
 	ACPI_FUNCTION_TRACE("acpi_pcc_write_brightness");
 
+	if (!hotkey || (count > sizeof(write_string) - 1))
+		return_VALUE(-EINVAL);
+
 	if (!sinf) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't allocate %li bytes\n", 
 		       sizeof(u32) * hotkey->num_sifr));
-		return count;
+		return_VALUE(-EFAULT);
 	}
 
+	if (copy_from_user(write_string, buffer, count))
+		return_VALUE(-EFAULT);
+	
+	write_string[count] = '\0';
+
 	if (!acpi_pcc_retrieve_biosdata(sinf, hotkey)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't retrieve BIOS data\n"));
 		goto end;
 	}
-	
-	if (!sscanf(buffer, "%i", &bright)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid DC brightness\n"));
-		goto end;
-	}
 
-	if (bright >= sinf[min_index] && bright <= sinf[max_index]) {
-		write_sset(cur_index, bright, hotkey);
+	if (sscanf(write_string, "%i", &bright) == 1 && 
+		bright >= sinf[min_index] && bright <= sinf[max_index]) {
+			acpi_pcc_write_sset(cur_index, bright, hotkey);
 	}
 
 end: 
 	kfree(sinf);
-	return count;
+	return_VALUE(count);
 }
 
-
-static unsigned long acpi_pcc_write_ac_brightness(const char* buffer, 
-						  unsigned long count, struct acpi_hotkey *hotkey)
+static ssize_t acpi_pcc_write_ac_brightness(struct file *file, const char __user *buffer,
+					 size_t count, loff_t *ppos)
 {
-	return acpi_pcc_write_brightness(buffer, count, SINF_AC_MIN_BRIGHT, 
+	return acpi_pcc_write_brightness(file, buffer, count, SINF_AC_MIN_BRIGHT, 
 					 SINF_AC_MAX_BRIGHT, 
-					 SINF_AC_CUR_BRIGHT, hotkey);
+					 SINF_AC_CUR_BRIGHT);
 }
 
-static unsigned long acpi_pcc_write_dc_brightness(const char* buffer, 
-						  unsigned long count, struct acpi_hotkey *hotkey)
+static ssize_t acpi_pcc_write_dc_brightness(struct file *file, const char __user *buffer,
+					 size_t count, loff_t *ppos)
 {
-	return acpi_pcc_write_brightness(buffer, count, SINF_DC_MIN_BRIGHT, 
+	return acpi_pcc_write_brightness(file, buffer, count, SINF_DC_MIN_BRIGHT, 
 					 SINF_DC_MAX_BRIGHT, 
-					 SINF_DC_CUR_BRIGHT, hotkey);
+					 SINF_DC_CUR_BRIGHT);
+}
+
+static int acpi_pcc_version_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_hotkey *hotkey = (struct acpi_hotkey *) seq->private;
+
+	ACPI_FUNCTION_TRACE("acpi_pcc_version_seq_show");
+
+	if (!hotkey || !hotkey->device)
+		return 0;
+
+	seq_printf(seq, "%s version %s\n", ACPI_PCC_DRIVER_NAME, ACPI_PCC_VERSION);
+	seq_printf(seq, "%li functions\n", hotkey->num_sifr);
+
+	return_VALUE(0);
+}
+
+/* oepn proc file fs*/
+static int acpi_pcc_dc_brightness_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_pcc_dc_brightness_show, PDE(inode)->data);
+}
+
+static int acpi_pcc_numbatteries_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_pcc_numbatteries_show, PDE(inode)->data);
+}
+
+static int acpi_pcc_lcdtype_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_pcc_lcdtype_show, PDE(inode)->data);
+}
+
+static int acpi_pcc_ac_brightness_max_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_pcc_ac_max_brightness_show, PDE(inode)->data);
+}
+
+static int acpi_pcc_ac_brightness_min_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_pcc_ac_min_brightness_show, PDE(inode)->data);
+}
+
+static int acpi_pcc_ac_brightness_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_pcc_ac_brightness_show, PDE(inode)->data);
+}
+
+static int acpi_pcc_dc_brightness_max_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_pcc_dc_max_brightness_show, PDE(inode)->data);
+}
+
+static int acpi_pcc_dc_brightness_min_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_pcc_dc_min_brightness_show, PDE(inode)->data);
+}
+
+static int acpi_pcc_mute_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_pcc_mute_show, PDE(inode)->data);
 }
 
-static char* acpi_pcc_read_version(char* p, struct acpi_hotkey *hotkey)
+static int acpi_pcc_version_open_fs(struct inode *inode, struct file *file)
 {
-	p += sprintf(p, "%s version %s\n", ACPI_PCC_DRIVER_NAME, 
-		     ACPI_PCC_VERSION);
-	p += sprintf(p, "%li functions\n", hotkey->num_sifr);
-	return p;
+	return single_open(file, acpi_pcc_version_show, PDE(inode)->data);
 }
 
-/* hotkey driver */
+/* --------------------------------------------------------------------------
+                            hotkey driver 
+   -------------------------------------------------------------------------- */
+
 static int acpi_pcc_hotkey_get_key(struct acpi_hotkey *hotkey)
 {
 	unsigned long result;
@@ -456,6 +559,7 @@
 	switch(event) {
 	case HKEY_NOTIFY:
 		if (acpi_pcc_hotkey_get_key(hotkey)) {
+			/* generate event like 'pcc HKEY 0004 0001' when Fn+F4 pressed */
 			acpi_bus_generate_event(hotkey->device, event, hotkey->status);
 		}
 		break;
@@ -463,54 +567,57 @@
 		/* nothing to do */
 		break;
 	}
-	return;
+	return_VOID;
 }
 
-/*
- * proc and module init
-*/
+/* --------------------------------------------------------------------------
+                         proc init
+   -------------------------------------------------------------------------- */
+
+typedef struct _ProcItem
+{
+	const char* name;
+	struct file_operations *fops;
+	mode_t flag;
+} ProcItem;
 
 /* Note: These functions map *exactly* to the SINF/SSET functions */
 ProcItem pcc_proc_items[] =
 {
-	{ "num_batteries", acpi_pcc_read_num_batteries, NULL, NULL },
-	{ "lcd_type", acpi_pcc_read_lcd_type, NULL, NULL },
-	{ "ac_brightness_max" , acpi_pcc_read_ac_max_brightness, NULL, NULL },
-	{ "ac_brightness_min" , acpi_pcc_read_ac_min_brightness, NULL, NULL },
-	{ "ac_brightness" , acpi_pcc_read_ac_brightness, 
-	  acpi_pcc_write_ac_brightness, NULL },
-	{ "dc_brightness_max" , acpi_pcc_read_dc_max_brightness, NULL, NULL },
-	{ "dc_brightness_min" , acpi_pcc_read_dc_min_brightness, NULL, NULL },
-	{ "dc_brightness" , acpi_pcc_read_dc_brightness, 
-	  acpi_pcc_write_dc_brightness, NULL },
-	{ "mute", acpi_pcc_read_mute, acpi_pcc_write_mute, NULL },
-	{ "version", acpi_pcc_read_version , NULL, NULL },
-	{ "environment_state", acpi_pcc_read_env_state, NULL, NULL },
-	{ NULL 	   , NULL	  , NULL, NULL },
+	{ "num_batteries",      &acpi_pcc_numbatteries_fops,     S_IRUGO },
+	{ "lcd_type",           &acpi_pcc_lcdtype_fops,          S_IRUGO },
+	{ "ac_brightness_max" , &acpi_pcc_ac_brightness_max_fops,S_IRUGO },
+	{ "ac_brightness_min" , &acpi_pcc_ac_brightness_min_fops,S_IRUGO },
+	{ "ac_brightness" ,     &acpi_pcc_ac_brightness_fops,    S_IFREG | S_IRUGO | S_IWUSR },
+	{ "dc_brightness_max" , &acpi_pcc_dc_brightness_max_fops,S_IRUGO },
+	{ "dc_brightness_min" , &acpi_pcc_dc_brightness_min_fops,S_IRUGO },
+	{ "dc_brightness" ,     &acpi_pcc_dc_brightness_fops,    S_IFREG | S_IRUGO | S_IWUSR }, 
+	{ "mute",               &acpi_pcc_mute_fops,             S_IFREG | S_IRUGO | S_IWUSR },
+	{ "version",            &acpi_pcc_version_fops,          S_IRUGO },
+	{ NULL, NULL, 0 },
 };
 
 static int __init add_device(ProcItem *proc_items, 
-				     struct proc_dir_entry* proc_entry,
-				     struct acpi_device *device)
+			     struct acpi_device *device)
 {
 	struct proc_dir_entry* proc;
 	ProcItem* item;
 	int i;
 	struct acpi_hotkey *hotkey = (struct acpi_hotkey*)acpi_driver_data(device);
 
-	for (item = proc_items, i = 0; item->name && i <= hotkey->num_sifr; 
+	for (item = proc_items, i = 0; item->name && i < hotkey->num_sifr + 1; 
 	     ++item, ++i) {
-		item->hotkey = hotkey;
-		proc = create_proc_read_entry(item->name,
-					      S_IFREG | S_IRUGO | S_IWUSR,
-					      proc_entry, 
-					      (read_proc_t*)dispatch_read, 
-					      item);
-		if (proc) {
+		proc = create_proc_entry(item->name, item->flag, hotkey->proc_dir_entry); 
+		if (likely(proc)) {
+			proc->proc_fops = item->fops;
+			proc->data = hotkey;
 			proc->owner = THIS_MODULE;
-		}
-		if (proc && item->write_func) {
-			proc->write_proc = (write_proc_t*)dispatch_write;
+		} else {
+			while (i-- > 0) {
+				item--;
+				remove_proc_entry(item->name, hotkey->proc_dir_entry);
+			}
+			return -ENODEV;
 		}
 	}
 	return 0;
@@ -518,7 +625,9 @@
 
 static int __init acpi_pcc_proc_init(struct acpi_device *device)
 {
-	int status;
+	struct proc_dir_entry* acpi_pcc_dir;
+	struct acpi_hotkey *hotkey = (struct acpi_hotkey*)acpi_driver_data(device);
+	acpi_status status;
 
 	ACPI_FUNCTION_TRACE("acpi_pcc_proc_init");
 
@@ -530,25 +639,36 @@
 	}
 
 	acpi_pcc_dir->owner = THIS_MODULE;
-	status = add_device(pcc_proc_items, acpi_pcc_dir, device);
+	hotkey->proc_dir_entry = acpi_pcc_dir;
+
+	status = add_device(pcc_proc_items, device);
 	if (unlikely(status)) {
 		remove_proc_entry(PROC_PCC, acpi_root_dir);
+		hotkey->proc_dir_entry = NULL;
+		return_VALUE(-ENODEV);
 	}
 
 	return_VALUE(status);
 }
 
 static void __exit remove_device(ProcItem *proc_items, 
-					struct proc_dir_entry* proc_entry)
+					struct acpi_device *device)
 {
+	struct acpi_hotkey *hotkey = (struct acpi_hotkey*)acpi_driver_data(device);
 	ProcItem* item;
+	int i;
 
-	for (item = proc_items; item->name; ++item) {
-		remove_proc_entry(item->name, proc_entry);
+	for (item = proc_items, i = 0; item->name && i <= hotkey->num_sifr; ++item, ++i) {
+		remove_proc_entry(item->name, hotkey->proc_dir_entry);
 	}
+
 	return;
 }
 
+/* --------------------------------------------------------------------------
+                         module init
+   -------------------------------------------------------------------------- */
+
 static int acpi_pcc_hotkey_add (struct acpi_device *device)
 {
 	acpi_status		status = AE_OK;
@@ -580,8 +700,8 @@
 	hotkey->handle = device->handle;
 	hotkey->num_sifr = num_sifr;
 	acpi_driver_data(device) = hotkey;
-	strcpy(acpi_device_name(device), ACPI_HOTKEY_DEVICE_NAME);
-	strcpy(acpi_device_class(device), ACPI_HOTKEY_CLASS);
+	strcpy(acpi_device_name(device), ACPI_PCC_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_PCC_CLASS);
 
 	status = acpi_install_notify_handler (
 			hotkey->handle,
@@ -601,20 +721,18 @@
 static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)
 {
 	acpi_status		status = AE_OK;
-	struct acpi_hotkey	*hotkey = NULL;
+	struct acpi_hotkey	*hotkey = acpi_driver_data(device);
 
 	ACPI_FUNCTION_TRACE("acpi_pcc_hotkey_remove");
 
-	if (!device || !acpi_driver_data(device))
+	if (!device || !hotkey)
 		return_VALUE(-EINVAL);
 
-	if (acpi_pcc_dir) {
-		remove_device(pcc_proc_items, acpi_pcc_dir);
+	if (hotkey->proc_dir_entry) {
+		remove_device(pcc_proc_items, device);
 		remove_proc_entry(PROC_PCC, acpi_root_dir);
 	}
 
-	hotkey = acpi_driver_data(device);
-
 	status = acpi_remove_notify_handler(hotkey->handle,
 		    ACPI_DEVICE_NOTIFY, acpi_pcc_hotkey_notify);
 
@@ -635,7 +753,7 @@
 		return_VALUE(-ENODEV);
 	}
 
-	result = acpi_bus_register_driver(&acpi_hotkey_driver);
+	result = acpi_bus_register_driver(&acpi_pcc_driver);
 	if (result < 0) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error registering hotkey driver\n"));
 		return_VALUE(-ENODEV);
@@ -644,12 +762,11 @@
 	return_VALUE(0);
 }
 
-static void __exit
-acpi_pcc_exit(void)
+static void __exit acpi_pcc_exit(void)
 {
 	ACPI_FUNCTION_TRACE("acpi_pcc_exit");
 
-	acpi_bus_unregister_driver(&acpi_hotkey_driver); 
+	acpi_bus_unregister_driver(&acpi_pcc_driver); 
 
 	return_VOID;
 }

[-- Attachment #3: hotkey-handler-1.2.tar.gz --]
[-- Type: application/octet-stream, Size: 3027 bytes --]

      parent reply	other threads:[~2004-09-15  0:42 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-08-19  6:00 [PATCH]Panasonic Hotkey Driver David Bronaugh
     [not found] ` <41244219.1090603-Jp3n8lUXroSX6QiC4yPwbg@public.gmane.org>
2004-08-20  2:51   ` Hiroshi Miura
     [not found]     ` <871xi2s555.wl%miura@da-cha.org>
     [not found]       ` <871xi2s555.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-08-20  6:25         ` [PATCH]Panasonic Hotkey Driver v0.5 [1/2] Hiroshi Miura
     [not found]           ` <87vffeqqaq.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-08-20 17:11             ` Len Brown
2004-08-21  1:30               ` [letsnote-tech:00074] " Hiroshi Miura
     [not found]     ` <87acwqserw.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-08-20  6:25       ` [PATCH]Panasonic Hotkey Driver v0.5 [2/2] Hiroshi Miura
     [not found]         ` <87u0uyqqa7.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-08-20  7:44           ` David Bronaugh
     [not found]             ` <4125ABEF.9090106-Jp3n8lUXroSX6QiC4yPwbg@public.gmane.org>
2004-08-20  8:43               ` Hiroshi Miura
     [not found]                 ` <87pt5mqjxj.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-08-20 12:46                   ` Stefan Seyfried
2004-08-20 17:14                   ` David Bronaugh
     [not found]                     ` <41263192.7010300-Jp3n8lUXroSX6QiC4yPwbg@public.gmane.org>
2004-08-20 17:43                       ` Nate Lawson
     [not found]                         ` <41263840.1010003-Y6VGUYTwhu0@public.gmane.org>
2004-08-21  0:46                           ` Hiroshi Miura
2004-08-21  5:39                           ` Hiroshi Miura
2004-08-21  1:30                       ` Hiroshi Miura
2004-08-24 23:00           ` John Belmonte
2004-08-21  1:42   ` [PATCH]Panasonic Hotkey Driver Hiroshi Miura
     [not found]     ` <87zn4pl116.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-08-21  5:33       ` Hiroshi Miura
     [not found]         ` <87n00pkqc5.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-08-21  8:44           ` David Bronaugh
     [not found]             ` <41270B53.3060903-Jp3n8lUXroSX6QiC4yPwbg@public.gmane.org>
2004-08-21 10:34               ` Hiroshi Miura
     [not found]                 ` <87d61klqzh.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-08-21 11:50                   ` vgod spam
2004-08-22  6:45                   ` David Bronaugh
     [not found]                     ` <41284119.1060504-Jp3n8lUXroSX6QiC4yPwbg@public.gmane.org>
2004-08-22  8:27                       ` David Bronaugh
     [not found]                         ` <412858F0.8050406-Jp3n8lUXroSX6QiC4yPwbg@public.gmane.org>
2004-08-23  5:07                           ` David Bronaugh
     [not found]                             ` <41297BA7.3050503-Jp3n8lUXroSX6QiC4yPwbg@public.gmane.org>
2004-08-26  8:45                               ` [PATCH]Panasonic Hotkey Driver v0.6.3 Hiroshi Miura
     [not found]                                 ` <87pt5e5lu3.wl%miura-yiisDzvROlQdnm+yROfE0A@public.gmane.org>
2004-09-15  0:42                                   ` Hiroshi Miura [this message]

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=878ybc8isn.wl%miura@da-cha.org \
    --to=miura-yiisdzvrolqdnm+yrofe0a@public.gmane.org \
    --cc=acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=dbronaugh-Jp3n8lUXroSX6QiC4yPwbg@public.gmane.org \
    --cc=letsnote-tech-eXqGM+LsbTTAqL8d+zIrHngSJqDPrsil@public.gmane.org \
    --cc=ryuta-rkWIgeFJRjg@public.gmane.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