From patchwork Sun Aug 5 20:43:42 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Anthony Olech (Opensource)" X-Patchwork-Id: 1277171 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id F090BDFF71 for ; Mon, 6 Aug 2012 07:43:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753338Ab2HFHnl (ORCPT ); Mon, 6 Aug 2012 03:43:41 -0400 Received: from mailrelay1.diasemi.com ([82.210.246.133]:46912 "EHLO mailrelay1.diasemi.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753024Ab2HFHnl (ORCPT ); Mon, 6 Aug 2012 03:43:41 -0400 Received: from ubuntu (Not Verified[10.20.27.23]) by mailrelay1.diasemi.com with ESMTP Gateway id ; Mon, 06 Aug 2012 09:43:39 +0200 Received: from ubuntu (localhost [127.0.0.1]) by ubuntu (8.14.4/8.14.4/Debian-2ubuntu2) with ESMTP id q767fqg2005766; Mon, 6 Aug 2012 08:41:52 +0100 Received: (from root@localhost) by ubuntu (8.14.4/8.14.4/Submit) id q767flhO005759; Mon, 6 Aug 2012 08:41:47 +0100 Message-Id: <201208060741.q767flhO005759@ubuntu> From: Anthony Olech Date: Sun, 5 Aug 2012 21:43:42 +0100 Subject: [NEW DRIVER V2 2/7] DA9058 ONKEY driver To: Dmitry Torokhov Cc: Mark Brown Cc: Samuel Ortiz Cc: Ashish Jangam Cc: Eric Andersson Cc: Andrew Jones Cc: Donggeun Kim Cc: linux-input@vger.kernel.org Cc: LKML Cc: David Dajun Chen Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org This is the ONKEY component driver of the Dialog DA9058 PMIC. This driver is just one component of the whole DA9058 PMIC driver. It depends on the core DA9058 MFD driver. Signed-off-by: Anthony Olech Signed-off-by: David Dajun Chen --- drivers/input/misc/Kconfig | 10 ++ drivers/input/misc/Makefile | 1 + drivers/input/misc/da9058_onkey.c | 171 +++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 0 deletions(-) create mode 100644 drivers/input/misc/da9058_onkey.c diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7faf4a7..697b703 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -73,6 +73,16 @@ config INPUT_BMA150 To compile this driver as a module, choose M here: the module will be called bma150. +config INPUT_DA9058_ONKEY + tristate "DA9058 ONKEY support" + depends on MFD_DA9058 + help + Support the ONKEY of DA9058 PMICs as an input device + reporting power button status. + + To compile this driver as a module, choose M here: the module + will be called da9058_onkey. + config INPUT_PCSPKR tristate "PC Speaker support" depends on PCSPKR_PLATFORM diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index f55cdf4..048d50e 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o obj-$(CONFIG_INPUT_PM8XXX_VIBRATOR) += pm8xxx-vibrator.o obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) += pmic8xxx-pwrkey.o +obj-$(CONFIG_INPUT_DA9058_ONKEY) += da9058_onkey.o obj-$(CONFIG_INPUT_POWERMATE) += powermate.o obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o diff --git a/drivers/input/misc/da9058_onkey.c b/drivers/input/misc/da9058_onkey.c new file mode 100644 index 0000000..fb29c14 --- /dev/null +++ b/drivers/input/misc/da9058_onkey.c @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2012 Dialog Semiconductor Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +struct da9058_onkey { + struct da9058 *da9058; + struct platform_device *pdev; + struct input_dev *input; + struct delayed_work work; + int irq; +}; + +static void da9058_onkey_poll(struct work_struct *work) +{ + struct da9058_onkey *onkey = container_of(work, struct da9058_onkey, + work.work); + struct da9058 *da9058 = onkey->da9058; + int poll, ret; + unsigned int sa; + + ret = da9058_reg_read(da9058, DA9058_STATUSA_REG, &sa); + if (ret) { + dev_dbg(&onkey->pdev->dev, "Failed to read ONKEY: %d\n", ret); + poll = 1; + } else if (sa & DA9058_STATUSA_NONKEY) { + poll = 0; + } else { + poll = 1; + } + + input_report_key(onkey->input, KEY_POWER, poll); + input_sync(onkey->input); + + if (poll) + schedule_delayed_work(&onkey->work, msecs_to_jiffies(50)); +} + +static irqreturn_t da9058_onkey_event_handler(int irq, void *data) +{ + struct da9058_onkey *onkey = data; + + schedule_delayed_work(&onkey->work, 0); + + return IRQ_HANDLED; +} + +static int __devinit da9058_onkey_probe(struct platform_device *pdev) +{ + struct da9058 *da9058 = dev_get_drvdata(pdev->dev.parent); + const struct mfd_cell *cell = mfd_get_cell(pdev); + struct da9058_onkey_pdata *onkey_pdata; + struct da9058_onkey *onkey; + int ret; + + if (cell == NULL) { + ret = -ENODEV; + goto exit; + } + + onkey_pdata = cell->platform_data; + + if (onkey_pdata == NULL) { + ret = -EINVAL; + goto exit; + } + + dev_info(&pdev->dev, "Starting ONKEY\n"); + + onkey = devm_kzalloc(&pdev->dev, sizeof(struct da9058_onkey), + GFP_KERNEL); + if (!onkey) { + ret = -ENOMEM; + goto exit; + } + + platform_set_drvdata(pdev, onkey); + + onkey->da9058 = da9058; + onkey->pdev = pdev; + + INIT_DELAYED_WORK(&onkey->work, da9058_onkey_poll); + + onkey->input = input_allocate_device(); + if (!onkey->input) { + dev_err(&pdev->dev, "failed to allocate data device\n"); + ret = -ENOMEM; + goto err1; + } + + onkey->input->evbit[0] = BIT_MASK(EV_KEY); + onkey->input->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); + onkey->input->name = "da9058-onkey"; + onkey->input->phys = "da9058-onkey/input0"; + onkey->input->dev.parent = &pdev->dev; + + ret = input_register_device(onkey->input); + if (ret) { + dev_err(&pdev->dev, + "Unable to register input ONKEY device: %d\n", ret); + goto err2; + } + onkey->irq = DA9058_IRQ_ENONKEY; + + ret = request_threaded_irq(da9058_to_virt_irq_num(da9058, onkey->irq), + NULL, da9058_onkey_event_handler, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "DA9058 keydown", onkey); + + if (ret) { + dev_err(&pdev->dev, "Failed to get ONKEY keydown IRQ %d: %d\n", + onkey->irq, ret); + goto err3; + } + goto exit; + +err3: +err2: + input_free_device(onkey->input); +err1: + platform_set_drvdata(pdev, NULL); +exit: + return ret; +} + +static int __devexit da9058_onkey_remove(struct platform_device *pdev) +{ + struct da9058_onkey *onkey = platform_get_drvdata(pdev); + struct da9058 *da9058 = onkey->da9058; + + free_irq(da9058_to_virt_irq_num(da9058, onkey->irq), onkey); + cancel_delayed_work_sync(&onkey->work); + input_unregister_device(onkey->input); + + return 0; +} + +static struct platform_driver da9058_onkey_driver = { + .probe = da9058_onkey_probe, + .remove = __devexit_p(da9058_onkey_remove), + .driver = { + .name = "da9058-onkey", + .owner = THIS_MODULE, + } +}; + +module_platform_driver(da9058_onkey_driver); + +MODULE_AUTHOR("Anthony Olech "); +MODULE_DESCRIPTION("Dialog DA9058 PMIC Onkey Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:da9058-onkey");