@@ 1,9 1,11 @@
#include <linux/backlight.h>
#include <linux/delay.h>
+#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
+#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ 52,18 54,21 @@ struct ppbbq10_data {
struct input_dev *input;
};
+
/* function declarations */
static int ppbbq10_backlight_update_status(struct backlight_device *bd);
static void __exit ppbbq10_exit(void);
static int __init ppbbq10_init(void);
static irqreturn_t ppbbq10_irq_handler(int irq, void *dev_id);
-static int ppbbq10_probe(struct i2c_client *client, const struct i2c_device_id *id);
+static int ppbbq10_poll_kthread(void *data);
+static int ppbbq10_probe(struct i2c_client *client);
static void ppbbq10_read_fifo(struct ppbbq10_data *drv_data);
static int ppbbq10_read_reg(struct ppbbq10_data *drv_data, u8 reg, u8 *buf, u8 len);
static void ppbbq10_update_locks(struct ppbbq10_data *drv_data);
static int ppbbq10_write_data(struct ppbbq10_data *drv_data, u8 reg, const u8 *buf, u8 len);
static int ppbbq10_write_reg(struct ppbbq10_data *drv_data, u8 reg);
+
/* variables */
static unsigned short keymap_norm[NUM_KEYCODES] = {
[0x01] = KEY_UP,
@@ 123,6 128,9 @@ static struct backlight_properties backlight_props = {
.max_brightness = 255,
.brightness = 127,
};
+static struct task_struct *ppbbq10_kthread;
+struct ppbbq10_data *drv_data;
+
/* function implementations */
static int
@@ 140,6 148,8 @@ ppbbq10_exit(void)
{
printk(KERN_INFO "Unregister ppbbq10 kernel module.\n");
i2c_unregister_device(client);
+ kthread_stop(ppbbq10_kthread);
+
/*i2c_del_driver(&ppbbq10_driver);*/
}
@@ 154,13 164,15 @@ ppbbq10_init(void)
}
client = i2c_new_client_device(adapter, ppbbq10_i2c_board_info);
//client->irq = gpio_to_irq(2);
+ ppbbq10_probe(client);
+ ppbbq10_kthread = kthread_create(ppbbq10_poll_kthread, NULL, "ppbbq10_pollthread");
+ wake_up_process(ppbbq10_kthread);
return 0;
}
static irqreturn_t
ppbbq10_irq_handler(int irq, void *dev_id)
{
- struct ppbbq10_data *drv_data = dev_id;
struct i2c_client *client = drv_data->client;
int error;
u8 reg;
@@ 197,11 209,19 @@ ppbbq10_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int ppbbq10_poll_kthread(void *data)
+{
+ while (!kthread_should_stop()) {
+ usleep_range(1000 * 10, (1000 * 10) + 1); // 10ms poll
+ ppbbq10_irq_handler(0, NULL);
+ }
+ return 0;
+}
+
static int
-ppbbq10_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ppbbq10_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
- struct ppbbq10_data *drv_data;
struct backlight_device *bd;
struct input_dev *input;
int error;
@@ 276,7 296,7 @@ ppbbq10_probe(struct i2c_client *client, const struct i2c_device_id *id)
client->name, drv_data);
if (error) {
dev_err(dev, "Failed to claim irq %d; error %d\n", client->irq, error);
- return error;
+ //return error;
}
error = input_register_device(input);