aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/files/0016-Quark-GIP-Cypress-I-O-expander-quark.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/files/0016-Quark-GIP-Cypress-I-O-expander-quark.patch')
-rw-r--r--recipes-kernel/linux/files/0016-Quark-GIP-Cypress-I-O-expander-quark.patch1128
1 files changed, 964 insertions, 164 deletions
diff --git a/recipes-kernel/linux/files/0016-Quark-GIP-Cypress-I-O-expander-quark.patch b/recipes-kernel/linux/files/0016-Quark-GIP-Cypress-I-O-expander-quark.patch
index 8488759..811e609 100644
--- a/recipes-kernel/linux/files/0016-Quark-GIP-Cypress-I-O-expander-quark.patch
+++ b/recipes-kernel/linux/files/0016-Quark-GIP-Cypress-I-O-expander-quark.patch
@@ -1,22 +1,27 @@
From xxxx Mon Sep 17 00:00:00 2001
From: Josef Ahmad <josef.ahmad@linux.intel.com>
-Date: Tue, 25 Feb 2014 12:09:04 +0000
+Date: Mon, 31 Mar 2014 18:03:09 +0100
Subject: [PATCH 16/21] Quark GIP + Cypress I/O expander
---
- drivers/mfd/Kconfig | 38 +
- drivers/mfd/Makefile | 8 +
- drivers/mfd/cy8c9540a.c | 970 ++++++++++++++++++++++++++
- drivers/mfd/intel_qrk_gip.h | 104 +++
- drivers/mfd/intel_qrk_gip_core.c | 335 +++++++++
- drivers/mfd/intel_qrk_gip_gpio.c | 659 ++++++++++++++++++
- drivers/mfd/intel_qrk_gip_i2c.c | 248 +++++++
- drivers/mfd/intel_qrk_gip_pdata.c | 25 +
- drivers/mfd/intel_qrk_gip_test.c | 1131 +++++++++++++++++++++++++++++++
+ drivers/mfd/Kconfig | 48 ++
+ drivers/mfd/Makefile | 10 +
+ drivers/mfd/cy8c9540a.c | 963 ++++++++++++++++++++++++++
+ drivers/mfd/intel_qrk_gip.h | 97 +++
+ drivers/mfd/intel_qrk_gip_core.c | 328 +++++++++
+ drivers/mfd/intel_qrk_gip_gpio.c | 652 ++++++++++++++++++
+ drivers/mfd/intel_qrk_gip_i2c.c | 241 +++++++
+ drivers/mfd/intel_qrk_gip_pdata.c | 18 +
+ drivers/mfd/intel_qrk_gip_test.c | 1124 +++++++++++++++++++++++++++++++
drivers/mfd/lpc_sch.c | 76 ++-
- include/linux/mfd/cy8c9540a.h | 38 +
- include/linux/mfd/intel_qrk_gip_pdata.h | 32 +
- 12 files changed, 3651 insertions(+), 13 deletions(-)
+ drivers/mfd/pca9685-core.c | 283 ++++++++
+ drivers/mfd/pca9685-gpio.c | 108 +++
+ drivers/mfd/pca9685-pwm.c | 262 +++++++
+ drivers/mfd/pca9685.h | 110 +++
+ include/linux/mfd/cy8c9540a.h | 31 +
+ include/linux/mfd/intel_qrk_gip_pdata.h | 25 +
+ include/linux/platform_data/pca9685.h | 51 ++
+ 17 files changed, 4414 insertions(+), 13 deletions(-)
create mode 100644 drivers/mfd/cy8c9540a.c
create mode 100644 drivers/mfd/intel_qrk_gip.h
create mode 100644 drivers/mfd/intel_qrk_gip_core.c
@@ -24,14 +29,19 @@ Subject: [PATCH 16/21] Quark GIP + Cypress I/O expander
create mode 100644 drivers/mfd/intel_qrk_gip_i2c.c
create mode 100644 drivers/mfd/intel_qrk_gip_pdata.c
create mode 100644 drivers/mfd/intel_qrk_gip_test.c
+ create mode 100644 drivers/mfd/pca9685-core.c
+ create mode 100644 drivers/mfd/pca9685-gpio.c
+ create mode 100644 drivers/mfd/pca9685-pwm.c
+ create mode 100644 drivers/mfd/pca9685.h
create mode 100644 include/linux/mfd/cy8c9540a.h
create mode 100644 include/linux/mfd/intel_qrk_gip_pdata.h
+ create mode 100644 include/linux/platform_data/pca9685.h
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
-index ff553ba..b8029bd 100644
+index ff553ba..74358c2 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
-@@ -907,6 +907,44 @@ config MFD_TIMBERDALE
+@@ -907,6 +907,54 @@ config MFD_TIMBERDALE
The timberdale FPGA can be found on the Intel Atom development board
for in-vehicle infontainment, called Russellville.
@@ -44,6 +54,16 @@ index ff553ba..b8029bd 100644
+ Select this option to enable support for the CY8C9540 I/O expander.
+ This device provides 40 interrupt-capable GPIOs, 8 PWMs and an EEPROM.
+
++config MFD_PCA9685
++ tristate "NPX Semiconductors PCA9685 (PWM/GPIO) driver"
++ depends on GPIOLIB && I2C && PWM
++ select REGMAP_I2C
++ help
++ NPX PCA9685 I2C-bus PWM controller with GPIO output interface support.
++ The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
++ Additionally, the driver allows the channels to be configured as GPIO
++ interface (output only).
++
+config INTEL_QRK_GIP
+ tristate "Intel Quark GIP"
+ depends on PCI && X86 && INTEL_QUARK_X1000_SOC
@@ -77,14 +97,16 @@ index ff553ba..b8029bd 100644
tristate "Intel SCH LPC"
depends on PCI
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
-index 8b977f8..b17d50c 100644
+index 8b977f8..38706ff 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
-@@ -123,6 +123,14 @@ obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
+@@ -123,6 +123,16 @@ obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
+obj-$(CONFIG_CY8C9540A) += cy8c9540a.o
++pca9685-objs := pca9685-core.o pca9685-gpio.o pca9685-pwm.o
++obj-$(CONFIG_MFD_PCA9685) += pca9685.o
+obj-$(CONFIG_INTEL_QRK_GIP) += intel_qrk_gip.o
+intel_qrk_gip-objs := intel_qrk_gip_core.o \
+ intel_qrk_gip_gpio.o \
@@ -97,28 +119,21 @@ index 8b977f8..b17d50c 100644
obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
diff --git a/drivers/mfd/cy8c9540a.c b/drivers/mfd/cy8c9540a.c
new file mode 100644
-index 0000000..444e5ab
+index 0000000..9e3966a
--- /dev/null
+++ b/drivers/mfd/cy8c9540a.c
-@@ -0,0 +1,970 @@
+@@ -0,0 +1,963 @@
+/*
+ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of version 2 of the GNU General Public License as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Contact Information:
-+ * Intel Corporation
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ */
+
+/*
@@ -1073,28 +1088,21 @@ index 0000000..444e5ab
+
diff --git a/drivers/mfd/intel_qrk_gip.h b/drivers/mfd/intel_qrk_gip.h
new file mode 100644
-index 0000000..d1e8316
+index 0000000..3dfc487
--- /dev/null
+++ b/drivers/mfd/intel_qrk_gip.h
-@@ -0,0 +1,104 @@
+@@ -0,0 +1,97 @@
+/*
+ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of version 2 of the GNU General Public License as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
+ *
-+ * Contact Information:
-+ * Intel Corporation
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ */
+/*
+ * Intel Quark GIP (GPIO/I2C) driver
@@ -1183,28 +1191,21 @@ index 0000000..d1e8316
+#endif /* __INTEL_QRKGIP_H__ */
diff --git a/drivers/mfd/intel_qrk_gip_core.c b/drivers/mfd/intel_qrk_gip_core.c
new file mode 100644
-index 0000000..8b8727b
+index 0000000..44209f0
--- /dev/null
+++ b/drivers/mfd/intel_qrk_gip_core.c
-@@ -0,0 +1,335 @@
+@@ -0,0 +1,328 @@
+/*
+ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of version 2 of the GNU General Public License as
-+ * published by the Free Software Foundation.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Contact Information:
-+ * Intel Corporation
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ */
+/*
+ * Intel Quark GIP (GPIO/I2C) PCI driver
@@ -1524,28 +1525,21 @@ index 0000000..8b8727b
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/mfd/intel_qrk_gip_gpio.c b/drivers/mfd/intel_qrk_gip_gpio.c
new file mode 100644
-index 0000000..ef19e2f
+index 0000000..f823957
--- /dev/null
+++ b/drivers/mfd/intel_qrk_gip_gpio.c
-@@ -0,0 +1,659 @@
+@@ -0,0 +1,652 @@
+/*
+ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of version 2 of the GNU General Public License as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Contact Information:
-+ * Intel Corporation
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ */
+/*
+ * Intel Quark GIP (GPIO/I2C) - GPIO-specific PCI and core driver
@@ -2189,28 +2183,21 @@ index 0000000..ef19e2f
+}
diff --git a/drivers/mfd/intel_qrk_gip_i2c.c b/drivers/mfd/intel_qrk_gip_i2c.c
new file mode 100644
-index 0000000..9ecbeb5
+index 0000000..08e8f9d
--- /dev/null
+++ b/drivers/mfd/intel_qrk_gip_i2c.c
-@@ -0,0 +1,248 @@
+@@ -0,0 +1,241 @@
+/*
+ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of version 2 of the GNU General Public License as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Contact Information:
-+ * Intel Corporation
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ */
+/*
+ * Intel Quark GIP (GPIO/I2C) - I2C-specific PCI driver
@@ -2443,28 +2430,21 @@ index 0000000..9ecbeb5
+}
diff --git a/drivers/mfd/intel_qrk_gip_pdata.c b/drivers/mfd/intel_qrk_gip_pdata.c
new file mode 100644
-index 0000000..a764215
+index 0000000..cc230be
--- /dev/null
+++ b/drivers/mfd/intel_qrk_gip_pdata.c
-@@ -0,0 +1,25 @@
+@@ -0,0 +1,18 @@
+/*
+ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of version 2 of the GNU General Public License as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Contact Information:
-+ * Intel Corporation
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ */
+
+#include <linux/module.h>
@@ -2474,28 +2454,21 @@ index 0000000..a764215
+EXPORT_SYMBOL_GPL(intel_qrk_gip_get_pdata);
diff --git a/drivers/mfd/intel_qrk_gip_test.c b/drivers/mfd/intel_qrk_gip_test.c
new file mode 100644
-index 0000000..2b07e9e
+index 0000000..e444c81
--- /dev/null
+++ b/drivers/mfd/intel_qrk_gip_test.c
-@@ -0,0 +1,1131 @@
+@@ -0,0 +1,1124 @@
+/*
+ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of version 2 of the GNU General Public License as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Contact Information:
-+ * Intel Corporation
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ */
+/*
+ * Intel Quark GIP (GPIO/I2C) Test module
@@ -3735,30 +3708,810 @@ index 5624fcb..4afc687 100644
if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC
|| id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) {
pci_read_config_dword(dev, WDTBASE, &base_addr_cfg);
-diff --git a/include/linux/mfd/cy8c9540a.h b/include/linux/mfd/cy8c9540a.h
+diff --git a/drivers/mfd/pca9685-core.c b/drivers/mfd/pca9685-core.c
new file mode 100644
-index 0000000..a32c6f0
+index 0000000..11cb8d9
--- /dev/null
-+++ b/include/linux/mfd/cy8c9540a.h
-@@ -0,0 +1,38 @@
++++ b/drivers/mfd/pca9685-core.c
+@@ -0,0 +1,283 @@
+/*
++ * Driver for NPX PCA9685 I2C-bus PWM controller with GPIO output interface
++ * support.
++ *
+ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of version 2 of the GNU General Public License as
-+ * published by the Free Software Foundation.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
++ * Additionally, the driver allows the channels to be configured as GPIO
++ * interface (output only).
++ */
++
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/pwm.h>
++#include <linux/gpio.h>
++#include <linux/regmap.h>
++#include <linux/slab.h>
++
++#include "pca9685.h"
++
++static unsigned int en_invrt;
++module_param(en_invrt, uint, 0);
++MODULE_PARM_DESC(en_invrt, "Enable output logic state inverted mode");
++
++static unsigned int en_open_dr;
++module_param(en_open_dr, uint, 0);
++MODULE_PARM_DESC(en_open_dr,
++ "The outputs are configured with an open-drain structure");
++
++static int gpio_base = -1; /* requests dynamic ID allocation */
++module_param(gpio_base, int, 0);
++MODULE_PARM_DESC(gpio_base, "GPIO base number");
++
++static unsigned int pwm_period = PWM_PERIOD_DEF; /* PWM clock period */
++module_param(pwm_period, uint, 0);
++MODULE_PARM_DESC(pwm_period, "PWM clock period (nanoseconds)");
++
++static bool pca9685_register_volatile(struct device *dev, unsigned int reg)
++{
++ if (unlikely(reg == PCA9685_MODE1))
++ return true;
++ else
++ return false;
++}
++
++static struct regmap_config pca9685_regmap_i2c_config = {
++ .reg_bits = 8,
++ .val_bits = 8,
++ .max_register = PCA9685_NUMREGS,
++ .volatile_reg = pca9685_register_volatile,
++ .cache_type = REGCACHE_RBTREE,
++};
++
++ssize_t pca9685_pwm_period_sysfs_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct pca9685 *pca = dev_get_drvdata(dev);
++
++ return scnprintf(buf, PAGE_SIZE, "%u\n", pca->pwm_period);
++}
++
++ssize_t pca9685_pwm_period_sysfs_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct pca9685 *pca = dev_get_drvdata(dev);
++ unsigned period_ns;
++ int ret;
++
++ sscanf(buf, "%u", &period_ns);
++
++ ret = pca9685_update_prescale(pca, period_ns, true);
++ if (ret)
++ return ret;
++
++ return count;
++}
++
++/* Sysfs attribute to allow PWM clock period adjustment at run-time
++ * NOTE: All active channels will switch off momentarily if the
++ * PWM clock period is changed
++ */
++static DEVICE_ATTR(pwm_period, S_IWUSR | S_IRUGO,
++ pca9685_pwm_period_sysfs_show,
++ pca9685_pwm_period_sysfs_store);
++
++static int pca9685_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct pca9685_pdata *pdata;
++ struct pca9685 *pca;
++ int ret;
++ int mode2;
++
++ pca = devm_kzalloc(&client->dev, sizeof(*pca), GFP_KERNEL);
++ if (unlikely(!pca))
++ return -ENOMEM;
++
++ pdata = client->dev.platform_data;
++ if (likely(pdata)) {
++ memcpy(pca->chan_mapping, pdata->chan_mapping,
++ ARRAY_SIZE(pca->chan_mapping));
++ pca->gpio_base = pdata->gpio_base;
++ en_invrt = pdata->en_invrt;
++ en_open_dr = pdata->en_open_dr;
++ } else {
++ dev_warn(&client->dev,
++ "Platform data not provided."
++ "Using default or mod params configuration.\n");
++ pca->gpio_base = gpio_base;
++ memset(pca->chan_mapping, PWM_CH_UNDEFINED,
++ ARRAY_SIZE(pca->chan_mapping));
++ }
++
++ if (unlikely(!i2c_check_functionality(client->adapter,
++ I2C_FUNC_I2C |
++ I2C_FUNC_SMBUS_BYTE_DATA))) {
++ dev_err(&client->dev,
++ "i2c adapter doesn't support required functionality\n");
++ return -EIO;
++ }
++
++ pca->regmap = devm_regmap_init_i2c(client, &pca9685_regmap_i2c_config);
++ if (IS_ERR(pca->regmap)) {
++ ret = PTR_ERR(pca->regmap);
++ dev_err(&client->dev, "Failed to initialize register map: %d\n",
++ ret);
++ return ret;
++ }
++
++ i2c_set_clientdata(client, pca);
++
++ /* registration of GPIO chip */
++ pca->gpio_chip.label = "pca9685-gpio";
++ pca->gpio_chip.owner = THIS_MODULE;
++ pca->gpio_chip.set = pca9685_gpio_set;
++ pca->gpio_chip.get = pca9685_gpio_get;
++ pca->gpio_chip.can_sleep = 1;
++ pca->gpio_chip.ngpio = PCA9685_MAXCHAN;
++ pca->gpio_chip.base = pca->gpio_base;
++ pca->gpio_chip.request = pca9685_gpio_request;
++ pca->gpio_chip.free = pca9685_gpio_free;
++
++ mutex_init(&pca->lock);
++
++ ret = gpiochip_add(&pca->gpio_chip);
++ if (unlikely(ret < 0)) {
++ dev_err(&client->dev, "Could not register gpiochip, %d\n", ret);
++ goto err;
++ }
++
++ /* configure initial PWM settings */
++ ret = pca9685_init_pwm_regs(pca, pwm_period);
++ if (ret) {
++ pr_err("Failed to initialize PWM registers\n");
++ goto err_gpiochip;
++ }
++
++ /* registration of PWM chip */
++
++ regmap_read(pca->regmap, PCA9685_MODE2, &mode2);
++
++ /* update mode2 register */
++ if (en_invrt)
++ mode2 |= MODE2_INVRT;
++ else
++ mode2 &= ~MODE2_INVRT;
++
++ if (en_open_dr)
++ mode2 &= ~MODE2_OUTDRV;
++ else
++ mode2 |= MODE2_OUTDRV;
++
++ regmap_write(pca->regmap, PCA9685_MODE2, mode2);
++
++ pca->pwm_chip.ops = &pca9685_pwm_ops;
++ /* add an extra channel for ALL_LED */
++ pca->pwm_chip.npwm = PCA9685_MAXCHAN + 1;
++ pca->pwm_chip.dev = &client->dev;
++ pca->pwm_chip.base = -1;
++
++ ret = pwmchip_add(&pca->pwm_chip);
++ if (unlikely(ret < 0)) {
++ dev_err(&client->dev, "pwmchip_add failed %d\n", ret);
++ goto err_gpiochip;
++ }
++
++ /* Also create a sysfs interface, providing a cmd line config option */
++ ret = sysfs_create_file(&client->dev.kobj, &dev_attr_pwm_period.attr);
++ if (unlikely(ret < 0)) {
++ dev_err(&client->dev, "sysfs_create_file failed %d\n", ret);
++ goto err_pwmchip;
++ }
++
++ return ret;
++
++err_pwmchip:
++ if (unlikely(pwmchip_remove(&pca->pwm_chip)))
++ dev_warn(&client->dev, "%s failed\n", "pwmchip_remove()");
++
++err_gpiochip:
++ if (unlikely(gpiochip_remove(&pca->gpio_chip)))
++ dev_warn(&client->dev, "%s failed\n", "gpiochip_remove()");
++err:
++ mutex_destroy(&pca->lock);
++
++ return ret;
++}
++
++static int pca9685_remove(struct i2c_client *client)
++{
++ struct pca9685 *pca = i2c_get_clientdata(client);
++ int ret;
++
++ regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP,
++ MODE1_SLEEP);
++
++ ret = gpiochip_remove(&pca->gpio_chip);
++ if (unlikely(ret))
++ dev_err(&client->dev, "%s failed, %d\n",
++ "gpiochip_remove()", ret);
++
++ sysfs_remove_file(&client->dev.kobj, &dev_attr_pwm_period.attr);
++
++ ret = pwmchip_remove(&pca->pwm_chip);
++ if (unlikely(ret))
++ dev_err(&client->dev, "%s failed, %d\n",
++ "pwmchip_remove()", ret);
++
++ mutex_destroy(&pca->lock);
++
++ return ret;
++}
++
++static const struct i2c_device_id pca9685_id[] = {
++ { "pca9685", 0 },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(i2c, pca9685_id);
++
++static struct i2c_driver pca9685_i2c_driver = {
++ .driver = {
++ .name = "mfd-pca9685",
++ .owner = THIS_MODULE,
++ },
++ .probe = pca9685_probe,
++ .remove = pca9685_remove,
++ .id_table = pca9685_id,
++};
++
++static int __init pca9685_init(void)
++{
++ if (unlikely((pwm_period < PWM_PERIOD_MIN) ||
++ (PWM_PERIOD_MAX < pwm_period))) {
++ pr_err("Invalid PWM period specified (valid range: %d-%d)\n",
++ PWM_PERIOD_MIN, PWM_PERIOD_MAX);
++ return -EINVAL;
++ }
++
++ return i2c_add_driver(&pca9685_i2c_driver);
++}
++/* register after i2c postcore initcall */
++subsys_initcall(pca9685_init);
++
++static void __exit pca9685_exit(void)
++{
++ i2c_del_driver(&pca9685_i2c_driver);
++}
++module_exit(pca9685_exit);
++
++MODULE_AUTHOR("Wojciech Ziemba <wojciech.ziemba@emutex.com>");
++MODULE_DESCRIPTION("NPX Semiconductors PCA9685 (PWM/GPIO) driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/mfd/pca9685-gpio.c b/drivers/mfd/pca9685-gpio.c
+new file mode 100644
+index 0000000..7cfff86
+--- /dev/null
++++ b/drivers/mfd/pca9685-gpio.c
+@@ -0,0 +1,108 @@
++/*
++ * Driver for NPX PCA9685 I2C-bus PWM controller with GPIO output interface
++ * support.
++ *
++ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ *
-+ * Contact Information:
-+ * Intel Corporation
++ * The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
++ * Additionally, the driver allows the channels to be configured as GPIO
++ * interface (output only).
++ */
++
++#include <linux/device.h>
++#include <linux/module.h>
++#include <linux/gpio.h>
++#include <linux/pwm.h>
++#include <linux/regmap.h>
++
++#include "pca9685.h"
++
++static inline struct pca9685 *gpio_to_pca(struct gpio_chip *gpio_chip)
++{
++ return container_of(gpio_chip, struct pca9685, gpio_chip);
++}
++
++static inline int is_gpio_allowed(const struct pca9685 *pca, unsigned channel)
++{
++ return pca->chan_mapping[channel] & PWM_CH_GPIO;
++}
++
++int pca9685_gpio_request(struct gpio_chip *chip, unsigned offset)
++{
++ struct pca9685 *pca;
++ struct pwm_device *pwm;
++ int ret = 0;
++ pca = gpio_to_pca(chip);
++
++ /* validate channel constrains */
++ if (!is_gpio_allowed(pca, offset))
++ return -ENODEV;
++
++ /* return busy if channel is already allocated for pwm */
++ pwm = &pca->pwm_chip.pwms[offset];
++ if (test_bit(PWMF_REQUESTED, &pwm->flags))
++ return -EBUSY;
++
++ /* clear the on counter */
++ regmap_write(pca->regmap, LED_N_ON_L(offset), 0x0);
++ regmap_write(pca->regmap, LED_N_ON_H(offset), 0x0);
++
++ /* clear the off counter */
++ regmap_write(pca->regmap, LED_N_OFF_L(offset), 0x0);
++ ret = regmap_write(pca->regmap, LED_N_OFF_H(offset), 0x0);
++
++ clear_sleep_bit(pca);
++
++ return ret;
++}
++
++void pca9685_gpio_free(struct gpio_chip *chip, unsigned offset)
++{
++ struct pca9685 *pca;
++
++ pca = gpio_to_pca(chip);
++
++ /* clear the on counter reg */
++ regmap_write(pca->regmap, LED_N_ON_L(offset), 0x0);
++ regmap_write(pca->regmap, LED_N_ON_H(offset), 0x0);
++
++ set_sleep_bit(pca);
++
++ return;
++}
++
++void pca9685_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
++{
++ struct pca9685 *pca;
++
++ pca = gpio_to_pca(chip);
++
++ /* set the full-on bit */
++ regmap_write(pca->regmap, LED_N_ON_H(offset), (value << 4) & LED_FULL);
++
++ return;
++}
++
++int pca9685_gpio_get(struct gpio_chip *chip, unsigned offset)
++{
++ struct pca9685 *pca;
++ unsigned int val;
++
++ pca = gpio_to_pca(chip);
++
++ /* read the full-on bit */
++ regmap_read(pca->regmap, LED_N_ON_H(offset), &val);
++
++ return !!val;
++}
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/mfd/pca9685-pwm.c b/drivers/mfd/pca9685-pwm.c
+new file mode 100644
+index 0000000..13f82b8
+--- /dev/null
++++ b/drivers/mfd/pca9685-pwm.c
+@@ -0,0 +1,262 @@
++/*
++ * Driver for NPX PCA9685 I2C-bus PWM controller with GPIO output interface
++ * support.
++ *
++ * Copyright(c) 2013 Intel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
++ * Additionally, the driver allows the channels to be configured as GPIO
++ * interface (output only).
++ */
++
++#include <linux/module.h>
++#include <linux/pwm.h>
++#include <linux/gpio.h>
++#include <linux/regmap.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++
++#include "pca9685.h"
++
++static inline struct pca9685 *pwm_to_pca(struct pwm_chip *pwm_chip)
++{
++ return container_of(pwm_chip, struct pca9685, pwm_chip);
++}
++
++static inline int period_ns_to_prescale(unsigned period_ns)
++{
++ return (DIV_ROUND_CLOSEST(OSC_CLK_MHZ * period_ns,
++ SAMPLE_RES * 1000)) - 1;
++}
++
++static inline int is_pwm_allowed(const struct pca9685 *pca, unsigned channel)
++{
++ return pca->chan_mapping[channel] & PWM_CH_PWM;
++}
++
++int pca9685_update_prescale(struct pca9685 *pca, unsigned period_ns,
++ bool reconfigure_channels)
++{
++ int pre_scale, i;
++ struct pwm_device *pwm;
++ unsigned long long duty_scale;
++ unsigned long long new_duty_ns;
++
++ if (unlikely((period_ns < PWM_PERIOD_MIN) ||
++ (PWM_PERIOD_MAX < period_ns))) {
++ pr_err("Invalid PWM period specified (valid range: %d-%d)\n",
++ PWM_PERIOD_MIN, PWM_PERIOD_MAX);
++ return -EINVAL;
++ }
++
++ mutex_lock(&pca->lock);
++
++ /* update pre_scale to the closest period */
++ pre_scale = period_ns_to_prescale(period_ns);
++ /* ensure sleep-mode bit is set
++ * NOTE: All active channels will switch off for at least 500 usecs
++ */
++ regmap_update_bits(pca->regmap, PCA9685_MODE1,
++ MODE1_SLEEP, MODE1_SLEEP);
++ regmap_write(pca->regmap, PCA9685_PRESCALE, pre_scale);
++ /* clear sleep mode flag if at least 1 channel is active */
++ if (pca->active_cnt > 0) {
++ regmap_update_bits(pca->regmap, PCA9685_MODE1,
++ MODE1_SLEEP, 0x0);
++ usleep_range(MODE1_RESTART_DELAY, MODE1_RESTART_DELAY * 2);
++ regmap_update_bits(pca->regmap, PCA9685_MODE1,
++ MODE1_RESTART, MODE1_RESTART);
++ }
++
++ if (reconfigure_channels) {
++ for (i = 0; i < pca->pwm_chip.npwm; i++) {
++ pwm = &pca->pwm_chip.pwms[i];
++ pwm->period = period_ns;
++ if (pwm->duty_cycle > 0) {
++ /* Scale the rise time to maintain duty cycle */
++ duty_scale = period_ns;
++ duty_scale *= 1000000;
++ do_div(duty_scale, pca->pwm_period);
++ new_duty_ns = duty_scale * pwm->duty_cycle;
++ do_div(new_duty_ns, 1000000);
++ /* Update the duty_cycle */
++ pwm_config(pwm, (int)new_duty_ns, pwm->period);
++ }
++ }
++ }
++ pca->pwm_period = period_ns;
++
++ mutex_unlock(&pca->lock);
++ return 0;
++}
++
++int pca9685_init_pwm_regs(struct pca9685 *pca, unsigned period_ns)
++{
++ int ret, chan;
++
++ /* set MODE1_SLEEP */
++ ret = regmap_update_bits(pca->regmap, PCA9685_MODE1,
++ MODE1_SLEEP, MODE1_SLEEP);
++ if (unlikely(ret < 0))
++ return ret;
++
++ /* configure the initial PWM clock period */
++ ret = pca9685_update_prescale(pca, period_ns, false);
++ if (unlikely(ret < 0))
++ return ret;
++
++ /* reset PWM channel registers to power-on default values */
++ for (chan = 0; chan < PCA9685_MAXCHAN; chan++) {
++ ret = regmap_write(pca->regmap, LED_N_ON_L(chan), 0);
++ if (unlikely(ret < 0))
++ return ret;
++ ret = regmap_write(pca->regmap, LED_N_ON_H(chan), 0);
++ if (unlikely(ret < 0))
++ return ret;
++ ret = regmap_write(pca->regmap, LED_N_OFF_L(chan), 0);
++ if (unlikely(ret < 0))
++ return ret;
++ ret = regmap_write(pca->regmap, LED_N_OFF_H(chan), LED_FULL);
++ if (unlikely(ret < 0))
++ return ret;
++ }
++ /* reset ALL_LED registers to power-on default values */
++ ret = regmap_write(pca->regmap, PCA9685_ALL_LED_ON_L, 0);
++ if (unlikely(ret < 0))
++ return ret;
++ ret = regmap_write(pca->regmap, PCA9685_ALL_LED_ON_H, 0);
++ if (unlikely(ret < 0))
++ return ret;
++ ret = regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_L, 0);
++ if (unlikely(ret < 0))
++ return ret;
++ ret = regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_H, LED_FULL);
++ if (unlikely(ret < 0))
++ return ret;
++
++ return ret;
++}
++
++static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
++ int duty_ns, int period_ns)
++{
++ struct pca9685 *pca = pwm_to_pca(chip);
++ unsigned long long duty;
++ unsigned int reg_on_h,
++ reg_off_l,
++ reg_off_h;
++ int full_off;
++
++ /* Changing PWM period for a single channel at run-time not allowed.
++ * The PCA9685 PWM clock is shared across all PWM channels
++ */
++ if (unlikely(period_ns != pwm->period))
++ return -EPERM;
++
++ if (unlikely(pwm->hwpwm >= PCA9685_MAXCHAN)) {
++ reg_on_h = PCA9685_ALL_LED_ON_H;
++ reg_off_l = PCA9685_ALL_LED_OFF_L;
++ reg_off_h = PCA9685_ALL_LED_OFF_H;
++ } else {
++ reg_on_h = LED_N_ON_H(pwm->hwpwm);
++ reg_off_l = LED_N_OFF_L(pwm->hwpwm);
++ reg_off_h = LED_N_OFF_H(pwm->hwpwm);
++ }
++
++ duty = SAMPLE_RES * (unsigned long long)duty_ns;
++ duty = DIV_ROUND_UP_ULL(duty, period_ns);
++
++ if (duty >= SAMPLE_RES) /* set the LED_FULL bit */
++ return regmap_write(pca->regmap, reg_on_h, LED_FULL);
++ else /* clear the LED_FULL bit */
++ regmap_write(pca->regmap, reg_on_h, 0x00);
++
++ full_off = !test_bit(PWMF_ENABLED, &pwm->flags) << 4;
++
++ regmap_write(pca->regmap, reg_off_l, (int)duty & 0xff);
++
++ return regmap_write(pca->regmap, reg_off_h,
++ ((int)duty >> 8 | full_off) & 0x1f);
++}
++
++static int pca9685_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++ struct pca9685 *pca = pwm_to_pca(chip);
++ int ret;
++
++ unsigned int reg_off_h;
++
++ if (unlikely(pwm->hwpwm >= PCA9685_MAXCHAN))
++ reg_off_h = PCA9685_ALL_LED_OFF_H;
++ else
++ reg_off_h = LED_N_OFF_H(pwm->hwpwm);
++
++ /* clear the full-off bit */
++ ret = regmap_update_bits(pca->regmap, reg_off_h, LED_FULL, 0x0);
++
++ clear_sleep_bit(pca);
++
++ return ret;
++}
++
++static void pca9685_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++ struct pca9685 *pca = pwm_to_pca(chip);
++
++ unsigned int reg_off_h;
++
++ if (unlikely(pwm->hwpwm >= PCA9685_MAXCHAN))
++ reg_off_h = PCA9685_ALL_LED_OFF_H;
++ else
++ reg_off_h = LED_N_OFF_H(pwm->hwpwm);
++
++ /* set the LED_OFF counter. */
++ regmap_update_bits(pca->regmap, reg_off_h, LED_FULL, LED_FULL);
++
++ set_sleep_bit(pca);
++
++ return;
++}
++
++static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++ struct pca9685 *pca;
++ struct gpio_chip *gpio_chip;
++ unsigned channel = pwm->hwpwm;
++
++ pca = pwm_to_pca(chip);
++
++ /* validate channel constrains */
++ if (!is_pwm_allowed(pca, channel))
++ return -ENODEV;
++
++ /* return busy if channel is already allocated for gpio */
++ gpio_chip = &pca->gpio_chip;
++
++ if ((channel < PCA9685_MAXCHAN) &&
++ (gpiochip_is_requested(gpio_chip, channel)))
++ return -EBUSY;
++
++ pwm->period = pca->pwm_period;
++
++ return 0;
++}
++
++const struct pwm_ops pca9685_pwm_ops = {
++ .enable = pca9685_pwm_enable,
++ .disable = pca9685_pwm_disable,
++ .config = pca9685_pwm_config,
++ .request = pca9685_pwm_request,
++ .owner = THIS_MODULE,
++};
++
++MODULE_LICENSE("GPL");
+diff --git a/drivers/mfd/pca9685.h b/drivers/mfd/pca9685.h
+new file mode 100644
+index 0000000..3627097
+--- /dev/null
++++ b/drivers/mfd/pca9685.h
+@@ -0,0 +1,110 @@
++/*
++ * Driver for NPX PCA9685 I2C-bus PWM controller with GPIO output interface
++ * support.
++ *
++ * Copyright(c) 2013 Intel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * The I2C-bus LED controller provides 16-channel, 12-bit PWM Fm+.
++ * Additionally, the driver allows the channels to be configured as GPIO
++ * interface (output only).
++ */
++
++#ifndef __LINUX_MFD_PCA9685_H
++#define __LINUX_MFD_PCA9685_H
++
++#include <linux/mutex.h>
++#include <linux/gpio.h>
++#include <linux/pwm.h>
++#include <linux/platform_data/pca9685.h>
++
++#define PCA9685_MODE1 0x00
++#define PCA9685_MODE2 0x01
++#define PCA9685_SUBADDR1 0x02
++#define PCA9685_SUBADDR2 0x03
++#define PCA9685_SUBADDR3 0x04
++#define PCA9685_LEDX_ON_L 0x06
++#define PCA9685_LEDX_ON_H 0x07
++#define PCA9685_LEDX_OFF_L 0x08
++#define PCA9685_LEDX_OFF_H 0x09
++
++#define PCA9685_ALL_LED_ON_L 0xFA
++#define PCA9685_ALL_LED_ON_H 0xFB
++#define PCA9685_ALL_LED_OFF_L 0xFC
++#define PCA9685_ALL_LED_OFF_H 0xFD
++#define PCA9685_PRESCALE 0xFE
++
++#define PCA9685_NUMREGS 0xFF
++
++#define LED_FULL (1 << 4)
++#define MODE1_SLEEP (1 << 4)
++#define MODE1_RESTART (1 << 7)
++
++#define MODE1_RESTART_DELAY 500
++
++#define LED_N_ON_H(N) (PCA9685_LEDX_ON_H + (4 * (N)))
++#define LED_N_ON_L(N) (PCA9685_LEDX_ON_L + (4 * (N)))
++#define LED_N_OFF_H(N) (PCA9685_LEDX_OFF_H + (4 * (N)))
++#define LED_N_OFF_L(N) (PCA9685_LEDX_OFF_L + (4 * (N)))
++
++#define OSC_CLK_MHZ 25 /* 25 MHz */
++#define SAMPLE_RES 4096 /* 12 bits */
++#define PWM_PERIOD_MIN 666666 /* ~1525 Hz */
++#define PWM_PERIOD_MAX 41666666 /* 24 Hz */
++#define PWM_PERIOD_DEF 5000000 /* default 200 Hz */
++
++struct pca9685 {
++ struct gpio_chip gpio_chip;
++ struct pwm_chip pwm_chip;
++ struct regmap *regmap;
++ struct mutex lock; /* mutual exclusion semaphore */
++ /* Array of channel allocation constrains */
++ /* add an extra channel for ALL_LED */
++ u8 chan_mapping[PCA9685_MAXCHAN + 1];
++ int gpio_base;
++ int active_cnt;
++ int pwm_exported_cnt;
++ int pwm_period;
++};
++
++extern const struct pwm_ops pca9685_pwm_ops;
++
++int pca9685_gpio_request(struct gpio_chip *chip, unsigned offset);
++void pca9685_gpio_free(struct gpio_chip *chip, unsigned offset);
++void pca9685_gpio_set(struct gpio_chip *chip, unsigned offset, int value);
++int pca9685_gpio_get(struct gpio_chip *chip, unsigned offset);
++
++int pca9685_init_pwm_regs(struct pca9685 *pca, unsigned period_ns);
++int pca9685_update_prescale(struct pca9685 *pca, unsigned period_ns,
++ bool reconfigure_channels);
++
++static inline void set_sleep_bit(struct pca9685 *pca)
++{
++ mutex_lock(&pca->lock);
++ /* set sleep mode flag if no more active LED channel*/
++ if (--pca->active_cnt == 0)
++ regmap_update_bits(pca->regmap, PCA9685_MODE1, MODE1_SLEEP,
++ MODE1_SLEEP);
++ mutex_unlock(&pca->lock);
++}
++
++static inline void clear_sleep_bit(struct pca9685 *pca)
++{
++ mutex_lock(&pca->lock);
++ /* clear sleep mode flag if at least 1 LED channel is active */
++ if (pca->active_cnt++ == 0)
++ regmap_update_bits(pca->regmap, PCA9685_MODE1,
++ MODE1_SLEEP, 0x0);
++
++ mutex_unlock(&pca->lock);
++}
++
++#endif /* __LINUX_MFD_PCA9685_H */
+diff --git a/include/linux/mfd/cy8c9540a.h b/include/linux/mfd/cy8c9540a.h
+new file mode 100644
+index 0000000..4d79825
+--- /dev/null
++++ b/include/linux/mfd/cy8c9540a.h
+@@ -0,0 +1,31 @@
++/*
++ * Copyright(c) 2013 Intel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ */
+
+#ifndef LINUX_CY8C9540A_PDATA_H
@@ -3781,28 +4534,21 @@ index 0000000..a32c6f0
+#endif
diff --git a/include/linux/mfd/intel_qrk_gip_pdata.h b/include/linux/mfd/intel_qrk_gip_pdata.h
new file mode 100644
-index 0000000..1378f5c
+index 0000000..eab17d9
--- /dev/null
+++ b/include/linux/mfd/intel_qrk_gip_pdata.h
-@@ -0,0 +1,32 @@
+@@ -0,0 +1,25 @@
+/*
+ * Copyright(c) 2013 Intel Corporation.
+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of version 2 of the GNU General Public License as
-+ * published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
+ *
-+ * Contact Information:
-+ * Intel Corporation
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
+ */
+
+#ifndef LINUX_INTEL_QRK_GIP_DATA_H
@@ -3817,6 +4563,60 @@ index 0000000..1378f5c
+extern struct intel_qrk_gip_pdata *(*intel_qrk_gip_get_pdata)(void);
+
+#endif
---
-1.7.4.1
-
+diff --git a/include/linux/platform_data/pca9685.h b/include/linux/platform_data/pca9685.h
+new file mode 100644
+index 0000000..903d30d
+--- /dev/null
++++ b/include/linux/platform_data/pca9685.h
+@@ -0,0 +1,51 @@
++/*
++ * Platform data for pca9685 driver
++ *
++ * Copyright(c) 2013 Intel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ */
++
++#ifndef _PLAT_PCA9685_H_
++#define _PLAT_PCA9685_H_
++
++#define PCA9685_MAXCHAN 16
++#define MODE2_INVRT (1 << 4)
++#define MODE2_OUTDRV (1 << 2)
++
++/* PWM channel allocation flags */
++enum {
++ PWM_CH_DISABLED = 0,
++ PWM_CH_PWM = 1 << 0,
++ PWM_CH_GPIO = 1 << 1,
++ /* allow PWM or GPIO */
++ PWM_CH_UNDEFINED = PWM_CH_PWM | PWM_CH_GPIO,
++};
++
++/**
++ * struct pca9685_pdata - Platform data for pca9685 driver
++ * @chan_mapping: Array of channel allocation constrains
++ * @gpio_base: GPIO base
++ * mode2_flags: mode2 register modification flags: INVRT and OUTDRV
++ **/
++struct pca9685_pdata {
++ /* Array of channel allocation constrains */
++ /* add an extra channel for ALL_LED */
++ u8 chan_mapping[PCA9685_MAXCHAN + 1];
++ /* GPIO base */
++ int gpio_base;
++ /* mode2 flags */
++ u8 en_invrt:1, /* enable output logic state inverted mode */
++ en_open_dr:1, /* enable if outputs are configured with an
++ open-drain structure */
++ unused:6;
++};
++
++#endif /* _PLAT_PCA9685_H_ */