Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Driver for TCA8418 I2C keyboard
0003  *
0004  * Copyright (C) 2011 Fuel7, Inc.  All rights reserved.
0005  *
0006  * Author: Kyle Manna <kyle.manna@fuel7.com>
0007  *
0008  * This program is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU General Public
0010  * License v2 as published by the Free Software Foundation.
0011  *
0012  * This program is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU General Public
0018  * License along with this program; if not, write to the
0019  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
0020  * Boston, MA 021110-1307, USA.
0021  *
0022  * If you can't comply with GPLv2, alternative licensing terms may be
0023  * arranged. Please contact Fuel7, Inc. (http://fuel7.com/) for proprietary
0024  * alternative licensing inquiries.
0025  */
0026 
0027 #include <linux/delay.h>
0028 #include <linux/i2c.h>
0029 #include <linux/init.h>
0030 #include <linux/input.h>
0031 #include <linux/input/matrix_keypad.h>
0032 #include <linux/interrupt.h>
0033 #include <linux/module.h>
0034 #include <linux/of.h>
0035 #include <linux/property.h>
0036 #include <linux/slab.h>
0037 #include <linux/types.h>
0038 
0039 /* TCA8418 hardware limits */
0040 #define TCA8418_MAX_ROWS    8
0041 #define TCA8418_MAX_COLS    10
0042 
0043 /* TCA8418 register offsets */
0044 #define REG_CFG         0x01
0045 #define REG_INT_STAT        0x02
0046 #define REG_KEY_LCK_EC      0x03
0047 #define REG_KEY_EVENT_A     0x04
0048 #define REG_KEY_EVENT_B     0x05
0049 #define REG_KEY_EVENT_C     0x06
0050 #define REG_KEY_EVENT_D     0x07
0051 #define REG_KEY_EVENT_E     0x08
0052 #define REG_KEY_EVENT_F     0x09
0053 #define REG_KEY_EVENT_G     0x0A
0054 #define REG_KEY_EVENT_H     0x0B
0055 #define REG_KEY_EVENT_I     0x0C
0056 #define REG_KEY_EVENT_J     0x0D
0057 #define REG_KP_LCK_TIMER    0x0E
0058 #define REG_UNLOCK1     0x0F
0059 #define REG_UNLOCK2     0x10
0060 #define REG_GPIO_INT_STAT1  0x11
0061 #define REG_GPIO_INT_STAT2  0x12
0062 #define REG_GPIO_INT_STAT3  0x13
0063 #define REG_GPIO_DAT_STAT1  0x14
0064 #define REG_GPIO_DAT_STAT2  0x15
0065 #define REG_GPIO_DAT_STAT3  0x16
0066 #define REG_GPIO_DAT_OUT1   0x17
0067 #define REG_GPIO_DAT_OUT2   0x18
0068 #define REG_GPIO_DAT_OUT3   0x19
0069 #define REG_GPIO_INT_EN1    0x1A
0070 #define REG_GPIO_INT_EN2    0x1B
0071 #define REG_GPIO_INT_EN3    0x1C
0072 #define REG_KP_GPIO1        0x1D
0073 #define REG_KP_GPIO2        0x1E
0074 #define REG_KP_GPIO3        0x1F
0075 #define REG_GPI_EM1     0x20
0076 #define REG_GPI_EM2     0x21
0077 #define REG_GPI_EM3     0x22
0078 #define REG_GPIO_DIR1       0x23
0079 #define REG_GPIO_DIR2       0x24
0080 #define REG_GPIO_DIR3       0x25
0081 #define REG_GPIO_INT_LVL1   0x26
0082 #define REG_GPIO_INT_LVL2   0x27
0083 #define REG_GPIO_INT_LVL3   0x28
0084 #define REG_DEBOUNCE_DIS1   0x29
0085 #define REG_DEBOUNCE_DIS2   0x2A
0086 #define REG_DEBOUNCE_DIS3   0x2B
0087 #define REG_GPIO_PULL1      0x2C
0088 #define REG_GPIO_PULL2      0x2D
0089 #define REG_GPIO_PULL3      0x2E
0090 
0091 /* TCA8418 bit definitions */
0092 #define CFG_AI          BIT(7)
0093 #define CFG_GPI_E_CFG       BIT(6)
0094 #define CFG_OVR_FLOW_M      BIT(5)
0095 #define CFG_INT_CFG     BIT(4)
0096 #define CFG_OVR_FLOW_IEN    BIT(3)
0097 #define CFG_K_LCK_IEN       BIT(2)
0098 #define CFG_GPI_IEN     BIT(1)
0099 #define CFG_KE_IEN      BIT(0)
0100 
0101 #define INT_STAT_CAD_INT    BIT(4)
0102 #define INT_STAT_OVR_FLOW_INT   BIT(3)
0103 #define INT_STAT_K_LCK_INT  BIT(2)
0104 #define INT_STAT_GPI_INT    BIT(1)
0105 #define INT_STAT_K_INT      BIT(0)
0106 
0107 /* TCA8418 register masks */
0108 #define KEY_LCK_EC_KEC      0x7
0109 #define KEY_EVENT_CODE      0x7f
0110 #define KEY_EVENT_VALUE     0x80
0111 
0112 struct tca8418_keypad {
0113     struct i2c_client *client;
0114     struct input_dev *input;
0115 
0116     unsigned int row_shift;
0117 };
0118 
0119 /*
0120  * Write a byte to the TCA8418
0121  */
0122 static int tca8418_write_byte(struct tca8418_keypad *keypad_data,
0123                   int reg, u8 val)
0124 {
0125     int error;
0126 
0127     error = i2c_smbus_write_byte_data(keypad_data->client, reg, val);
0128     if (error < 0) {
0129         dev_err(&keypad_data->client->dev,
0130             "%s failed, reg: %d, val: %d, error: %d\n",
0131             __func__, reg, val, error);
0132         return error;
0133     }
0134 
0135     return 0;
0136 }
0137 
0138 /*
0139  * Read a byte from the TCA8418
0140  */
0141 static int tca8418_read_byte(struct tca8418_keypad *keypad_data,
0142                  int reg, u8 *val)
0143 {
0144     int error;
0145 
0146     error = i2c_smbus_read_byte_data(keypad_data->client, reg);
0147     if (error < 0) {
0148         dev_err(&keypad_data->client->dev,
0149                 "%s failed, reg: %d, error: %d\n",
0150                 __func__, reg, error);
0151         return error;
0152     }
0153 
0154     *val = (u8)error;
0155 
0156     return 0;
0157 }
0158 
0159 static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
0160 {
0161     struct input_dev *input = keypad_data->input;
0162     unsigned short *keymap = input->keycode;
0163     int error, col, row;
0164     u8 reg, state, code;
0165 
0166     do {
0167         error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg);
0168         if (error < 0) {
0169             dev_err(&keypad_data->client->dev,
0170                 "unable to read REG_KEY_EVENT_A\n");
0171             break;
0172         }
0173 
0174         /* Assume that key code 0 signifies empty FIFO */
0175         if (reg <= 0)
0176             break;
0177 
0178         state = reg & KEY_EVENT_VALUE;
0179         code  = reg & KEY_EVENT_CODE;
0180 
0181         row = code / TCA8418_MAX_COLS;
0182         col = code % TCA8418_MAX_COLS;
0183 
0184         row = (col) ? row : row - 1;
0185         col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
0186 
0187         code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
0188         input_event(input, EV_MSC, MSC_SCAN, code);
0189         input_report_key(input, keymap[code], state);
0190 
0191     } while (1);
0192 
0193     input_sync(input);
0194 }
0195 
0196 /*
0197  * Threaded IRQ handler and this can (and will) sleep.
0198  */
0199 static irqreturn_t tca8418_irq_handler(int irq, void *dev_id)
0200 {
0201     struct tca8418_keypad *keypad_data = dev_id;
0202     u8 reg;
0203     int error;
0204 
0205     error = tca8418_read_byte(keypad_data, REG_INT_STAT, &reg);
0206     if (error) {
0207         dev_err(&keypad_data->client->dev,
0208             "unable to read REG_INT_STAT\n");
0209         return IRQ_NONE;
0210     }
0211 
0212     if (!reg)
0213         return IRQ_NONE;
0214 
0215     if (reg & INT_STAT_OVR_FLOW_INT)
0216         dev_warn(&keypad_data->client->dev, "overflow occurred\n");
0217 
0218     if (reg & INT_STAT_K_INT)
0219         tca8418_read_keypad(keypad_data);
0220 
0221     /* Clear all interrupts, even IRQs we didn't check (GPI, CAD, LCK) */
0222     reg = 0xff;
0223     error = tca8418_write_byte(keypad_data, REG_INT_STAT, reg);
0224     if (error)
0225         dev_err(&keypad_data->client->dev,
0226             "unable to clear REG_INT_STAT\n");
0227 
0228     return IRQ_HANDLED;
0229 }
0230 
0231 /*
0232  * Configure the TCA8418 for keypad operation
0233  */
0234 static int tca8418_configure(struct tca8418_keypad *keypad_data,
0235                  u32 rows, u32 cols)
0236 {
0237     int reg, error = 0;
0238 
0239     /* Assemble a mask for row and column registers */
0240     reg  =  ~(~0 << rows);
0241     reg += (~(~0 << cols)) << 8;
0242 
0243     /* Set registers to keypad mode */
0244     error |= tca8418_write_byte(keypad_data, REG_KP_GPIO1, reg);
0245     error |= tca8418_write_byte(keypad_data, REG_KP_GPIO2, reg >> 8);
0246     error |= tca8418_write_byte(keypad_data, REG_KP_GPIO3, reg >> 16);
0247 
0248     /* Enable column debouncing */
0249     error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS1, reg);
0250     error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS2, reg >> 8);
0251     error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS3, reg >> 16);
0252 
0253     if (error)
0254         return error;
0255 
0256     error = tca8418_write_byte(keypad_data, REG_CFG,
0257                 CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
0258 
0259     return error;
0260 }
0261 
0262 static int tca8418_keypad_probe(struct i2c_client *client,
0263                 const struct i2c_device_id *id)
0264 {
0265     struct device *dev = &client->dev;
0266     struct tca8418_keypad *keypad_data;
0267     struct input_dev *input;
0268     u32 rows = 0, cols = 0;
0269     int error, row_shift;
0270     u8 reg;
0271 
0272     /* Check i2c driver capabilities */
0273     if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
0274         dev_err(dev, "%s adapter not supported\n",
0275             dev_driver_string(&client->adapter->dev));
0276         return -ENODEV;
0277     }
0278 
0279     error = matrix_keypad_parse_properties(dev, &rows, &cols);
0280     if (error)
0281         return error;
0282 
0283     if (!rows || rows > TCA8418_MAX_ROWS) {
0284         dev_err(dev, "invalid rows\n");
0285         return -EINVAL;
0286     }
0287 
0288     if (!cols || cols > TCA8418_MAX_COLS) {
0289         dev_err(dev, "invalid columns\n");
0290         return -EINVAL;
0291     }
0292 
0293     row_shift = get_count_order(cols);
0294 
0295     /* Allocate memory for keypad_data and input device */
0296     keypad_data = devm_kzalloc(dev, sizeof(*keypad_data), GFP_KERNEL);
0297     if (!keypad_data)
0298         return -ENOMEM;
0299 
0300     keypad_data->client = client;
0301     keypad_data->row_shift = row_shift;
0302 
0303     /* Read key lock register, if this fails assume device not present */
0304     error = tca8418_read_byte(keypad_data, REG_KEY_LCK_EC, &reg);
0305     if (error)
0306         return -ENODEV;
0307 
0308     /* Configure input device */
0309     input = devm_input_allocate_device(dev);
0310     if (!input)
0311         return -ENOMEM;
0312 
0313     keypad_data->input = input;
0314 
0315     input->name = client->name;
0316     input->id.bustype = BUS_I2C;
0317     input->id.vendor  = 0x0001;
0318     input->id.product = 0x001;
0319     input->id.version = 0x0001;
0320 
0321     error = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL, input);
0322     if (error) {
0323         dev_err(dev, "Failed to build keymap\n");
0324         return error;
0325     }
0326 
0327     if (device_property_read_bool(dev, "keypad,autorepeat"))
0328         __set_bit(EV_REP, input->evbit);
0329 
0330     input_set_capability(input, EV_MSC, MSC_SCAN);
0331 
0332     error = devm_request_threaded_irq(dev, client->irq,
0333                       NULL, tca8418_irq_handler,
0334                       IRQF_SHARED | IRQF_ONESHOT,
0335                       client->name, keypad_data);
0336     if (error) {
0337         dev_err(dev, "Unable to claim irq %d; error %d\n",
0338             client->irq, error);
0339         return error;
0340     }
0341 
0342     /* Initialize the chip */
0343     error = tca8418_configure(keypad_data, rows, cols);
0344     if (error < 0)
0345         return error;
0346 
0347     error = input_register_device(input);
0348     if (error) {
0349         dev_err(dev, "Unable to register input device, error: %d\n",
0350             error);
0351         return error;
0352     }
0353 
0354     return 0;
0355 }
0356 
0357 static const struct i2c_device_id tca8418_id[] = {
0358     { "tca8418", 8418, },
0359     { }
0360 };
0361 MODULE_DEVICE_TABLE(i2c, tca8418_id);
0362 
0363 static const struct of_device_id tca8418_dt_ids[] = {
0364     { .compatible = "ti,tca8418", },
0365     { }
0366 };
0367 MODULE_DEVICE_TABLE(of, tca8418_dt_ids);
0368 
0369 static struct i2c_driver tca8418_keypad_driver = {
0370     .driver = {
0371         .name   = "tca8418_keypad",
0372         .of_match_table = tca8418_dt_ids,
0373     },
0374     .probe      = tca8418_keypad_probe,
0375     .id_table   = tca8418_id,
0376 };
0377 
0378 static int __init tca8418_keypad_init(void)
0379 {
0380     return i2c_add_driver(&tca8418_keypad_driver);
0381 }
0382 subsys_initcall(tca8418_keypad_init);
0383 
0384 static void __exit tca8418_keypad_exit(void)
0385 {
0386     i2c_del_driver(&tca8418_keypad_driver);
0387 }
0388 module_exit(tca8418_keypad_exit);
0389 
0390 MODULE_AUTHOR("Kyle Manna <kyle.manna@fuel7.com>");
0391 MODULE_DESCRIPTION("Keypad driver for TCA8418");
0392 MODULE_LICENSE("GPL");