All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Wayne Lin <00601wayne@gmail.com>
Cc: linux-input@vger.kernel.org, wayne <wayne.lin@quantatw.com>
Subject: Re: [RFC 04/36]  [Driver][Qualcomm 1070][EC_KB] Adding new qci keyboard driver
Date: Mon, 26 Jul 2010 01:55:08 -0700	[thread overview]
Message-ID: <20100726085507.GB27151@core.coreip.homeip.net> (raw)
In-Reply-To: <1280133045-25945-4-git-send-email-wayne.lin@quantatw.com>

On Mon, Jul 26, 2010 at 04:30:13PM +0800, Wayne Lin wrote:
> From: wayne <wayne.lin@quantatw.com>
> 

- Change log?
- run through checkpatch.pl
- Get rid of debug printks (or convert to dev_dbg)?
- use dev_XXX instrad of pr_xxx when you have device? Get rig
- I have seen lots of time people trying to call input_free_device
  after calling input_unregister_device (which is forbidden,
  input_unregister_device is sufficient alone) but you are the first to
  call free _before_ unregister.
- No need to initialize keymap with zeroes (NOKEYS)
- threaded IRQ
- copy keymap into device and set keycode, keycodemax, keycodesize so
  that keymap can be adjusted from userspace
- why do you export input device?

I dont think you tried applying this patch... At least I do not have
qci_kbd.c in my tree so it would not apply.



