Path: blob/master/drivers/input/keyboard/adp5589-keys.c
15109 views
/*1* Description: keypad driver for ADP55892* I2C QWERTY Keypad and IO Expander3* Bugs: Enter bugs at http://blackfin.uclinux.org/4*5* Copyright (C) 2010-2011 Analog Devices Inc.6* Licensed under the GPL-2.7*/89#include <linux/module.h>10#include <linux/version.h>11#include <linux/init.h>12#include <linux/interrupt.h>13#include <linux/irq.h>14#include <linux/workqueue.h>15#include <linux/errno.h>16#include <linux/pm.h>17#include <linux/platform_device.h>18#include <linux/input.h>19#include <linux/i2c.h>20#include <linux/gpio.h>21#include <linux/slab.h>2223#include <linux/input/adp5589.h>2425/* GENERAL_CFG Register */26#define OSC_EN (1 << 7)27#define CORE_CLK(x) (((x) & 0x3) << 5)28#define LCK_TRK_LOGIC (1 << 4)29#define LCK_TRK_GPI (1 << 3)30#define INT_CFG (1 << 1)31#define RST_CFG (1 << 0)3233/* INT_EN Register */34#define LOGIC2_IEN (1 << 5)35#define LOGIC1_IEN (1 << 4)36#define LOCK_IEN (1 << 3)37#define OVRFLOW_IEN (1 << 2)38#define GPI_IEN (1 << 1)39#define EVENT_IEN (1 << 0)4041/* Interrupt Status Register */42#define LOGIC2_INT (1 << 5)43#define LOGIC1_INT (1 << 4)44#define LOCK_INT (1 << 3)45#define OVRFLOW_INT (1 << 2)46#define GPI_INT (1 << 1)47#define EVENT_INT (1 << 0)4849/* STATUS Register */5051#define LOGIC2_STAT (1 << 7)52#define LOGIC1_STAT (1 << 6)53#define LOCK_STAT (1 << 5)54#define KEC 0xF5556/* PIN_CONFIG_D Register */57#define C4_EXTEND_CFG (1 << 6) /* RESET2 */58#define R4_EXTEND_CFG (1 << 5) /* RESET1 */5960/* LOCK_CFG */61#define LOCK_EN (1 << 0)6263#define PTIME_MASK 0x364#define LTIME_MASK 0x36566/* Key Event Register xy */67#define KEY_EV_PRESSED (1 << 7)68#define KEY_EV_MASK (0x7F)6970#define KEYP_MAX_EVENT 167172#define MAXGPIO 1973#define ADP_BANK(offs) ((offs) >> 3)74#define ADP_BIT(offs) (1u << ((offs) & 0x7))7576struct adp5589_kpad {77struct i2c_client *client;78struct input_dev *input;79unsigned short keycode[ADP5589_KEYMAPSIZE];80const struct adp5589_gpi_map *gpimap;81unsigned short gpimapsize;82unsigned extend_cfg;83#ifdef CONFIG_GPIOLIB84unsigned char gpiomap[MAXGPIO];85bool export_gpio;86struct gpio_chip gc;87struct mutex gpio_lock; /* Protect cached dir, dat_out */88u8 dat_out[3];89u8 dir[3];90#endif91};9293static int adp5589_read(struct i2c_client *client, u8 reg)94{95int ret = i2c_smbus_read_byte_data(client, reg);9697if (ret < 0)98dev_err(&client->dev, "Read Error\n");99100return ret;101}102103static int adp5589_write(struct i2c_client *client, u8 reg, u8 val)104{105return i2c_smbus_write_byte_data(client, reg, val);106}107108#ifdef CONFIG_GPIOLIB109static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off)110{111struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc);112unsigned int bank = ADP_BANK(kpad->gpiomap[off]);113unsigned int bit = ADP_BIT(kpad->gpiomap[off]);114115return !!(adp5589_read(kpad->client, ADP5589_GPI_STATUS_A + bank) &116bit);117}118119static void adp5589_gpio_set_value(struct gpio_chip *chip,120unsigned off, int val)121{122struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc);123unsigned int bank = ADP_BANK(kpad->gpiomap[off]);124unsigned int bit = ADP_BIT(kpad->gpiomap[off]);125126mutex_lock(&kpad->gpio_lock);127128if (val)129kpad->dat_out[bank] |= bit;130else131kpad->dat_out[bank] &= ~bit;132133adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank,134kpad->dat_out[bank]);135136mutex_unlock(&kpad->gpio_lock);137}138139static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off)140{141struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc);142unsigned int bank = ADP_BANK(kpad->gpiomap[off]);143unsigned int bit = ADP_BIT(kpad->gpiomap[off]);144int ret;145146mutex_lock(&kpad->gpio_lock);147148kpad->dir[bank] &= ~bit;149ret = adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank,150kpad->dir[bank]);151152mutex_unlock(&kpad->gpio_lock);153154return ret;155}156157static int adp5589_gpio_direction_output(struct gpio_chip *chip,158unsigned off, int val)159{160struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc);161unsigned int bank = ADP_BANK(kpad->gpiomap[off]);162unsigned int bit = ADP_BIT(kpad->gpiomap[off]);163int ret;164165mutex_lock(&kpad->gpio_lock);166167kpad->dir[bank] |= bit;168169if (val)170kpad->dat_out[bank] |= bit;171else172kpad->dat_out[bank] &= ~bit;173174ret = adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank,175kpad->dat_out[bank]);176ret |= adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank,177kpad->dir[bank]);178179mutex_unlock(&kpad->gpio_lock);180181return ret;182}183184static int __devinit adp5589_build_gpiomap(struct adp5589_kpad *kpad,185const struct adp5589_kpad_platform_data *pdata)186{187bool pin_used[MAXGPIO];188int n_unused = 0;189int i;190191memset(pin_used, false, sizeof(pin_used));192193for (i = 0; i < MAXGPIO; i++)194if (pdata->keypad_en_mask & (1 << i))195pin_used[i] = true;196197for (i = 0; i < kpad->gpimapsize; i++)198pin_used[kpad->gpimap[i].pin - ADP5589_GPI_PIN_BASE] = true;199200if (kpad->extend_cfg & R4_EXTEND_CFG)201pin_used[4] = true;202203if (kpad->extend_cfg & C4_EXTEND_CFG)204pin_used[12] = true;205206for (i = 0; i < MAXGPIO; i++)207if (!pin_used[i])208kpad->gpiomap[n_unused++] = i;209210return n_unused;211}212213static int __devinit adp5589_gpio_add(struct adp5589_kpad *kpad)214{215struct device *dev = &kpad->client->dev;216const struct adp5589_kpad_platform_data *pdata = dev->platform_data;217const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data;218int i, error;219220if (!gpio_data)221return 0;222223kpad->gc.ngpio = adp5589_build_gpiomap(kpad, pdata);224if (kpad->gc.ngpio == 0) {225dev_info(dev, "No unused gpios left to export\n");226return 0;227}228229kpad->export_gpio = true;230231kpad->gc.direction_input = adp5589_gpio_direction_input;232kpad->gc.direction_output = adp5589_gpio_direction_output;233kpad->gc.get = adp5589_gpio_get_value;234kpad->gc.set = adp5589_gpio_set_value;235kpad->gc.can_sleep = 1;236237kpad->gc.base = gpio_data->gpio_start;238kpad->gc.label = kpad->client->name;239kpad->gc.owner = THIS_MODULE;240241mutex_init(&kpad->gpio_lock);242243error = gpiochip_add(&kpad->gc);244if (error) {245dev_err(dev, "gpiochip_add failed, err: %d\n", error);246return error;247}248249for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {250kpad->dat_out[i] = adp5589_read(kpad->client,251ADP5589_GPO_DATA_OUT_A + i);252kpad->dir[i] = adp5589_read(kpad->client,253ADP5589_GPIO_DIRECTION_A + i);254}255256if (gpio_data->setup) {257error = gpio_data->setup(kpad->client,258kpad->gc.base, kpad->gc.ngpio,259gpio_data->context);260if (error)261dev_warn(dev, "setup failed, %d\n", error);262}263264return 0;265}266267static void __devexit adp5589_gpio_remove(struct adp5589_kpad *kpad)268{269struct device *dev = &kpad->client->dev;270const struct adp5589_kpad_platform_data *pdata = dev->platform_data;271const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data;272int error;273274if (!kpad->export_gpio)275return;276277if (gpio_data->teardown) {278error = gpio_data->teardown(kpad->client,279kpad->gc.base, kpad->gc.ngpio,280gpio_data->context);281if (error)282dev_warn(dev, "teardown failed %d\n", error);283}284285error = gpiochip_remove(&kpad->gc);286if (error)287dev_warn(dev, "gpiochip_remove failed %d\n", error);288}289#else290static inline int adp5589_gpio_add(struct adp5589_kpad *kpad)291{292return 0;293}294295static inline void adp5589_gpio_remove(struct adp5589_kpad *kpad)296{297}298#endif299300static void adp5589_report_switches(struct adp5589_kpad *kpad,301int key, int key_val)302{303int i;304305for (i = 0; i < kpad->gpimapsize; i++) {306if (key_val == kpad->gpimap[i].pin) {307input_report_switch(kpad->input,308kpad->gpimap[i].sw_evt,309key & KEY_EV_PRESSED);310break;311}312}313}314315static void adp5589_report_events(struct adp5589_kpad *kpad, int ev_cnt)316{317int i;318319for (i = 0; i < ev_cnt; i++) {320int key = adp5589_read(kpad->client, ADP5589_FIFO_1 + i);321int key_val = key & KEY_EV_MASK;322323if (key_val >= ADP5589_GPI_PIN_BASE &&324key_val <= ADP5589_GPI_PIN_END) {325adp5589_report_switches(kpad, key, key_val);326} else {327input_report_key(kpad->input,328kpad->keycode[key_val - 1],329key & KEY_EV_PRESSED);330}331}332}333334static irqreturn_t adp5589_irq(int irq, void *handle)335{336struct adp5589_kpad *kpad = handle;337struct i2c_client *client = kpad->client;338int status, ev_cnt;339340status = adp5589_read(client, ADP5589_INT_STATUS);341342if (status & OVRFLOW_INT) /* Unlikely and should never happen */343dev_err(&client->dev, "Event Overflow Error\n");344345if (status & EVENT_INT) {346ev_cnt = adp5589_read(client, ADP5589_STATUS) & KEC;347if (ev_cnt) {348adp5589_report_events(kpad, ev_cnt);349input_sync(kpad->input);350}351}352353adp5589_write(client, ADP5589_INT_STATUS, status); /* Status is W1C */354355return IRQ_HANDLED;356}357358static int __devinit adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key)359{360int i;361362for (i = 0; i < ADP5589_KEYMAPSIZE; i++)363if (key == kpad->keycode[i])364return (i + 1) | KEY_EV_PRESSED;365366dev_err(&kpad->client->dev, "RESET/UNLOCK key not in keycode map\n");367368return -EINVAL;369}370371static int __devinit adp5589_setup(struct adp5589_kpad *kpad)372{373struct i2c_client *client = kpad->client;374const struct adp5589_kpad_platform_data *pdata =375client->dev.platform_data;376int i, ret;377unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0;378unsigned char pull_mask = 0;379380ret = adp5589_write(client, ADP5589_PIN_CONFIG_A,381pdata->keypad_en_mask & 0xFF);382ret |= adp5589_write(client, ADP5589_PIN_CONFIG_B,383(pdata->keypad_en_mask >> 8) & 0xFF);384ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C,385(pdata->keypad_en_mask >> 16) & 0xFF);386387if (pdata->en_keylock) {388ret |= adp5589_write(client, ADP5589_UNLOCK1,389pdata->unlock_key1);390ret |= adp5589_write(client, ADP5589_UNLOCK2,391pdata->unlock_key2);392ret |= adp5589_write(client, ADP5589_UNLOCK_TIMERS,393pdata->unlock_timer & LTIME_MASK);394ret |= adp5589_write(client, ADP5589_LOCK_CFG, LOCK_EN);395}396397for (i = 0; i < KEYP_MAX_EVENT; i++)398ret |= adp5589_read(client, ADP5589_FIFO_1 + i);399400for (i = 0; i < pdata->gpimapsize; i++) {401unsigned short pin = pdata->gpimap[i].pin;402403if (pin <= ADP5589_GPI_PIN_ROW_END) {404evt_mode1 |= (1 << (pin - ADP5589_GPI_PIN_ROW_BASE));405} else {406evt_mode2 |=407((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) & 0xFF);408evt_mode3 |=409((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) >> 8);410}411}412413if (pdata->gpimapsize) {414ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_A, evt_mode1);415ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_B, evt_mode2);416ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_C, evt_mode3);417}418419if (pdata->pull_dis_mask & pdata->pullup_en_100k &420pdata->pullup_en_300k & pdata->pulldown_en_300k)421dev_warn(&client->dev, "Conflicting pull resistor config\n");422423for (i = 0; i < MAXGPIO; i++) {424unsigned val = 0;425426if (pdata->pullup_en_300k & (1 << i))427val = 0;428else if (pdata->pulldown_en_300k & (1 << i))429val = 1;430else if (pdata->pullup_en_100k & (1 << i))431val = 2;432else if (pdata->pull_dis_mask & (1 << i))433val = 3;434435pull_mask |= val << (2 * (i & 0x3));436437if ((i & 0x3) == 0x3 || i == MAXGPIO - 1) {438ret |= adp5589_write(client,439ADP5589_RPULL_CONFIG_A + (i >> 2),440pull_mask);441pull_mask = 0;442}443}444445if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) {446ret |= adp5589_write(client, ADP5589_RESET1_EVENT_A,447adp5589_get_evcode(kpad,448pdata->reset1_key_1));449ret |= adp5589_write(client, ADP5589_RESET1_EVENT_B,450adp5589_get_evcode(kpad,451pdata->reset1_key_2));452ret |= adp5589_write(client, ADP5589_RESET1_EVENT_C,453adp5589_get_evcode(kpad,454pdata->reset1_key_3));455kpad->extend_cfg |= R4_EXTEND_CFG;456}457458if (pdata->reset2_key_1 && pdata->reset2_key_2) {459ret |= adp5589_write(client, ADP5589_RESET2_EVENT_A,460adp5589_get_evcode(kpad,461pdata->reset2_key_1));462ret |= adp5589_write(client, ADP5589_RESET2_EVENT_B,463adp5589_get_evcode(kpad,464pdata->reset2_key_2));465kpad->extend_cfg |= C4_EXTEND_CFG;466}467468if (kpad->extend_cfg) {469ret |= adp5589_write(client, ADP5589_RESET_CFG,470pdata->reset_cfg);471ret |= adp5589_write(client, ADP5589_PIN_CONFIG_D,472kpad->extend_cfg);473}474475for (i = 0; i <= ADP_BANK(MAXGPIO); i++)476ret |= adp5589_write(client, ADP5589_DEBOUNCE_DIS_A + i,477pdata->debounce_dis_mask >> (i * 8));478479ret |= adp5589_write(client, ADP5589_POLL_PTIME_CFG,480pdata->scan_cycle_time & PTIME_MASK);481ret |= adp5589_write(client, ADP5589_INT_STATUS, LOGIC2_INT |482LOGIC1_INT | OVRFLOW_INT | LOCK_INT |483GPI_INT | EVENT_INT); /* Status is W1C */484485ret |= adp5589_write(client, ADP5589_GENERAL_CFG,486INT_CFG | OSC_EN | CORE_CLK(3));487ret |= adp5589_write(client, ADP5589_INT_EN,488OVRFLOW_IEN | GPI_IEN | EVENT_IEN);489490if (ret < 0) {491dev_err(&client->dev, "Write Error\n");492return ret;493}494495return 0;496}497498static void __devinit adp5589_report_switch_state(struct adp5589_kpad *kpad)499{500int gpi_stat1 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_A);501int gpi_stat2 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_B);502int gpi_stat3 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_C);503int gpi_stat_tmp, pin_loc;504int i;505506for (i = 0; i < kpad->gpimapsize; i++) {507unsigned short pin = kpad->gpimap[i].pin;508509if (pin <= ADP5589_GPI_PIN_ROW_END) {510gpi_stat_tmp = gpi_stat1;511pin_loc = pin - ADP5589_GPI_PIN_ROW_BASE;512} else if ((pin - ADP5589_GPI_PIN_COL_BASE) < 8) {513gpi_stat_tmp = gpi_stat2;514pin_loc = pin - ADP5589_GPI_PIN_COL_BASE;515} else {516gpi_stat_tmp = gpi_stat3;517pin_loc = pin - ADP5589_GPI_PIN_COL_BASE - 8;518}519520if (gpi_stat_tmp < 0) {521dev_err(&kpad->client->dev,522"Can't read GPIO_DAT_STAT switch"523" %d default to OFF\n", pin);524gpi_stat_tmp = 0;525}526527input_report_switch(kpad->input,528kpad->gpimap[i].sw_evt,529!(gpi_stat_tmp & (1 << pin_loc)));530}531532input_sync(kpad->input);533}534535static int __devinit adp5589_probe(struct i2c_client *client,536const struct i2c_device_id *id)537{538struct adp5589_kpad *kpad;539const struct adp5589_kpad_platform_data *pdata;540struct input_dev *input;541unsigned int revid;542int ret, i;543int error;544545if (!i2c_check_functionality(client->adapter,546I2C_FUNC_SMBUS_BYTE_DATA)) {547dev_err(&client->dev, "SMBUS Byte Data not Supported\n");548return -EIO;549}550551pdata = client->dev.platform_data;552if (!pdata) {553dev_err(&client->dev, "no platform data?\n");554return -EINVAL;555}556557if (!((pdata->keypad_en_mask & 0xFF) &&558(pdata->keypad_en_mask >> 8)) || !pdata->keymap) {559dev_err(&client->dev, "no rows, cols or keymap from pdata\n");560return -EINVAL;561}562563if (pdata->keymapsize != ADP5589_KEYMAPSIZE) {564dev_err(&client->dev, "invalid keymapsize\n");565return -EINVAL;566}567568if (!pdata->gpimap && pdata->gpimapsize) {569dev_err(&client->dev, "invalid gpimap from pdata\n");570return -EINVAL;571}572573if (pdata->gpimapsize > ADP5589_GPIMAPSIZE_MAX) {574dev_err(&client->dev, "invalid gpimapsize\n");575return -EINVAL;576}577578for (i = 0; i < pdata->gpimapsize; i++) {579unsigned short pin = pdata->gpimap[i].pin;580581if (pin < ADP5589_GPI_PIN_BASE || pin > ADP5589_GPI_PIN_END) {582dev_err(&client->dev, "invalid gpi pin data\n");583return -EINVAL;584}585586if ((1 << (pin - ADP5589_GPI_PIN_ROW_BASE)) &587pdata->keypad_en_mask) {588dev_err(&client->dev, "invalid gpi row/col data\n");589return -EINVAL;590}591}592593if (!client->irq) {594dev_err(&client->dev, "no IRQ?\n");595return -EINVAL;596}597598kpad = kzalloc(sizeof(*kpad), GFP_KERNEL);599input = input_allocate_device();600if (!kpad || !input) {601error = -ENOMEM;602goto err_free_mem;603}604605kpad->client = client;606kpad->input = input;607608ret = adp5589_read(client, ADP5589_ID);609if (ret < 0) {610error = ret;611goto err_free_mem;612}613614revid = (u8) ret & ADP5589_DEVICE_ID_MASK;615616input->name = client->name;617input->phys = "adp5589-keys/input0";618input->dev.parent = &client->dev;619620input_set_drvdata(input, kpad);621622input->id.bustype = BUS_I2C;623input->id.vendor = 0x0001;624input->id.product = 0x0001;625input->id.version = revid;626627input->keycodesize = sizeof(kpad->keycode[0]);628input->keycodemax = pdata->keymapsize;629input->keycode = kpad->keycode;630631memcpy(kpad->keycode, pdata->keymap,632pdata->keymapsize * input->keycodesize);633634kpad->gpimap = pdata->gpimap;635kpad->gpimapsize = pdata->gpimapsize;636637/* setup input device */638__set_bit(EV_KEY, input->evbit);639640if (pdata->repeat)641__set_bit(EV_REP, input->evbit);642643for (i = 0; i < input->keycodemax; i++)644__set_bit(kpad->keycode[i] & KEY_MAX, input->keybit);645__clear_bit(KEY_RESERVED, input->keybit);646647if (kpad->gpimapsize)648__set_bit(EV_SW, input->evbit);649for (i = 0; i < kpad->gpimapsize; i++)650__set_bit(kpad->gpimap[i].sw_evt, input->swbit);651652error = input_register_device(input);653if (error) {654dev_err(&client->dev, "unable to register input device\n");655goto err_free_mem;656}657658error = request_threaded_irq(client->irq, NULL, adp5589_irq,659IRQF_TRIGGER_FALLING | IRQF_ONESHOT,660client->dev.driver->name, kpad);661if (error) {662dev_err(&client->dev, "irq %d busy?\n", client->irq);663goto err_unreg_dev;664}665666error = adp5589_setup(kpad);667if (error)668goto err_free_irq;669670if (kpad->gpimapsize)671adp5589_report_switch_state(kpad);672673error = adp5589_gpio_add(kpad);674if (error)675goto err_free_irq;676677device_init_wakeup(&client->dev, 1);678i2c_set_clientdata(client, kpad);679680dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);681return 0;682683err_free_irq:684free_irq(client->irq, kpad);685err_unreg_dev:686input_unregister_device(input);687input = NULL;688err_free_mem:689input_free_device(input);690kfree(kpad);691692return error;693}694695static int __devexit adp5589_remove(struct i2c_client *client)696{697struct adp5589_kpad *kpad = i2c_get_clientdata(client);698699adp5589_write(client, ADP5589_GENERAL_CFG, 0);700free_irq(client->irq, kpad);701input_unregister_device(kpad->input);702adp5589_gpio_remove(kpad);703kfree(kpad);704705return 0;706}707708#ifdef CONFIG_PM_SLEEP709static int adp5589_suspend(struct device *dev)710{711struct adp5589_kpad *kpad = dev_get_drvdata(dev);712struct i2c_client *client = kpad->client;713714disable_irq(client->irq);715716if (device_may_wakeup(&client->dev))717enable_irq_wake(client->irq);718719return 0;720}721722static int adp5589_resume(struct device *dev)723{724struct adp5589_kpad *kpad = dev_get_drvdata(dev);725struct i2c_client *client = kpad->client;726727if (device_may_wakeup(&client->dev))728disable_irq_wake(client->irq);729730enable_irq(client->irq);731732return 0;733}734#endif735736static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume);737738static const struct i2c_device_id adp5589_id[] = {739{"adp5589-keys", 0},740{}741};742743MODULE_DEVICE_TABLE(i2c, adp5589_id);744745static struct i2c_driver adp5589_driver = {746.driver = {747.name = KBUILD_MODNAME,748.owner = THIS_MODULE,749.pm = &adp5589_dev_pm_ops,750},751.probe = adp5589_probe,752.remove = __devexit_p(adp5589_remove),753.id_table = adp5589_id,754};755756static int __init adp5589_init(void)757{758return i2c_add_driver(&adp5589_driver);759}760module_init(adp5589_init);761762static void __exit adp5589_exit(void)763{764i2c_del_driver(&adp5589_driver);765}766module_exit(adp5589_exit);767768MODULE_LICENSE("GPL");769MODULE_AUTHOR("Michael Hennerich <[email protected]>");770MODULE_DESCRIPTION("ADP5589 Keypad driver");771772773