linux/drivers/input/keyboard/mtk-pmic-keys.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2017 MediaTek, Inc.
   3 *
   4 * Author: Chen Zhong <chen.zhong@mediatek.com>
   5 *
   6 * This software is licensed under the terms of the GNU General Public
   7 * License version 2, as published by the Free Software Foundation, and
   8 * may be copied, distributed, and modified under those terms.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 */
  16
  17#include <linux/module.h>
  18#include <linux/kernel.h>
  19#include <linux/input.h>
  20#include <linux/interrupt.h>
  21#include <linux/platform_device.h>
  22#include <linux/kernel.h>
  23#include <linux/of.h>
  24#include <linux/of_device.h>
  25#include <linux/regmap.h>
  26#include <linux/mfd/mt6323/registers.h>
  27#include <linux/mfd/mt6397/registers.h>
  28#include <linux/mfd/mt6397/core.h>
  29
  30#define MTK_PMIC_PWRKEY_RST_EN_MASK     0x1
  31#define MTK_PMIC_PWRKEY_RST_EN_SHIFT    6
  32#define MTK_PMIC_HOMEKEY_RST_EN_MASK    0x1
  33#define MTK_PMIC_HOMEKEY_RST_EN_SHIFT   5
  34#define MTK_PMIC_RST_DU_MASK            0x3
  35#define MTK_PMIC_RST_DU_SHIFT           8
  36
  37#define MTK_PMIC_PWRKEY_RST             \
  38        (MTK_PMIC_PWRKEY_RST_EN_MASK << MTK_PMIC_PWRKEY_RST_EN_SHIFT)
  39#define MTK_PMIC_HOMEKEY_RST            \
  40        (MTK_PMIC_HOMEKEY_RST_EN_MASK << MTK_PMIC_HOMEKEY_RST_EN_SHIFT)
  41
  42#define MTK_PMIC_PWRKEY_INDEX   0
  43#define MTK_PMIC_HOMEKEY_INDEX  1
  44#define MTK_PMIC_MAX_KEY_COUNT  2
  45
  46struct mtk_pmic_keys_regs {
  47        u32 deb_reg;
  48        u32 deb_mask;
  49        u32 intsel_reg;
  50        u32 intsel_mask;
  51};
  52
  53#define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_mask,         \
  54        _intsel_reg, _intsel_mask)                      \
  55{                                                       \
  56        .deb_reg                = _deb_reg,             \
  57        .deb_mask               = _deb_mask,            \
  58        .intsel_reg             = _intsel_reg,          \
  59        .intsel_mask            = _intsel_mask,         \
  60}
  61
  62struct mtk_pmic_regs {
  63        const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT];
  64        u32 pmic_rst_reg;
  65};
  66
  67static const struct mtk_pmic_regs mt6397_regs = {
  68        .keys_regs[MTK_PMIC_PWRKEY_INDEX] =
  69                MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS,
  70                0x8, MT6397_INT_RSV, 0x10),
  71        .keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
  72                MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2,
  73                0x10, MT6397_INT_RSV, 0x8),
  74        .pmic_rst_reg = MT6397_TOP_RST_MISC,
  75};
  76
  77static const struct mtk_pmic_regs mt6323_regs = {
  78        .keys_regs[MTK_PMIC_PWRKEY_INDEX] =
  79                MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
  80                0x2, MT6323_INT_MISC_CON, 0x10),
  81        .keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
  82                MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
  83                0x4, MT6323_INT_MISC_CON, 0x8),
  84        .pmic_rst_reg = MT6323_TOP_RST_MISC,
  85};
  86
  87struct mtk_pmic_keys_info {
  88        struct mtk_pmic_keys *keys;
  89        const struct mtk_pmic_keys_regs *regs;
  90        unsigned int keycode;
  91        int irq;
  92        bool wakeup:1;
  93};
  94
  95struct mtk_pmic_keys {
  96        struct input_dev *input_dev;
  97        struct device *dev;
  98        struct regmap *regmap;
  99        struct mtk_pmic_keys_info keys[MTK_PMIC_MAX_KEY_COUNT];
 100};
 101
 102enum mtk_pmic_keys_lp_mode {
 103        LP_DISABLE,
 104        LP_ONEKEY,
 105        LP_TWOKEY,
 106};
 107
 108static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys,
 109                u32 pmic_rst_reg)
 110{
 111        int ret;
 112        u32 long_press_mode, long_press_debounce;
 113
 114        ret = of_property_read_u32(keys->dev->of_node,
 115                "power-off-time-sec", &long_press_debounce);
 116        if (ret)
 117                long_press_debounce = 0;
 118
 119        regmap_update_bits(keys->regmap, pmic_rst_reg,
 120                           MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT,
 121                           long_press_debounce << MTK_PMIC_RST_DU_SHIFT);
 122
 123        ret = of_property_read_u32(keys->dev->of_node,
 124                "mediatek,long-press-mode", &long_press_mode);
 125        if (ret)
 126                long_press_mode = LP_DISABLE;
 127
 128        switch (long_press_mode) {
 129        case LP_ONEKEY:
 130                regmap_update_bits(keys->regmap, pmic_rst_reg,
 131                                   MTK_PMIC_PWRKEY_RST,
 132                                   MTK_PMIC_PWRKEY_RST);
 133                regmap_update_bits(keys->regmap, pmic_rst_reg,
 134                                   MTK_PMIC_HOMEKEY_RST,
 135                                   0);
 136                break;
 137        case LP_TWOKEY:
 138                regmap_update_bits(keys->regmap, pmic_rst_reg,
 139                                   MTK_PMIC_PWRKEY_RST,
 140                                   MTK_PMIC_PWRKEY_RST);
 141                regmap_update_bits(keys->regmap, pmic_rst_reg,
 142                                   MTK_PMIC_HOMEKEY_RST,
 143                                   MTK_PMIC_HOMEKEY_RST);
 144                break;
 145        case LP_DISABLE:
 146                regmap_update_bits(keys->regmap, pmic_rst_reg,
 147                                   MTK_PMIC_PWRKEY_RST,
 148                                   0);
 149                regmap_update_bits(keys->regmap, pmic_rst_reg,
 150                                   MTK_PMIC_HOMEKEY_RST,
 151                                   0);
 152                break;
 153        default:
 154                break;
 155        }
 156}
 157
 158static irqreturn_t mtk_pmic_keys_irq_handler_thread(int irq, void *data)
 159{
 160        struct mtk_pmic_keys_info *info = data;
 161        u32 key_deb, pressed;
 162
 163        regmap_read(info->keys->regmap, info->regs->deb_reg, &key_deb);
 164
 165        key_deb &= info->regs->deb_mask;
 166
 167        pressed = !key_deb;
 168
 169        input_report_key(info->keys->input_dev, info->keycode, pressed);
 170        input_sync(info->keys->input_dev);
 171
 172        dev_dbg(info->keys->dev, "(%s) key =%d using PMIC\n",
 173                 pressed ? "pressed" : "released", info->keycode);
 174
 175        return IRQ_HANDLED;
 176}
 177
 178static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys,
 179                struct mtk_pmic_keys_info *info)
 180{
 181        int ret;
 182
 183        info->keys = keys;
 184
 185        ret = regmap_update_bits(keys->regmap, info->regs->intsel_reg,
 186                                 info->regs->intsel_mask,
 187                                 info->regs->intsel_mask);
 188        if (ret < 0)
 189                return ret;
 190
 191        ret = devm_request_threaded_irq(keys->dev, info->irq, NULL,
 192                                        mtk_pmic_keys_irq_handler_thread,
 193                                        IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
 194                                        "mtk-pmic-keys", info);
 195        if (ret) {
 196                dev_err(keys->dev, "Failed to request IRQ: %d: %d\n",
 197                        info->irq, ret);
 198                return ret;
 199        }
 200
 201        input_set_capability(keys->input_dev, EV_KEY, info->keycode);
 202
 203        return 0;
 204}
 205
 206static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev)
 207{
 208        struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
 209        int index;
 210
 211        for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
 212                if (keys->keys[index].wakeup)
 213                        enable_irq_wake(keys->keys[index].irq);
 214        }
 215
 216        return 0;
 217}
 218
 219static int __maybe_unused mtk_pmic_keys_resume(struct device *dev)
 220{
 221        struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
 222        int index;
 223
 224        for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
 225                if (keys->keys[index].wakeup)
 226                        disable_irq_wake(keys->keys[index].irq);
 227        }
 228
 229        return 0;
 230}
 231
 232static SIMPLE_DEV_PM_OPS(mtk_pmic_keys_pm_ops, mtk_pmic_keys_suspend,
 233                        mtk_pmic_keys_resume);
 234
 235static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = {
 236        {
 237                .compatible = "mediatek,mt6397-keys",
 238                .data = &mt6397_regs,
 239        }, {
 240                .compatible = "mediatek,mt6323-keys",
 241                .data = &mt6323_regs,
 242        }, {
 243                /* sentinel */
 244        }
 245};
 246MODULE_DEVICE_TABLE(of, of_mtk_pmic_keys_match_tbl);
 247
 248static int mtk_pmic_keys_probe(struct platform_device *pdev)
 249{
 250        int error, index = 0;
 251        unsigned int keycount;
 252        struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent);
 253        struct device_node *node = pdev->dev.of_node, *child;
 254        struct mtk_pmic_keys *keys;
 255        const struct mtk_pmic_regs *mtk_pmic_regs;
 256        struct input_dev *input_dev;
 257        const struct of_device_id *of_id =
 258                of_match_device(of_mtk_pmic_keys_match_tbl, &pdev->dev);
 259
 260        keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL);
 261        if (!keys)
 262                return -ENOMEM;
 263
 264        keys->dev = &pdev->dev;
 265        keys->regmap = pmic_chip->regmap;
 266        mtk_pmic_regs = of_id->data;
 267
 268        keys->input_dev = input_dev = devm_input_allocate_device(keys->dev);
 269        if (!input_dev) {
 270                dev_err(keys->dev, "input allocate device fail.\n");
 271                return -ENOMEM;
 272        }
 273
 274        input_dev->name = "mtk-pmic-keys";
 275        input_dev->id.bustype = BUS_HOST;
 276        input_dev->id.vendor = 0x0001;
 277        input_dev->id.product = 0x0001;
 278        input_dev->id.version = 0x0001;
 279
 280        keycount = of_get_available_child_count(node);
 281        if (keycount > MTK_PMIC_MAX_KEY_COUNT) {
 282                dev_err(keys->dev, "too many keys defined (%d)\n", keycount);
 283                return -EINVAL;
 284        }
 285
 286        for_each_child_of_node(node, child) {
 287                keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];
 288
 289                keys->keys[index].irq = platform_get_irq(pdev, index);
 290                if (keys->keys[index].irq < 0)
 291                        return keys->keys[index].irq;
 292
 293                error = of_property_read_u32(child,
 294                        "linux,keycodes", &keys->keys[index].keycode);
 295                if (error) {
 296                        dev_err(keys->dev,
 297                                "failed to read key:%d linux,keycode property: %d\n",
 298                                index, error);
 299                        return error;
 300                }
 301
 302                if (of_property_read_bool(child, "wakeup-source"))
 303                        keys->keys[index].wakeup = true;
 304
 305                error = mtk_pmic_key_setup(keys, &keys->keys[index]);
 306                if (error)
 307                        return error;
 308
 309                index++;
 310        }
 311
 312        error = input_register_device(input_dev);
 313        if (error) {
 314                dev_err(&pdev->dev,
 315                        "register input device failed (%d)\n", error);
 316                return error;
 317        }
 318
 319        mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs->pmic_rst_reg);
 320
 321        platform_set_drvdata(pdev, keys);
 322
 323        return 0;
 324}
 325
 326static struct platform_driver pmic_keys_pdrv = {
 327        .probe = mtk_pmic_keys_probe,
 328        .driver = {
 329                   .name = "mtk-pmic-keys",
 330                   .of_match_table = of_mtk_pmic_keys_match_tbl,
 331                   .pm = &mtk_pmic_keys_pm_ops,
 332        },
 333};
 334
 335module_platform_driver(pmic_keys_pdrv);
 336
 337MODULE_LICENSE("GPL v2");
 338MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
 339MODULE_DESCRIPTION("MTK pmic-keys driver v0.1");
 340