> ---
>  drivers/input/keyboard/qci_kbd.c | 1101 +++++++++++++++++++-------------------
>  1 files changed, 551 insertions(+), 550 deletions(-)
> 
> diff --git a/drivers/input/keyboard/qci_kbd.c b/drivers/input/keyboard/qci_kbd.c
> index aa7a64a..0cf2f7e 100755
> --- a/drivers/input/keyboard/qci_kbd.c
> +++ b/drivers/input/keyboard/qci_kbd.c
> @@ -1,550 +1,551 @@
> -/* Quanta I2C Keyboard Driver
> - *
> - * Copyright (C) 2009 Quanta Computer Inc.
> - * Author: Hsin Wu <hsin.wu@quantatw.com>
> - * Author: Austin Lai <austin.lai@quantatw.com>
> - *
> - * This software is licensed under the terms of the GNU General Public
> - * License version 2, as published by the Free Software Foundation, and
> - * may be copied, distributed, and modified under those terms.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - */
> -
> - /*
> - *
> - *  The Driver with I/O communications via the I2C Interface for ON2 of AP BU.
> - *  And it is only working on the nuvoTon WPCE775x Embedded Controller.
> - *
> - */
> -
> -#include <linux/kernel.h>
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/slab.h>
> -#include <linux/jiffies.h>
> -#include <linux/i2c.h>
> -#include <linux/mutex.h>
> -#include <linux/interrupt.h>
> -#include <linux/input.h>
> -#include <linux/keyboard.h>
> -#include <linux/gpio.h>
> -#include <linux/delay.h>
> -
> -/* Keyboard special scancode */
> -#define RC_KEY_FN          0x70
> -#define RC_KEY_BREAK       0x80
> -#define KEY_ACK_FA      0xFA
> -
> -/* Keyboard keycodes */
> -#define NOKEY           KEY_RESERVED
> -#define KEY_LEFTWIN     KEY_LEFTMETA
> -#define KEY_RIGHTWIN    KEY_RIGHTMETA
> -#define KEY_APPS        KEY_COMPOSE
> -#define KEY_PRINTSCR    KEY_SYSRQ
> -
> -#define KEYBOARD_ID_NAME          "qci-i2ckbd"
> -#define KEYBOARD_NAME                "Quanta Keyboard"
> -#define KEYBOARD_DEVICE             "/i2c/input0"
> -#define KEYBOARD_CMD_ENABLE             0xF4
> -
> -/*-----------------------------------------------------------------------------
> - * Keyboard scancode to linux keycode translation table
> - *---------------------------------------------------------------------------*/
> -
> -static const unsigned char on2_keycode[256] = {
> -	[0]   = NOKEY,
> -	[1]   = NOKEY,
> -	[2]   = NOKEY,
> -	[3]   = KEY_5,
> -	[4]   = KEY_7,
> -	[5]   = KEY_9,
> -	[6]   = KEY_MINUS,
> -	[7]   = NOKEY,
> -	[8]   = NOKEY,
> -	[9]   = NOKEY,
> -	[10]  = NOKEY,
> -	[11]  = KEY_LEFTBRACE,
> -	[12]  = KEY_F10,
> -	[13]  = KEY_INSERT,
> -	[14]  = KEY_F11,
> -	[15]  = KEY_ESC,
> -	[16]  = NOKEY,
> -	[17]  = NOKEY,
> -	[18]  = NOKEY,
> -	[19]  = KEY_4,
> -	[20]  = KEY_6,
> -	[21]  = KEY_8,
> -	[22]  = KEY_0,
> -	[23]  = KEY_EQUAL,
> -	[24]  = NOKEY,
> -	[25]  = NOKEY,
> -	[26]  = NOKEY,
> -	[27]  = KEY_P,
> -	[28]  = KEY_F9,
> -	[29]  = KEY_DELETE,
> -	[30]  = KEY_F12,
> -	[31]  = KEY_GRAVE,
> -	[32]  = KEY_W,
> -	[33]  = NOKEY,
> -	[34]  = NOKEY,
> -	[35]  = KEY_R,
> -	[36]  = KEY_T,
> -	[37]  = KEY_U,
> -	[38]  = KEY_O,
> -	[39]  = KEY_RIGHTBRACE,
> -	[40]  = NOKEY,
> -	[41]  = NOKEY,
> -	[42]  = NOKEY,
> -	[43]  = KEY_APOSTROPHE,
> -	[44]  = KEY_BACKSPACE,
> -	[45]  = NOKEY,
> -	[46]  = KEY_F8,
> -	[47]  = KEY_F5,
> -	[48]  = KEY_S,
> -	[49]  = NOKEY,
> -	[50]  = NOKEY,
> -	[51]  = KEY_E,
> -	[52]  = KEY_H,
> -	[53]  = KEY_Y,
> -	[54]  = KEY_I,
> -	[55]  = KEY_ENTER,
> -	[56]  = NOKEY,
> -	[57]  = NOKEY,
> -	[58]  = NOKEY,
> -	[59]  = KEY_SEMICOLON,
> -	[60]  = KEY_3,
> -	[61]  = KEY_PAGEUP,
> -	[62]  = KEY_Q,
> -	[63]  = KEY_TAB,
> -	[64]  = KEY_A,
> -	[65]  = NOKEY,
> -	[66]  = NOKEY,
> -	[67]  = KEY_F,
> -	[68]  = KEY_G,
> -	[69]  = KEY_J,
> -	[70]  = KEY_L,
> -	[71]  = NOKEY,
> -	[72]  = KEY_RIGHTSHIFT,
> -	[73]  = NOKEY,
> -	[74]  = NOKEY,
> -	[75]  = KEY_SLASH,
> -	[76]  = KEY_2,
> -	[77]  = KEY_PAGEDOWN,
> -	[78]  = KEY_F4,
> -	[79]  = KEY_F1,
> -	[80]  = KEY_Z,
> -	[81]  = NOKEY,
> -	[82]  = NOKEY,
> -	[83]  = KEY_D,
> -	[84]  = KEY_V,
> -	[85]  = KEY_N,
> -	[86]  = KEY_K,
> -	[87]  = NOKEY,
> -	[88]  = KEY_LEFTSHIFT,
> -	[89]  = KEY_RIGHTCTRL,
> -	[90]  = NOKEY,
> -	[91]  = KEY_DOT,
> -	[92]  = KEY_UP,
> -	[93]  = KEY_RIGHT,
> -	[94]  = KEY_F3,
> -	[95]  = KEY_F2,
> -	[96]  = NOKEY,
> -	[97]  = NOKEY,
> -	[98]  = KEY_RIGHTALT,
> -	[99]  = KEY_X,
> -	[100] = KEY_C,
> -	[101] = KEY_B,
> -	[102] = KEY_COMMA,
> -	[103] = NOKEY,
> -	[104] = NOKEY,
> -	[105] = NOKEY,
> -	[106] = NOKEY,
> -	[107] = NOKEY,
> -	[108] = KEY_PRINTSCR,
> -	[109] = KEY_DOWN,
> -	[110] = KEY_1,
> -	[111] = KEY_CAPSLOCK,
> -	[112] = KEY_F24,
> -	[113] = KEY_HOME,
> -	[114] = KEY_LEFTALT,
> -	[115] = NOKEY,
> -	[116] = KEY_SPACE,
> -	[117] = KEY_BACKSLASH,
> -	[118] = KEY_M,
> -	[119] = KEY_COMPOSE,
> -	[120] = NOKEY,
> -	[121] = KEY_LEFTCTRL,
> -	[122] = NOKEY,
> -	[123] = NOKEY,
> -	[124] = KEY_PAUSE,
> -	[125] = KEY_LEFT,
> -	[126] = KEY_F7,
> -	[127] = KEY_F6,
> -	[128] = NOKEY,
> -	[129] = NOKEY,
> -	[130] = NOKEY,
> -	[131] = NOKEY,
> -	[132] = NOKEY,
> -	[133] = NOKEY,
> -	[134] = NOKEY,
> -	[135] = NOKEY,
> -	[136] = NOKEY,
> -	[137] = NOKEY,
> -	[138] = NOKEY,
> -	[139] = NOKEY,
> -	[140] = NOKEY,
> -	[141] = NOKEY,
> -	[142] = NOKEY,
> -	[143] = NOKEY,
> -	[144] = NOKEY,
> -	[145] = NOKEY,
> -	[146] = NOKEY,
> -	[147] = NOKEY,
> -	[148] = NOKEY,
> -	[149] = NOKEY,
> -	[150] = NOKEY,
> -	[151] = NOKEY,
> -	[152] = NOKEY,
> -	[153] = NOKEY,
> -	[154] = NOKEY,
> -	[155] = NOKEY,
> -	[156] = NOKEY,
> -	[157] = NOKEY,
> -	[158] = NOKEY,
> -	[159] = NOKEY,
> -	[160] = NOKEY,
> -	[161] = NOKEY,
> -	[162] = NOKEY,
> -	[163] = NOKEY,
> -	[164] = NOKEY,
> -	[165] = NOKEY,
> -	[166] = NOKEY,
> -	[167] = NOKEY,
> -	[168] = NOKEY,
> -	[169] = NOKEY,
> -	[170] = NOKEY,
> -	[171] = NOKEY,
> -	[172] = NOKEY,
> -	[173] = NOKEY,
> -	[174] = NOKEY,
> -	[175] = NOKEY,
> -	[176] = NOKEY,
> -	[177] = NOKEY,
> -	[178] = NOKEY,
> -	[179] = NOKEY,
> -	[180] = NOKEY,
> -	[181] = NOKEY,
> -	[182] = NOKEY,
> -	[183] = NOKEY,
> -	[184] = NOKEY,
> -	[185] = NOKEY,
> -	[186] = NOKEY,
> -	[187] = NOKEY,
> -	[188] = NOKEY,
> -	[189] = KEY_HOME,
> -	[190] = NOKEY,
> -	[191] = NOKEY,
> -	[192] = NOKEY,
> -	[193] = NOKEY,
> -	[194] = NOKEY,
> -	[195] = NOKEY,
> -	[196] = NOKEY,
> -	[197] = NOKEY,
> -	[198] = NOKEY,
> -	[199] = NOKEY,
> -	[200] = NOKEY,
> -	[201] = NOKEY,
> -	[202] = NOKEY,
> -	[203] = NOKEY,
> -	[204] = NOKEY,
> -	[205] = KEY_END,
> -	[206] = NOKEY,
> -	[207] = NOKEY,
> -	[208] = NOKEY,
> -	[209] = NOKEY,
> -	[210] = NOKEY,
> -	[211] = NOKEY,
> -	[212] = NOKEY,
> -	[213] = NOKEY,
> -	[214] = NOKEY,
> -	[215] = NOKEY,
> -	[216] = NOKEY,
> -	[217] = NOKEY,
> -	[218] = NOKEY,
> -	[219] = NOKEY,
> -	[220] = KEY_VOLUMEUP,
> -	[221] = KEY_BRIGHTNESSUP,
> -	[222] = NOKEY,
> -	[223] = NOKEY,
> -	[224] = NOKEY,
> -	[225] = NOKEY,
> -	[226] = NOKEY,
> -	[227] = NOKEY,
> -	[228] = NOKEY,
> -	[229] = NOKEY,
> -	[230] = NOKEY,
> -	[231] = NOKEY,
> -	[232] = NOKEY,
> -	[233] = NOKEY,
> -	[234] = NOKEY,
> -	[235] = NOKEY,
> -	[236] = NOKEY,
> -	[237] = KEY_VOLUMEDOWN,
> -	[238] = NOKEY,
> -	[239] = NOKEY,
> -	[240] = NOKEY,
> -	[241] = NOKEY,
> -	[242] = NOKEY,
> -	[243] = NOKEY,
> -	[244] = NOKEY,
> -	[245] = NOKEY,
> -	[246] = NOKEY,
> -	[247] = NOKEY,
> -	[248] = NOKEY,
> -	[249] = NOKEY,
> -	[250] = NOKEY,
> -	[251] = NOKEY,
> -	[252] = NOKEY,
> -	[253] = KEY_BRIGHTNESSDOWN,
> -	[254] = NOKEY,
> -	[255] = NOKEY,
> -};
> -/*-----------------------------------------------------------------------------
> - * Global variables
> - *---------------------------------------------------------------------------*/
> -
> -struct input_dev *g_qci_keyboard_dev;
> -
> -/* General structure to hold the driver data */
> -struct i2ckbd_drv_data {
> -	struct i2c_client *ki2c_client;
> -	struct work_struct work;
> -	struct input_dev *qcikbd_dev;
> -	unsigned int qcikbd_gpio; /* GPIO used for interrupt */
> -	unsigned int qcikbd_irq;
> -	unsigned int key_down;
> -	unsigned int escape;
> -	unsigned int pause_seq;
> -	unsigned int fn;
> -};
> -#ifdef CONFIG_PM
> -static int qcikbd_suspend(struct device *dev)
> -{
> -	return 0;
> -}
> -
> -static int qcikbd_resume(struct device *dev)
> -{
> -	return 0;
> -}
> -#endif
> -static int __devinit qcikbd_probe(struct i2c_client *client,
> -	const struct i2c_device_id *id);
> -static int __devexit qcikbd_remove(struct i2c_client *kbd);
> -
> -static const struct i2c_device_id qcikbd_idtable[] = {
> -	{ KEYBOARD_ID_NAME, 0 },
> -	{ }
> -};
> -
> -MODULE_DEVICE_TABLE(i2c, qcikbd_idtable);
> -
> -#ifdef CONFIG_PM
> -static struct dev_pm_ops qcikbd_pm_ops = {
> -	.suspend  = qcikbd_suspend,
> -	.resume   = qcikbd_resume,
> -};
> -#endif
> -static struct i2c_driver i2ckbd_driver = {
> -	.driver = {
> -		.owner = THIS_MODULE,
> -		.name  = KEYBOARD_ID_NAME,
> -#ifdef CONFIG_PM
> -		.pm = &qcikbd_pm_ops,
> -#endif
> -	},
> -	.probe	  = qcikbd_probe,
> -	.remove = __devexit_p(qcikbd_remove),
> -	.id_table = qcikbd_idtable,
> -};
> -
> -/*-----------------------------------------------------------------------------
> - * Driver functions
> - *---------------------------------------------------------------------------*/
> -
> -static irqreturn_t qcikbd_interrupt(int irq, void *dev_id)
> -{
> -	struct i2ckbd_drv_data *ikbd_drv_data = dev_id;
> -	schedule_work(&ikbd_drv_data->work);
> -	return IRQ_HANDLED;
> -}
> -
> -static void qcikbd_work_handler(struct work_struct *_work)
> -{
> -	unsigned char scancode;
> -	unsigned int  keycode;
> -
> -	struct i2ckbd_drv_data *ikbd_drv_data =
> -		container_of(_work, struct i2ckbd_drv_data, work);
> -
> -	struct i2c_client *ikbdclient = ikbd_drv_data->ki2c_client;
> -	struct input_dev *ikbdev = ikbd_drv_data->qcikbd_dev;
> -
> -	scancode = i2c_smbus_read_byte(ikbdclient);
> -
> -	if (scancode == KEY_ACK_FA) {
> -		return;
> -	} else if (scancode == RC_KEY_FN) {
> -		ikbd_drv_data->fn = 0x80;     /* select keycode table  > 0x7F */
> -	} else {
> -		ikbd_drv_data->key_down = 1;
> -		if (scancode & RC_KEY_BREAK) {
> -			ikbd_drv_data->key_down = 0;
> -			if ((scancode & 0x7F) == RC_KEY_FN)
> -				ikbd_drv_data->fn = 0;
> -		}
> -		keycode = on2_keycode[(scancode & 0x7F) | ikbd_drv_data->fn];
> -		if (keycode != NOKEY) {
> -			input_report_key(ikbdev,
> -					 keycode,
> -					 ikbd_drv_data->key_down);
> -			input_sync(ikbdev);
> -		}
> -	}
> -}
> -
> -
> -static int qcikbd_open(struct input_dev *dev)
> -{
> -	struct i2ckbd_drv_data *ikbd_drv_data = input_get_drvdata(dev);
> -	struct i2c_client *ikbdclient = ikbd_drv_data->ki2c_client;
> -
> -	/* Send F4h - enable keyboard */
> -	i2c_smbus_write_byte(ikbdclient, KEYBOARD_CMD_ENABLE);
> -	return 0;
> -}
> -
> -static int __devinit qcikbd_probe(struct i2c_client *client,
> -				    const struct i2c_device_id *id)
> -{
> -	int err;
> -	int i;
> -	struct i2ckbd_drv_data *context;
> -	context = kzalloc(sizeof(struct i2ckbd_drv_data), GFP_KERNEL);
> -	if (!context)
> -		return -ENOMEM;
> -	i2c_set_clientdata(client, context);
> -	context->ki2c_client = client;
> -	context->qcikbd_gpio = client->irq;
> -	client->driver = &i2ckbd_driver;
> -
> -	INIT_WORK(&context->work, qcikbd_work_handler);
> -
> -	err = gpio_request(context->qcikbd_gpio, "qci-kbd");
> -	if (err) {
> -		pr_err("[KBD] err gpio request\n");
> -		goto gpio_request_fail;
> -	}
> -
> -	context->qcikbd_irq = gpio_to_irq(context->qcikbd_gpio);
> -	err = request_irq(context->qcikbd_irq,
> -			  qcikbd_interrupt,
> -			  IRQF_TRIGGER_FALLING,
> -			  KEYBOARD_ID_NAME,
> -			  context);
> -	if (err) {
> -		pr_err("[KBD] err unable to get IRQ\n");
> -		goto request_irq_fail;
> -	}
> -
> -	context->qcikbd_dev = input_allocate_device();
> -	if (!context->qcikbd_dev) {
> -		pr_err("[KBD]allocting memory err\n");
> -		err = -ENOMEM;
> -		goto allocate_fail;
> -	}
> -
> -	context->qcikbd_dev->name       = KEYBOARD_NAME;
> -	context->qcikbd_dev->phys       = KEYBOARD_DEVICE;
> -	context->qcikbd_dev->id.bustype = BUS_I2C;
> -	context->qcikbd_dev->id.vendor  = 0x1050;
> -	context->qcikbd_dev->id.product = 0x0006;
> -	context->qcikbd_dev->id.version = 0x0004;
> -	context->qcikbd_dev->open       = qcikbd_open;
> -	set_bit(EV_KEY, context->qcikbd_dev->evbit);
> -	set_bit(EV_REP, context->qcikbd_dev->evbit);
> -
> -	/* Enable all supported keys */
> -	for (i = 1; i < ARRAY_SIZE(on2_keycode) ; i++)
> -		set_bit(on2_keycode[i], context->qcikbd_dev->keybit);
> -
> -	set_bit(KEY_POWER, context->qcikbd_dev->keybit);
> -	set_bit(KEY_END, context->qcikbd_dev->keybit);
> -	set_bit(KEY_VOLUMEUP, context->qcikbd_dev->keybit);
> -	set_bit(KEY_VOLUMEDOWN, context->qcikbd_dev->keybit);
> -	set_bit(KEY_ZOOMIN, context->qcikbd_dev->keybit);
> -	set_bit(KEY_ZOOMOUT, context->qcikbd_dev->keybit);
> -
> -	input_set_drvdata(context->qcikbd_dev, context);
> -	err = input_register_device(context->qcikbd_dev);
> -	if (err) {
> -		pr_err("[KBD] err input register device\n");
> -		goto register_fail;
> -	}
> -	g_qci_keyboard_dev = context->qcikbd_dev;
> -	return 0;
> -register_fail:
> -	input_free_device(context->qcikbd_dev);
> -
> -allocate_fail:
> -	free_irq(context->qcikbd_irq, context);
> -
> -request_irq_fail:
> -	gpio_free(context->qcikbd_gpio);
> -
> -gpio_request_fail:
> -	i2c_set_clientdata(client, NULL);
> -	kfree(context);
> -	return err;
> -}
> -
> -static int __devexit qcikbd_remove(struct i2c_client *dev)
> -{
> -	struct i2ckbd_drv_data *context = i2c_get_clientdata(dev);
> -
> -	free_irq(context->qcikbd_irq, context);
> -	gpio_free(context->qcikbd_gpio);
> -	input_free_device(context->qcikbd_dev);
> -	input_unregister_device(context->qcikbd_dev);
> -	kfree(context);
> -
> -	return 0;
> -}
> -
> -static int __init qcikbd_init(void)
> -{
> -	return i2c_add_driver(&i2ckbd_driver);
> -}
> -
> -static void __exit qcikbd_exit(void)
> -{
> -	i2c_del_driver(&i2ckbd_driver);
> -}
> -
> -struct input_dev *nkbc_keypad_get_input_dev(void)
> -{
> -	return g_qci_keyboard_dev;
> -}
> -EXPORT_SYMBOL(nkbc_keypad_get_input_dev);
> -module_init(qcikbd_init);
> -module_exit(qcikbd_exit);
> -
> -MODULE_AUTHOR("Quanta Computer Inc.");
> -MODULE_DESCRIPTION("Quanta Embedded Controller I2C Keyboard Driver");
> -MODULE_LICENSE("GPL v2");
> -
> +/* Quanta I2C Keyboard Driver
> + *
> + * Copyright (C) 2009 Quanta Computer Inc.
> + * Author: Hsin Wu <hsin.wu@quantatw.com>
> + * Author: Austin Lai <austin.lai@quantatw.com>
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> + /*
> + *
> + *  The Driver with I/O communications via the I2C Interface for ON2 of AP BU.
> + *  And it is only working on the nuvoTon WPCE775x Embedded Controller.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/jiffies.h>
> +#include <linux/i2c.h>
> +#include <linux/mutex.h>
> +#include <linux/interrupt.h>
> +#include <linux/input.h>
> +#include <linux/keyboard.h>
> +#include <linux/gpio.h>
> +#include <linux/delay.h>
> +
> +/* Keyboard special scancode */
> +#define RC_KEY_FN          0x70
> +#define RC_KEY_BREAK       0x80
> +#define KEY_ACK_FA      0xFA
> +
> +/* Keyboard keycodes */
> +#define NOKEY           KEY_RESERVED
> +#define KEY_LEFTWIN     KEY_LEFTMETA
> +#define KEY_RIGHTWIN    KEY_RIGHTMETA
> +#define KEY_APPS        KEY_COMPOSE
> +#define KEY_PRINTSCR    KEY_SYSRQ
> +
> +#define KEYBOARD_ID_NAME          "qci-i2ckbd"
> +#define KEYBOARD_NAME                "Quanta Keyboard"
> +#define KEYBOARD_DEVICE             "/i2c/input0"
> +#define KEYBOARD_CMD_ENABLE             0xF4
> +
> +/*-----------------------------------------------------------------------------
> + * Keyboard scancode to linux keycode translation table
> + *---------------------------------------------------------------------------*/
> +
> +static const unsigned char on2_keycode[256] = {
> +        [0]   = KEY_RESERVED,
> +        [1]   = KEY_ESC,
> +        [2]   = KEY_1,
> +        [3]   = KEY_2,
> +        [4]   = KEY_3,
> +        [5]   = KEY_4,
> +        [6]   = KEY_5,
> +        [7]   = KEY_6,
> +        [8]   = KEY_7,
> +        [9]   = KEY_8,
> +        [10]  = KEY_9,
> +        [11]  = KEY_0,
> +        [12]  = KEY_MINUS,
> +        [13]  = KEY_EQUAL,
> +        [14]  = KEY_BACKSPACE,
> +        [15]  = KEY_TAB,
> +        [16]  = KEY_Q,
> +        [17]  = KEY_W,
> +        [18]  = KEY_E,
> +        [19]  = KEY_R,
> +        [20]  = KEY_T,
> +        [21]  = KEY_Y,
> +        [22]  = KEY_U,
> +        [23]  = KEY_I,
> +        [24]  = KEY_O,
> +        [25]  = KEY_P,
> +        [26]  = KEY_LEFTBRACE,
> +        [27]  = KEY_RIGHTBRACE,
> +        [28]  = KEY_ENTER,
> +        [29]  = KEY_LEFTCTRL,
> +        [30]  = KEY_A,
> +        [31]  = KEY_S,
> +        [32]  = KEY_D,
> +        [33]  = KEY_F,
> +        [34]  = KEY_G,
> +        [35]  = KEY_H,
> +        [36]  = KEY_J,
> +        [37]  = KEY_K,
> +        [38]  = KEY_L,
> +        [39]  = KEY_SEMICOLON,
> +        [40]  = KEY_APOSTROPHE,
> +        [41]  = KEY_GRAVE,
> +        [42]  = KEY_LEFTSHIFT,
> +        [43]  = KEY_BACKSLASH,
> +        [44]  = KEY_Z,
> +        [45]  = KEY_X,
> +        [46]  = KEY_C,
> +        [47]  = KEY_V,
> +        [48]  = KEY_B,
> +        [49]  = KEY_N,
> +        [50]  = KEY_M,
> +        [51]  = KEY_COMMA,
> +        [52]  = KEY_DOT,
> +        [53]  = KEY_SLASH,
> +        [54]  = KEY_RIGHTSHIFT,
> +        [55]  = KEY_KPASTERISK,
> +        [56]  = KEY_LEFTALT,
> +        [57]  = KEY_SPACE,
> +        [58]  = KEY_CAPSLOCK,
> +        [59]  = KEY_F1,
> +        [60]  = KEY_F2,
> +        [61]  = KEY_F3,
> +        [62]  = KEY_F4,
> +        [63]  = KEY_F5,
> +        [64]  = KEY_F6,
> +        [65]  = KEY_F7,
> +        [66]  = KEY_F8,
> +        [67]  = KEY_F9,
> +        [68]  = KEY_F10,
> +        [69]  = KEY_NUMLOCK,
> +        [70]  = KEY_SCROLLLOCK,
> +        [71]  = KEY_KP7,
> +        [72]  = KEY_KP8,
> +        [73]  = KEY_KP9,
> +        [74]  = KEY_KPMINUS,
> +        [75]  = KEY_KP4,
> +        [76]  = KEY_KP5,
> +        [77]  = KEY_KP6,
> +        [78]  = KEY_KPPLUS,
> +        [79]  = KEY_KP1,
> +        [80]  = KEY_KP2,
> +        [81]  = KEY_KP3,
> +        [82]  = KEY_KP0,
> +        [83]  = KEY_KPDOT,
> +        [84]  = KEY_RESERVED,
> +        [85]  = KEY_ZENKAKUHANKAKU,
> +        [86]  = KEY_102ND,
> +        [87]  = KEY_F11,
> +        [88]  = KEY_F12,
> +        [89]  = KEY_RO,
> +        [90]  = KEY_KATAKANA,
> +        [91]  = KEY_HIRAGANA,
> +        [92]  = KEY_HENKAN,
> +        [93]  = KEY_KATAKANAHIRAGANA,
> +        [94]  = KEY_MUHENKAN,
> +        [95]  = KEY_KPJPCOMMA,
> +        [96]  = KEY_KPENTER,
> +        [97]  = KEY_RIGHTCTRL,
> +        [98]  = KEY_KPSLASH,
> +        [99]  = KEY_SYSRQ,
> +        [100] = KEY_RIGHTALT,
> +        [101] = KEY_LINEFEED,
> +        [102] = KEY_HOME,
> +        [103] = KEY_UP,
> +        [104] = KEY_PAGEUP,
> +        [105] = KEY_LEFT,
> +        [106] = KEY_RIGHT,
> +        [107] = KEY_END,
> +        [108] = KEY_DOWN,
> +        [109] = KEY_PAGEDOWN,
> +        [110] = KEY_INSERT,
> +        [111] = KEY_DELETE,
> +        [112] = KEY_MACRO,
> +        [113] = KEY_MUTE,
> +        [114] = KEY_VOLUMEDOWN,
> +        [115] = KEY_VOLUMEUP,
> +        [116] = KEY_POWER,
> +        [117] = KEY_KPEQUAL,
> +        [118] = KEY_KPPLUSMINUS,
> +        [119] = KEY_PAUSE,
> +        [120] = KEY_SCALE,
> +        [121] = KEY_KPCOMMA,
> +        [122] = KEY_HANGEUL,
> +        [123] = KEY_HANGUEL,
> +        [124] = KEY_HANJA,
> +        [125] = KEY_YEN,
> +        [126] = KEY_LEFTMETA,
> +        [127] = KEY_RIGHTMETA,
> +        [128] = KEY_COMPOSE,
> +        [129] = NOKEY,
> +        [130] = NOKEY,
> +        [131] = NOKEY,
> +        [132] = NOKEY,
> +        [133] = NOKEY,
> +        [134] = NOKEY,
> +        [135] = NOKEY,
> +        [136] = NOKEY,
> +        [137] = NOKEY,
> +        [138] = NOKEY,
> +        [139] = NOKEY,
> +        [140] = NOKEY,
> +        [141] = NOKEY,
> +        [142] = NOKEY,
> +        [143] = NOKEY,
> +        [144] = NOKEY,
> +        [145] = NOKEY,
> +        [146] = NOKEY,
> +        [147] = NOKEY,
> +        [148] = NOKEY,
> +        [149] = NOKEY,
> +        [150] = NOKEY,
> +        [151] = NOKEY,
> +        [152] = NOKEY,
> +        [153] = NOKEY,
> +        [154] = NOKEY,
> +        [155] = NOKEY,
> +        [156] = NOKEY,
> +        [157] = NOKEY,
> +        [158] = NOKEY,
> +        [159] = NOKEY,
> +        [160] = NOKEY,
> +        [161] = NOKEY,
> +        [162] = NOKEY,
> +        [163] = NOKEY,
> +        [164] = NOKEY,
> +        [165] = NOKEY,
> +        [166] = NOKEY,
> +        [167] = NOKEY,
> +        [168] = NOKEY,
> +        [169] = NOKEY,
> +        [170] = NOKEY,
> +        [171] = NOKEY,
> +        [172] = NOKEY,
> +        [173] = NOKEY,
> +        [174] = NOKEY,
> +        [175] = NOKEY,
> +        [176] = NOKEY,
> +        [177] = NOKEY,
> +        [178] = NOKEY,
> +        [179] = NOKEY,
> +        [180] = NOKEY,
> +        [181] = NOKEY,
> +        [182] = NOKEY,
> +        [183] = NOKEY,
> +        [184] = NOKEY,
> +        [185] = NOKEY,
> +        [186] = NOKEY,
> +        [187] = NOKEY,
> +        [188] = NOKEY,
> +        [189] = KEY_HOME,
> +        [190] = NOKEY,
> +        [191] = NOKEY,
> +        [192] = NOKEY,
> +        [193] = NOKEY,
> +        [194] = NOKEY,
> +        [195] = NOKEY,
> +        [196] = NOKEY,
> +        [197] = NOKEY,
> +        [198] = NOKEY,
> +        [199] = NOKEY,
> +        [200] = NOKEY,
> +        [201] = NOKEY,
> +        [202] = NOKEY,
> +        [203] = NOKEY,
> +        [204] = NOKEY,
> +        [205] = KEY_END,
> +        [206] = NOKEY,
> +        [207] = NOKEY,
> +        [208] = NOKEY,
> +        [209] = NOKEY,
> +        [210] = NOKEY,
> +        [211] = NOKEY,
> +        [212] = NOKEY,
> +        [213] = NOKEY,
> +        [214] = NOKEY,
> +        [215] = NOKEY,
> +        [216] = NOKEY,
> +        [217] = NOKEY,
> +        [218] = NOKEY,
> +        [219] = NOKEY,
> +        [220] = KEY_VOLUMEUP,
> +        [221] = KEY_BRIGHTNESSUP,
> +        [222] = NOKEY,
> +        [223] = NOKEY,
> +        [224] = NOKEY,
> +        [225] = NOKEY,
> +        [226] = NOKEY,
> +        [227] = NOKEY,
> +        [228] = NOKEY,
> +        [229] = NOKEY,
> +        [230] = NOKEY,
> +        [231] = NOKEY,
> +        [232] = NOKEY,
> +        [233] = NOKEY,
> +        [234] = NOKEY,
> +        [235] = NOKEY,
> +        [236] = NOKEY,
> +        [237] = KEY_VOLUMEDOWN,
> +        [238] = NOKEY,
> +        [239] = NOKEY,
> +        [240] = NOKEY,
> +        [241] = NOKEY,
> +        [242] = NOKEY,
> +        [243] = NOKEY,
> +        [244] = NOKEY,
> +        [245] = NOKEY,
> +        [246] = NOKEY,
> +        [247] = NOKEY,
> +        [248] = NOKEY,
> +        [249] = NOKEY,
> +        [250] = NOKEY,
> +        [251] = NOKEY,
> +        [252] = NOKEY,
> +        [253] = KEY_BRIGHTNESSDOWN,
> +        [254] = NOKEY,
> +        [255] = NOKEY,
> +};
> +/*-----------------------------------------------------------------------------
> + * Global variables
> + *---------------------------------------------------------------------------*/
> +
> +struct input_dev *g_qci_keyboard_dev;
> +
> +/* General structure to hold the driver data */
> +struct i2ckbd_drv_data {
> +        struct i2c_client *ki2c_client;
> +        struct work_struct work;
> +        struct input_dev *qcikbd_dev;
> +        unsigned int qcikbd_gpio; /* GPIO used for interrupt */
> +        unsigned int qcikbd_irq;
> +        unsigned int key_down;
> +        unsigned int escape;
> +        unsigned int pause_seq;
> +        unsigned int fn;
> +};
> +#ifdef CONFIG_PM
> +static int qcikbd_suspend(struct device *dev)
> +{
> +        return 0;
> +}
> +
> +static int qcikbd_resume(struct device *dev)
> +{
> +        return 0;
> +}
> +#endif
> +static int __devinit qcikbd_probe(struct i2c_client *client,
> +        const struct i2c_device_id *id);
> +static int __devexit qcikbd_remove(struct i2c_client *kbd);
> +
> +static const struct i2c_device_id qcikbd_idtable[] = {
> +        { KEYBOARD_ID_NAME, 0 },
> +        { }
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, qcikbd_idtable);
> +
> +#ifdef CONFIG_PM
> +static struct dev_pm_ops qcikbd_pm_ops = {
> +        .suspend  = qcikbd_suspend,
> +        .resume   = qcikbd_resume,
> +};
> +#endif
> +static struct i2c_driver i2ckbd_driver = {
> +        .driver = {
> +                .owner = THIS_MODULE,
> +                .name  = KEYBOARD_ID_NAME,
> +#ifdef CONFIG_PM
> +                .pm = &qcikbd_pm_ops,
> +#endif
> +        },
> +        .probe    = qcikbd_probe,
> +        .remove = __devexit_p(qcikbd_remove),
> +        .id_table = qcikbd_idtable,
> +};
> +
> +/*-----------------------------------------------------------------------------
> + * Driver functions
> + *---------------------------------------------------------------------------*/
> +
> +static irqreturn_t qcikbd_interrupt(int irq, void *dev_id)
> +{
> +        struct i2ckbd_drv_data *ikbd_drv_data = dev_id;
> +        schedule_work(&ikbd_drv_data->work);
> +        return IRQ_HANDLED;
> +}
> +
> +static void qcikbd_work_handler(struct work_struct *_work)
> +{
> +        unsigned char scancode;
> +        unsigned int  keycode;
> +
> +        struct i2ckbd_drv_data *ikbd_drv_data =
> +                container_of(_work, struct i2ckbd_drv_data, work);
> +
> +        struct i2c_client *ikbdclient = ikbd_drv_data->ki2c_client;
> +        struct input_dev *ikbdev = ikbd_drv_data->qcikbd_dev;
> +
> +        scancode = i2c_smbus_read_byte(ikbdclient);
> +      printk("   scancode = %x\n", scancode);
> +
> +        if (scancode == 0xFA)
> +        {
> +                return;
> +        } else {
> +                ikbd_drv_data->key_down = 1;
> +                if (scancode & 0x80) {
> +                        ikbd_drv_data->key_down = 0;
> +                }
> +                keycode = on2_keycode[(scancode & 0x7F)];
> +                if (keycode != NOKEY) {
> +
> +                        input_event(ikbdev, EV_MSC, MSC_SCAN, scancode);
> +
> +                        input_report_key(ikbdev,
> +                                         keycode,
> +                                         ikbd_drv_data->key_down);
> +                        input_sync(ikbdev);
> +                }
> +        }
> +}
> +
> +
> +static int qcikbd_open(struct input_dev *dev)
> +{
> +        struct i2ckbd_drv_data *ikbd_drv_data = input_get_drvdata(dev);
> +        struct i2c_client *ikbdclient = ikbd_drv_data->ki2c_client;
> +
> +        /* Send F4h - enable keyboard */
> +        i2c_smbus_write_byte(ikbdclient, KEYBOARD_CMD_ENABLE);
> +        return 0;
> +}
> +
> +static int __devinit qcikbd_probe(struct i2c_client *client,
> +                                    const struct i2c_device_id *id)
> +{
> +        int err;
> +        int i;
> +        struct i2ckbd_drv_data *context;
> +        context = kzalloc(sizeof(struct i2ckbd_drv_data), GFP_KERNEL);
> +        if (!context)
> +                return -ENOMEM;
> +        i2c_set_clientdata(client, context);
> +        context->ki2c_client = client;
> +        context->qcikbd_gpio = client->irq;
> +        client->driver = &i2ckbd_driver;
> +
> +        INIT_WORK(&context->work, qcikbd_work_handler);
> +
> +        err = gpio_request(context->qcikbd_gpio, "qci-kbd");
> +        if (err) {
> +                pr_err("[KBD] err gpio request\n");
> +                goto gpio_request_fail;
> +        }
> +
> +        context->qcikbd_irq = gpio_to_irq(context->qcikbd_gpio);
> +        err = request_irq(context->qcikbd_irq,
> +                          qcikbd_interrupt,
> +                          IRQF_TRIGGER_FALLING,
> +                          KEYBOARD_ID_NAME,
> +                          context);
> +        if (err) {
> +                pr_err("[KBD] err unable to get IRQ\n");
> +                goto request_irq_fail;
> +        }
> +
> +        context->qcikbd_dev = input_allocate_device();
> +        if (!context->qcikbd_dev) {
> +                pr_err("[KBD]allocting memory err\n");
> +                err = -ENOMEM;
> +                goto allocate_fail;
> +        }
> +
> +        context->qcikbd_dev->name       = KEYBOARD_NAME;
> +        context->qcikbd_dev->phys       = KEYBOARD_DEVICE;
> +        context->qcikbd_dev->id.bustype = BUS_I2C;
> +        context->qcikbd_dev->id.vendor  = 0x1050;
> +        context->qcikbd_dev->id.product = 0x0006;
> +        context->qcikbd_dev->id.version = 0x0004;
> +        context->qcikbd_dev->open       = qcikbd_open;
> +        context->qcikbd_dev->evbit[0]   = BIT_MASK(EV_KEY);
> +
> +        /* Enable all supported keys */
> +        for (i = 1; i < ARRAY_SIZE(on2_keycode) ; i++)
> +                set_bit(on2_keycode[i], context->qcikbd_dev->keybit);
> +
> +        set_bit(KEY_POWER, context->qcikbd_dev->keybit);
> +        set_bit(KEY_END, context->qcikbd_dev->keybit);
> +        set_bit(KEY_VOLUMEUP, context->qcikbd_dev->keybit);
> +        set_bit(KEY_VOLUMEDOWN, context->qcikbd_dev->keybit);
> +        set_bit(KEY_ZOOMIN, context->qcikbd_dev->keybit);
> +        set_bit(KEY_ZOOMOUT, context->qcikbd_dev->keybit);
> +
> +        input_set_drvdata(context->qcikbd_dev, context);
> +        err = input_register_device(context->qcikbd_dev);
> +        if (err) {
> +                pr_err("[KBD] err input register device\n");
> +                goto register_fail;
> +        }
> +        g_qci_keyboard_dev = context->qcikbd_dev;
> +	printk("QCI_KBD PROBE\n");
> +        return 0;
> +register_fail:
> +        input_free_device(context->qcikbd_dev);
> +
> +allocate_fail:
> +        free_irq(context->qcikbd_irq, context);
> +
> +request_irq_fail:
> +        gpio_free(context->qcikbd_gpio);
> +
> +gpio_request_fail:
> +        i2c_set_clientdata(client, NULL);
> +        kfree(context);
> +        return err;
> +}
> +
> +static int __devexit qcikbd_remove(struct i2c_client *dev)
> +{
> +        struct i2ckbd_drv_data *context = i2c_get_clientdata(dev);
> +
> +        free_irq(context->qcikbd_irq, context);
> +        gpio_free(context->qcikbd_gpio);
> +        input_free_device(context->qcikbd_dev);
> +        input_unregister_device(context->qcikbd_dev);
> +        kfree(context);
> +
> +        return 0;
> +}
> +
> +static int __init qcikbd_init(void)
> +{
> +        return i2c_add_driver(&i2ckbd_driver);
> +}
> +
> +static void __exit qcikbd_exit(void)
> +{
> +        i2c_del_driver(&i2ckbd_driver);
> +}
> +
> +struct input_dev *nkbc_keypad_get_input_dev(void)
> +{
> +        return g_qci_keyboard_dev;
> +}
> +EXPORT_SYMBOL(nkbc_keypad_get_input_dev);
> +module_init(qcikbd_init);
> +module_exit(qcikbd_exit);
> +
> +MODULE_AUTHOR("Quanta Computer Inc.");
> +MODULE_DESCRIPTION("Quanta Embedded Controller I2C Keyboard Driver");
> +MODULE_LICENSE("GPL v2");
> +
> -- 
> 1.7.0.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Dmitry

  reply	other threads:[~2010-07-26  8:55 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-26  8:30 [RFC 01/36] [Driver][Qualcomm 1070][LCD] Resolve the booting to Chromium issue Wayne Lin
2010-07-26  8:30 ` [RFC 02/36] [Driver][Qualcomm 1070][USB] Register GPIO#109 for USB analog switch configuration Wayne Lin
2010-07-26  8:30 ` [RFC 04/36] [Driver][Qualcomm 1070][EC_KB] Adding new qci keyboard driver Wayne Lin
2010-07-26  8:55   ` Dmitry Torokhov [this message]
2010-07-26 11:16     ` Trilok Soni
2010-07-26  8:59   ` Datta, Shubhrajyoti
2010-07-26  8:30 ` [RFC 05/36] [Driver][Qualcomm 1070][TPM] Enable TPM module Wayne Lin
2010-07-26  8:30 ` [RFC 06/36] [Driver][Qualcomm 1070][EC_BRG] EC Bridge driver porting Wayne Lin
2010-07-26  8:30 ` [RFC 07/36] [Driver][Qualcomm 1070][EC_BRG] Enable EC Bridge Wayne Lin
2010-07-26  8:30 ` [RFC 08/36] [Driver][Qualcomm 1070][EC_BAT] EC battery driver porting Wayne Lin
2010-07-26  8:30 ` [RFC 09/36] [Driver][Qualcomm 1070][EC_BAT] Enable EC battery Wayne Lin
2010-07-26  8:30 ` [RFC 11/36] [Driver][Qualcomm 1070][EC_G_SENSOR] Enable EC gravitation sensor Wayne Lin
2010-07-26  8:30 ` [RFC 12/36] [Driver][Qualcomm 1070][EC_C_SENSOR] EC compass sensor driver porting Wayne Lin
2010-07-26  8:30 ` [RFC 13/36] [Driver][Qualcomm 1070][EC_C_SENSOR] Enable EC compass sensor driver Wayne Lin
2010-07-26  8:30 ` [RFC 14/36] [Driver][Qualcomm 1070][CLOCK] Modify the AXI bus speed Wayne Lin
2010-07-26  8:30 ` [RFC 15/36] [Driver][Qualcomm 1070][VERSION] Adding version definition Wayne Lin
2010-07-26  8:30 ` [RFC 17/36] [Driver][Qualcomm 1070][WIFI/BT] Enable Athros WIFI driver Wayne Lin
2010-07-26  8:30 ` [RFC 18/36] [Driver][Qualcomm 1070][WIFI] Turn on the Athros WIFI power Wayne Lin
2010-07-26  8:30 ` [RFC 19/36] [Driver][Qualcomm 1070][BT] Enable Athros BT driver Wayne Lin
2010-07-26  8:30 ` [RFC 20/36] [Driver][Qualcomm 1070][WIFI/BT] Enable MMC1 dummy send read and configure Athros WIFI build-in driver Wayne Lin
2010-07-26  8:30 ` [RFC 21/36] Revert " [Driver][Qualcomm 1070][CLOCK] Modify the AXI bus speed" Wayne Lin
2010-07-26  8:46   ` Dmitry Torokhov
2010-07-26  8:30 ` [RFC 22/36] [Driver][Qualcomm 1070][CLOCK] Modify the AXI bus maximum speed Wayne Lin
2010-07-26  8:30 ` [RFC 23/36] [Driver][Qualcomm 1065][AT_COMMAND]retrieve message Wayne Lin
2010-07-26  8:30 ` [RFC 24/36] [Driver][Qualcomm 1070][CLOCK] Modify the AXI clock for 1.2Ghz Wayne Lin
2010-07-26  8:30 ` [RFC 25/36] [Driver][Qualcomm 1070][EC_BRG] Adding new EC bridge driver Wayne Lin
2010-07-26  8:30 ` [RFC 26/36] [Driver][Qualcomm 1070][EC_BL] New EC backlight driver porting Wayne Lin
2010-07-26  8:30 ` [RFC 27/36] [Driver][Qualcomm 1070][EC_BRG] Enable NuvoTon WPCE775X driver and disable WinBond WPCE775X driver Wayne Lin
2010-07-26  8:30 ` [RFC 28/36] [Driver][Qualcomm 1070][EC_BL] Enable QCI backlight driver Wayne Lin
2010-07-26  8:30 ` [RFC 29/36] [Driver][Qualcomm 1070][EC_BRG] Correct new EC bridge driver Makefile and Kconfig Wayne Lin
2010-07-26  8:30 ` [RFC 30/36] [Driver][Qualcomm 1070][EC_G_SENSOR] Enable EC gravitation sensor Wayne Lin
2010-07-26  8:30 ` [RFC 31/36] [Driver][Qualcomm 1070][VERSION] 0.1.1 Wayne Lin
2010-07-26  8:30 ` [RFC 32/36] [Driver][Qualcomm 1070][MMC] Enable MMC1 HW detection Wayne Lin
2010-07-26  8:30 ` [RFC 33/36] [Driver][Qualcomm 1070][VERSION] 0.1.2 Wayne Lin
2010-07-26  8:30 ` [RFC 34/36] [Driver][Qualcomm 1070][EC_BAT] Adding newer version battery driver Wayne Lin
2010-07-26  8:30 ` [RFC 35/36] [Driver][Qualcomm 1070][EC_BAT] Enable EC battery Wayne Lin
2010-07-26  8:30 ` [RFC 36/36] [Driver][Qualcomm 1070][VERSION] 0.2.0 Wayne Lin
2010-07-26  8:40   ` Premi, Sanjeev
2010-07-26  8:47   ` Premi, Sanjeev

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=20100726085507.GB27151@core.coreip.homeip.net \
    --to=dmitry.torokhov@gmail.com \
    --cc=00601wayne@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=wayne.lin@quantatw.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.