max7359_keypad.c 8.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * max7359_keypad.c - MAX7359 Key Switch Controller Driver
 *
 * Copyright (C) 2009 Samsung Electronics
 * Kim Kyuwon <q1.kim@samsung.com>
 *
 * Based on pxa27x_keypad.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Datasheet: http://www.maxim-ic.com/quick_view2.cfm/qv_pk/5456
 */

#include <linux/module.h>
#include <linux/i2c.h>
18
#include <linux/slab.h>
19
#include <linux/interrupt.h>
20
#include <linux/pm.h>
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>

#define MAX7359_MAX_KEY_ROWS	8
#define MAX7359_MAX_KEY_COLS	8
#define MAX7359_MAX_KEY_NUM	(MAX7359_MAX_KEY_ROWS * MAX7359_MAX_KEY_COLS)
#define MAX7359_ROW_SHIFT	3

/*
 * MAX7359 registers
 */
#define MAX7359_REG_KEYFIFO	0x00
#define MAX7359_REG_CONFIG	0x01
#define MAX7359_REG_DEBOUNCE	0x02
#define MAX7359_REG_INTERRUPT	0x03
#define MAX7359_REG_PORTS	0x04
#define MAX7359_REG_KEYREP	0x05
#define MAX7359_REG_SLEEP	0x06

/*
 * Configuration register bits
 */
#define MAX7359_CFG_SLEEP	(1 << 7)
#define MAX7359_CFG_INTERRUPT	(1 << 5)
#define MAX7359_CFG_KEY_RELEASE	(1 << 3)
#define MAX7359_CFG_WAKEUP	(1 << 1)
#define MAX7359_CFG_TIMEOUT	(1 << 0)

/*
 * Autosleep register values (ms)
 */
#define MAX7359_AUTOSLEEP_8192	0x01
#define MAX7359_AUTOSLEEP_4096	0x02
#define MAX7359_AUTOSLEEP_2048	0x03
#define MAX7359_AUTOSLEEP_1024	0x04
#define MAX7359_AUTOSLEEP_512	0x05
#define MAX7359_AUTOSLEEP_256	0x06

struct max7359_keypad {
	/* matrix key code map */
	unsigned short keycodes[MAX7359_MAX_KEY_NUM];

	struct input_dev *input_dev;
	struct i2c_client *client;
};

static int max7359_write_reg(struct i2c_client *client, u8 reg, u8 val)
{
	int ret = i2c_smbus_write_byte_data(client, reg, val);

	if (ret < 0)
		dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",
			__func__, reg, val, ret);
	return ret;
}

static int max7359_read_reg(struct i2c_client *client, int reg)
{
	int ret = i2c_smbus_read_byte_data(client, reg);

	if (ret < 0)
		dev_err(&client->dev, "%s: reg 0x%x, err %d\n",
			__func__, reg, ret);
	return ret;
}

static void max7359_build_keycode(struct max7359_keypad *keypad,
				const struct matrix_keymap_data *keymap_data)
{
	struct input_dev *input_dev = keypad->input_dev;
	int i;

	for (i = 0; i < keymap_data->keymap_size; i++) {
		unsigned int key = keymap_data->keymap[i];
		unsigned int row = KEY_ROW(key);
		unsigned int col = KEY_COL(key);
		unsigned int scancode = MATRIX_SCAN_CODE(row, col,
						MAX7359_ROW_SHIFT);
		unsigned short keycode = KEY_VAL(key);

		keypad->keycodes[scancode] = keycode;
		__set_bit(keycode, input_dev->keybit);
	}
	__clear_bit(KEY_RESERVED, input_dev->keybit);
}

107 108
/* runs in an IRQ thread -- can (and will!) sleep */
static irqreturn_t max7359_interrupt(int irq, void *dev_id)
109
{
110
	struct max7359_keypad *keypad = dev_id;
111 112 113 114 115 116 117 118 119 120
	struct input_dev *input_dev = keypad->input_dev;
	int val, row, col, release, code;

	val = max7359_read_reg(keypad->client, MAX7359_REG_KEYFIFO);
	row = val & 0x7;
	col = (val >> 3) & 0x7;
	release = val & 0x40;

	code = MATRIX_SCAN_CODE(row, col, MAX7359_ROW_SHIFT);

121 122 123
	dev_dbg(&keypad->client->dev,
		"key[%d:%d] %s\n", row, col, release ? "release" : "press");

124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
	input_event(input_dev, EV_MSC, MSC_SCAN, code);
	input_report_key(input_dev, keypad->keycodes[code], !release);
	input_sync(input_dev);

	return IRQ_HANDLED;
}

/*
 * Let MAX7359 fall into a deep sleep:
 * If no keys are pressed, enter sleep mode for 8192 ms. And if any
 * key is pressed, the MAX7359 returns to normal operating mode.
 */
static inline void max7359_fall_deepsleep(struct i2c_client *client)
{
	max7359_write_reg(client, MAX7359_REG_SLEEP, MAX7359_AUTOSLEEP_8192);
}

/*
 * Let MAX7359 take a catnap:
 * Autosleep just for 256 ms.
 */
static inline void max7359_take_catnap(struct i2c_client *client)
{
	max7359_write_reg(client, MAX7359_REG_SLEEP, MAX7359_AUTOSLEEP_256);
}

