0001
0002
0003
0004
0005
0006
0007 #include <linux/devm-helpers.h>
0008 #include <linux/module.h>
0009 #include <linux/errno.h>
0010 #include <linux/input.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/workqueue.h>
0014 #include <linux/regmap.h>
0015 #include <linux/of.h>
0016 #include <linux/mfd/da9063/core.h>
0017 #include <linux/mfd/da9063/registers.h>
0018 #include <linux/mfd/da9062/core.h>
0019 #include <linux/mfd/da9062/registers.h>
0020
0021 struct da906x_chip_config {
0022
0023 int onkey_status;
0024 int onkey_pwr_signalling;
0025 int onkey_fault_log;
0026 int onkey_shutdown;
0027
0028 int onkey_nonkey_mask;
0029 int onkey_nonkey_lock_mask;
0030 int onkey_key_reset_mask;
0031 int onkey_shutdown_mask;
0032
0033 const char *name;
0034 };
0035
0036 struct da9063_onkey {
0037 struct delayed_work work;
0038 struct input_dev *input;
0039 struct device *dev;
0040 struct regmap *regmap;
0041 const struct da906x_chip_config *config;
0042 char phys[32];
0043 bool key_power;
0044 };
0045
0046 static const struct da906x_chip_config da9063_regs = {
0047
0048 .onkey_status = DA9063_REG_STATUS_A,
0049 .onkey_pwr_signalling = DA9063_REG_CONTROL_B,
0050 .onkey_fault_log = DA9063_REG_FAULT_LOG,
0051 .onkey_shutdown = DA9063_REG_CONTROL_F,
0052
0053 .onkey_nonkey_mask = DA9063_NONKEY,
0054 .onkey_nonkey_lock_mask = DA9063_NONKEY_LOCK,
0055 .onkey_key_reset_mask = DA9063_KEY_RESET,
0056 .onkey_shutdown_mask = DA9063_SHUTDOWN,
0057
0058 .name = DA9063_DRVNAME_ONKEY,
0059 };
0060
0061 static const struct da906x_chip_config da9062_regs = {
0062
0063 .onkey_status = DA9062AA_STATUS_A,
0064 .onkey_pwr_signalling = DA9062AA_CONTROL_B,
0065 .onkey_fault_log = DA9062AA_FAULT_LOG,
0066 .onkey_shutdown = DA9062AA_CONTROL_F,
0067
0068 .onkey_nonkey_mask = DA9062AA_NONKEY_MASK,
0069 .onkey_nonkey_lock_mask = DA9062AA_NONKEY_LOCK_MASK,
0070 .onkey_key_reset_mask = DA9062AA_KEY_RESET_MASK,
0071 .onkey_shutdown_mask = DA9062AA_SHUTDOWN_MASK,
0072
0073 .name = "da9062-onkey",
0074 };
0075
0076 static const struct of_device_id da9063_compatible_reg_id_table[] = {
0077 { .compatible = "dlg,da9063-onkey", .data = &da9063_regs },
0078 { .compatible = "dlg,da9062-onkey", .data = &da9062_regs },
0079 { },
0080 };
0081 MODULE_DEVICE_TABLE(of, da9063_compatible_reg_id_table);
0082
0083 static void da9063_poll_on(struct work_struct *work)
0084 {
0085 struct da9063_onkey *onkey = container_of(work,
0086 struct da9063_onkey,
0087 work.work);
0088 const struct da906x_chip_config *config = onkey->config;
0089 unsigned int val;
0090 int fault_log = 0;
0091 bool poll = true;
0092 int error;
0093
0094
0095 error = regmap_read(onkey->regmap,
0096 config->onkey_status,
0097 &val);
0098 if (error) {
0099 dev_err(onkey->dev,
0100 "Failed to read ON status: %d\n", error);
0101 goto err_poll;
0102 }
0103
0104 if (!(val & config->onkey_nonkey_mask)) {
0105 error = regmap_update_bits(onkey->regmap,
0106 config->onkey_pwr_signalling,
0107 config->onkey_nonkey_lock_mask,
0108 0);
0109 if (error) {
0110 dev_err(onkey->dev,
0111 "Failed to reset the Key Delay %d\n", error);
0112 goto err_poll;
0113 }
0114
0115 input_report_key(onkey->input, KEY_POWER, 0);
0116 input_sync(onkey->input);
0117
0118 poll = false;
0119 }
0120
0121
0122
0123
0124
0125 error = regmap_read(onkey->regmap,
0126 config->onkey_fault_log,
0127 &fault_log);
0128 if (error) {
0129 dev_warn(&onkey->input->dev,
0130 "Cannot read FAULT_LOG: %d\n", error);
0131 } else if (fault_log & config->onkey_key_reset_mask) {
0132 error = regmap_write(onkey->regmap,
0133 config->onkey_fault_log,
0134 config->onkey_key_reset_mask);
0135 if (error) {
0136 dev_warn(&onkey->input->dev,
0137 "Cannot reset KEY_RESET fault log: %d\n",
0138 error);
0139 } else {
0140
0141
0142
0143 dev_dbg(&onkey->input->dev,
0144 "Sending SHUTDOWN to PMIC ...\n");
0145 error = regmap_write(onkey->regmap,
0146 config->onkey_shutdown,
0147 config->onkey_shutdown_mask);
0148 if (error)
0149 dev_err(&onkey->input->dev,
0150 "Cannot SHUTDOWN PMIC: %d\n",
0151 error);
0152 }
0153 }
0154
0155 err_poll:
0156 if (poll)
0157 schedule_delayed_work(&onkey->work, msecs_to_jiffies(50));
0158 }
0159
0160 static irqreturn_t da9063_onkey_irq_handler(int irq, void *data)
0161 {
0162 struct da9063_onkey *onkey = data;
0163 const struct da906x_chip_config *config = onkey->config;
0164 unsigned int val;
0165 int error;
0166
0167 error = regmap_read(onkey->regmap,
0168 config->onkey_status,
0169 &val);
0170 if (onkey->key_power && !error && (val & config->onkey_nonkey_mask)) {
0171 input_report_key(onkey->input, KEY_POWER, 1);
0172 input_sync(onkey->input);
0173 schedule_delayed_work(&onkey->work, 0);
0174 dev_dbg(onkey->dev, "KEY_POWER long press.\n");
0175 } else {
0176 input_report_key(onkey->input, KEY_POWER, 1);
0177 input_sync(onkey->input);
0178 input_report_key(onkey->input, KEY_POWER, 0);
0179 input_sync(onkey->input);
0180 dev_dbg(onkey->dev, "KEY_POWER short press.\n");
0181 }
0182
0183 return IRQ_HANDLED;
0184 }
0185
0186 static int da9063_onkey_probe(struct platform_device *pdev)
0187 {
0188 struct da9063_onkey *onkey;
0189 const struct of_device_id *match;
0190 int irq;
0191 int error;
0192
0193 match = of_match_node(da9063_compatible_reg_id_table,
0194 pdev->dev.of_node);
0195 if (!match)
0196 return -ENXIO;
0197
0198 onkey = devm_kzalloc(&pdev->dev, sizeof(struct da9063_onkey),
0199 GFP_KERNEL);
0200 if (!onkey) {
0201 dev_err(&pdev->dev, "Failed to allocate memory.\n");
0202 return -ENOMEM;
0203 }
0204
0205 onkey->config = match->data;
0206 onkey->dev = &pdev->dev;
0207
0208 onkey->regmap = dev_get_regmap(pdev->dev.parent, NULL);
0209 if (!onkey->regmap) {
0210 dev_err(&pdev->dev, "Parent regmap unavailable.\n");
0211 return -ENXIO;
0212 }
0213
0214 onkey->key_power = !of_property_read_bool(pdev->dev.of_node,
0215 "dlg,disable-key-power");
0216
0217 onkey->input = devm_input_allocate_device(&pdev->dev);
0218 if (!onkey->input) {
0219 dev_err(&pdev->dev, "Failed to allocated input device.\n");
0220 return -ENOMEM;
0221 }
0222
0223 onkey->input->name = onkey->config->name;
0224 snprintf(onkey->phys, sizeof(onkey->phys), "%s/input0",
0225 onkey->config->name);
0226 onkey->input->phys = onkey->phys;
0227 onkey->input->dev.parent = &pdev->dev;
0228
0229 input_set_capability(onkey->input, EV_KEY, KEY_POWER);
0230
0231 error = devm_delayed_work_autocancel(&pdev->dev, &onkey->work,
0232 da9063_poll_on);
0233 if (error) {
0234 dev_err(&pdev->dev,
0235 "Failed to add cancel poll action: %d\n",
0236 error);
0237 return error;
0238 }
0239
0240 irq = platform_get_irq_byname(pdev, "ONKEY");
0241 if (irq < 0)
0242 return irq;
0243
0244 error = devm_request_threaded_irq(&pdev->dev, irq,
0245 NULL, da9063_onkey_irq_handler,
0246 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
0247 "ONKEY", onkey);
0248 if (error) {
0249 dev_err(&pdev->dev,
0250 "Failed to request IRQ %d: %d\n", irq, error);
0251 return error;
0252 }
0253
0254 error = input_register_device(onkey->input);
0255 if (error) {
0256 dev_err(&pdev->dev,
0257 "Failed to register input device: %d\n", error);
0258 return error;
0259 }
0260
0261 return 0;
0262 }
0263
0264 static struct platform_driver da9063_onkey_driver = {
0265 .probe = da9063_onkey_probe,
0266 .driver = {
0267 .name = DA9063_DRVNAME_ONKEY,
0268 .of_match_table = da9063_compatible_reg_id_table,
0269 },
0270 };
0271 module_platform_driver(da9063_onkey_driver);
0272
0273 MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>");
0274 MODULE_DESCRIPTION("Onkey device driver for Dialog DA9063, DA9062 and DA9061");
0275 MODULE_LICENSE("GPL");
0276 MODULE_ALIAS("platform:" DA9063_DRVNAME_ONKEY);