Path: blob/master/drivers/input/keyboard/max7359_keypad.c
15111 views
/*1* max7359_keypad.c - MAX7359 Key Switch Controller Driver2*3* Copyright (C) 2009 Samsung Electronics4* Kim Kyuwon <[email protected]>5*6* Based on pxa27x_keypad.c7*8* This program is free software; you can redistribute it and/or modify9* it under the terms of the GNU General Public License version 2 as10* published by the Free Software Foundation.11*12* Datasheet: http://www.maxim-ic.com/quick_view2.cfm/qv_pk/545613*/1415#include <linux/module.h>16#include <linux/i2c.h>17#include <linux/slab.h>18#include <linux/interrupt.h>19#include <linux/pm.h>20#include <linux/input.h>21#include <linux/input/matrix_keypad.h>2223#define MAX7359_MAX_KEY_ROWS 824#define MAX7359_MAX_KEY_COLS 825#define MAX7359_MAX_KEY_NUM (MAX7359_MAX_KEY_ROWS * MAX7359_MAX_KEY_COLS)26#define MAX7359_ROW_SHIFT 32728/*29* MAX7359 registers30*/31#define MAX7359_REG_KEYFIFO 0x0032#define MAX7359_REG_CONFIG 0x0133#define MAX7359_REG_DEBOUNCE 0x0234#define MAX7359_REG_INTERRUPT 0x0335#define MAX7359_REG_PORTS 0x0436#define MAX7359_REG_KEYREP 0x0537#define MAX7359_REG_SLEEP 0x063839/*40* Configuration register bits41*/42#define MAX7359_CFG_SLEEP (1 << 7)43#define MAX7359_CFG_INTERRUPT (1 << 5)44#define MAX7359_CFG_KEY_RELEASE (1 << 3)45#define MAX7359_CFG_WAKEUP (1 << 1)46#define MAX7359_CFG_TIMEOUT (1 << 0)4748/*49* Autosleep register values (ms)50*/51#define MAX7359_AUTOSLEEP_8192 0x0152#define MAX7359_AUTOSLEEP_4096 0x0253#define MAX7359_AUTOSLEEP_2048 0x0354#define MAX7359_AUTOSLEEP_1024 0x0455#define MAX7359_AUTOSLEEP_512 0x0556#define MAX7359_AUTOSLEEP_256 0x065758struct max7359_keypad {59/* matrix key code map */60unsigned short keycodes[MAX7359_MAX_KEY_NUM];6162struct input_dev *input_dev;63struct i2c_client *client;64};6566static int max7359_write_reg(struct i2c_client *client, u8 reg, u8 val)67{68int ret = i2c_smbus_write_byte_data(client, reg, val);6970if (ret < 0)71dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",72__func__, reg, val, ret);73return ret;74}7576static int max7359_read_reg(struct i2c_client *client, int reg)77{78int ret = i2c_smbus_read_byte_data(client, reg);7980if (ret < 0)81dev_err(&client->dev, "%s: reg 0x%x, err %d\n",82__func__, reg, ret);83return ret;84}8586static void max7359_build_keycode(struct max7359_keypad *keypad,87const struct matrix_keymap_data *keymap_data)88{89struct input_dev *input_dev = keypad->input_dev;90int i;9192for (i = 0; i < keymap_data->keymap_size; i++) {93unsigned int key = keymap_data->keymap[i];94unsigned int row = KEY_ROW(key);95unsigned int col = KEY_COL(key);96unsigned int scancode = MATRIX_SCAN_CODE(row, col,97MAX7359_ROW_SHIFT);98unsigned short keycode = KEY_VAL(key);99100keypad->keycodes[scancode] = keycode;101__set_bit(keycode, input_dev->keybit);102}103__clear_bit(KEY_RESERVED, input_dev->keybit);104}105106/* runs in an IRQ thread -- can (and will!) sleep */107static irqreturn_t max7359_interrupt(int irq, void *dev_id)108{109struct max7359_keypad *keypad = dev_id;110struct input_dev *input_dev = keypad->input_dev;111int val, row, col, release, code;112113val = max7359_read_reg(keypad->client, MAX7359_REG_KEYFIFO);114row = val & 0x7;115col = (val >> 3) & 0x7;116release = val & 0x40;117118code = MATRIX_SCAN_CODE(row, col, MAX7359_ROW_SHIFT);119120dev_dbg(&keypad->client->dev,121"key[%d:%d] %s\n", row, col, release ? "release" : "press");122123input_event(input_dev, EV_MSC, MSC_SCAN, code);124input_report_key(input_dev, keypad->keycodes[code], !release);125input_sync(input_dev);126127return IRQ_HANDLED;128}129130/*131* Let MAX7359 fall into a deep sleep:132* If no keys are pressed, enter sleep mode for 8192 ms. And if any133* key is pressed, the MAX7359 returns to normal operating mode.134*/135static inline void max7359_fall_deepsleep(struct i2c_client *client)136{137max7359_write_reg(client, MAX7359_REG_SLEEP, MAX7359_AUTOSLEEP_8192);138}139140/*141* Let MAX7359 take a catnap:142* Autosleep just for 256 ms.143*/144static inline void max7359_take_catnap(struct i2c_client *client)145{146max7359_write_reg(client, MAX7359_REG_SLEEP, MAX7359_AUTOSLEEP_256);147}148149static int max7359_open(struct input_dev *dev)150{151struct max7359_keypad *keypad = input_get_drvdata(dev);152153max7359_take_catnap(keypad->client);154155return 0;156}157158static void max7359_close(struct input_dev *dev)159{160struct max7359_keypad *keypad = input_get_drvdata(dev);161162max7359_fall_deepsleep(keypad->client);163}164165static void max7359_initialize(struct i2c_client *client)166{167max7359_write_reg(client, MAX7359_REG_CONFIG,168MAX7359_CFG_INTERRUPT | /* Irq clears after host read */169MAX7359_CFG_KEY_RELEASE | /* Key release enable */170MAX7359_CFG_WAKEUP); /* Key press wakeup enable */171172/* Full key-scan functionality */173max7359_write_reg(client, MAX7359_REG_DEBOUNCE, 0x1F);174175/* nINT asserts every debounce cycles */176max7359_write_reg(client, MAX7359_REG_INTERRUPT, 0x01);177178max7359_fall_deepsleep(client);179}180181static int __devinit max7359_probe(struct i2c_client *client,182const struct i2c_device_id *id)183{184const struct matrix_keymap_data *keymap_data = client->dev.platform_data;185struct max7359_keypad *keypad;186struct input_dev *input_dev;187int ret;188int error;189190if (!client->irq) {191dev_err(&client->dev, "The irq number should not be zero\n");192return -EINVAL;193}194195/* Detect MAX7359: The initial Keys FIFO value is '0x3F' */196ret = max7359_read_reg(client, MAX7359_REG_KEYFIFO);197if (ret < 0) {198dev_err(&client->dev, "failed to detect device\n");199return -ENODEV;200}201202dev_dbg(&client->dev, "keys FIFO is 0x%02x\n", ret);203204keypad = kzalloc(sizeof(struct max7359_keypad), GFP_KERNEL);205input_dev = input_allocate_device();206if (!keypad || !input_dev) {207dev_err(&client->dev, "failed to allocate memory\n");208error = -ENOMEM;209goto failed_free_mem;210}211212keypad->client = client;213keypad->input_dev = input_dev;214215input_dev->name = client->name;216input_dev->id.bustype = BUS_I2C;217input_dev->open = max7359_open;218input_dev->close = max7359_close;219input_dev->dev.parent = &client->dev;220221input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);222input_dev->keycodesize = sizeof(keypad->keycodes[0]);223input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);224input_dev->keycode = keypad->keycodes;225226input_set_capability(input_dev, EV_MSC, MSC_SCAN);227input_set_drvdata(input_dev, keypad);228229max7359_build_keycode(keypad, keymap_data);230231error = request_threaded_irq(client->irq, NULL, max7359_interrupt,232IRQF_TRIGGER_LOW | IRQF_ONESHOT,233client->name, keypad);234if (error) {235dev_err(&client->dev, "failed to register interrupt\n");236goto failed_free_mem;237}238239/* Register the input device */240error = input_register_device(input_dev);241if (error) {242dev_err(&client->dev, "failed to register input device\n");243goto failed_free_irq;244}245246/* Initialize MAX7359 */247max7359_initialize(client);248249i2c_set_clientdata(client, keypad);250device_init_wakeup(&client->dev, 1);251252return 0;253254failed_free_irq:255free_irq(client->irq, keypad);256failed_free_mem:257input_free_device(input_dev);258kfree(keypad);259return error;260}261262static int __devexit max7359_remove(struct i2c_client *client)263{264struct max7359_keypad *keypad = i2c_get_clientdata(client);265266free_irq(client->irq, keypad);267input_unregister_device(keypad->input_dev);268kfree(keypad);269270return 0;271}272273#ifdef CONFIG_PM274static int max7359_suspend(struct device *dev)275{276struct i2c_client *client = to_i2c_client(dev);277278max7359_fall_deepsleep(client);279280if (device_may_wakeup(&client->dev))281enable_irq_wake(client->irq);282283return 0;284}285286static int max7359_resume(struct device *dev)287{288struct i2c_client *client = to_i2c_client(dev);289290if (device_may_wakeup(&client->dev))291disable_irq_wake(client->irq);292293/* Restore the default setting */294max7359_take_catnap(client);295296return 0;297}298#endif299300static SIMPLE_DEV_PM_OPS(max7359_pm, max7359_suspend, max7359_resume);301302static const struct i2c_device_id max7359_ids[] = {303{ "max7359", 0 },304{ }305};306MODULE_DEVICE_TABLE(i2c, max7359_ids);307308static struct i2c_driver max7359_i2c_driver = {309.driver = {310.name = "max7359",311.pm = &max7359_pm,312},313.probe = max7359_probe,314.remove = __devexit_p(max7359_remove),315.id_table = max7359_ids,316};317318static int __init max7359_init(void)319{320return i2c_add_driver(&max7359_i2c_driver);321}322module_init(max7359_init);323324static void __exit max7359_exit(void)325{326i2c_del_driver(&max7359_i2c_driver);327}328module_exit(max7359_exit);329330MODULE_AUTHOR("Kim Kyuwon <[email protected]>");331MODULE_DESCRIPTION("MAX7359 Key Switch Controller Driver");332MODULE_LICENSE("GPL v2");333334335