blob: a9c53f219c3ee9b2fc2758765e9a60ac52445114 [file] [log] [blame]
/*
* da9052-gpio.c -- GPIO Driver for Dialog DA9052
*
* Copyright(c) 2009 Dialog Semiconductor Ltd.
*
* Author: Dialog Semiconductor Ltd <dchen@diasemi.com>
*
* 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.
*
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/syscalls.h>
#include <linux/seq_file.h>
#include <linux/gpio.h>
#include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/reg.h>
#include <linux/mfd/da9052/gpio.h>
#define DRIVER_NAME "da9052-gpio"
static inline struct da9052_gpio_chip *to_da9052_gpio(struct gpio_chip *chip)
{
return container_of(chip, struct da9052_gpio_chip, gp);
}
void da9052_gpio_notifier(struct da9052_eh_nb *eh_data, unsigned int event)
{
struct da9052_gpio_chip *gpio =
container_of(eh_data, struct da9052_gpio_chip, eh_data);
kobject_uevent(&gpio->gp.dev->kobj, KOBJ_CHANGE);
printk(KERN_INFO "Event received from GPIO8\n");
}
static u8 create_gpio_config_value(u8 gpio_function, u8 gpio_type, u8 gpio_mode)
{
/* The format is -
function - 2 bits
type - 1 bit
mode - 1 bit */
return gpio_function | (gpio_type << 2) | (gpio_mode << 3);
}
static s32 write_default_gpio_values(struct da9052 *da9052)
{
struct da9052_ssc_msg msg;
u8 created_val = 0;
#if (DA9052_GPIO_PIN_0 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0001_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO0_FUNCTION,
DEFAULT_GPIO0_TYPE, DEFAULT_GPIO0_MODE);
msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
#if (DA9052_GPIO_PIN_1 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0001_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO1_FUNCTION,
DEFAULT_GPIO1_TYPE, DEFAULT_GPIO1_MODE);
created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT;
msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
/* GPIO 2-3*/
#if (DA9052_GPIO_PIN_2 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0203_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO2_FUNCTION,
DEFAULT_GPIO2_TYPE, DEFAULT_GPIO2_MODE);
msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
#if (DA9052_GPIO_PIN_3 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0203_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO3_FUNCTION,
DEFAULT_GPIO3_TYPE, DEFAULT_GPIO3_MODE);
created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT;
msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
/* GPIO 4-5*/
#if (DA9052_GPIO_PIN_4 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0405_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO4_FUNCTION,
DEFAULT_GPIO4_TYPE, DEFAULT_GPIO4_MODE);
msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
#if (DA9052_GPIO_PIN_5 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0405_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO5_FUNCTION,
DEFAULT_GPIO5_TYPE, DEFAULT_GPIO5_MODE);
created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT;
msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
/* GPIO 6-7*/
#if (DA9052_GPIO_PIN_6 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0607_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO6_FUNCTION,
DEFAULT_GPIO6_TYPE, DEFAULT_GPIO6_MODE);
msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
#if (DA9052_GPIO_PIN_7 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0607_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO7_FUNCTION,
DEFAULT_GPIO7_TYPE, DEFAULT_GPIO7_MODE);
created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT;
msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
/* GPIO 8-9*/
#if (DA9052_GPIO_PIN_8 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0809_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO8_FUNCTION,
DEFAULT_GPIO8_TYPE, DEFAULT_GPIO8_MODE);
msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
#if (DA9052_GPIO_PIN_9 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO0809_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO9_FUNCTION,
DEFAULT_GPIO9_TYPE, DEFAULT_GPIO9_MODE);
created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT;
msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
/* GPIO 10-11*/
#if (DA9052_GPIO_PIN_10 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO1011_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO10_FUNCTION,
DEFAULT_GPIO10_TYPE, DEFAULT_GPIO10_MODE);
msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
#if (DA9052_GPIO_PIN_11 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO1011_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO11_FUNCTION,
DEFAULT_GPIO11_TYPE, DEFAULT_GPIO11_MODE);
created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT;
msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
/* GPIO 12-13*/
#if (DA9052_GPIO_PIN_12 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO1213_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO12_FUNCTION,
DEFAULT_GPIO12_TYPE, DEFAULT_GPIO12_MODE);
msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
#if (DA9052_GPIO_PIN_13 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO1213_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO13_FUNCTION,
DEFAULT_GPIO13_TYPE, DEFAULT_GPIO13_MODE);
created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT;
msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
/* GPIO 14-15*/
#if (DA9052_GPIO_PIN_14 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO1415_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO14_FUNCTION,
DEFAULT_GPIO14_TYPE, DEFAULT_GPIO14_MODE);
msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
#if (DA9052_GPIO_PIN_15 == DA9052_GPIO_CONFIG)
da9052_lock(da9052);
msg.addr = DA9052_GPIO1415_REG;
msg.data = 0;
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
created_val = create_gpio_config_value(DEFAULT_GPIO15_FUNCTION,
DEFAULT_GPIO15_TYPE, DEFAULT_GPIO15_MODE);
created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT;
msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE;
msg.data |= created_val;
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
#endif
return 0;
}
s32 da9052_gpio_read_port(struct da9052_gpio_read_write *read_port,
struct da9052 *da9052)
{
struct da9052_ssc_msg msg;
u8 shift_value = 0;
u8 port_functionality = 0;
msg.addr = (read_port->port_number / 2) + DA9052_GPIO0001_REG;
msg.data = 0;
da9052_lock(da9052);
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
port_functionality =
(read_port->port_number % 2) ?
((msg.data & DA9052_GPIO_ODD_PORT_FUNCTIONALITY) >>
DA9052_GPIO_NIBBLE_SHIFT) :
(msg.data & DA9052_GPIO_EVEN_PORT_FUNCTIONALITY);
if (port_functionality != INPUT)
return DA9052_GPIO_INVALID_PORTNUMBER;
if (read_port->port_number >= (DA9052_GPIO_MAX_PORTNUMBER))
return DA9052_GPIO_INVALID_PORTNUMBER;
if (read_port->port_number < DA9052_GPIO_MAX_PORTS_PER_REGISTER)
msg.addr = DA9052_STATUSC_REG;
else
msg.addr = DA9052_STATUSD_REG;
msg.data = 0;
da9052_lock(da9052);
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
shift_value = msg.data &
(1 << DA9052_GPIO_SHIFT_COUNT(read_port->port_number));
read_port->read_write_value = (shift_value >>
DA9052_GPIO_SHIFT_COUNT(read_port->port_number));
return 0;
}
s32 da9052_gpio_multiple_read(struct da9052_gpio_multiple_read *multiple_port,
struct da9052 *da9052)
{
struct da9052_ssc_msg msg[2];
u8 port_number = 0;
u8 loop_index = 0;
msg[loop_index++].addr = DA9052_STATUSC_REG;
msg[loop_index++].addr = DA9052_STATUSD_REG;
da9052_lock(da9052);
if (da9052->read_many(da9052, msg, loop_index)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
loop_index = 0;
for (port_number = 0; port_number < DA9052_GPIO_MAX_PORTS_PER_REGISTER;
port_number++) {
multiple_port->signal_value[port_number] =
msg[loop_index].data & 1;
msg[loop_index].data = msg[loop_index].data >> 1;
}
loop_index++;
for (port_number = DA9052_GPIO_MAX_PORTS_PER_REGISTER;
port_number < DA9052_GPIO_MAX_PORTNUMBER; port_number++) {
multiple_port->signal_value[port_number] =
msg[loop_index].data & 1;
msg[loop_index].data = msg[loop_index].data >> 1;
}
return 0;
}
EXPORT_SYMBOL(da9052_gpio_multiple_read);
s32 da9052_gpio_write_port(struct da9052_gpio_read_write *write_port,
struct da9052 *da9052)
{
struct da9052_ssc_msg msg;
u8 port_functionality = 0;
u8 bit_pos = 0;
msg.addr = DA9052_GPIO0001_REG + (write_port->port_number / 2);
msg.data = 0;
da9052_lock(da9052);
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
port_functionality =
(write_port->port_number % 2) ?
((msg.data & DA9052_GPIO_ODD_PORT_FUNCTIONALITY) >>
DA9052_GPIO_NIBBLE_SHIFT) :
(msg.data & DA9052_GPIO_EVEN_PORT_FUNCTIONALITY);
if (port_functionality < 2)
return DA9052_GPIO_INVALID_PORTNUMBER;
bit_pos = (write_port->port_number % 2) ?
DA9052_GPIO_ODD_PORT_WRITE_MODE :
DA9052_GPIO_EVEN_PORT_WRITE_MODE;
if (write_port->read_write_value)
msg.data = msg.data | bit_pos;
else
msg.data = (msg.data & ~(bit_pos));
da9052_lock(da9052);
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
return 0;
}
s32 da9052_gpio_configure_port(struct da9052_gpio *gpio_data,
struct da9052 *da9052)
{
struct da9052_ssc_msg msg;
u8 register_value = 0;
u8 function = 0;
u8 port_functionality = 0;
msg.addr = (gpio_data->port_number / 2) + DA9052_GPIO0001_REG;
msg.data = 0;
da9052_lock(da9052);
if (da9052->read(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
port_functionality =
(gpio_data->port_number % 2) ?
((msg.data & DA9052_GPIO_ODD_PORT_FUNCTIONALITY) >>
DA9052_GPIO_NIBBLE_SHIFT) :
(msg.data & DA9052_GPIO_EVEN_PORT_FUNCTIONALITY);
if (port_functionality < INPUT)
return DA9052_GPIO_INVALID_PORTNUMBER;
if (gpio_data->gpio_config.input.type > ACTIVE_HIGH)
return DA9052_GPIO_INVALID_TYPE;
if (gpio_data->gpio_config.input.mode > DEBOUNCING_ON)
return DA9052_GPIO_INVALID_MODE;
function = gpio_data->gpio_function;
switch (function) {
case INPUT:
register_value = create_gpio_config_value(function,
gpio_data->gpio_config.input.type,
gpio_data->gpio_config.input.mode);
break;
case OUTPUT_OPENDRAIN:
case OUTPUT_PUSHPULL:
register_value = create_gpio_config_value(function,
gpio_data->gpio_config.input.type,
gpio_data->gpio_config.input.mode);
break;
default:
return DA9052_GPIO_INVALID_FUNCTION;
break;
}
if (gpio_data->port_number % 2) {
msg.data = (msg.data & ~(DA9052_GPIO_MASK_UPPER_NIBBLE)) |
(register_value << DA9052_GPIO_NIBBLE_SHIFT);
} else {
msg.data = (msg.data & ~(DA9052_GPIO_MASK_LOWER_NIBBLE)) |
register_value;
}
da9052_lock(da9052);
if (da9052->write(da9052, &msg)) {
da9052_unlock(da9052);
return -EIO;
}
da9052_unlock(da9052);
return 0;
}
static s32 da9052_gpio_read(struct gpio_chip *gc, u32 offset)
{
struct da9052_gpio_chip *gpio;
gpio = to_da9052_gpio(gc);
gpio->read_write.port_number = offset;
da9052_gpio_read_port(&gpio->read_write, gpio->da9052);
return gpio->read_write.read_write_value;
}
static void da9052_gpio_write(struct gpio_chip *gc, u32 offset, s32 value)
{
struct da9052_gpio_chip *gpio;
gpio = to_da9052_gpio(gc);
gpio->read_write.port_number = offset;
gpio->read_write.read_write_value = (u8)value;
da9052_gpio_write_port(&gpio->read_write, gpio->da9052);
}
static s32 da9052_gpio_ip(struct gpio_chip *gc, u32 offset)
{
struct da9052_gpio_chip *gpio;
gpio = to_da9052_gpio(gc);
gpio->gpio.gpio_function = INPUT;
gpio->gpio.gpio_config.input.type = ACTIVE_LOW;
gpio->gpio.gpio_config.input.mode = DEBOUNCING_ON;
gpio->gpio.port_number = offset;
return da9052_gpio_configure_port(&gpio->gpio, gpio->da9052);
}
static s32 da9052_gpio_op(struct gpio_chip *gc, u32 offset, s32 value)
{
struct da9052_gpio_chip *gpio;
gpio = to_da9052_gpio(gc);
gpio->gpio.gpio_function = OUTPUT_PUSHPULL;
gpio->gpio.gpio_config.output.type = SUPPLY_VDD_IO1;
gpio->gpio.gpio_config.output.mode = value;
gpio->gpio.port_number = offset;
return da9052_gpio_configure_port(&gpio->gpio, gpio->da9052);
}
static int da9052_gpio_to_irq(struct gpio_chip *gc, u32 offset)
{
struct da9052_gpio_chip *gpio;
gpio = to_da9052_gpio(gc);
kobject_uevent(&gpio->gp.dev->kobj, KOBJ_CHANGE);
printk(KERN_INFO"gpio->gp.base +offset = %d\n", gpio->gp.base + offset);
printk(KERN_INFO"Test1\n\n");
return gpio->gp.base + offset;
}
static int __devinit da9052_gpio_probe(struct platform_device *pdev)
{
struct da9052_gpio_chip *gpio;
struct da9052_platform_data *pdata = (pdev->dev.platform_data);
s32 ret;
gpio = kzalloc(sizeof(*gpio), GFP_KERNEL);
if (gpio == NULL)
return -ENOMEM;
gpio->da9052 = dev_get_drvdata(pdev->dev.parent);
gpio->gp.get = da9052_gpio_read;
gpio->gp.direction_input = da9052_gpio_ip;
gpio->gp.direction_output = da9052_gpio_op;
gpio->gp.set = da9052_gpio_write;
gpio->gp.base = pdata->gpio_base;
gpio->gp.ngpio = DA9052_GPIO_MAX_PORTNUMBER;
gpio->gp.can_sleep = 1;
gpio->gp.dev = &pdev->dev;
gpio->gp.owner = THIS_MODULE;
gpio->gp.label = "da9052-gpio";
gpio->gp.to_irq = da9052_gpio_to_irq;
gpio->eh_data.eve_type = GPI8_EVE;
gpio->eh_data.call_back = &da9052_gpio_notifier;
ret = gpio->da9052->register_event_notifier(gpio->da9052,
&gpio->eh_data);
ret = write_default_gpio_values(gpio->da9052);
if (ret < 0) {
dev_err(&pdev->dev, "GPIO initial config failed, %d\n",
ret);
goto ret;
}
ret = gpiochip_add(&gpio->gp);
if (ret < 0) {
dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
ret);
goto ret;
}
platform_set_drvdata(pdev, gpio);
return ret;
ret:
kfree(gpio);
return ret;
}
static int __devexit da9052_gpio_remove(struct platform_device *pdev)
{
struct da9052_gpio_chip *gpio = platform_get_drvdata(pdev);
int ret;
gpio->da9052->unregister_event_notifier
(gpio->da9052, &gpio->eh_data);
ret = gpiochip_remove(&gpio->gp);
if (ret == 0)
kfree(gpio);
return 0;
}
static struct platform_driver da9052_gpio_driver = {
.probe = da9052_gpio_probe,
.remove = __devexit_p(da9052_gpio_remove),
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
};
static int __init da9052_gpio_init(void)
{
return platform_driver_register(&da9052_gpio_driver);
}
static void __exit da9052_gpio_exit(void)
{
return platform_driver_unregister(&da9052_gpio_driver);
}
module_init(da9052_gpio_init);
module_exit(da9052_gpio_exit);
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
MODULE_DESCRIPTION("DA9052 GPIO Device Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRIVER_NAME);