Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7437916 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-next' of git://git.o-hand.com/linux-mfd

* 'for-next' of git://git.o-hand.com/linux-mfd:
  mfd: Fix twl4030-core build
  mfd: Ensure sm501 GPIO pin mode is GPIO when configured
  mfd: dm355 evm MMC/SD card detection
  regulator: PCF50633 pmic driver
  input: PCF50633 input driver
  power_supply: PCF50633 battery charger driver
  rtc: PCF50633 rtc driver
  mfd: PCF50633 gpio support
  mfd: PCF50633 adc driver
  mfd: PCF50633 core driver
parents 9219a3b9 b29c06ae
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -220,4 +220,11 @@ config HP_SDC_RTC
	  Say Y here if you want to support the built-in real time clock
	  of the HP SDC controller.

config INPUT_PCF50633_PMU
	tristate "PCF50633 PMU events"
	depends on MFD_PCF50633
	help
	 Say Y to include support for delivering  PMU events via  input
	 layer on NXP PCF50633.

endif
+1 −0
Original line number Diff line number Diff line
@@ -21,3 +21,4 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
obj-$(CONFIG_INPUT_PCF50633_PMU)	+= pcf50633-input.o
+132 −0
Original line number Diff line number Diff line
/* NXP PCF50633 Input Driver
 *
 * (C) 2006-2008 by Openmoko, Inc.
 * Author: Balaji Rao <balajirrao@openmoko.org>
 * All rights reserved.
 *
 * Broken down from monstrous PCF50633 driver mainly by
 * Harald Welte, Andy Green and Werner Almesberger
 *
 *  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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/input.h>

#include <linux/mfd/pcf50633/core.h>

#define PCF50633_OOCSTAT_ONKEY	0x01
#define PCF50633_REG_OOCSTAT	0x12
#define PCF50633_REG_OOCMODE	0x10

struct pcf50633_input {
	struct pcf50633 *pcf;
	struct input_dev *input_dev;
};

static void
pcf50633_input_irq(int irq, void *data)
{
	struct pcf50633_input *input;
	int onkey_released;

	input = data;

	/* We report only one event depending on the key press status */
	onkey_released = pcf50633_reg_read(input->pcf, PCF50633_REG_OOCSTAT)
						& PCF50633_OOCSTAT_ONKEY;

	if (irq == PCF50633_IRQ_ONKEYF && !onkey_released)
		input_report_key(input->input_dev, KEY_POWER, 1);
	else if (irq == PCF50633_IRQ_ONKEYR && onkey_released)
		input_report_key(input->input_dev, KEY_POWER, 0);

	input_sync(input->input_dev);
}

static int __devinit pcf50633_input_probe(struct platform_device *pdev)
{
	struct pcf50633_input *input;
	struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
	struct input_dev *input_dev;
	int ret;


	input = kzalloc(sizeof(*input), GFP_KERNEL);
	if (!input)
		return -ENOMEM;

	input_dev = input_allocate_device();
	if (!input_dev) {
		kfree(input);
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, input);
	input->pcf = pdata->pcf;
	input->input_dev = input_dev;

	input_dev->name = "PCF50633 PMU events";
	input_dev->id.bustype = BUS_I2C;
	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR);
	set_bit(KEY_POWER, input_dev->keybit);

	ret = input_register_device(input_dev);
	if (ret) {
		input_free_device(input_dev);
		kfree(input);
		return ret;
	}
	pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR,
				pcf50633_input_irq, input);
	pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF,
				pcf50633_input_irq, input);

	return 0;
}

static int __devexit pcf50633_input_remove(struct platform_device *pdev)
{
	struct pcf50633_input *input  = platform_get_drvdata(pdev);

	pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYR);
	pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYF);

	input_unregister_device(input->input_dev);
	kfree(input);

	return 0;
}

static struct platform_driver pcf50633_input_driver = {
	.driver = {
		.name = "pcf50633-input",
	},
	.probe = pcf50633_input_probe,
	.remove = __devexit_p(pcf50633_input_remove),
};

static int __init pcf50633_input_init(void)
{
	return platform_driver_register(&pcf50633_input_driver);
}
module_init(pcf50633_input_init);

static void __exit pcf50633_input_exit(void)
{
	platform_driver_unregister(&pcf50633_input_driver);
}
module_exit(pcf50633_input_exit);

MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
MODULE_DESCRIPTION("PCF50633 input driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pcf50633-input");
+23 −0
Original line number Diff line number Diff line
@@ -217,6 +217,29 @@ config MFD_WM8350_I2C
	  I2C as the control interface.  Additional options must be
	  selected to enable support for the functionality of the chip.

config MFD_PCF50633
	tristate "Support for NXP PCF50633"
	depends on I2C
	help
	  Say yes here if you have NXP PCF50633 chip on your board.
	  This core driver provides register access and IRQ handling
	  facilities, and registers devices for the various functions
	  so that function-specific drivers can bind to them.

config PCF50633_ADC
	tristate "Support for NXP PCF50633 ADC"
	depends on MFD_PCF50633
	help
	 Say yes here if you want to include support for ADC in the
	 NXP PCF50633 chip.

config PCF50633_GPIO
	tristate "Support for NXP PCF50633 GPIO"
	depends on MFD_PCF50633
	help
	 Say yes here if you want to include support GPIO for pins on
	 the PCF50633 chip.

endmenu

menu "Multimedia Capabilities Port drivers"
+4 −0
Original line number Diff line number Diff line
@@ -37,3 +37,7 @@ endif
obj-$(CONFIG_UCB1400_CORE)	+= ucb1400_core.o

obj-$(CONFIG_PMIC_DA903X)	+= da903x.o

obj-$(CONFIG_MFD_PCF50633)	+= pcf50633-core.o
obj-$(CONFIG_PCF50633_ADC)	+= pcf50633-adc.o
obj-$(CONFIG_PCF50633_GPIO)	+= pcf50633-gpio.o
 No newline at end of file
Loading