From 48aae93268a5788f399f0df6074f458a5373ba1a Mon Sep 17 00:00:00 2001 From: Angelo Arrifano Date: Thu, 24 Sep 2009 02:48:39 +0100 Subject: [PATCH 3/3] htcpld: Cleanup the driver. * Improve driver Kconfig description. * Remove unused variables. * Scan/fix code format with checkpatch.pl * Rename the driver as other chip drivers were renamed too. Signed-off-by: Angelo Arrifano --- drivers/i2c/chips/Kconfig | 12 +- drivers/i2c/chips/Makefile | 2 +- drivers/i2c/chips/htcpld.c | 410 +++++++++++++++++++++++++++++++++++++++ drivers/i2c/chips/i2c-htcpld.c | 412 ---------------------------------------- include/linux/i2c/htcpld.h | 16 ++ include/linux/i2c/i2c-htcpld.h | 16 -- 6 files changed, 433 insertions(+), 435 deletions(-) create mode 100644 drivers/i2c/chips/htcpld.c delete mode 100644 drivers/i2c/chips/i2c-htcpld.c create mode 100644 include/linux/i2c/htcpld.h delete mode 100644 include/linux/i2c/i2c-htcpld.h diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 5f36b4b..5519e90 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -75,11 +75,11 @@ config SENSORS_TSL2550 will be called tsl2550. config I2C_HTCPLD - tristate "HTC CPLD on I2C" - depends on I2C=y && EXPERIMENTAL + tristate "HTC Wizard/Herald CPLD" + depends on I2C=y help - If you say yes here you get support for the unknown cpld device - found on HTC omap850 boards. This device controls backlight, - leds, rumble and also the dpad. - + If you say yes here you get support for the unknown CPLD + found on omap850 HTC devices like the HTC Wizard and HTC Herald. + This driver allows controlling the backlight, leds, rumble and + creates a inputdev for the directional pad. endmenu diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index 295bbc9..8650012 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_PCF8575) += pcf8575.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o -obj-$(CONFIG_I2C_HTCPLD) += i2c-htcpld.o +obj-$(CONFIG_I2C_HTCPLD) += htcpld.o ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/i2c/chips/htcpld.c b/drivers/i2c/chips/htcpld.c new file mode 100644 index 0000000..849df12 --- /dev/null +++ b/drivers/i2c/chips/htcpld.c @@ -0,0 +1,410 @@ +/* + * i2c-htcpld.c + * Chip driver for a unknown cpld found on HTC boards with omap850. + * The cpld is located on the i2c bus and controls backlight, leds, + * vibrator and other power devices. The cpld also returns buttons status + * of the directional pads found on this HTC devices. + * + * Copyright (C) 2009 Cory Maccarrone + * Copyright (C) 2008-2009 Angelo Arrifano + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define HTCPLD_ADDR_MAX 16 + +struct htcpld_chip_data { + u8 reset; + u8 cache; +}; + +static struct i2c_client *htcpld_chip[HTCPLD_ADDR_MAX]; +static struct i2c_client *htcpld_dkbd_chip; +static struct i2c_client *htcpld_dpad_chip; + +static const unsigned char htcpld_btns_map[] = { + KEY_RIGHT, + KEY_UP, + KEY_LEFT, + KEY_DOWN, + KEY_ENTER +}; + +struct htcpld_btns_dev { + unsigned char keycode[ARRAY_SIZE(htcpld_btns_map)]; + char keymap[ARRAY_SIZE(htcpld_btns_map)]; + char previous_keymap[ARRAY_SIZE(htcpld_btns_map)]; + int irq; + int poll_interval; + struct input_dev *input; + struct timer_list timer; +}; + +struct platform_device *htcpld_pdev = NULL; +void htcpld_btns_poll(unsigned long data); +void htcpld_btns_dowork(struct work_struct *data); + +DECLARE_DELAYED_WORK(htcpld_work, &htcpld_btns_dowork); + +void htcpld_chip_set(u8 chip_addr, u8 val) +{ + struct htcpld_chip_data *chip_data; + + if (chip_addr > HTCPLD_ADDR_MAX) + return; + + if (! htcpld_chip[chip_addr]) + return; + + chip_data = i2c_get_clientdata(htcpld_chip[chip_addr]); + if (! chip_data) + return; + + i2c_smbus_read_byte_data(htcpld_chip[chip_addr], + (chip_data->cache = val)); +} + +u8 htcpld_chip_get(u8 chip_addr) +{ + struct htcpld_chip_data *chip_data; + + if (! htcpld_chip[chip_addr]) + return 0; + + chip_data = i2c_get_clientdata(htcpld_chip[chip_addr]); + if (! chip_data) + return 0; + + return chip_data->cache; +} + + +void htcpld_chip_reset(u8 chip_addr) +{ + struct htcpld_chip_data *chip_data; + + if (chip_addr > HTCPLD_ADDR_MAX) + return; + + if (! htcpld_chip[chip_addr]) + return; + + chip_data = i2c_get_clientdata(htcpld_chip[chip_addr]); + if (! chip_data) + return; + + i2c_smbus_read_byte_data(htcpld_chip[chip_addr], + (chip_data->cache = chip_data->reset)); +} + + +/* + * Driver handling + */ + +static inline u8 _htcpld_chip_cache_read(struct i2c_client *client) +{ + return i2c_smbus_read_byte_data(client, + ((struct htcpld_chip_data *)i2c_get_clientdata(client))->cache); +} + +static int htcpld_probe(struct i2c_client *client) +{ + struct htcpld_chip_data *chip_data; + struct device *dev = &client->dev; + struct htcpld_chip_platform_data *pdata; + + if (!dev) + return -ENODEV; + + pdata = (struct htcpld_chip_platform_data *)dev->platform_data; + if (!pdata) { + printk("Platform data not found for chip at 0x%x!\n", client->addr); + return -ENXIO; + } + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) + return -ENODEV; + + if (client->addr > HTCPLD_ADDR_MAX) { + printk("Address above range.\n"); + return -ENOMEM; + } + + if (htcpld_chip[client->addr]) { + printk("Address already on use.\n"); + return -EINVAL; + } + + chip_data = kzalloc(sizeof(struct htcpld_chip_data), GFP_KERNEL); + if (! chip_data) + return -ENOMEM; + + chip_data->reset = pdata->reset; + i2c_set_clientdata(client, chip_data); + snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%x", client->addr); + htcpld_chip[client->addr] = client; + + /* Even addresses are read as directional pad events, + * odd addresses as directional keyboard events. */ + if (client->addr % 2 == 0) + htcpld_dpad_chip = client; + else + htcpld_dkbd_chip = client; + + printk("i2c-htcpld: Detected chip at 0x%x\n", client->addr); + htcpld_chip_reset(client->addr); + + return 0; +} + +static int htcpld_remove(struct i2c_client *client) +{ + htcpld_chip[client->addr] = NULL; + kfree(i2c_get_clientdata(client)); + + return 0; +} + +static irqreturn_t htcpld_btns_irq(int irq, void *dev_id) +{ + /* Disable further IRQs until we process the one we just got */ + disable_irq(irq); + + /* Set that an interrupt is pending so we can go process it */ + schedule_delayed_work(&htcpld_work, 0); + + return IRQ_HANDLED; +} + +void htcpld_btns_dowork(struct work_struct *data) { + htcpld_btns_poll(0); +} + +void htcpld_btns_poll(unsigned long data) +{ + struct device *dev = &htcpld_pdev->dev; + struct htcpld_btns_dev *bdev = dev_get_drvdata(dev); + struct htcpld_btns_platform_data *pdata = dev->platform_data; + u8 dpad_status, dkbd_status; + int i, we_continue = 0; + + dkbd_status = _htcpld_chip_cache_read(htcpld_dkbd_chip); + dpad_status = _htcpld_chip_cache_read(htcpld_dpad_chip); + + /* Check for changes in the maps */ + for (i=0; i> (7 - i)) & 0x01) || !((dkbd_status >> (7 - i)) & 0x01)) { + val = 1; + we_continue = 1; + } + + bdev->keymap[i] = val; + } + + /* Send events */ + for (i = 0; i < ARRAY_SIZE(htcpld_btns_map); i++) { + if (bdev->keymap[i] != bdev->previous_keymap[i]) { + input_report_key(bdev->input, bdev->keycode[i], bdev->keymap[i]); + bdev->previous_keymap[i] = bdev->keymap[i]; + } + } + + input_sync(bdev->input); + + /* Copy the new state into the previous state */ + memcpy(bdev->previous_keymap, bdev->keymap, sizeof(bdev->keymap)); + + if (we_continue) { + /* Poll again */ + schedule_delayed_work(&htcpld_work, pdata->poll_interval); + return; + } + + /* Enable front DPAD interrupts */ + htcpld_chip_set(0x05, (htcpld_chip_get(0x05) | 0x80) & 0xfe); + + /* Reenable the IRQ */ + enable_irq(bdev->irq); +} + +static int __devinit htcpld_btns_probe(struct platform_device *pdev) +{ + struct htcpld_btns_dev *bdev; + struct htcpld_btns_platform_data *pdata; + struct input_dev *input; + struct resource *res; + int error, i; + + if (!htcpld_dkbd_chip || !htcpld_dpad_chip) + return -ENODEV; + + bdev = kzalloc(sizeof(struct htcpld_btns_dev), GFP_KERNEL); + input = input_allocate_device(); + if (!bdev || !input) { + error = -ENOMEM; + goto err_free_mem; + } + + platform_set_drvdata(pdev, bdev); + + pdata = pdev->dev.platform_data; + if (!pdata) { + printk("Platform data not found for buttons device!\n"); + error = -ENXIO; + goto err_free_mem; + } + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + error = -EBUSY; + goto err_free_mem; + } + + bdev->irq = res->start; + bdev->input = input; + bdev->poll_interval = HZ / pdata->poll_interval; + memcpy(bdev->keycode, htcpld_btns_map, sizeof(bdev->keycode)); + + input->name = "I2C HTCPLD Buttons"; + input->keycode = bdev->keycode; + input->keycodemax = ARRAY_SIZE(bdev->keycode); + input->keycodesize = sizeof(unsigned char); + + set_bit(EV_KEY, input->evbit); + set_bit(EV_REP, input->evbit); + for (i = 0; i < ARRAY_SIZE(htcpld_btns_map); i++) + set_bit(bdev->keycode[i], input->keybit); + + error = input_register_device(input); + if (error) + goto err_free_mem; + + error = request_irq(bdev->irq, htcpld_btns_irq, + IRQF_TRIGGER_FALLING | IRQF_SAMPLE_RANDOM, pdev->name, pdev); + if (error) + goto err_unreg; + + htcpld_pdev = pdev; + + memset(bdev->previous_keymap, 0, sizeof(bdev->keymap)); + + printk(KERN_INFO "i2c-htcpld: I2C HTCPLD Buttons\n"); + printk(KERN_INFO "i2c-htcpld: Using IRQ: %d\n", bdev->irq); + printk(KERN_INFO "i2c-htcpld: DKbd chip at 0x%x\n", + htcpld_dkbd_chip->addr); + printk(KERN_INFO "i2c-htcpld: DPad chip at 0x%x\n", + htcpld_dpad_chip->addr); + + /* Enable front DPAD interrupts */ + htcpld_chip_set(0x05, (htcpld_chip_get(0x05) | 0x80) & 0xfe); + + return 0; + + err_unreg: + input_unregister_device(input); + err_free_mem: + input_free_device(input); + kfree(bdev); + dev_set_drvdata(&pdev->dev, NULL); + return error; +} + +static int __devexit htcpld_btns_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct htcpld_btns_dev *bdev = dev_get_drvdata(dev); + + del_timer_sync(&bdev->timer); + input_unregister_device(bdev->input); + input_free_device(bdev->input); + free_irq(bdev->irq, pdev); + kfree(bdev); + dev_set_drvdata(dev, NULL); + + return 0; +} + +static struct i2c_driver htcpld_driver = { + .driver = { + .name = "i2c-htcpld", + }, + .probe = htcpld_probe, + .remove = htcpld_remove, +}; + +static struct platform_driver htcpld_btns_driver = { + .probe = htcpld_btns_probe, + .remove = __devexit_p(htcpld_btns_remove), + .driver = { + .name = "i2c-htcpld-btns", + .owner = THIS_MODULE, + }, +}; + +static int __init htcpld_init(void) +{ + int ret; + + ret = i2c_add_driver(&htcpld_driver); + if (ret) + return ret; + + ret = platform_driver_register(&htcpld_btns_driver); + if (ret) + goto fail_drv_register; + + return 0; + +fail_drv_register: + i2c_del_driver(&htcpld_driver); + + return ret; +} + +static void __exit htcpld_exit(void) +{ + i2c_del_driver(&htcpld_driver); + + platform_driver_unregister(&htcpld_btns_driver); +} + +module_init(htcpld_init); +module_exit(htcpld_exit); + +EXPORT_SYMBOL_GPL(htcpld_chip_set); +EXPORT_SYMBOL_GPL(htcpld_chip_get); +EXPORT_SYMBOL_GPL(htcpld_chip_reset); + +MODULE_AUTHOR("Angelo Arrifano "); +MODULE_DESCRIPTION("I2C HTCPLD Driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/i2c/chips/i2c-htcpld.c b/drivers/i2c/chips/i2c-htcpld.c deleted file mode 100644 index 8fef7f1..0000000 --- a/drivers/i2c/chips/i2c-htcpld.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * i2c-htcpld.c - * Chip driver for a unknown cpld found on HTC boards with omap850. - * The cpld is located on the i2c bus and controls backlight, leds, - * vibrator and other power devices. The cpld also returns buttons status - * of the directional pads found on this HTC devices. - * - * Copyright (C) 2009 Cory Maccarrone - * Copyright (C) 2008 Angelo Arrifano - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define HTCPLD_ADDR_MAX 16 - -struct htcpld_chip_data { - u8 reset; - u8 cache; -}; - -static struct i2c_client *htcpld_chip[HTCPLD_ADDR_MAX]; -static struct i2c_client *htcpld_dkbd_chip; -static struct i2c_client *htcpld_dpad_chip; - -static const unsigned char htcpld_btns_map[] = { - KEY_RIGHT, - KEY_UP, - KEY_LEFT, - KEY_DOWN, - KEY_ENTER -}; - -struct htcpld_btns_dev { - unsigned char keycode[ARRAY_SIZE(htcpld_btns_map)]; - char keymap[ARRAY_SIZE(htcpld_btns_map)]; - char previous_keymap[ARRAY_SIZE(htcpld_btns_map)]; - int irq; - int poll_interval; - struct input_dev *input; - struct timer_list timer; -}; - -struct platform_device *htcpld_pdev = NULL; -void htcpld_btns_poll(unsigned long data); -void htcpld_btns_dowork(struct work_struct *data); - -DECLARE_DELAYED_WORK(htcpld_work, &htcpld_btns_dowork); - -void htcpld_chip_set(u8 chip_addr, u8 val) -{ - struct htcpld_chip_data *chip_data; - - if (chip_addr > HTCPLD_ADDR_MAX) - return; - - if (! htcpld_chip[chip_addr]) - return; - - chip_data = i2c_get_clientdata(htcpld_chip[chip_addr]); - if (! chip_data) - return; - - i2c_smbus_read_byte_data(htcpld_chip[chip_addr], - (chip_data->cache = val)); -} - -u8 htcpld_chip_get(u8 chip_addr) -{ - struct htcpld_chip_data *chip_data; - - if (! htcpld_chip[chip_addr]) - return 0; - - chip_data = i2c_get_clientdata(htcpld_chip[chip_addr]); - if (! chip_data) - return 0; - - return chip_data->cache; -} - - -void htcpld_chip_reset(u8 chip_addr) -{ - struct htcpld_chip_data *chip_data; - - if (chip_addr > HTCPLD_ADDR_MAX) - return; - - if (! htcpld_chip[chip_addr]) - return; - - chip_data = i2c_get_clientdata(htcpld_chip[chip_addr]); - if (! chip_data) - return; - - i2c_smbus_read_byte_data(htcpld_chip[chip_addr], - (chip_data->cache = chip_data->reset)); -} - - -/* - * Driver handling - */ - -static inline u8 _htcpld_chip_cache_read(struct i2c_client *client) -{ - return i2c_smbus_read_byte_data(client, - ((struct htcpld_chip_data *)i2c_get_clientdata(client))->cache); -} - -static int htcpld_probe(struct i2c_client *client) -{ - struct htcpld_chip_data *chip_data; - struct device *dev = &client->dev; - struct htcpld_chip_platform_data *pdata; - - if (!dev) - return -ENODEV; - - pdata = (struct htcpld_chip_platform_data *)dev->platform_data; - if (!pdata) { - printk("Platform data not found for chip at 0x%x!\n", client->addr); - return -ENXIO; - } - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_BYTE_DATA)) - return -ENODEV; - - if (client->addr > HTCPLD_ADDR_MAX) { - printk("Address above range.\n"); - return -ENOMEM; - } - - if (htcpld_chip[client->addr]) { - printk("Address already on use.\n"); - return -EINVAL; - } - - chip_data = kzalloc(sizeof(struct htcpld_chip_data), GFP_KERNEL); - if (! chip_data) - return -ENOMEM; - - chip_data->reset = pdata->reset; - i2c_set_clientdata(client, chip_data); - snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%x", client->addr); - htcpld_chip[client->addr] = client; - - /* Even addresses are read as directional pad events, - * odd addresses as directional keyboard events. */ - if (client->addr % 2 == 0) - htcpld_dpad_chip = client; - else - htcpld_dkbd_chip = client; - - printk("i2c-htcpld: Detected chip at 0x%x\n", client->addr); - htcpld_chip_reset(client->addr); - - return 0; -} - -static int htcpld_remove(struct i2c_client *client) -{ - htcpld_chip[client->addr] = NULL; - kfree(i2c_get_clientdata(client)); - - return 0; -} - -static irqreturn_t htcpld_btns_irq(int irq, void *dev_id) -{ - struct device *dev = &htcpld_pdev->dev; - struct htcpld_btns_dev *bdev = dev_get_drvdata(dev); - struct htcpld_btns_platform_data *pdata = dev->platform_data; - - /* Disable further IRQs until we process the one we just got */ - disable_irq(irq); - - /* Set that an interrupt is pending so we can go process it */ - schedule_delayed_work(&htcpld_work, 0); - - return IRQ_HANDLED; -} - -void htcpld_btns_dowork(struct work_struct *data) { - htcpld_btns_poll(0); -} - -void htcpld_btns_poll(unsigned long data) -{ - struct device *dev = &htcpld_pdev->dev; - struct htcpld_btns_dev *bdev = dev_get_drvdata(dev); - struct htcpld_btns_platform_data *pdata = dev->platform_data; - u8 dpad_status, dkbd_status; - int i, we_continue = 0; - - dkbd_status = _htcpld_chip_cache_read(htcpld_dkbd_chip); - dpad_status = _htcpld_chip_cache_read(htcpld_dpad_chip); - - /* Check for changes in the maps */ - for (i=0; i> (7 - i)) & 0x01) || !((dkbd_status >> (7 - i)) & 0x01)) { - val = 1; - we_continue = 1; - } - - bdev->keymap[i] = val; - } - - /* Send events */ - for (i = 0; i < ARRAY_SIZE(htcpld_btns_map); i++) { - if (bdev->keymap[i] != bdev->previous_keymap[i]) { - input_report_key(bdev->input, bdev->keycode[i], bdev->keymap[i]); - bdev->previous_keymap[i] = bdev->keymap[i]; - } - } - - input_sync(bdev->input); - - /* Copy the new state into the previous state */ - memcpy(bdev->previous_keymap, bdev->keymap, sizeof(bdev->keymap)); - - if (we_continue) { - /* Poll again */ - schedule_delayed_work(&htcpld_work, pdata->poll_interval); - return; - } - - /* Enable front DPAD interrupts */ - htcpld_chip_set(0x05, (htcpld_chip_get(0x05) | 0x80) & 0xfe); - - /* Reenable the IRQ */ - enable_irq(bdev->irq); -} - -static int __devinit htcpld_btns_probe(struct platform_device *pdev) -{ - struct htcpld_btns_dev *bdev; - struct htcpld_btns_platform_data *pdata; - struct input_dev *input; - struct resource *res; - int error, i; - - if (!htcpld_dkbd_chip || !htcpld_dpad_chip) - return -ENODEV; - - bdev = kzalloc(sizeof(struct htcpld_btns_dev), GFP_KERNEL); - input = input_allocate_device(); - if (!bdev || !input) { - error = -ENOMEM; - goto err_free_mem; - } - - platform_set_drvdata(pdev, bdev); - - pdata = pdev->dev.platform_data; - if (!pdata) { - printk("Platform data not found for buttons device!\n"); - error = -ENXIO; - goto err_free_mem; - } - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - error = -EBUSY; - goto err_free_mem; - } - - bdev->irq = res->start; - bdev->input = input; - bdev->poll_interval = HZ / pdata->poll_interval; - memcpy(bdev->keycode, htcpld_btns_map, sizeof(bdev->keycode)); - - input->name = "HTC I2C CPLD Buttons"; - input->keycode = bdev->keycode; - input->keycodemax = ARRAY_SIZE(bdev->keycode); - input->keycodesize = sizeof(unsigned char); - - set_bit(EV_KEY, input->evbit); - set_bit(EV_REP, input->evbit); - for (i = 0; i < ARRAY_SIZE(htcpld_btns_map); i++) - set_bit(bdev->keycode[i], input->keybit); - - error = input_register_device(input); - if (error) - goto err_free_mem; - - error = request_irq(bdev->irq, htcpld_btns_irq, - IRQF_TRIGGER_FALLING | IRQF_SAMPLE_RANDOM, pdev->name, pdev); - if (error) - goto err_unreg; - - htcpld_pdev = pdev; - - memset(bdev->previous_keymap, 0, sizeof(bdev->keymap)); - - printk("i2c-htcpld: HTC I2C CPLD Buttons\n"); - printk("i2c-htcpld: Using IRQ: %d\n", bdev->irq); - printk("i2c-htcpld: DKbd chip at 0x%x\n", htcpld_dkbd_chip->addr); - printk("i2c-htcpld: DPad chip at 0x%x\n", htcpld_dpad_chip->addr); - - /* Enable front DPAD interrupts */ - htcpld_chip_set(0x05, (htcpld_chip_get(0x05) | 0x80) & 0xfe); - - return 0; - - err_unreg: - input_unregister_device(input); - err_free_mem: - input_free_device(input); - kfree(bdev); - dev_set_drvdata(&pdev->dev, NULL); - return error; -} - -static int __devexit htcpld_btns_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct htcpld_btns_dev *bdev = dev_get_drvdata(dev); - - del_timer_sync(&bdev->timer); - input_unregister_device(bdev->input); - input_free_device(bdev->input); - free_irq(bdev->irq, pdev); - kfree(bdev); - dev_set_drvdata(dev, NULL); - - return 0; -} - -static struct i2c_driver htcpld_driver = { - .driver = { - .name = "i2c-htcpld", - }, - .probe = htcpld_probe, - .remove = htcpld_remove, -}; - -static struct platform_driver htcpld_btns_driver = { - .probe = htcpld_btns_probe, - .remove = __devexit_p(htcpld_btns_remove), - .driver = { - .name = "i2c-htcpld-btns", - .owner = THIS_MODULE, - }, -}; - -static int __init htcpld_init(void) -{ - int ret; - - ret = i2c_add_driver(&htcpld_driver); - if (ret) - return ret; - - ret = platform_driver_register(&htcpld_btns_driver); - if (ret) - goto fail_drv_register; - - return 0; - -fail_drv_register: - i2c_del_driver(&htcpld_driver); - - return ret; -} - -static void __exit htcpld_exit(void) -{ - i2c_del_driver(&htcpld_driver); - - platform_driver_unregister(&htcpld_btns_driver); -} - -module_init(htcpld_init); -module_exit(htcpld_exit); - -EXPORT_SYMBOL_GPL(htcpld_chip_set); -EXPORT_SYMBOL_GPL(htcpld_chip_get); -EXPORT_SYMBOL_GPL(htcpld_chip_reset); - -MODULE_AUTHOR("Angelo Arrifano "); -MODULE_DESCRIPTION("HTC I2C CPLD Driver"); -MODULE_LICENSE("GPL"); - diff --git a/include/linux/i2c/htcpld.h b/include/linux/i2c/htcpld.h new file mode 100644 index 0000000..41a2502 --- /dev/null +++ b/include/linux/i2c/htcpld.h @@ -0,0 +1,16 @@ +#ifndef __LINUX_HTCPLD_H +#define __LINUX_HTCPLD_H + +struct htcpld_chip_platform_data { + u8 reset; +}; + +struct htcpld_btns_platform_data { + int poll_interval; +}; + +u8 htcpld_chip_get(u8 chip_addr); +void htcpld_chip_set(u8 chip_addr, u8 val); +void htcpld_chip_reset(u8 chip_addr); + +#endif /* __LINUX_HTCPLD_H */ diff --git a/include/linux/i2c/i2c-htcpld.h b/include/linux/i2c/i2c-htcpld.h deleted file mode 100644 index 83675b8..0000000 --- a/include/linux/i2c/i2c-htcpld.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __LINUX_I2C_HTCPLD_H -#define __LINUX_I2C_HTCPLD_H - -struct htcpld_chip_platform_data { - u8 reset; -}; - -struct htcpld_btns_platform_data { - int poll_interval; -}; - -u8 htcpld_chip_get(u8 chip_addr); -void htcpld_chip_set(u8 chip_addr, u8 val); -void htcpld_chip_reset(u8 chip_addr); - -#endif /* __LINUX_I2C_HTCPLD_H */ -- 1.6.3.3