root/drivers/input/misc/da9063_onkey.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. da9063_poll_on
  2. da9063_onkey_irq_handler
  3. da9063_cancel_poll
  4. da9063_onkey_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * OnKey device driver for DA9063, DA9062 and DA9061 PMICs
   4  * Copyright (C) 2015  Dialog Semiconductor Ltd.
   5  */
   6 
   7 #include <linux/module.h>
   8 #include <linux/errno.h>
   9 #include <linux/input.h>
  10 #include <linux/interrupt.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/workqueue.h>
  13 #include <linux/regmap.h>
  14 #include <linux/of.h>
  15 #include <linux/mfd/da9063/core.h>
  16 #include <linux/mfd/da9063/registers.h>
  17 #include <linux/mfd/da9062/core.h>
  18 #include <linux/mfd/da9062/registers.h>
  19 
  20 struct da906x_chip_config {
  21         /* REGS */
  22         int onkey_status;
  23         int onkey_pwr_signalling;
  24         int onkey_fault_log;
  25         int onkey_shutdown;
  26         /* MASKS */
  27         int onkey_nonkey_mask;
  28         int onkey_nonkey_lock_mask;
  29         int onkey_key_reset_mask;
  30         int onkey_shutdown_mask;
  31         /* NAMES */
  32         const char *name;
  33 };
  34 
  35 struct da9063_onkey {
  36         struct delayed_work work;
  37         struct input_dev *input;
  38         struct device *dev;
  39         struct regmap *regmap;
  40         const struct da906x_chip_config *config;
  41         char phys[32];
  42         bool key_power;
  43 };
  44 
  45 static const struct da906x_chip_config da9063_regs = {
  46         /* REGS */
  47         .onkey_status = DA9063_REG_STATUS_A,
  48         .onkey_pwr_signalling = DA9063_REG_CONTROL_B,
  49         .onkey_fault_log = DA9063_REG_FAULT_LOG,
  50         .onkey_shutdown = DA9063_REG_CONTROL_F,
  51         /* MASKS */
  52         .onkey_nonkey_mask = DA9063_NONKEY,
  53         .onkey_nonkey_lock_mask = DA9063_NONKEY_LOCK,
  54         .onkey_key_reset_mask = DA9063_KEY_RESET,
  55         .onkey_shutdown_mask = DA9063_SHUTDOWN,
  56         /* NAMES */
  57         .name = DA9063_DRVNAME_ONKEY,
  58 };
  59 
  60 static const struct da906x_chip_config da9062_regs = {
  61         /* REGS */
  62         .onkey_status = DA9062AA_STATUS_A,
  63         .onkey_pwr_signalling = DA9062AA_CONTROL_B,
  64         .onkey_fault_log = DA9062AA_FAULT_LOG,
  65         .onkey_shutdown = DA9062AA_CONTROL_F,
  66         /* MASKS */
  67         .onkey_nonkey_mask = DA9062AA_NONKEY_MASK,
  68         .onkey_nonkey_lock_mask = DA9062AA_NONKEY_LOCK_MASK,
  69         .onkey_key_reset_mask = DA9062AA_KEY_RESET_MASK,
  70         .onkey_shutdown_mask = DA9062AA_SHUTDOWN_MASK,
  71         /* NAMES */
  72         .name = "da9062-onkey",
  73 };
  74 
  75 static const struct of_device_id da9063_compatible_reg_id_table[] = {
  76         { .compatible = "dlg,da9063-onkey", .data = &da9063_regs },
  77         { .compatible = "dlg,da9062-onkey", .data = &da9062_regs },
  78         { },
  79 };
  80 MODULE_DEVICE_TABLE(of, da9063_compatible_reg_id_table);
  81 
  82 static void da9063_poll_on(struct work_struct *work)
  83 {
  84         struct da9063_onkey *onkey = container_of(work,
  85                                                 struct da9063_onkey,
  86                                                 work.work);
  87         const struct da906x_chip_config *config = onkey->config;
  88         unsigned int val;
  89         int fault_log = 0;
  90         bool poll = true;
  91         int error;
  92 
  93         /* Poll to see when the pin is released */
  94         error = regmap_read(onkey->regmap,
  95                             config->onkey_status,
  96                             &val);
  97         if (error) {
  98                 dev_err(onkey->dev,
  99                         "Failed to read ON status: %d\n", error);
 100                 goto err_poll;
 101         }
 102 
 103         if (!(val & config->onkey_nonkey_mask)) {
 104                 error = regmap_update_bits(onkey->regmap,
 105                                            config->onkey_pwr_signalling,
 106                                            config->onkey_nonkey_lock_mask,
 107                                            0);
 108                 if (error) {
 109                         dev_err(onkey->dev,
 110                                 "Failed to reset the Key Delay %d\n", error);
 111                         goto err_poll;
 112                 }
 113 
 114                 input_report_key(onkey->input, KEY_POWER, 0);
 115                 input_sync(onkey->input);
 116 
 117                 poll = false;
 118         }
 119 
 120         /*
 121          * If the fault log KEY_RESET is detected, then clear it
 122          * and shut down the system.
 123          */
 124         error = regmap_read(onkey->regmap,
 125                             config->onkey_fault_log,
 126                             &fault_log);
 127         if (error) {
 128                 dev_warn(&onkey->input->dev,
 129                          "Cannot read FAULT_LOG: %d\n", error);
 130         } else if (fault_log & config->onkey_key_reset_mask) {
 131                 error = regmap_write(onkey->regmap,
 132                                      config->onkey_fault_log,
 133                                      config->onkey_key_reset_mask);
 134                 if (error) {
 135                         dev_warn(&onkey->input->dev,
 136                                  "Cannot reset KEY_RESET fault log: %d\n",
 137                                  error);
 138                 } else {
 139                         /* at this point we do any S/W housekeeping
 140                          * and then send shutdown command
 141                          */
 142                         dev_dbg(&onkey->input->dev,
 143                                 "Sending SHUTDOWN to PMIC ...\n");
 144                         error = regmap_write(onkey->regmap,
 145                                              config->onkey_shutdown,
 146                                              config->onkey_shutdown_mask);
 147                         if (error)
 148                                 dev_err(&onkey->input->dev,
 149                                         "Cannot SHUTDOWN PMIC: %d\n",
 150                                         error);
 151                 }
 152         }
 153 
 154 err_poll:
 155         if (poll)
 156                 schedule_delayed_work(&onkey->work, msecs_to_jiffies(50));
 157 }
 158 
 159 static irqreturn_t da9063_onkey_irq_handler(int irq, void *data)
 160 {
 161         struct da9063_onkey *onkey = data;
 162         const struct da906x_chip_config *config = onkey->config;
 163         unsigned int val;
 164         int error;
 165 
 166         error = regmap_read(onkey->regmap,
 167                             config->onkey_status,
 168                             &val);
 169         if (onkey->key_power && !error && (val & config->onkey_nonkey_mask)) {
 170                 input_report_key(onkey->input, KEY_POWER, 1);
 171                 input_sync(onkey->input);
 172                 schedule_delayed_work(&onkey->work, 0);
 173                 dev_dbg(onkey->dev, "KEY_POWER long press.\n");
 174         } else {
 175                 input_report_key(onkey->input, KEY_POWER, 1);
 176                 input_sync(onkey->input);
 177                 input_report_key(onkey->input, KEY_POWER, 0);
 178                 input_sync(onkey->input);
 179                 dev_dbg(onkey->dev, "KEY_POWER short press.\n");
 180         }
 181 
 182         return IRQ_HANDLED;
 183 }
 184 
 185 static void da9063_cancel_poll(void *data)
 186 {
 187         struct da9063_onkey *onkey = data;
 188 
 189         cancel_delayed_work_sync(&onkey->work);
 190 }
 191 
 192 static int da9063_onkey_probe(struct platform_device *pdev)
 193 {
 194         struct da9063_onkey *onkey;
 195         const struct of_device_id *match;
 196         int irq;
 197         int error;
 198 
 199         match = of_match_node(da9063_compatible_reg_id_table,
 200                               pdev->dev.of_node);
 201         if (!match)
 202                 return -ENXIO;
 203 
 204         onkey = devm_kzalloc(&pdev->dev, sizeof(struct da9063_onkey),
 205                              GFP_KERNEL);
 206         if (!onkey) {
 207                 dev_err(&pdev->dev, "Failed to allocate memory.\n");
 208                 return -ENOMEM;
 209         }
 210 
 211         onkey->config = match->data;
 212         onkey->dev = &pdev->dev;
 213 
 214         onkey->regmap = dev_get_regmap(pdev->dev.parent, NULL);
 215         if (!onkey->regmap) {
 216                 dev_err(&pdev->dev, "Parent regmap unavailable.\n");
 217                 return -ENXIO;
 218         }
 219 
 220         onkey->key_power = !of_property_read_bool(pdev->dev.of_node,
 221                                                   "dlg,disable-key-power");
 222 
 223         onkey->input = devm_input_allocate_device(&pdev->dev);
 224         if (!onkey->input) {
 225                 dev_err(&pdev->dev, "Failed to allocated input device.\n");
 226                 return -ENOMEM;
 227         }
 228 
 229         onkey->input->name = onkey->config->name;
 230         snprintf(onkey->phys, sizeof(onkey->phys), "%s/input0",
 231                  onkey->config->name);
 232         onkey->input->phys = onkey->phys;
 233         onkey->input->dev.parent = &pdev->dev;
 234 
 235         input_set_capability(onkey->input, EV_KEY, KEY_POWER);
 236 
 237         INIT_DELAYED_WORK(&onkey->work, da9063_poll_on);
 238 
 239         error = devm_add_action(&pdev->dev, da9063_cancel_poll, onkey);
 240         if (error) {
 241                 dev_err(&pdev->dev,
 242                         "Failed to add cancel poll action: %d\n",
 243                         error);
 244                 return error;
 245         }
 246 
 247         irq = platform_get_irq_byname(pdev, "ONKEY");
 248         if (irq < 0)
 249                 return irq;
 250 
 251         error = devm_request_threaded_irq(&pdev->dev, irq,
 252                                           NULL, da9063_onkey_irq_handler,
 253                                           IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 254                                           "ONKEY", onkey);
 255         if (error) {
 256                 dev_err(&pdev->dev,
 257                         "Failed to request IRQ %d: %d\n", irq, error);
 258                 return error;
 259         }
 260 
 261         error = input_register_device(onkey->input);
 262         if (error) {
 263                 dev_err(&pdev->dev,
 264                         "Failed to register input device: %d\n", error);
 265                 return error;
 266         }
 267 
 268         return 0;
 269 }
 270 
 271 static struct platform_driver da9063_onkey_driver = {
 272         .probe  = da9063_onkey_probe,
 273         .driver = {
 274                 .name   = DA9063_DRVNAME_ONKEY,
 275                 .of_match_table = da9063_compatible_reg_id_table,
 276         },
 277 };
 278 module_platform_driver(da9063_onkey_driver);
 279 
 280 MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>");
 281 MODULE_DESCRIPTION("Onkey device driver for Dialog DA9063, DA9062 and DA9061");
 282 MODULE_LICENSE("GPL");
 283 MODULE_ALIAS("platform:" DA9063_DRVNAME_ONKEY);

/* [<][>][^][v][top][bottom][index][help] */