diff options
author | Beomho Seo <beomho.seo@samsung.com> | 2013-08-12 22:04:13 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-08-08 14:35:59 +0900 |
commit | e67e28225ee82976843d137187b971c26c0e11be (patch) | |
tree | a35ed809f7f43df535f16dc9788e574638712a8a /drivers/input | |
parent | 4c330f0f5c90f21cfb527c8be741ebaf72990bdf (diff) | |
download | linux-3.10-e67e28225ee82976843d137187b971c26c0e11be.tar.gz linux-3.10-e67e28225ee82976843d137187b971c26c0e11be.tar.bz2 linux-3.10-e67e28225ee82976843d137187b971c26c0e11be.zip |
Input: mcs_touchkey: Add parse DT function from device tree
Add parse DT function for support mcs touchkey driver
Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/keyboard/mcs_touchkey.c | 76 |
1 files changed, 71 insertions, 5 deletions
diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index 7c236f9c6a5..9668d3e1be8 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c @@ -20,6 +20,8 @@ #include <linux/irq.h> #include <linux/slab.h> #include <linux/pm.h> +#include <linux/of_platform.h> +#include <linux/of_gpio.h> /* MCS5000 Touchkey */ #define MCS5000_TOUCHKEY_STATUS 0x04 @@ -97,6 +99,60 @@ static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +#ifdef CONFIG_OF +static struct mcs_platform_data *mcs_touchkey_parse_dt(struct device *dev) +{ + struct mcs_platform_data *pdata; + struct device_node *np = dev->of_node; + unsigned int keymap[2]; + unsigned int len; + int i = 0; + const __be32 *prop; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dev_err(dev, "Failed to allocate platform data\n"); + return ERR_PTR(-ENOMEM); + } + + prop = of_get_property(np, "linux,code", &len); + if (!prop) { + dev_err(dev, "Failed to get code\n"); + return ERR_PTR(-EINVAL); + } + + if (len % sizeof(u32)) { + dev_err(dev, "Malformed keycode property\n"); + return ERR_PTR(-EINVAL); + } + + pdata->keymap_size = len / sizeof(u32); + + if (of_property_read_u32(np, "key_maxval", &pdata->key_maxval)) { + dev_err(dev, "Failed to get key max value data\n"); + return ERR_PTR(-EINVAL); + } + + if (pdata->keymap_size > pdata->key_maxval) { + dev_err(dev, "Key map size overflow\n"); + return ERR_PTR(-EINVAL); + } + + for (i = 0; i < pdata->keymap_size; i++) { + u32 code = be32_to_cpup(prop + i); + keymap[i] = MCS_KEY_MAP(i, code); + } + pdata->keymap = keymap; + return pdata; +} +#else +static inline struct mcs_platform_data *mcs_touchkey_parse_dt + (struct device *dev) +{ + return NULL; +} +#endif + static int mcs_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -108,10 +164,14 @@ static int mcs_touchkey_probe(struct i2c_client *client, int error; int i; - pdata = client->dev.platform_data; - if (!pdata) { - dev_err(&client->dev, "no platform data defined\n"); - return -EINVAL; + if (&client->dev.of_node) + pdata = mcs_touchkey_parse_dt(&client->dev); + else + pdata = client->dev.platform_data; + + if (IS_ERR(pdata)) { + dev_err(&client->dev, "Failed to get platform data\n"); + return PTR_ERR(pdata); } data = kzalloc(sizeof(struct mcs_touchkey_data) + @@ -148,7 +208,7 @@ static int mcs_touchkey_probe(struct i2c_client *client, } dev_info(&client->dev, "Firmware version: %d\n", fw_ver); - input_dev->name = "MELPAS MCS Touchkey"; + input_dev->name = "MELFAS MCS Touchkey"; input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; input_dev->evbit[0] = BIT_MASK(EV_KEY); @@ -263,11 +323,17 @@ static const struct i2c_device_id mcs_touchkey_id[] = { }; MODULE_DEVICE_TABLE(i2c, mcs_touchkey_id); +static struct of_device_id mcs_touchkey_dt_match[] = { + { .compatible = "mcs5000_touchkey", }, + { .compatible = "mcs5080_touchkey", }, +}; + static struct i2c_driver mcs_touchkey_driver = { .driver = { .name = "mcs_touchkey", .owner = THIS_MODULE, .pm = &mcs_touchkey_pm_ops, + .of_match_table = of_match_ptr(mcs_touchkey_dt_match), }, .probe = mcs_touchkey_probe, .remove = mcs_touchkey_remove, |