static int max7359_open(struct input_dev *dev)
{
	struct max7359_keypad *keypad = input_get_drvdata(dev);

	max7359_take_catnap(keypad->client);

	return 0;
}

static void max7359_close(struct input_dev *dev)
{
	struct max7359_keypad *keypad = input_get_drvdata(dev);

	max7359_fall_deepsleep(keypad->client);
}

static void max7359_initialize(struct i2c_client *client)
{
	max7359_write_reg(client, MAX7359_REG_CONFIG,
		MAX7359_CFG_INTERRUPT | /* Irq clears after host read */
		MAX7359_CFG_KEY_RELEASE | /* Key release enable */
		MAX7359_CFG_WAKEUP); /* Key press wakeup enable */

	/* Full key-scan functionality */
	max7359_write_reg(client, MAX7359_REG_DEBOUNCE, 0x1F);

	/* nINT asserts every debounce cycles */
	max7359_write_reg(client, MAX7359_REG_INTERRUPT, 0x01);

	max7359_fall_deepsleep(client);
}

static int __devinit max7359_probe(struct i2c_client *client,
					const struct i2c_device_id *id)
{
	const struct matrix_keymap_data *keymap_data = client->dev.platform_data;
	struct max7359_keypad *keypad;
	struct input_dev *input_dev;
	int ret;
	int error;

	if (!client->irq) {
		dev_err(&client->dev, "The irq number should not be zero\n");
		return -EINVAL;
	}

	/* Detect MAX7359: The initial Keys FIFO value is '0x3F' */
	ret = max7359_read_reg(client, MAX7359_REG_KEYFIFO);
	if (ret < 0) {
		dev_err(&client->dev, "failed to detect device\n");
		return -ENODEV;
	}

	dev_dbg(&client->dev, "keys FIFO is 0x%02x\n", ret);

	keypad = kzalloc(sizeof(struct max7359_keypad), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!keypad || !input_dev) {
		dev_err(&client->dev, "failed to allocate memory\n");
		error = -ENOMEM;
		goto failed_free_mem;
	}

	keypad->client = client;
	keypad->input_dev = input_dev;

	input_dev->name = client->name;
	input_dev->id.bustype = BUS_I2C;
	input_dev->open = max7359_open;
	input_dev->close = max7359_close;
	input_dev->dev.parent = &client->dev;

	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
	input_dev->keycodesize = sizeof(keypad->keycodes[0]);
	input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
	input_dev->keycode = keypad->keycodes;

	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
	input_set_drvdata(input_dev, keypad);

	max7359_build_keycode(keypad, keymap_data);

232 233 234
	error = request_threaded_irq(client->irq, NULL, max7359_interrupt,
				     IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				     client->name, keypad);
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
	if (error) {
		dev_err(&client->dev, "failed to register interrupt\n");
		goto failed_free_mem;
	}

	/* Register the input device */
	error = input_register_device(input_dev);
	if (error) {
		dev_err(&client->dev, "failed to register input device\n");
		goto failed_free_irq;
	}

	/* Initialize MAX7359 */
	max7359_initialize(client);

	i2c_set_clientdata(client, keypad);
	device_init_wakeup(&client->dev, 1);

	return 0;

failed_free_irq:
256
	free_irq(client->irq, keypad);
257 258 259 260 261 262 263 264 265 266
failed_free_mem:
	input_free_device(input_dev);
	kfree(keypad);
	return error;
}

static int __devexit max7359_remove(struct i2c_client *client)
{
	struct max7359_keypad *keypad = i2c_get_clientdata(client);

267
	free_irq(client->irq, keypad);
268 269 270 271 272 273 274
	input_unregister_device(keypad->input_dev);
	kfree(keypad);

	return 0;
}

#ifdef CONFIG_PM
275
static int max7359_suspend(struct device *dev)
276
{
277 278
	struct i2c_client *client = to_i2c_client(dev);

279 280 281
	max7359_fall_deepsleep(client);

	if (device_may_wakeup(&client->dev))
282
		enable_irq_wake(client->irq);
283 284 285 286

	return 0;
}

287
static int max7359_resume(struct device *dev)
288
{
289 290
	struct i2c_client *client = to_i2c_client(dev);

291
	if (device_may_wakeup(&client->dev))
292
		disable_irq_wake(client->irq);
293 294 295 296 297 298 299 300

	/* Restore the default setting */
	max7359_take_catnap(client);

	return 0;
}
#endif

301 302
static SIMPLE_DEV_PM_OPS(max7359_pm, max7359_suspend, max7359_resume);

303 304 305 306 307 308 309 310 311
static const struct i2c_device_id max7359_ids[] = {
	{ "max7359", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, max7359_ids);

static struct i2c_driver max7359_i2c_driver = {
	.driver = {
		.name = "max7359",
312
		.pm   = &max7359_pm,
313 314 315 316 317 318
	},
	.probe		= max7359_probe,
	.remove		= __devexit_p(max7359_remove),
	.id_table	= max7359_ids,
};

319
module_i2c_driver(max7359_i2c_driver);
320 321 322 323

MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
MODULE_DESCRIPTION("MAX7359 Key Switch Controller Driver");
MODULE_LICENSE("GPL v2");