[Armadeus-commitlog] armadeus branch, master, updated. release-3.2-508-g5d8ba17
Brought to you by:
sszy
|
From: Fabien M <fa...@us...> - 2010-07-01 12:29:30
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via 5d8ba1710593b2adc5d5a0290c22a1d8e7fd0b3a (commit)
from 9d9d471c44c8df8d92bd4ccd07de7efb0cd98b73 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 5d8ba1710593b2adc5d5a0290c22a1d8e7fd0b3a
Author: Fabien Marteau <fab...@ar...>
Date: Thu Jul 1 14:28:29 2010 +0200
[linux] Working version of as5011 joystick driver
-----------------------------------------------------------------------
Summary of changes:
...us-joystick-adding_as5011_joystick_driver.patch | 362 ++++++++++++++++++--
1 files changed, 334 insertions(+), 28 deletions(-)
diff --git a/buildroot/target/device/armadeus/linux/kernel-patches/2.6.29/359-armadeus-joystick-adding_as5011_joystick_driver.patch b/buildroot/target/device/armadeus/linux/kernel-patches/2.6.29/359-armadeus-joystick-adding_as5011_joystick_driver.patch
index 71598d7..24292bf 100644
--- a/buildroot/target/device/armadeus/linux/kernel-patches/2.6.29/359-armadeus-joystick-adding_as5011_joystick_driver.patch
+++ b/buildroot/target/device/armadeus/linux/kernel-patches/2.6.29/359-armadeus-joystick-adding_as5011_joystick_driver.patch
@@ -5,8 +5,8 @@ Signed-off-by: Fabien Marteau <fab...@ar...>
Index: linux-2.6.29.6/drivers/input/joystick/as5011.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.29.6/drivers/input/joystick/as5011.c 2010-06-25 17:58:01.000000000 +0200
-@@ -0,0 +1,200 @@
++++ linux-2.6.29.6/drivers/input/joystick/as5011.c 2010-07-01 14:26:46.000000000 +0200
+@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2010 Fabien Marteau <fab...@ar...>
+ *
@@ -31,6 +31,9 @@ Index: linux-2.6.29.6/drivers/input/joystick/as5011.c
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * TODO:
++ * - Manage power mode
+ */
+
+#include <linux/module.h>
@@ -52,6 +55,7 @@ Index: linux-2.6.29.6/drivers/input/joystick/as5011.c
+
+#include <linux/input.h>
+#include <linux/gpio.h>
++#include <linux/workqueue.h>
+
+#include <linux/as5011.h>
+#define DRIVER_DESC "Driver for Austria Microsystems AS5011 joystick"
@@ -61,34 +65,134 @@ Index: linux-2.6.29.6/drivers/input/joystick/as5011.c
+MODULE_LICENSE("GPL");
+
+#define SIZE_NAME 30
++#define AS5011_MAX_AXIS 80
++#define AS5011_MIN_AXIS (-80)
++#define AS5011_FUZZ 8
++#define AS5011_FLAT 40
++
++static int g_num = 0; /* device counter */
++
++static signed char as5011_i2c_read(struct i2c_client *client,
++ uint8_t aRegAddr);
++static int as5011_i2c_write(struct i2c_client *client,
++ uint8_t aRegAddr,
++ uint8_t aValue);
++
+/*
-+ * input operations
++ * interrupts operations
+ */
+
+static irqreturn_t button_interrupt(int irq, void *dev_id)
+{
+ struct as5011_platform_data *plat_dat = (struct as5011_platform_data *)dev_id;
+ int ret;
++
+ ret = gpio_get_value(plat_dat->button_gpio);
-+ input_report_key(plat_dat->input_dev, BTN_0, 1);
++ if (ret) {
++ input_report_key(plat_dat->input_dev, BTN_JOYSTICK, 0);
++ } else {
++ input_report_key(plat_dat->input_dev, BTN_JOYSTICK, 1);
++ }
+ input_sync(plat_dat->input_dev);
+ return IRQ_HANDLED;
+}
+
++static void as5011_update_axes(struct work_struct *work)
++{
++ struct as5011_platform_data *plat_dat = container_of(work, struct as5011_platform_data, update_axes_work);
++ signed char x, y;
++
++ x = as5011_i2c_read(plat_dat->i2c_client, AS5011_X_RES_INT);
++ y = as5011_i2c_read(plat_dat->i2c_client, AS5011_Y_RES_INT);
++ input_report_abs(plat_dat->input_dev, ABS_X, x);
++ input_report_abs(plat_dat->input_dev, ABS_Y, y);
++ input_sync(plat_dat->input_dev);
++}
++
++static irqreturn_t as5011_int_interrupt(int irq, void *dev_id)
++{
++ struct as5011_platform_data *plat_dat = (struct as5011_platform_data *)dev_id;
++
++ queue_work(plat_dat->workqueue, &plat_dat->update_axes_work);
++
++ return IRQ_HANDLED;
++}
++
+/*
+ * I2C bus operation
+ */
++
++static int as5011_i2c_write(struct i2c_client *client,
++ uint8_t aRegAddr,
++ uint8_t aValue)
++{
++ int ret;
++ uint8_t data[2] = { aRegAddr, aValue };
++ struct i2c_msg msg = { client->addr, I2C_M_IGNORE_NAK, 2, (uint8_t *)data };
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ return -EINVAL;
++ }
++ return 1;
++}
++
++static signed char as5011_i2c_read(struct i2c_client *client,
++ uint8_t aRegAddr)
++{
++ int ret;
++ uint8_t data[2];
++ struct i2c_msg msg_set[2];
++ struct i2c_msg msg1 = {client->addr, I2C_M_REV_DIR_ADDR, 1, (uint8_t *)data};
++ struct i2c_msg msg2 = {client->addr, I2C_M_RD|I2C_M_NOSTART, 1, (uint8_t *)data};
++
++ data[0] = aRegAddr;
++ msg_set[0] = msg1;
++ msg_set[1] = msg2;
++
++ ret = i2c_transfer(client->adapter, msg_set, 2);
++ if (ret < 0) {
++ return -EINVAL;
++ }
++
++ if (data[0] & 0x80) {
++ return (-1*(1+(~data[0])));
++ } else {
++ return data[0];
++ }
++}
++
+static int as5011_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct as5011_platform_data *plat_dat = client->dev.platform_data;
+ int retval = 0;
+
++ plat_dat->num = g_num;
++ g_num++;
++
++ retval = snprintf(plat_dat->workqueue_name, SIZE_NAME, "as5011_%d_workqueue", plat_dat->num);
++ if (retval < 0)
++ {
++ dev_err(&client->dev, "as5011: Failed to give workqueue name\n");
++ retval = -1;
++ goto workqueue_name_error;
++ }
++ plat_dat->workqueue = create_singlethread_workqueue(plat_dat->workqueue_name);
++ if (plat_dat->workqueue == NULL) {
++ dev_err(&client->dev, "as5011: Failed to create workqueue\n");
++ retval = -EINVAL;
++ goto workqueue_create_error;
++ }
++
++ INIT_WORK(&plat_dat->update_axes_work, as5011_update_axes);
++
+ if (!i2c_check_functionality(client->adapter,I2C_FUNC_PROTOCOL_MANGLING)) {
+ dev_err(&client->dev,
+ "i2c bus does not support protocol mangling, as5011 can't work\n");
+ retval = -ENODEV;
+ goto i2c_protocol_error;
+ }
++ plat_dat->i2c_client = client;
+
+ plat_dat->input_dev = input_allocate_device();
+ if (plat_dat->input_dev < 0) {
@@ -98,10 +202,21 @@ Index: linux-2.6.29.6/drivers/input/joystick/as5011.c
+ goto input_allocate_device_error;
+ }
+
-+ plat_dat->input_dev->evbit[0] = BIT_MASK(EV_KEY);
-+ plat_dat->input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
-+
-+ plat_dat->button_irq_name = (unsigned char *)kmalloc(sizeof(unsigned char)*SIZE_NAME, GFP_KERNEL);
++ plat_dat->input_dev->name = "Austria Microsystem as5011 joystick";
++ plat_dat->input_dev->uniq = "Austria0";//XXX
++ plat_dat->input_dev->id.bustype = BUS_I2C;
++ plat_dat->input_dev->phys = "/dev/input/event0";//XXX
++ plat_dat->input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
++ plat_dat->input_dev->keybit[BIT_WORD(BTN_JOYSTICK)] = BIT_MASK(BTN_JOYSTICK);
++
++ input_set_abs_params(plat_dat->input_dev, ABS_X,
++ AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
++ input_set_abs_params(plat_dat->input_dev, ABS_Y,
++ AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
++
++ plat_dat->button_irq_name =
++ (unsigned char *)kmalloc(sizeof(unsigned char)*SIZE_NAME,
++ GFP_KERNEL);
+ if (plat_dat->button_irq_name == NULL)
+ {
+ dev_err(&client->dev,
@@ -115,43 +230,154 @@ Index: linux-2.6.29.6/drivers/input/joystick/as5011.c
+ if (retval < 0)
+ {
+ dev_err(&client->dev, "as5011: Failed to give button irq name\n");
-+ retval = -1; //FIXME:Â find the right code
++ retval = -EINVAL;
+ goto button_irq_name_error;
+ }
+
+ if (request_irq(plat_dat->button_irq, button_interrupt,
+ 0, plat_dat->button_irq_name, (void *)plat_dat)) {
-+ dev_err(&client->dev, "as5011: Can't allocate irq %d\n",
++ dev_err(&client->dev, "as5011: Can't allocate irq %d\n",
+ plat_dat->button_irq);
-+ retval = -EBUSY;
++ retval = -EBUSY;
+ goto request_irq_error;
-+ }
++ }
++
++ plat_dat->int_irq_name =
++ (unsigned char *)kmalloc(sizeof(unsigned char)*SIZE_NAME,
++ GFP_KERNEL);
++ if (plat_dat->int_irq_name == NULL)
++ {
++ dev_err(&client->dev,
++ "not enough memory for input devices int irq name\n");
++ retval = -ENOMEM;
++ goto input_allocate_int_device_name_error;
++ }
++
++ retval = snprintf(plat_dat->int_irq_name, SIZE_NAME, "as5011_%d_int", plat_dat->num);
++ if (retval < 0)
++ {
++ dev_err(&client->dev, "as5011: Failed to give int irq name\n");
++ retval = -EINVAL;
++ goto int_irq_name_error;
++ }
++
++
++ if (request_irq(plat_dat->int_irq, as5011_int_interrupt,
++ 0, plat_dat->int_irq_name, (void *)plat_dat)) {
++ dev_err(&client->dev, "as5011: Can't allocate int irq %d\n",
++ plat_dat->int_irq);
++ retval = -EBUSY;
++ goto request_int_irq_error;
++ }
+
+ retval = input_register_device(plat_dat->input_dev);
+ if (retval) {
+ dev_err(&client->dev, "as5011: Failed to register device\n");
-+ retval = -1; //FIXME:Â find the right code
++ retval = -EINVAL;
+ goto input_register_device_error;
+ }
+
+ retval = plat_dat->init_gpio();
+ if (retval < 0) {
+ dev_err(&client->dev, "as5011: Failed to init gpios\n");
-+ retval = -1; //FIXME:Â find the right code
++ retval = -EINVAL;
+ goto init_gpio_error;
+ }
+
++ /* chip soft reset */
++ retval = as5011_i2c_write(plat_dat->i2c_client,
++ AS5011_CTRL1,
++ AS5011_CTRL1_SOFT_RST);
++ if (retval < 0) {
++ dev_err(&plat_dat->i2c_client->dev,
++ "as5011: soft reset failed\n");
++ retval = -EINVAL;
++ goto soft_reset_error;
++ }
++
++ retval = as5011_i2c_write(plat_dat->i2c_client,
++ AS5011_CTRL1,
++ AS5011_CTRL1_LP_PULSED |
++ //AS5011_CTRL1_LP_ACTIVE |
++ //AS5011_CTRL1_INT_ACT_EN|
++ AS5011_CTRL1_INT_WUP_EN
++ );
++ if (retval < 0) {
++ dev_err(&plat_dat->i2c_client->dev,
++ "as5011: power config failed\n");
++ retval = -EINVAL;
++ goto soft_reset_error;
++ }
+
++ retval = as5011_i2c_write(plat_dat->i2c_client,
++ AS5011_CTRL2,
++ AS5011_CTRL2_INV_SPINNING);
++ if (retval < 0) {
++ dev_err(&plat_dat->i2c_client->dev,
++ "as5011: can't invert spinning\n");
++ retval = -EINVAL;
++ goto invert_spinning_error;
++ }
++
++ /* write threshold */
++ retval = as5011_i2c_write(plat_dat->i2c_client,
++ AS5011_XP,
++ plat_dat->Xp);
++ if (retval < 0) {
++ dev_err(&plat_dat->i2c_client->dev,
++ "as5011: can't write threshold\n");
++ retval = -EINVAL;
++ goto threshold_error;
++ }
++
++ retval = as5011_i2c_write(plat_dat->i2c_client,
++ AS5011_XN,
++ plat_dat->Xn);
++ if (retval < 0) {
++ dev_err(&plat_dat->i2c_client->dev,
++ "as5011: can't write threshold\n");
++ retval = -EINVAL;
++ goto threshold_error;
++ }
++
++ retval = as5011_i2c_write(plat_dat->i2c_client,
++ AS5011_YP,
++ plat_dat->Yp);
++ if (retval < 0) {
++ dev_err(&plat_dat->i2c_client->dev,
++ "as5011: can't write threshold\n");
++ retval = -EINVAL;
++ goto threshold_error;
++ }
++
++ retval = as5011_i2c_write(plat_dat->i2c_client,
++ AS5011_YN,
++ plat_dat->Yn);
++ if (retval < 0) {
++ dev_err(&plat_dat->i2c_client->dev,
++ "as5011: can't write threshold\n");
++ retval = -EINVAL;
++ goto threshold_error;
++ }
++
++ /* to free irq gpio in chip*/
++ as5011_i2c_read(plat_dat->i2c_client, AS5011_X_RES_INT);
+
-+ printk(KERN_DEBUG "as5011 probed\n");//XXX
+ return 0;
+
+ /* Error management */
-+
++threshold_error:
++invert_spinning_error:
++soft_reset_error:
+ plat_dat->exit_gpio();
+init_gpio_error:
+ input_unregister_device(plat_dat->input_dev);
+input_register_device_error:
++ free_irq(plat_dat->int_irq, as5011_int_interrupt);
++request_int_irq_error:
++int_irq_name_error:
++ kfree(plat_dat->int_irq_name);
++input_allocate_int_device_name_error:
+ free_irq(plat_dat->button_irq, button_interrupt);
+request_irq_error:
+button_irq_name_error:
@@ -160,19 +386,24 @@ Index: linux-2.6.29.6/drivers/input/joystick/as5011.c
+ input_free_device(plat_dat->input_dev);
+input_allocate_device_error:
+i2c_protocol_error:
++ destroy_workqueue(plat_dat->workqueue);
++workqueue_create_error:
++ kfree(plat_dat->workqueue_name);
++workqueue_name_error:
+ return retval;
+}
+static int as5011_remove(struct i2c_client *client)
+{
+ struct as5011_platform_data *plat_dat = client->dev.platform_data;
+
++ destroy_workqueue(plat_dat->workqueue);
+ input_unregister_device(plat_dat->input_dev);
+ free_irq(plat_dat->button_irq, plat_dat);
++ free_irq(plat_dat->int_irq, plat_dat);
+ kfree(plat_dat->button_irq_name);
+ input_free_device(plat_dat->input_dev);
+ plat_dat->exit_gpio();
+
-+ printk(KERN_DEBUG "as5011_remove\n");//XXX
+ return 0;
+}
+static const struct i2c_device_id as5011_id[] = {
@@ -184,9 +415,9 @@ Index: linux-2.6.29.6/drivers/input/joystick/as5011.c
+ .driver = {
+ .name = "as5011",
+ },
-+ .probe = as5011_probe,
-+ .remove = as5011_remove,
-+ .id_table = as5011_id,
++ .probe = as5011_probe,
++ .remove = as5011_remove,
++ .id_table = as5011_id,
+};
+
+/*
@@ -195,22 +426,20 @@ Index: linux-2.6.29.6/drivers/input/joystick/as5011.c
+
+static int __init as5011_init(void)
+{
-+ printk(KERN_DEBUG "as5011_init\n");//XXX
-+ return i2c_add_driver(&as5011_driver);
++ return i2c_add_driver(&as5011_driver);
+}
+
+static void __exit as5011_exit(void)
+{
-+ printk(KERN_DEBUG "as5011_exit\n");//XXX
-+ i2c_del_driver(&as5011_driver);
++ i2c_del_driver(&as5011_driver);
+}
+
+module_init(as5011_init);
+module_exit(as5011_exit);
Index: linux-2.6.29.6/drivers/input/joystick/Kconfig
===================================================================
---- linux-2.6.29.6.orig/drivers/input/joystick/Kconfig 2010-06-24 15:11:45.000000000 +0200
-+++ linux-2.6.29.6/drivers/input/joystick/Kconfig 2010-06-24 15:15:16.000000000 +0200
+--- linux-2.6.29.6.orig/drivers/input/joystick/Kconfig 2009-03-24 00:12:14.000000000 +0100
++++ linux-2.6.29.6/drivers/input/joystick/Kconfig 2010-06-28 09:20:47.000000000 +0200
@@ -254,6 +254,15 @@
To compile this driver as a module, choose M here: the
module will be called amijoy.
@@ -229,8 +458,8 @@ Index: linux-2.6.29.6/drivers/input/joystick/Kconfig
select GAMEPORT
Index: linux-2.6.29.6/drivers/input/joystick/Makefile
===================================================================
---- linux-2.6.29.6.orig/drivers/input/joystick/Makefile 2010-06-24 15:11:05.000000000 +0200
-+++ linux-2.6.29.6/drivers/input/joystick/Makefile 2010-06-24 15:11:27.000000000 +0200
+--- linux-2.6.29.6.orig/drivers/input/joystick/Makefile 2009-03-24 00:12:14.000000000 +0100
++++ linux-2.6.29.6/drivers/input/joystick/Makefile 2010-06-28 09:20:47.000000000 +0200
@@ -7,6 +7,7 @@
obj-$(CONFIG_JOYSTICK_A3D) += a3d.o
obj-$(CONFIG_JOYSTICK_ADI) += adi.o
@@ -239,3 +468,80 @@ Index: linux-2.6.29.6/drivers/input/joystick/Makefile
obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o
obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o
obj-$(CONFIG_JOYSTICK_DB9) += db9.o
+Index: linux-2.6.29.6/include/linux/as5011.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.29.6/include/linux/as5011.h 2010-07-01 11:11:11.000000000 +0200
+@@ -0,0 +1,72 @@
++#ifndef _AS5011_H
++#define _AS5011_H
++
++/*
++ * Copyright (c) 2010 Fabien Marteau
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ */
++
++#define AS5011_MAX_NAME_LENGTH 64
++#define AS5011_MAX_CNAME_LENGTH 16
++#define AS5011_MAX_PHYS_LENGTH 64
++#define AS5011_MAX_LENGTH 64
++
++/* registers */
++#define AS5011_CTRL1 0x76
++#define AS5011_CTRL2 0x75
++#define AS5011_XP 0x43
++#define AS5011_XN 0x44
++#define AS5011_YP 0x53
++#define AS5011_YN 0x54
++#define AS5011_X_REG 0x41
++#define AS5011_Y_REG 0x42
++#define AS5011_X_RES_INT 0x51
++#define AS5011_Y_RES_INT 0x52
++
++/* CTRL1 bits */
++#define AS5011_CTRL1_LP_PULSED 0x80
++#define AS5011_CTRL1_LP_ACTIVE 0x40
++#define AS5011_CTRL1_LP_CONTINUE 0x20
++#define AS5011_CTRL1_INT_WUP_EN 0x10
++#define AS5011_CTRL1_INT_ACT_EN 0x08
++#define AS5011_CTRL1_EXT_CLK_EN 0x04
++#define AS5011_CTRL1_SOFT_RST 0x02
++#define AS5011_CTRL1_DATA_VALID 0x01
++
++/* CTRL2 bits */
++#define AS5011_CTRL2_EXT_SAMPLE_EN 0x08
++#define AS5011_CTRL2_RC_BIAS_ON 0x04
++#define AS5011_CTRL2_INV_SPINNING 0x02
++
++
++struct as5011_platform_data {
++ /* public */
++ int button_gpio;
++ int button_irq;
++ int int_gpio;
++ int int_irq;
++ char Xp, Xn; /* threshold for x axis */
++ char Yp, Yn; /* threshold for y axis */
++
++ int (*init_gpio)(void); /* init interrupts gpios */
++ void (*exit_gpio)(void);/* exit gpios */
++
++ /* private */
++ int num;
++ struct input_dev *input_dev;
++ struct i2c_client *i2c_client;
++ unsigned char *button_irq_name;
++ unsigned char *int_irq_name;
++ char name[AS5011_MAX_NAME_LENGTH];
++ char cname[AS5011_MAX_CNAME_LENGTH];
++ char phys[AS5011_MAX_PHYS_LENGTH];
++ unsigned char data[AS5011_MAX_LENGTH];
++ char workqueue_name[AS5011_MAX_NAME_LENGTH];
++ struct workqueue_struct *workqueue;
++ struct work_struct update_axes_work;
++};
++
++#endif /* _AS5011_H */
hooks/post-receive
--
armadeus
|