Re: [PATCH v3 0/4] LP3943 MFD driver for a GPIO expander and a PWM generator

2013-09-15 Thread Milo Kim

Hi Lee,

On 09/15/2013 08:17 PM, Thierry Reding wrote:

On Thu, Sep 12, 2013 at 04:28:09PM +0100, Lee Jones wrote:

* Documentation
   From Thierry's suggestion, detailed driver description was moved to
   'Documentation/lp3943.txt'.


Really? Why here? Do we really want 1000's of driver docs in /Documentation?


There is no subdirectory for GPIO and PWM documents under 'Documentation'.
That's why I put LP3943 documentation here.


No other driver does this (intel gained from a glancing look).


I thought it's no issue because I still found few driver documentations 
in that location.

It sounds like people are moving those into other subdirectories.
Thanks for this information.


Well, perhaps the top-level Documentation directory isn't optimal, but I
think it's a lot better than the commit description. Perhaps an 'mfd'
subdirectory could be created where documentation such as this could be
put.


I agree Thierry.
If you don't mind, can I create a MFD subdirectory with this patch-set 
in next version, v4?

Any other ideas are welcome.

Best regards,
Milo



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/6] backlight updates for 3.12-rc1

2013-09-04 Thread Milo Kim

Hi Jingoo,

On 09/05/2013 11:39 AM, Jingoo Han wrote:

Hi Andrew,

This is the backlight updates for 3.12-rc1.
Please add these patches to mm-tree.


Do you have a plan to create a git repository for the backlight subsystem?
It would be much better to maintain it and pull request.

And mailing-list also. Maybe most guys of kernel mailing list don't care 
the backlight subsystem. ;)


Thanks,
Milo

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 0/4] LP3943 MFD driver for a GPIO expander and a PWM generator

2013-09-11 Thread Milo Kim
LP3943 is an integrated device capable of driving 16 output channels.
It can be used for GPIO expander and PWM generators.
LP3493 registers are controlled via the I2C interface.

This patch-set consists of four parts - MFD, GPIO, PWM and documents.

Major updates in v3:

* MFD
  Lee Jones pointed confusing pin number notation.
  Now, each output pin number is exactly matched to each enum value.

  LP3943 has a static configuration from platform data or the device tree,
  So, I keep the driver structure instead of using the pin control subsystem.
  (https://lkml.org/lkml/2013/8/14/490)

* PWM
  Do not emulate 'set_polarity' function in case of unsupported feature by
  the chip.
  Code fixes based on Thierry Reding's comments.
  (https://lkml.org/lkml/2013/8/14/188)

* Documentation
  From Thierry's suggestion, detailed driver description was moved to
  'Documentation/lp3943.txt'.
  Fix device tree bindings from maintainers' comments.
  (https://lkml.org/lkml/2013/7/31/226)
  (https://lkml.org/lkml/2013/8/14/569)

Milo Kim (4):
  mfd: add LP3943 MFD driver
  gpio: add LP3943 I2C GPIO expander driver
  pwm: add LP3943 PWM driver
  Documentation: add LP3943 DT bindings and document

 Documentation/00-INDEX |2 +
 .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 +++
 Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 ++
 .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 
 Documentation/lp3943.txt   |   62 
 drivers/gpio/Kconfig   |8 +
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-lp3943.c |  242 +++
 drivers/mfd/Kconfig|   11 +
 drivers/mfd/Makefile   |1 +
 drivers/mfd/lp3943.c   |  148 +
 drivers/pwm/Kconfig|   10 +
 drivers/pwm/Makefile   |1 +
 drivers/pwm/pwm-lp3943.c   |  314 
 include/linux/mfd/lp3943.h |  114 +++
 15 files changed, 1042 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
 create mode 100644 Documentation/lp3943.txt
 create mode 100644 drivers/gpio/gpio-lp3943.c
 create mode 100644 drivers/mfd/lp3943.c
 create mode 100644 drivers/pwm/pwm-lp3943.c
 create mode 100644 include/linux/mfd/lp3943.h

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/4] mfd: add LP3943 MFD driver

2013-09-11 Thread Milo Kim
LP3943 has 16 output pins which can be used as GPIO expander and PWM generator.

* Regmap I2C interface for R/W LP3943 registers

* Atomic operations for output pin assignment
  The driver should check whether requested pin is available or not.
  If the pin is already used, pin request returns as a failure.
  A driver data, 'pin_used' is checked when gpio_request() and
  pwm_request() are called. If the pin is available, then pin_used is set.
  And it is cleared when gpio_free() and pwm_free().

* Device tree support
  Compatible strings for GPIO and PWM driver.
  LP3943 platform data is PWM related, so parsing the device tree is
  implemented in the PWM driver.

Cc: Lee Jones 
Cc: Linus Walleij 
Cc: Samuel Ortiz 
Cc: Thierry Reding 
Signed-off-by: Milo Kim 
---
* Patch v3
  Now, output pin number is exactly matched with enum value of '
  lp3943_pwm_output'.
  Use dev_get_platdata() helper function in probe().
  Use module_i2c_driver() for initcall.

* Patch v2
  Handle atomic operations for output pin assignment.

 drivers/mfd/Kconfig|   11 
 drivers/mfd/Makefile   |1 +
 drivers/mfd/lp3943.c   |  148 
 include/linux/mfd/lp3943.h |  114 ++
 4 files changed, 274 insertions(+)
 create mode 100644 drivers/mfd/lp3943.c
 create mode 100644 include/linux/mfd/lp3943.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index e0e46f5..7058358 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -715,6 +715,17 @@ config MFD_DM355EVM_MSP
  boards.  MSP430 firmware manages resets and power sequencing,
  inputs from buttons and the IR remote, LEDs, an RTC, and more.
 
+config MFD_LP3943
+   tristate "TI/National Semiconductor LP3943 MFD Driver"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ Support for the TI/National Semiconductor LP3943.
+ This driver consists of GPIO and PWM drivers.
+ With these functionalities, it can be used for LED string control or
+ general usage such like a GPIO controller and a PWM controller.
+
 config MFD_LP8788
bool "TI LP8788 Power Management Unit Driver"
depends on I2C=y && GENERIC_HARDIRQS
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 15b905c..a6d2b22 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_PMIC_DA9052)   += da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)   += da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)   += da9052-i2c.o
 
+obj-$(CONFIG_MFD_LP3943)   += lp3943.o
 obj-$(CONFIG_MFD_LP8788)   += lp8788.o lp8788-irq.o
 
 da9055-objs:= da9055-core.o da9055-i2c.o
diff --git a/drivers/mfd/lp3943.c b/drivers/mfd/lp3943.c
new file mode 100644
index 000..d25cc0a
--- /dev/null
+++ b/drivers/mfd/lp3943.c
@@ -0,0 +1,148 @@
+/*
+ * TI/National Semiconductor LP3943 MFD Core Driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LP3943_MAX_REGISTERS   0x09
+
+/* Register configuration for pin MUX */
+static const struct lp3943_reg_cfg lp3943_mux_cfg[] = {
+   /* address, mask, shift */
+   { LP3943_REG_MUX0, 0x03, 0 },
+   { LP3943_REG_MUX0, 0x0C, 2 },
+   { LP3943_REG_MUX0, 0x30, 4 },
+   { LP3943_REG_MUX0, 0xC0, 6 },
+   { LP3943_REG_MUX1, 0x03, 0 },
+   { LP3943_REG_MUX1, 0x0C, 2 },
+   { LP3943_REG_MUX1, 0x30, 4 },
+   { LP3943_REG_MUX1, 0xC0, 6 },
+   { LP3943_REG_MUX2, 0x03, 0 },
+   { LP3943_REG_MUX2, 0x0C, 2 },
+   { LP3943_REG_MUX2, 0x30, 4 },
+   { LP3943_REG_MUX2, 0xC0, 6 },
+   { LP3943_REG_MUX3, 0x03, 0 },
+   { LP3943_REG_MUX3, 0x0C, 2 },
+   { LP3943_REG_MUX3, 0x30, 4 },
+   { LP3943_REG_MUX3, 0xC0, 6 },
+};
+
+static struct mfd_cell lp3943_devs[] = {
+   {
+   .name = "lp3943-pwm",
+   .of_compatible = "ti,lp3943-pwm",
+   },
+   {
+   .name = "lp3943-gpio",
+   .of_compatible = "ti,lp3943-gpio",
+   },
+};
+
+int lp3943_read_byte(struct lp3943 *lp3943, u8 reg, u8 *read)
+{
+   int ret;
+   unsigned int val;
+
+   ret = regmap_read(lp3943->regmap, reg, &val);
+   if (ret < 0)
+   return ret;
+
+   *read = (u8)val;
+   return 0;
+}
+EXPORT_SYMBOL_GPL(lp3943_read_byte);
+
+int lp3943_write_byte(struct lp3943 *lp3943, u8 reg, u8 data)
+{
+   return regmap_write(lp3943->regmap, reg, data);
+}
+EXPORT_SYMBOL_GPL(lp3943_write_byte);
+
+int lp3943_update_bits(struct lp3943 *l

[PATCH v3 2/4] gpio: add LP3943 I2C GPIO expander driver

2013-09-11 Thread Milo Kim
This is one of LP3943 MFD driver.
LP3943 is configurable as a GPIO expander, up to 16 GPIOs.

* Application note: how to configure LP3943 as a GPIO expander
  http://www.ti.com/lit/an/snva287a/snva287a.pdf

* Supported GPIO controller operations
  request, free, direction_input, direction_output, get and set

* GPIO direction register not supported
  LP3943 doesn't have the GPIO direction register. It only provides input and
  output status registers.
  So, private data for the direction should be handled manually.
  This variable is updated whenever the direction is changed and
  used in 'get' operation.

* Pin assignment
  A driver data, 'pin_used' is checked when a GPIO is requested.
  If the GPIO is already assigned, then returns as failure.
  If the GPIO is available, 'pin_used' is set.
  When the GPIO is not used anymore, then it is cleared.
  It is defined as unsigned long type for atomic bit operation APIs,
  but only LSB 16bits are used because LP3943 has 16 outputs.

Reviewed-by: Linus Walleij 
Signed-off-by: Milo Kim 
---
* Patch v3
  Use inline function instead of macro(), to_lp3943_gpio().
  Add 'lp3943_gpio_set_mode()' and use it in lp3943_gpio_direction_input() and
  lp3943_gpio_set().
  Few code cosmetic applied - indentations.

* Patch v2
  Use bitops macros for bit manipulations.
  Support device tree structure for the GPIO controller.
  Add request() and free() for the pin assignment.

 drivers/gpio/Kconfig   |8 ++
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-lp3943.c |  242 
 3 files changed, 251 insertions(+)
 create mode 100644 drivers/gpio/gpio-lp3943.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 349b161..60fb6e7 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -360,6 +360,14 @@ config GPIO_ARIZONA
help
  Support for GPIOs on Wolfson Arizona class devices.
 
+config GPIO_LP3943
+   tristate "TI/National Semiconductor LP3943 GPIO expander"
+   depends on MFD_LP3943
+   help
+ GPIO driver for LP3943 MFD.
+ LP3943 can be used as a GPIO expander which provides up to 16 GPIOs.
+ Open drain outputs are required for this usage.
+
 config GPIO_MAX7300
tristate "Maxim MAX7300 GPIO expander"
depends on I2C
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 97438bf..d1e2836 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL)   += gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)  += gpio-kempld.o
 obj-$(CONFIG_ARCH_KS8695)  += gpio-ks8695.o
 obj-$(CONFIG_GPIO_LANGWELL)+= gpio-langwell.o
+obj-$(CONFIG_GPIO_LP3943)  += gpio-lp3943.o
 obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LYNXPOINT)   += gpio-lynxpoint.o
 obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
diff --git a/drivers/gpio/gpio-lp3943.c b/drivers/gpio/gpio-lp3943.c
new file mode 100644
index 000..7b8db88
--- /dev/null
+++ b/drivers/gpio/gpio-lp3943.c
@@ -0,0 +1,242 @@
+/*
+ * TI/National Semiconductor LP3943 GPIO driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * 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; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum lp3943_gpios {
+   LP3943_GPIO1,
+   LP3943_GPIO2,
+   LP3943_GPIO3,
+   LP3943_GPIO4,
+   LP3943_GPIO5,
+   LP3943_GPIO6,
+   LP3943_GPIO7,
+   LP3943_GPIO8,
+   LP3943_GPIO9,
+   LP3943_GPIO10,
+   LP3943_GPIO11,
+   LP3943_GPIO12,
+   LP3943_GPIO13,
+   LP3943_GPIO14,
+   LP3943_GPIO15,
+   LP3943_GPIO16,
+   LP3943_MAX_GPIO,
+};
+
+struct lp3943_gpio {
+   struct gpio_chip chip;
+   struct lp3943 *lp3943;
+   u16 input_mask; /* 1 = GPIO is input direction, 0 = output */
+};
+
+static inline struct lp3943_gpio *to_lp3943_gpio(struct gpio_chip *_chip)
+{
+   return container_of(_chip, struct lp3943_gpio, chip);
+}
+
+static int lp3943_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+   struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+   struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+   /* Return an error if the pin is already assigned */
+   if (test_and_set_bit(offset, &lp3943->pin_used))
+   return -EBUSY;
+
+   return 0;
+}
+
+static void lp3943_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+   struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+   struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+   clear_bit(offset, &lp3943->pin_used);
+}
+
+static int lp3943_gpio_set_mode(struct lp3943_gpio *lp3943_gpio, u8 offset,
+   

[PATCH v3 3/4] pwm: add LP3943 PWM driver

2013-09-11 Thread Milo Kim
This is the other of the LP3943 MFD driver.
LP3943 can be used as a PWM generator, up to 2 channels.

* Two PWM generators supported

* Supported PWM operations
  request, free, config, enable and disable

* Pin assignment
  A driver data, 'pin_used' is checked when a PWM is requested.
  If the output pin is already assigned, then returns as failure.
  If the pin is available, 'pin_used' is set.
  When the PWM is not used anymore, then it is cleared.
  It is defined as unsigned long type for atomic bit operation APIs,
  but only LSB 16bits are used because LP3943 has 16 outputs.

Cc: Thierry Reding 
Signed-off-by: Milo Kim 
---
* Patch v3
  Manual polarity not supported any more.
  Add encapsulation functions for accessing internal data structure.
  Use pwm_set_chip_data() and pwm_get_chip_data().
  And other code fixes based on Thierry's feedback.

 drivers/pwm/Kconfig  |   10 ++
 drivers/pwm/Makefile |1 +
 drivers/pwm/pwm-lp3943.c |  314 ++
 3 files changed, 325 insertions(+)
 create mode 100644 drivers/pwm/pwm-lp3943.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 75840b5..9cf38bc 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -81,6 +81,16 @@ config PWM_JZ4740
  To compile this driver as a module, choose M here: the module
  will be called pwm-jz4740.
 
+config PWM_LP3943
+   tristate "TI/National Semiconductor LP3943 PWM support"
+   depends on MFD_LP3943
+   help
+ Generic PWM framework driver for LP3943 which supports two PWM
+ channels.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-lp3943.
+
 config PWM_LPC32XX
tristate "LPC32XX PWM support"
depends on ARCH_LPC32XX
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 77a8c18..db8e349 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
 obj-$(CONFIG_PWM_IMX)  += pwm-imx.o
 obj-$(CONFIG_PWM_JZ4740)   += pwm-jz4740.o
+obj-$(CONFIG_PWM_LP3943)   += pwm-lp3943.o
 obj-$(CONFIG_PWM_LPC32XX)  += pwm-lpc32xx.o
 obj-$(CONFIG_PWM_MXS)  += pwm-mxs.o
 obj-$(CONFIG_PWM_PCA9685)  += pwm-pca9685.o
diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c
new file mode 100644
index 000..8a843a0
--- /dev/null
+++ b/drivers/pwm/pwm-lp3943.c
@@ -0,0 +1,314 @@
+/*
+ * TI/National Semiconductor LP3943 PWM driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * 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; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LP3943_MAX_DUTY255
+#define LP3943_MIN_PERIOD  6250
+#define LP3943_MAX_PERIOD  160
+
+struct lp3943_pwm {
+   struct pwm_chip chip;
+   struct lp3943 *lp3943;
+   struct lp3943_platform_data *pdata;
+};
+
+static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *_chip)
+{
+   return container_of(_chip, struct lp3943_pwm, chip);
+}
+
+static struct lp3943_pwm_map *
+lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm)
+{
+   struct lp3943_platform_data *pdata = lp3943_pwm->pdata;
+   struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+   struct lp3943_pwm_map *pwm_map;
+   int i, offset;
+
+   pwm_map = kzalloc(sizeof(*pwm_map), GFP_KERNEL);
+   if (!pwm_map)
+   return ERR_PTR(-ENOMEM);
+
+   pwm_map->output = pdata->pwms[hwpwm]->output;
+   pwm_map->num_outputs = pdata->pwms[hwpwm]->num_outputs;
+
+   for (i = 0; i < pwm_map->num_outputs; i++) {
+   offset = pwm_map->output[i];
+
+   /* Return an error if the pin is already assigned */
+   if (test_and_set_bit(offset, &lp3943->pin_used))
+   return ERR_PTR(-EBUSY);
+   }
+
+   return pwm_map;
+}
+
+static int lp3943_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+   struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
+   struct lp3943_pwm_map *pwm_map;
+
+   pwm_map = lp3943_pwm_request_map(lp3943_pwm, pwm->hwpwm);
+   if (IS_ERR(pwm_map))
+   return PTR_ERR(pwm_map);
+
+   return pwm_set_chip_data(pwm, pwm_map);
+}
+
+static void lp3943_pwm_free_map(struct lp3943_pwm *lp3943_pwm,
+   struct lp3943_pwm_map *pwm_map)
+{
+   struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+   int i, offset;
+
+   for (i = 0; i < pwm_map->num_outputs; i++) {
+   offset = pwm_map->output[i];
+   clear_bit(offs

[PATCH 4/4] Documentation: add LP3943 DT bindings and document

2013-09-11 Thread Milo Kim
Bindings for LP3943 MFD, GPIO and PWM controller are added.
And LP3943 driver document is added also.

Cc: devicet...@vger.kernel.org
Cc: Lee Jones 
Cc: Linus Walleij 
Cc: Samuel Ortiz 
Cc: Thierry Reding 
Signed-off-by: Milo Kim 
---
 Documentation/00-INDEX |2 +
 .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 
 Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 +++
 .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 ++
 Documentation/lp3943.txt   |   62 
 5 files changed, 192 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
 create mode 100644 Documentation/lp3943.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 0c4cc68..5dd921f 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -285,6 +285,8 @@ logo.gif
- full colour GIF image of Linux logo (penguin - Tux).
 logo.txt
- info on creator of above logo & site to get additional images from.
+lp3943.txt
+   - info on LP3943 MFD driver structure.
 m68k/
- directory with info about Linux on Motorola 68k architecture.
 magic-number.txt
diff --git a/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt 
b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
new file mode 100644
index 000..80fcb7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
@@ -0,0 +1,37 @@
+TI/National Semiconductor LP3943 GPIO controller
+
+Required properties:
+  - compatible: "ti,lp3943-gpio"
+  - gpio-controller: Marks the device node as a GPIO controller.
+  - #gpio-cells: Should be 2. See gpio.txt in this directory for a
+ description of the cells format.
+
+Example:
+Simple LED controls with LP3943 GPIO controller
+
+&i2c4 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+   };
+};
+
+leds {
+   compatible = "gpio-leds";
+   indicator1 {
+   label = "indi1";
+   gpios = <&gpioex 9 GPIO_ACTIVE_LOW>;
+   };
+
+   indicator2 {
+   label = "indi2";
+   gpios = <&gpioex 10 GPIO_ACTIVE_LOW>;
+   default-state = "off";
+   };
+};
diff --git a/Documentation/devicetree/bindings/mfd/lp3943.txt 
b/Documentation/devicetree/bindings/mfd/lp3943.txt
new file mode 100644
index 000..e8591d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/lp3943.txt
@@ -0,0 +1,33 @@
+TI/National Semiconductor LP3943 MFD driver
+
+Required properties:
+  - compatible: "ti,lp3943"
+  - reg: I2C slave address. From 0x60 to 0x67.
+
+LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm.
+
+For the LP3943 GPIO properties please refer to:
+Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
+
+For the LP3943 PWM properties please refer to:
+Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
+
+Example:
+
+lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+
+   pwm3943: pwm {
+   compatible = "ti,lp3943-pwm";
+   #pwm-cells = <2>;
+   ti,pwm0 = <8 9 10>;
+   ti,pwm1 = <15>;
+   };
+};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt 
b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
new file mode 100644
index 000..7bd9d3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
@@ -0,0 +1,58 @@
+TI/National Semiconductor LP3943 PWM controller
+
+Required properties:
+  - compatible: "ti,lp3943-pwm"
+  - #pwm-cells: Should be 2. See pwm.txt in this directory for a
+description of the cells format.
+Note that this hardware limits the period length to the
+range 6250~160.
+  - ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1.
+0 = output 0
+1 = output 1
+.
+.
+15 = output 15
+
+Example:
+PWM 0 is for RGB LED brightness control
+PWM 1 is for brightness control of LP8557 backlight device
+
+&i2c3 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   /*
+* PWM 0 : output 8, 9 and 10
+* PWM 1 : output 15
+*

[PATCH v3 4/4] Documentation: add LP3943 DT bindings and document

2013-09-11 Thread Milo Kim
Bindings for LP3943 MFD, GPIO and PWM controller are added.
And LP3943 driver document is added also.

Cc: devicet...@vger.kernel.org
Cc: Lee Jones 
Cc: Linus Walleij 
Cc: Samuel Ortiz 
Cc: Thierry Reding 
Signed-off-by: Milo Kim 
---
 Documentation/00-INDEX |2 +
 .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 
 Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 +++
 .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 ++
 Documentation/lp3943.txt   |   62 
 5 files changed, 192 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
 create mode 100644 Documentation/lp3943.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 0c4cc68..5dd921f 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -285,6 +285,8 @@ logo.gif
- full colour GIF image of Linux logo (penguin - Tux).
 logo.txt
- info on creator of above logo & site to get additional images from.
+lp3943.txt
+   - info on LP3943 MFD driver structure.
 m68k/
- directory with info about Linux on Motorola 68k architecture.
 magic-number.txt
diff --git a/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt 
b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
new file mode 100644
index 000..80fcb7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
@@ -0,0 +1,37 @@
+TI/National Semiconductor LP3943 GPIO controller
+
+Required properties:
+  - compatible: "ti,lp3943-gpio"
+  - gpio-controller: Marks the device node as a GPIO controller.
+  - #gpio-cells: Should be 2. See gpio.txt in this directory for a
+ description of the cells format.
+
+Example:
+Simple LED controls with LP3943 GPIO controller
+
+&i2c4 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+   };
+};
+
+leds {
+   compatible = "gpio-leds";
+   indicator1 {
+   label = "indi1";
+   gpios = <&gpioex 9 GPIO_ACTIVE_LOW>;
+   };
+
+   indicator2 {
+   label = "indi2";
+   gpios = <&gpioex 10 GPIO_ACTIVE_LOW>;
+   default-state = "off";
+   };
+};
diff --git a/Documentation/devicetree/bindings/mfd/lp3943.txt 
b/Documentation/devicetree/bindings/mfd/lp3943.txt
new file mode 100644
index 000..e8591d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/lp3943.txt
@@ -0,0 +1,33 @@
+TI/National Semiconductor LP3943 MFD driver
+
+Required properties:
+  - compatible: "ti,lp3943"
+  - reg: I2C slave address. From 0x60 to 0x67.
+
+LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm.
+
+For the LP3943 GPIO properties please refer to:
+Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
+
+For the LP3943 PWM properties please refer to:
+Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
+
+Example:
+
+lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+
+   pwm3943: pwm {
+   compatible = "ti,lp3943-pwm";
+   #pwm-cells = <2>;
+   ti,pwm0 = <8 9 10>;
+   ti,pwm1 = <15>;
+   };
+};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt 
b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
new file mode 100644
index 000..7bd9d3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
@@ -0,0 +1,58 @@
+TI/National Semiconductor LP3943 PWM controller
+
+Required properties:
+  - compatible: "ti,lp3943-pwm"
+  - #pwm-cells: Should be 2. See pwm.txt in this directory for a
+description of the cells format.
+Note that this hardware limits the period length to the
+range 6250~160.
+  - ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1.
+0 = output 0
+1 = output 1
+.
+.
+15 = output 15
+
+Example:
+PWM 0 is for RGB LED brightness control
+PWM 1 is for brightness control of LP8557 backlight device
+
+&i2c3 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   /*
+* PWM 0 : output 8, 9 and 10
+* PWM 1 : output 15
+*

Re: [PATCH 4/4] Documentation: add LP3943 DT bindings and document

2013-09-11 Thread Milo Kim

Hi Everyone,

Please ignore this mail. Version information, 'v3' is missing in the 
subject.

Fixed mail has just sent. Please find '[PATCH v3 4/4]' in your mailbox.
Sorry for the inconvenience.

Best regards,
Milo

On 09/12/2013 10:34 AM, Milo Kim wrote:

Bindings for LP3943 MFD, GPIO and PWM controller are added.
And LP3943 driver document is added also.

Cc: devicet...@vger.kernel.org
Cc: Lee Jones 
Cc: Linus Walleij 
Cc: Samuel Ortiz 
Cc: Thierry Reding 
Signed-off-by: Milo Kim 
---
  Documentation/00-INDEX |2 +
  .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 
  Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 +++
  .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 ++
  Documentation/lp3943.txt   |   62 
  5 files changed, 192 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
  create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
  create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
  create mode 100644 Documentation/lp3943.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 0c4cc68..5dd921f 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -285,6 +285,8 @@ logo.gif
- full colour GIF image of Linux logo (penguin - Tux).
  logo.txt
- info on creator of above logo & site to get additional images from.
+lp3943.txt
+   - info on LP3943 MFD driver structure.
  m68k/
- directory with info about Linux on Motorola 68k architecture.
  magic-number.txt
diff --git a/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt 
b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
new file mode 100644
index 000..80fcb7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
@@ -0,0 +1,37 @@
+TI/National Semiconductor LP3943 GPIO controller
+
+Required properties:
+  - compatible: "ti,lp3943-gpio"
+  - gpio-controller: Marks the device node as a GPIO controller.
+  - #gpio-cells: Should be 2. See gpio.txt in this directory for a
+ description of the cells format.
+
+Example:
+Simple LED controls with LP3943 GPIO controller
+
+&i2c4 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+   };
+};
+
+leds {
+   compatible = "gpio-leds";
+   indicator1 {
+   label = "indi1";
+   gpios = <&gpioex 9 GPIO_ACTIVE_LOW>;
+   };
+
+   indicator2 {
+   label = "indi2";
+   gpios = <&gpioex 10 GPIO_ACTIVE_LOW>;
+   default-state = "off";
+   };
+};
diff --git a/Documentation/devicetree/bindings/mfd/lp3943.txt 
b/Documentation/devicetree/bindings/mfd/lp3943.txt
new file mode 100644
index 000..e8591d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/lp3943.txt
@@ -0,0 +1,33 @@
+TI/National Semiconductor LP3943 MFD driver
+
+Required properties:
+  - compatible: "ti,lp3943"
+  - reg: I2C slave address. From 0x60 to 0x67.
+
+LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm.
+
+For the LP3943 GPIO properties please refer to:
+Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
+
+For the LP3943 PWM properties please refer to:
+Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
+
+Example:
+
+lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+
+   pwm3943: pwm {
+   compatible = "ti,lp3943-pwm";
+   #pwm-cells = <2>;
+   ti,pwm0 = <8 9 10>;
+   ti,pwm1 = <15>;
+   };
+};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt 
b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
new file mode 100644
index 000..7bd9d3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
@@ -0,0 +1,58 @@
+TI/National Semiconductor LP3943 PWM controller
+
+Required properties:
+  - compatible: "ti,lp3943-pwm"
+  - #pwm-cells: Should be 2. See pwm.txt in this directory for a
+description of the cells format.
+Note that this hardware limits the period length to the
+range 6250~160.
+  - ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1.
+0 = output 0
+1 = output 1
+.
+.
+15 = output 15
+
+Example:
+PWM 0 is for RGB LED brightness control
+PWM 1 is fo

Re: [PATCH v3 4/4] Documentation: add LP3943 DT bindings and document

2013-09-22 Thread Milo Kim


Hi Lee,

On 09/13/2013 12:24 AM, Lee Jones wrote:

On Thu, 12 Sep 2013, Milo Kim wrote:


...


new file mode 100644
index 000..576ebd0
--- /dev/null
+++ b/Documentation/lp3943.txt
@@ -0,0 +1,62 @@
+TI/National Semiconductor LP3943 MFD driver
+===
+
+LP3943 is an integrated device capable of driving 16 output channels.
+It can be used for GPIO expander and PWM generators.
+LP3493 registers are controlled via the I2C interface.
+
+Driver structure
+
+  LED controlGeneral usage for a device
+  ___   
+
+  LP3943 MFD  GPIO expanderleds-gpioeg) HW enable pin
+  |
+  --- PWM generatorleds-pwm eg) PWM input
+
+
+Why do we need GPIO and PWM drivers instead of LED driver?
+To support LED control and general usage, GPIO and PWM drivers are necessary.
+
+According to the datasheet(1), it's just a LED driver which has 16 channels.
+But here is another application, a GPIO expander.(2)
+
+  (1) http://www.ti.com/lit/ds/snvs256b/snvs256b.pdf
+  (2) http://www.ti.com/lit/an/snva287a/snva287a.pdf
+
+Internal two PWM channels are used for LED dimming effect.
+And each output pin can be used as a GPIO as well.
+LED functionality can work with GPIOs or PWMs.
+LEDs can be controlled with legacy leds-gpio(static brightness) or
+leds-pwm drivers(dynamic brightness control).
+Additionally, it can be used for generic GPIO and PWM controller.
+For example, a GPIO is HW enable pin of a device.
+PWM is input pin of a backlight device.
+
+
+LP3943 PWM port map
+---
+Each PWM channel can be mapped to one or multiple output pins.
+
+For example, PWM 0 is used for a backlight device.
+PWM 1 is for RGB LEDs.
+
+  PWM channelOutput pinsPWM consumer
+  ______
+  PWM 0  pin 1  backlight
+  PWM 1  pin 7, 8, 9RGB LEDs
+
+Then, PWM port map is as below.
+PWM 0: num_outputs = 1, output = pin 1
+PWM 1: num_outputs = 3, output = pin 7, 8, 9
+
+The 'lp3943_pwm_map' structure is used for this feature.
+
+
+Device tree supported
+-
+Please refer to the documents below.
+
+Documentation/devicetree/bindings/mfd/lp3943.txt
+Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
+Documentation/devicetree/bindings/pwm/pwm-lp3943.txt


Why do you need to document your driver in this way?

If this stuff is really important (and most of it really isn't), then
put it either in the commit log or in the driver.


Unnecessary documentation makes it noisy, but I think the LP3943 still 
needs the driver documentation for better understanding.


Many people think LP3943 is just LED driver, but I really want to share 
the application usages - PWM generators and GPIO expanders.
If the driver just supports LED functionality, then it would be created 
as LED class driver. However, this patch-set enables more generic driver 
usages.

So, this documentation would be helpful.

And I want to keep the code and the documentation separate.
If the link address is changed, then only documentation file will be 
modified, not source file.


So, I'd like to create the fifth patch-set with new MFD documentation 
subdirectory.
Additionally, LP3943 platform data example code will be added in the 
'Documentation/mfd/lp3943.txt'. It's for a platform which doesn't 
support the device tree.


Best regards,
Milo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 0/4] LP3943 MFD driver for a GPIO expander and a PWM generator

2013-09-24 Thread Milo Kim
LP3943 is an integrated device capable of driving 16 output channels.
It can be used for GPIO expander and PWM generators.
LP3493 registers are controlled via the I2C interface.

This patch-set consists of four parts - MFD, GPIO, PWM and documents.

Update from v3 to v4:
  Move the driver description from the documentation to the MFD driver file.

Milo Kim (4):
  mfd: add LP3943 MFD driver
  gpio: add LP3943 I2C GPIO expander driver
  pwm: add LP3943 PWM driver
  Documentation: add LP3943 DT bindings and document

 .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 +++
 Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 ++
 .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 
 drivers/gpio/Kconfig   |8 +
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-lp3943.c |  242 +++
 drivers/mfd/Kconfig|   11 +
 drivers/mfd/Makefile   |1 +
 drivers/mfd/lp3943.c   |  167 +++
 drivers/pwm/Kconfig|   10 +
 drivers/pwm/Makefile   |1 +
 drivers/pwm/pwm-lp3943.c   |  314 
 include/linux/mfd/lp3943.h |  114 +++
 13 files changed, 997 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
 create mode 100644 drivers/gpio/gpio-lp3943.c
 create mode 100644 drivers/mfd/lp3943.c
 create mode 100644 drivers/pwm/pwm-lp3943.c
 create mode 100644 include/linux/mfd/lp3943.h

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 1/4] mfd: add LP3943 MFD driver

2013-09-24 Thread Milo Kim
LP3943 has 16 output pins which can be used as GPIO expander and PWM generator.

* Regmap I2C interface for R/W LP3943 registers

* Atomic operations for output pin assignment
  The driver should check whether requested pin is available or not.
  If the pin is already used, pin request returns as a failure.
  A driver data, 'pin_used' is checked when gpio_request() and
  pwm_request() are called. If the pin is available, then pin_used is set.
  And it is cleared when gpio_free() and pwm_free().

* Device tree support
  Compatible strings for GPIO and PWM driver.
  LP3943 platform data is PWM related, so parsing the device tree is
  implemented in the PWM driver.

Signed-off-by: Milo Kim 
Acked-by: Lee Jones 
---
* Patch v4
  Driver description was moved from the documentation in patch v3.

* Patch v3
  Now, output pin number is exactly matched with enum value of '
  lp3943_pwm_output'.
  Use dev_get_platdata() helper function in probe().
  Use module_i2c_driver() for initcall.

* Patch v2
  Handle atomic operations for output pin assignment.

 drivers/mfd/Kconfig|   11 
 drivers/mfd/Makefile   |1 +
 drivers/mfd/lp3943.c   |  148 
 include/linux/mfd/lp3943.h |  114 ++
 4 files changed, 274 insertions(+)
 create mode 100644 drivers/mfd/lp3943.c
 create mode 100644 include/linux/mfd/lp3943.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index e0e46f5..7058358 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -715,6 +715,17 @@ config MFD_DM355EVM_MSP
  boards.  MSP430 firmware manages resets and power sequencing,
  inputs from buttons and the IR remote, LEDs, an RTC, and more.
 
+config MFD_LP3943
+   tristate "TI/National Semiconductor LP3943 MFD Driver"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ Support for the TI/National Semiconductor LP3943.
+ This driver consists of GPIO and PWM drivers.
+ With these functionalities, it can be used for LED string control or
+ general usage such like a GPIO controller and a PWM controller.
+
 drivers/mfd/Kconfig|   11 +++
 drivers/mfd/Makefile   |1 +
 drivers/mfd/lp3943.c   |  167 
 include/linux/mfd/lp3943.h |  114 ++
 4 files changed, 293 insertions(+)
 create mode 100644 drivers/mfd/lp3943.c
 create mode 100644 include/linux/mfd/lp3943.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index e0e46f5..7058358 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -715,6 +715,17 @@ config MFD_DM355EVM_MSP
  boards.  MSP430 firmware manages resets and power sequencing,
  inputs from buttons and the IR remote, LEDs, an RTC, and more.
 
+config MFD_LP3943
+   tristate "TI/National Semiconductor LP3943 MFD Driver"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ Support for the TI/National Semiconductor LP3943.
+ This driver consists of GPIO and PWM drivers.
+ With these functionalities, it can be used for LED string control or
+ general usage such like a GPIO controller and a PWM controller.
+
 config MFD_LP8788
bool "TI LP8788 Power Management Unit Driver"
depends on I2C=y && GENERIC_HARDIRQS
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 15b905c..a6d2b22 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_PMIC_DA9052)   += da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)   += da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)   += da9052-i2c.o
 
+obj-$(CONFIG_MFD_LP3943)   += lp3943.o
 obj-$(CONFIG_MFD_LP8788)   += lp8788.o lp8788-irq.o
 
 da9055-objs:= da9055-core.o da9055-i2c.o
diff --git a/drivers/mfd/lp3943.c b/drivers/mfd/lp3943.c
new file mode 100644
index 000..e322268
--- /dev/null
+++ b/drivers/mfd/lp3943.c
@@ -0,0 +1,167 @@
+/*
+ * TI/National Semiconductor LP3943 MFD Core Driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver structure:
+ *   LP3943 is an integrated device capable of driving 16 output channels.
+ *   It can be used for a GPIO expander and PWM generators.
+ *
+ *   LED controlGeneral usage for a device
+ *   ___   
+ *
+ *   LP3943 MFD  GPIO expanderleds-gpioeg) HW enable pin
+ *   |
+ *   --- PWM generatorleds-pwm eg) PWM input
+ *
+ *   Internal two PWM channels are used for LED dimming effect.
+ *   And ea

[PATCH v4 3/4] pwm: add LP3943 PWM driver

2013-09-24 Thread Milo Kim
This is the other of the LP3943 MFD driver.
LP3943 can be used as a PWM generator, up to 2 channels.

* Two PWM generators supported

* Supported PWM operations
  request, free, config, enable and disable

* Pin assignment
  A driver data, 'pin_used' is checked when a PWM is requested.
  If the output pin is already assigned, then returns as failure.
  If the pin is available, 'pin_used' is set.
  When the PWM is not used anymore, then it is cleared.
  It is defined as unsigned long type for atomic bit operation APIs,
  but only LSB 16bits are used because LP3943 has 16 outputs.

Cc: Thierry Reding 
Signed-off-by: Milo Kim 
---
* Patch v4
  No update, same as v3.

* Patch v3
  Manual polarity not supported any more.
  Add encapsulation functions for accessing internal data structure.
  Use pwm_set_chip_data() and pwm_get_chip_data().
  And other code fixes based on Thierry's feedback.

 drivers/pwm/Kconfig  |   10 ++
 drivers/pwm/Makefile |1 +
 drivers/pwm/pwm-lp3943.c |  314 ++
 3 files changed, 325 insertions(+)
 create mode 100644 drivers/pwm/pwm-lp3943.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 75840b5..9cf38bc 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -81,6 +81,16 @@ config PWM_JZ4740
  To compile this driver as a module, choose M here: the module
  will be called pwm-jz4740.
 
+config PWM_LP3943
+   tristate "TI/National Semiconductor LP3943 PWM support"
+   depends on MFD_LP3943
+   help
+ Generic PWM framework driver for LP3943 which supports two PWM
+ channels.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-lp3943.
+
 config PWM_LPC32XX
tristate "LPC32XX PWM support"
depends on ARCH_LPC32XX
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 77a8c18..db8e349 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
 obj-$(CONFIG_PWM_IMX)  += pwm-imx.o
 obj-$(CONFIG_PWM_JZ4740)   += pwm-jz4740.o
+obj-$(CONFIG_PWM_LP3943)   += pwm-lp3943.o
 obj-$(CONFIG_PWM_LPC32XX)  += pwm-lpc32xx.o
 obj-$(CONFIG_PWM_MXS)  += pwm-mxs.o
 obj-$(CONFIG_PWM_PCA9685)  += pwm-pca9685.o
diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c
new file mode 100644
index 000..8a843a0
--- /dev/null
+++ b/drivers/pwm/pwm-lp3943.c
@@ -0,0 +1,314 @@
+/*
+ * TI/National Semiconductor LP3943 PWM driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * 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; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LP3943_MAX_DUTY255
+#define LP3943_MIN_PERIOD  6250
+#define LP3943_MAX_PERIOD  160
+
+struct lp3943_pwm {
+   struct pwm_chip chip;
+   struct lp3943 *lp3943;
+   struct lp3943_platform_data *pdata;
+};
+
+static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *_chip)
+{
+   return container_of(_chip, struct lp3943_pwm, chip);
+}
+
+static struct lp3943_pwm_map *
+lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm)
+{
+   struct lp3943_platform_data *pdata = lp3943_pwm->pdata;
+   struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+   struct lp3943_pwm_map *pwm_map;
+   int i, offset;
+
+   pwm_map = kzalloc(sizeof(*pwm_map), GFP_KERNEL);
+   if (!pwm_map)
+   return ERR_PTR(-ENOMEM);
+
+   pwm_map->output = pdata->pwms[hwpwm]->output;
+   pwm_map->num_outputs = pdata->pwms[hwpwm]->num_outputs;
+
+   for (i = 0; i < pwm_map->num_outputs; i++) {
+   offset = pwm_map->output[i];
+
+   /* Return an error if the pin is already assigned */
+   if (test_and_set_bit(offset, &lp3943->pin_used))
+   return ERR_PTR(-EBUSY);
+   }
+
+   return pwm_map;
+}
+
+static int lp3943_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+   struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
+   struct lp3943_pwm_map *pwm_map;
+
+   pwm_map = lp3943_pwm_request_map(lp3943_pwm, pwm->hwpwm);
+   if (IS_ERR(pwm_map))
+   return PTR_ERR(pwm_map);
+
+   return pwm_set_chip_data(pwm, pwm_map);
+}
+
+static void lp3943_pwm_free_map(struct lp3943_pwm *lp3943_pwm,
+   struct lp3943_pwm_map *pwm_map)
+{
+   struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+   int i, offset;
+
+   for (i = 0; i < pwm_map->num_outputs; i++) {
+   offset = pwm_map-&g

[PATCH v4 2/4] gpio: add LP3943 I2C GPIO expander driver

2013-09-24 Thread Milo Kim
This is one of LP3943 MFD driver.
LP3943 is configurable as a GPIO expander, up to 16 GPIOs.

* Application note: how to configure LP3943 as a GPIO expander
  http://www.ti.com/lit/an/snva287a/snva287a.pdf

* Supported GPIO controller operations
  request, free, direction_input, direction_output, get and set

* GPIO direction register not supported
  LP3943 doesn't have the GPIO direction register. It only provides input and
  output status registers.
  So, private data for the direction should be handled manually.
  This variable is updated whenever the direction is changed and
  used in 'get' operation.

* Pin assignment
  A driver data, 'pin_used' is checked when a GPIO is requested.
  If the GPIO is already assigned, then returns as failure.
  If the GPIO is available, 'pin_used' is set.
  When the GPIO is not used anymore, then it is cleared.
  It is defined as unsigned long type for atomic bit operation APIs,
  but only LSB 16bits are used because LP3943 has 16 outputs.

Signed-off-by: Milo Kim 
Reviewed-by: Linus Walleij 
---
* Patch v4
  No update, same as v3

* Patch v3
  Use inline function instead of macro(), to_lp3943_gpio().
  Add 'lp3943_gpio_set_mode()' and use it in lp3943_gpio_direction_input() and
  lp3943_gpio_set().
  Few code cosmetic applied - indentations.

* Patch v2
  Use bitops macros for bit manipulations.
  Support device tree structure for the GPIO controller.
  Add request() and free() for the pin assignment.

 drivers/gpio/Kconfig   |8 ++
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-lp3943.c |  242 
 3 files changed, 251 insertions(+)
 create mode 100644 drivers/gpio/gpio-lp3943.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 349b161..60fb6e7 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -360,6 +360,14 @@ config GPIO_ARIZONA
help
  Support for GPIOs on Wolfson Arizona class devices.
 
+config GPIO_LP3943
+   tristate "TI/National Semiconductor LP3943 GPIO expander"
+   depends on MFD_LP3943
+   help
+ GPIO driver for LP3943 MFD.
+ LP3943 can be used as a GPIO expander which provides up to 16 GPIOs.
+ Open drain outputs are required for this usage.
+
 config GPIO_MAX7300
tristate "Maxim MAX7300 GPIO expander"
depends on I2C
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 97438bf..d1e2836 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL)   += gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)  += gpio-kempld.o
 obj-$(CONFIG_ARCH_KS8695)  += gpio-ks8695.o
 obj-$(CONFIG_GPIO_LANGWELL)+= gpio-langwell.o
+obj-$(CONFIG_GPIO_LP3943)  += gpio-lp3943.o
 obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LYNXPOINT)   += gpio-lynxpoint.o
 obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
diff --git a/drivers/gpio/gpio-lp3943.c b/drivers/gpio/gpio-lp3943.c
new file mode 100644
index 000..7b8db88
--- /dev/null
+++ b/drivers/gpio/gpio-lp3943.c
@@ -0,0 +1,242 @@
+/*
+ * TI/National Semiconductor LP3943 GPIO driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * 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; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum lp3943_gpios {
+   LP3943_GPIO1,
+   LP3943_GPIO2,
+   LP3943_GPIO3,
+   LP3943_GPIO4,
+   LP3943_GPIO5,
+   LP3943_GPIO6,
+   LP3943_GPIO7,
+   LP3943_GPIO8,
+   LP3943_GPIO9,
+   LP3943_GPIO10,
+   LP3943_GPIO11,
+   LP3943_GPIO12,
+   LP3943_GPIO13,
+   LP3943_GPIO14,
+   LP3943_GPIO15,
+   LP3943_GPIO16,
+   LP3943_MAX_GPIO,
+};
+
+struct lp3943_gpio {
+   struct gpio_chip chip;
+   struct lp3943 *lp3943;
+   u16 input_mask; /* 1 = GPIO is input direction, 0 = output */
+};
+
+static inline struct lp3943_gpio *to_lp3943_gpio(struct gpio_chip *_chip)
+{
+   return container_of(_chip, struct lp3943_gpio, chip);
+}
+
+static int lp3943_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+   struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+   struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+   /* Return an error if the pin is already assigned */
+   if (test_and_set_bit(offset, &lp3943->pin_used))
+   return -EBUSY;
+
+   return 0;
+}
+
+static void lp3943_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+   struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+   struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+   clear_bit(offset, &lp3943->pin_used);
+}
+
+static int lp3943_gpio_set_mode(struct lp3943_gpio *lp3943_gpio

[PATCH v4 4/4] Documentation: add LP3943 DT bindings and document

2013-09-24 Thread Milo Kim
Bindings for LP3943 MFD, GPIO and PWM controller are added.

Cc: devicet...@vger.kernel.org
Cc: Lee Jones 
Cc: Linus Walleij 
Cc: Samuel Ortiz 
Cc: Thierry Reding 
Signed-off-by: Milo Kim 
---
 .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 +
 Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 +++
 .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 
 3 files changed, 128 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt 
b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
new file mode 100644
index 000..80fcb7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
@@ -0,0 +1,37 @@
+TI/National Semiconductor LP3943 GPIO controller
+
+Required properties:
+  - compatible: "ti,lp3943-gpio"
+  - gpio-controller: Marks the device node as a GPIO controller.
+  - #gpio-cells: Should be 2. See gpio.txt in this directory for a
+ description of the cells format.
+
+Example:
+Simple LED controls with LP3943 GPIO controller
+
+&i2c4 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+   };
+};
+
+leds {
+   compatible = "gpio-leds";
+   indicator1 {
+   label = "indi1";
+   gpios = <&gpioex 9 GPIO_ACTIVE_LOW>;
+   };
+
+   indicator2 {
+   label = "indi2";
+   gpios = <&gpioex 10 GPIO_ACTIVE_LOW>;
+   default-state = "off";
+   };
+};
diff --git a/Documentation/devicetree/bindings/mfd/lp3943.txt 
b/Documentation/devicetree/bindings/mfd/lp3943.txt
new file mode 100644
index 000..e8591d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/lp3943.txt
@@ -0,0 +1,33 @@
+TI/National Semiconductor LP3943 MFD driver
+
+Required properties:
+  - compatible: "ti,lp3943"
+  - reg: I2C slave address. From 0x60 to 0x67.
+
+LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm.
+
+For the LP3943 GPIO properties please refer to:
+Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
+
+For the LP3943 PWM properties please refer to:
+Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
+
+Example:
+
+lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+
+   pwm3943: pwm {
+   compatible = "ti,lp3943-pwm";
+   #pwm-cells = <2>;
+   ti,pwm0 = <8 9 10>;
+   ti,pwm1 = <15>;
+   };
+};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt 
b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
new file mode 100644
index 000..7bd9d3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
@@ -0,0 +1,58 @@
+TI/National Semiconductor LP3943 PWM controller
+
+Required properties:
+  - compatible: "ti,lp3943-pwm"
+  - #pwm-cells: Should be 2. See pwm.txt in this directory for a
+description of the cells format.
+Note that this hardware limits the period length to the
+range 6250~160.
+  - ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1.
+0 = output 0
+1 = output 1
+.
+.
+15 = output 15
+
+Example:
+PWM 0 is for RGB LED brightness control
+PWM 1 is for brightness control of LP8557 backlight device
+
+&i2c3 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   /*
+* PWM 0 : output 8, 9 and 10
+* PWM 1 : output 15
+*/
+   pwm3943: pwm {
+   compatible = "ti,lp3943-pwm";
+   #pwm-cells = <2>;
+   ti,pwm0 = <8 9 10>;
+   ti,pwm1 = <15>;
+   };
+   };
+
+};
+
+/* LEDs control with PWM 0 of LP3943 */
+pwmleds {
+   compatible = "pwm-leds";
+   rgb {
+   label = "indi::rgb";
+   pwms = <&pwm3943 0 1>;
+   max-brightness = <255>;
+   };
+};
+
+&i2c4 {
+   /* Backlight control with PWM 1 of LP3943 */
+   backlight@2c {
+   compatible = "ti,lp8557";
+ 

[PATCH 00/10] leds: lp5521,5523: restore device attributes for running LED patterns

2013-08-08 Thread Milo Kim
This patch-set resolves the application conflict by restoring sysfs files.

For LP5521
  engine1/2/3_mode
  engine1/2/3_load

For LP5523
  engine1/2/3_mode
  engine1/2/3_load
  engine1/2/3_leds

Those attributes are accessed when LED pattern is run by custom application.
Those were removed when LED pattern interface was changed to generic firmware
interface. Please refer to commits below.

  git commit 9ce7cb170f97f83a78dc948bf7d25690f15e1328
  (leds-lp5521: use generic firmware interface)

  git commit db6eaf8388a413a5ee1b4547ce78506b9c6456b0
  (leds-lp5523: use generic firmware interface)

Necessary attributes are restored in this patch-set.

(Other changes)
New data structure is added for handling values from/to an application.
Few code fixes for reducing writing I2C commands.
Add LP55xx common macros for code refactoring.
Documentation updates.

You can also pull from the location below
This branch is based on 'for-next' of linux-leds.

  https://github.com/milokim/lp55xx.git resolve-missing-sysfs

Milo Kim (10):
  leds: lp55xx: add common data structure for program
  leds: lp55xx: add common macros for device attributes
  leds: lp5521: restore legacy device attributes
  leds: lp5521: remove unnecessary writing commands
  leds: lp5523: make separate API for loading engine
  leds: lp5523: LED MUX configuration on initializing
  leds: lp5523: restore legacy device attributes
  leds: lp5523: remove unnecessary writing commands
  Documentation: leds-lp5521,lp5523: update device attribute
information
  leds: lp5562: use LP55xx common macros for device attributes

 Documentation/leds/leds-lp5521.txt |   20 ++-
 Documentation/leds/leds-lp5523.txt |   21 ++-
 drivers/leds/leds-lp5521.c |  114 +++--
 drivers/leds/leds-lp5523.c |  321 ++--
 drivers/leds/leds-lp5562.c |4 +-
 drivers/leds/leds-lp55xx-common.h  |   66 
 6 files changed, 511 insertions(+), 35 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 06/10] leds: lp5523: LED MUX configuration on initializing

2013-08-08 Thread Milo Kim
LED MUX start and stop address should be updated in the program memory
on LP5523 initialization.
LED pattern doesn't work without additional MUX address configuration.
This handling is done by new function, lp5523_init_program_engine().
Eventually, it's called during device initialization, lp5523_post_init_device().

This is a conflict after git commit 632418bf65503405df3f9a6a1616f5a95f91db85
(leds-lp5523: clean up lp5523_configure()).
So it should be fixed.

Cc: Pali Rohár 
Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp5523.c |   70 +++-
 1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index b509480..29c8b19 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -49,6 +49,9 @@
 #define LP5523_REG_RESET   0x3D
 #define LP5523_REG_LED_TEST_CTRL   0x41
 #define LP5523_REG_LED_TEST_ADC0x42
+#define LP5523_REG_CH1_PROG_START  0x4C
+#define LP5523_REG_CH2_PROG_START  0x4D
+#define LP5523_REG_CH3_PROG_START  0x4E
 #define LP5523_REG_PROG_PAGE_SEL   0x4F
 #define LP5523_REG_PROG_MEM0x50
 
@@ -65,6 +68,7 @@
 #define LP5523_RESET   0xFF
 #define LP5523_ADC_SHORTCIRC_LIM   80
 #define LP5523_EXT_CLK_USED0x08
+#define LP5523_ENG_STATUS_MASK 0x07
 
 /* Memory Page Selection */
 #define LP5523_PAGE_ENG1   0
@@ -99,6 +103,8 @@ enum lp5523_chip_id {
LP55231,
 };
 
+static int lp5523_init_program_engine(struct lp55xx_chip *chip);
+
 static inline void lp5523_wait_opmode_done(void)
 {
usleep_range(1000, 2000);
@@ -134,7 +140,11 @@ static int lp5523_post_init_device(struct lp55xx_chip 
*chip)
if (ret)
return ret;
 
-   return lp55xx_write(chip, LP5523_REG_ENABLE_LEDS_LSB, 0xff);
+   ret = lp55xx_write(chip, LP5523_REG_ENABLE_LEDS_LSB, 0xff);
+   if (ret)
+   return ret;
+
+   return lp5523_init_program_engine(chip);
 }
 
 static void lp5523_load_engine(struct lp55xx_chip *chip)
@@ -233,6 +243,64 @@ static void lp5523_run_engine(struct lp55xx_chip *chip, 
bool start)
lp55xx_update_bits(chip, LP5523_REG_ENABLE, LP5523_EXEC_M, exec);
 }
 
+static int lp5523_init_program_engine(struct lp55xx_chip *chip)
+{
+   int i;
+   int j;
+   int ret;
+   u8 status;
+   /* one pattern per engine setting LED MUX start and stop addresses */
+   static const u8 pattern[][LP5523_PROGRAM_LENGTH] =  {
+   { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0},
+   { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
+   { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
+   };
+
+   /* hardcode 32 bytes of memory for each engine from program memory */
+   ret = lp55xx_write(chip, LP5523_REG_CH1_PROG_START, 0x00);
+   if (ret)
+   return ret;
+
+   ret = lp55xx_write(chip, LP5523_REG_CH2_PROG_START, 0x10);
+   if (ret)
+   return ret;
+
+   ret = lp55xx_write(chip, LP5523_REG_CH3_PROG_START, 0x20);
+   if (ret)
+   return ret;
+
+   /* write LED MUX address space for each engine */
+   for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) {
+   chip->engine_idx = i;
+   lp5523_load_engine_and_select_page(chip);
+
+   for (j = 0; j < LP5523_PROGRAM_LENGTH; j++) {
+   ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + j,
+   pattern[i - 1][j]);
+   if (ret)
+   goto out;
+   }
+   }
+
+   lp5523_run_engine(chip, true);
+
+   /* Let the programs run for couple of ms and check the engine status */
+   usleep_range(3000, 6000);
+   lp55xx_read(chip, LP5523_REG_STATUS, &status);
+   status &= LP5523_ENG_STATUS_MASK;
+
+   if (status != LP5523_ENG_STATUS_MASK) {
+   dev_err(&chip->cl->dev,
+   "cound not configure LED engine, status = 0x%.2x\n",
+   status);
+   ret = -1;
+   }
+
+out:
+   lp5523_stop_engine(chip);
+   return ret;
+}
+
 static int lp5523_update_program_memory(struct lp55xx_chip *chip,
const u8 *data, size_t size)
 {
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 09/10] Documentation: leds-lp5521,lp5523: update device attribute information

2013-08-08 Thread Milo Kim
Now, all legacy application interfaces are restored.
Each driver documentation is updated.

Cc: Pali Rohár 
Signed-off-by: Milo Kim 
---
 Documentation/leds/leds-lp5521.txt |   20 +++-
 Documentation/leds/leds-lp5523.txt |   21 -
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/Documentation/leds/leds-lp5521.txt 
b/Documentation/leds/leds-lp5521.txt
index 79e4c2e..d08d8c1 100644
--- a/Documentation/leds/leds-lp5521.txt
+++ b/Documentation/leds/leds-lp5521.txt
@@ -18,7 +18,25 @@ All three channels can be also controlled using the engine 
micro programs.
 More details of the instructions can be found from the public data sheet.
 
 LP5521 has the internal program memory for running various LED patterns.
-For the details, please refer to 'firmware' section in leds-lp55xx.txt
+There are two ways to run LED patterns.
+
+1) Legacy interface - enginex_mode and enginex_load
+  Control interface for the engines:
+  x is 1 .. 3
+  enginex_mode : disabled, load, run
+  enginex_load : store program (visible only in engine load mode)
+
+  Example (start to blink the channel 2 led):
+  cd   /sys/class/leds/lp5521:channel2/device
+  echo "load" > engine3_mode
+  echo "037f4d0003ff6000" > engine3_load
+  echo "run" > engine3_mode
+
+  To stop the engine:
+  echo "disabled" > engine3_mode
+
+2) Firmware interface - LP55xx common interface
+  For the details, please refer to 'firmware' section in leds-lp55xx.txt
 
 sysfs contains a selftest entry.
 The test communicates with the chip and checks that
diff --git a/Documentation/leds/leds-lp5523.txt 
b/Documentation/leds/leds-lp5523.txt
index 899fdad..5b3e91d 100644
--- a/Documentation/leds/leds-lp5523.txt
+++ b/Documentation/leds/leds-lp5523.txt
@@ -28,7 +28,26 @@ If both fields are NULL, 'lp5523' is used by default.
 /sys/class/leds/lp5523:channelN  (N: 0 ~ 8)
 
 LP5523 has the internal program memory for running various LED patterns.
-For the details, please refer to 'firmware' section in leds-lp55xx.txt
+There are two ways to run LED patterns.
+
+1) Legacy interface - enginex_mode, enginex_load and enginex_leds
+  Control interface for the engines:
+  x is 1 .. 3
+  enginex_mode : disabled, load, run
+  enginex_load : microcode load (visible only in load mode)
+  enginex_leds : led mux control (visible only in load mode)
+
+  cd /sys/class/leds/lp5523:channel2/device
+  echo "load" > engine3_mode
+  echo "9d8044ff05ff437f" > engine3_load
+  echo "1" > engine3_leds
+  echo "run" > engine3_mode
+
+  To stop the engine:
+  echo "disabled" > engine3_mode
+
+2) Firmware interface - LP55xx common interface
+  For the details, please refer to 'firmware' section in leds-lp55xx.txt
 
 Selftest uses always the current from the platform data.
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 10/10] leds: lp5562: use LP55xx common macros for device attributes

2013-08-08 Thread Milo Kim

Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp5562.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/leds/leds-lp5562.c b/drivers/leds/leds-lp5562.c
index a2c7398..2585cfd 100644
--- a/drivers/leds/leds-lp5562.c
+++ b/drivers/leds/leds-lp5562.c
@@ -477,8 +477,8 @@ static ssize_t lp5562_store_engine_mux(struct device *dev,
return len;
 }
 
-static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, lp5562_store_pattern);
-static DEVICE_ATTR(engine_mux, S_IWUSR, NULL, lp5562_store_engine_mux);
+static LP55XX_DEV_ATTR_WO(led_pattern, lp5562_store_pattern);
+static LP55XX_DEV_ATTR_WO(engine_mux, lp5562_store_engine_mux);
 
 static struct attribute *lp5562_attributes[] = {
&dev_attr_led_pattern.attr,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 02/10] leds: lp55xx: add common macros for device attributes

2013-08-08 Thread Milo Kim
This patch provides common macros for LP5521 and LP5523 device attributes and
functions.

(Device attributes)
LP5521: 'mode', 'load' and 'selftest'
LP5523: 'mode', 'load', 'leds' and 'selftest'

(Permissions)
mode: R/W
load: Write-only
leds: R/W
selftest: Read-only

Couple of lines are duplicate, so use these macros for adding device attributes
in LP5521 and LP5523 drivers.

Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp55xx-common.h |   47 +
 1 file changed, 47 insertions(+)

diff --git a/drivers/leds/leds-lp55xx-common.h 
b/drivers/leds/leds-lp55xx-common.h
index 04c1d4f..cceab48 100644
--- a/drivers/leds/leds-lp55xx-common.h
+++ b/drivers/leds/leds-lp55xx-common.h
@@ -29,6 +29,53 @@ enum lp55xx_engine_mode {
LP55XX_ENGINE_RUN,
 };
 
+#define LP55XX_DEV_ATTR_RW(name, show, store)  \
+   DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show, store)
+#define LP55XX_DEV_ATTR_RO(name, show) \
+   DEVICE_ATTR(name, S_IRUGO, show, NULL)
+#define LP55XX_DEV_ATTR_WO(name, store)\
+   DEVICE_ATTR(name, S_IWUSR, NULL, store)
+
+#define show_mode(nr)  \
+static ssize_t show_engine##nr##_mode(struct device *dev,  \
+   struct device_attribute *attr,  \
+   char *buf)  \
+{  \
+   return show_engine_mode(dev, attr, buf, nr);\
+}
+
+#define store_mode(nr) \
+static ssize_t store_engine##nr##_mode(struct device *dev, \
+struct device_attribute *attr, \
+const char *buf, size_t len)   \
+{  \
+   return store_engine_mode(dev, attr, buf, len, nr);  \
+}
+
+#define show_leds(nr)  \
+static ssize_t show_engine##nr##_leds(struct device *dev,  \
+   struct device_attribute *attr,  \
+   char *buf)  \
+{  \
+   return show_engine_leds(dev, attr, buf, nr);\
+}
+
+#define store_leds(nr) \
+static ssize_t store_engine##nr##_leds(struct device *dev, \
+struct device_attribute *attr, \
+const char *buf, size_t len)   \
+{  \
+   return store_engine_leds(dev, attr, buf, len, nr);  \
+}
+
+#define store_load(nr) \
+static ssize_t store_engine##nr##_load(struct device *dev, \
+struct device_attribute *attr, \
+const char *buf, size_t len)   \
+{  \
+   return store_engine_load(dev, attr, buf, len, nr);  \
+}
+
 struct lp55xx_led;
 struct lp55xx_chip;
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 08/10] leds: lp5523: remove unnecessary writing commands

2013-08-08 Thread Milo Kim
This patch reduces the number of programming commands.

(Count of sending commands)
Old code: 32 + program size (32 counts for clearing program memory)
New code: 32

Pattern buffer is initialized to 0 in this function.
Just update new program data and remaining buffers are filled with 0.
So it's needless to clear whole area.

Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp5523.c |   14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 9b8be6f6..fe3bcbb 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -312,17 +312,11 @@ static int lp5523_update_program_memory(struct 
lp55xx_chip *chip,
u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
unsigned cmd;
char c[3];
-   int update_size;
int nrchars;
-   int offset = 0;
int ret;
-   int i;
-
-   /* clear program memory before updating */
-   for (i = 0; i < LP5523_PROGRAM_LENGTH; i++)
-   lp55xx_write(chip, LP5523_REG_PROG_MEM + i, 0);
+   int offset = 0;
+   int i = 0;
 
-   i = 0;
while ((offset < size - 1) && (i < LP5523_PROGRAM_LENGTH)) {
/* separate sscanfs because length is working only for %s */
ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
@@ -342,11 +336,9 @@ static int lp5523_update_program_memory(struct lp55xx_chip 
*chip,
if (i % 2)
goto err;
 
-   update_size = i;
-
mutex_lock(&chip->lock);
 
-   for (i = 0; i < update_size; i++) {
+   for (i = 0; i < LP5523_PROGRAM_LENGTH; i++) {
ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + i, pattern[i]);
if (ret) {
mutex_unlock(&chip->lock);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 07/10] leds: lp5523: restore legacy device attributes

2013-08-08 Thread Milo Kim
git commit db6eaf8388a413a5ee1b4547ce78506b9c6456b0
(leds-lp5523: use generic firmware interface) causes an application conflict.
This interface should be maintained for compatibility.

Restored device attributes are 'engineN_mode', 'engineN_load' and
'engineN_leds'. (N = 1, 2 or 3)
A 'selftest' attribute macro is replaced with LP55xx common macro.
Those are accessed when a LED pattern is run by an application.

Use a mutex in lp5523_update_program_memory()
: This function is called when an user-application writes a 'engineN_load' file
or pattern data is loaded from generic firmware interface.
So, writing program memory should be protected.
If an error occurs on accessing this area, just it returns as -EINVAL quickly.
This error code is exact same as old driver function, lp5523_do_store_load()
because it should be kept for an user-application compatibility.
Even the driver is changed, we can use the application without re-compiling
sources.

Reported-by: Pali Rohár 
Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp5523.c |  227 +++-
 1 file changed, 223 insertions(+), 4 deletions(-)

diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 29c8b19..9b8be6f6 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -74,6 +74,9 @@
 #define LP5523_PAGE_ENG1   0
 #define LP5523_PAGE_ENG2   1
 #define LP5523_PAGE_ENG3   2
+#define LP5523_PAGE_MUX1   3
+#define LP5523_PAGE_MUX2   4
+#define LP5523_PAGE_MUX3   5
 
 /* Program Memory Operations */
 #define LP5523_MODE_ENG1_M 0x30/* Operation Mode Register */
@@ -98,6 +101,8 @@
 #define LP5523_RUN_ENG20x08
 #define LP5523_RUN_ENG30x02
 
+#define LED_ACTIVE(mux, led)   (!!(mux & (0x0001 << led)))
+
 enum lp5523_chip_id {
LP5523,
LP55231,
@@ -338,10 +343,20 @@ static int lp5523_update_program_memory(struct 
lp55xx_chip *chip,
goto err;
 
update_size = i;
-   for (i = 0; i < update_size; i++)
-   lp55xx_write(chip, LP5523_REG_PROG_MEM + i, pattern[i]);
 
-   return 0;
+   mutex_lock(&chip->lock);
+
+   for (i = 0; i < update_size; i++) {
+   ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + i, pattern[i]);
+   if (ret) {
+   mutex_unlock(&chip->lock);
+   return -EINVAL;
+   }
+   }
+
+   mutex_unlock(&chip->lock);
+
+   return size;
 
 err:
dev_err(&chip->cl->dev, "wrong pattern format\n");
@@ -368,6 +383,192 @@ static void lp5523_firmware_loaded(struct lp55xx_chip 
*chip)
lp5523_update_program_memory(chip, fw->data, fw->size);
 }
 
+static ssize_t show_engine_mode(struct device *dev,
+   struct device_attribute *attr,
+   char *buf, int nr)
+{
+   struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
+   struct lp55xx_chip *chip = led->chip;
+   enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode;
+
+   switch (mode) {
+   case LP55XX_ENGINE_RUN:
+   return sprintf(buf, "run\n");
+   case LP55XX_ENGINE_LOAD:
+   return sprintf(buf, "load\n");
+   case LP55XX_ENGINE_DISABLED:
+   default:
+   return sprintf(buf, "disabled\n");
+   }
+}
+show_mode(1)
+show_mode(2)
+show_mode(3)
+
+static ssize_t store_engine_mode(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t len, int nr)
+{
+   struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
+   struct lp55xx_chip *chip = led->chip;
+   struct lp55xx_engine *engine = &chip->engines[nr - 1];
+
+   mutex_lock(&chip->lock);
+
+   chip->engine_idx = nr;
+
+   if (!strncmp(buf, "run", 3)) {
+   lp5523_run_engine(chip, true);
+   engine->mode = LP55XX_ENGINE_RUN;
+   } else if (!strncmp(buf, "load", 4)) {
+   lp5523_stop_engine(chip);
+   lp5523_load_engine(chip);
+   engine->mode = LP55XX_ENGINE_LOAD;
+   } else if (!strncmp(buf, "disabled", 8)) {
+   lp5523_stop_engine(chip);
+   engine->mode = LP55XX_ENGINE_DISABLED;
+   }
+
+   mutex_unlock(&chip->lock);
+
+   return len;
+}
+store_mode(1)
+store_mode(2)
+store_mode(3)
+
+static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len)
+{
+   u16 tmp_mux = 0;
+   int i;
+
+   len = min_t(int, len, LP5523_MAX_LEDS);
+
+   for (i = 0; i < len; i++) {
+   switch (buf[i]) {

[PATCH 04/10] leds: lp5521: remove unnecessary writing commands

2013-08-08 Thread Milo Kim
This patch reduces the number of programming commands.

(Count of sending commands)
Old code: 32 + program size (32 counts for clearing program memory)
New code: 32

Pattern buffer is initialized to 0 in this function.
Just update new program data and remaining buffers are filled with 0.
So it's needless to clear whole area.

Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp5521.c |   14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index c00f922..0518835 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -220,17 +220,11 @@ static int lp5521_update_program_memory(struct 
lp55xx_chip *chip,
};
unsigned cmd;
char c[3];
-   int program_size;
int nrchars;
-   int offset = 0;
int ret;
-   int i;
-
-   /* clear program memory before updating */
-   for (i = 0; i < LP5521_PROGRAM_LENGTH; i++)
-   lp55xx_write(chip, addr[idx] + i, 0);
+   int offset = 0;
+   int i = 0;
 
-   i = 0;
while ((offset < size - 1) && (i < LP5521_PROGRAM_LENGTH)) {
/* separate sscanfs because length is working only for %s */
ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
@@ -250,11 +244,9 @@ static int lp5521_update_program_memory(struct lp55xx_chip 
*chip,
if (i % 2)
goto err;
 
-   program_size = i;
-
mutex_lock(&chip->lock);
 
-   for (i = 0; i < program_size; i++) {
+   for (i = 0; i < LP5521_PROGRAM_LENGTH; i++) {
ret = lp55xx_write(chip, addr[idx] + i, pattern[i]);
if (ret) {
mutex_unlock(&chip->lock);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 05/10] leds: lp5523: make separate API for loading engine

2013-08-08 Thread Milo Kim
lp5523_load_engine()
  It is called whenever the operation mode is changed to 'load'.
  It is used for simple operation mode change.
  It will be used when engine mode and LED selection is updated in later patch.

lp5523_load_engine_and_select_page()
  Change the operation mode to 'load' and select program page number.
  This is used for programming a LED pattern at a time.
  So load_engine() is replaced with new API, load_engine_and_select_page()
  in lp5523_firmware_loaded().

Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp5523.c |   14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 72c10e2..b509480 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -152,15 +152,21 @@ static void lp5523_load_engine(struct lp55xx_chip *chip)
[LP55XX_ENGINE_3] = LP5523_LOAD_ENG3,
};
 
+   lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], val[idx]);
+
+   lp5523_wait_opmode_done();
+}
+
+static void lp5523_load_engine_and_select_page(struct lp55xx_chip *chip)
+{
+   enum lp55xx_engine_index idx = chip->engine_idx;
u8 page_sel[] = {
[LP55XX_ENGINE_1] = LP5523_PAGE_ENG1,
[LP55XX_ENGINE_2] = LP5523_PAGE_ENG2,
[LP55XX_ENGINE_3] = LP5523_PAGE_ENG3,
};
 
-   lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], val[idx]);
-
-   lp5523_wait_opmode_done();
+   lp5523_load_engine(chip);
 
lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, page_sel[idx]);
 }
@@ -290,7 +296,7 @@ static void lp5523_firmware_loaded(struct lp55xx_chip *chip)
 *  2) write firmware data into program memory
 */
 
-   lp5523_load_engine(chip);
+   lp5523_load_engine_and_select_page(chip);
lp5523_update_program_memory(chip, fw->data, fw->size);
 }
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 03/10] leds: lp5521: restore legacy device attributes

2013-08-08 Thread Milo Kim
git commit 9ce7cb170f97f83a78dc948bf7d25690f15e1328
may cause an application confict, engineN_mode and engineN_load.
This interface should be maintained for compatibility.

Restored device attributes are 'engineN_mode' and 'engineN_load'.
A 'selftest' attribute macro is replaced with LP55xx common macro.

Use a mutex in lp5521_update_program_memory()
: This function is called when an user-application writes a 'engineN_load' file
or pattern data is loaded from generic firmware interface.
So, writing program memory should be protected.
If an error occurs on accessing this area, just it returns as -EINVAL quickly.
This error code is exact same as old driver function, lp5521_do_store_load()
because it should be kept for an user-application compatibility.
Even the driver is changed, we can use the application without re-compiling
sources.

'led_pattern' attribute is not included
: engineN_mode and _load were created for custom user-application.
'led_pattern' is an exception. I added this attribute not for custom application
but for simple test. Now it is used only in LP5562 driver, not LP5521.

Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp5521.c |  104 ++--
 1 file changed, 100 insertions(+), 4 deletions(-)

diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 9e28dd0..c00f922 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -251,10 +251,20 @@ static int lp5521_update_program_memory(struct 
lp55xx_chip *chip,
goto err;
 
program_size = i;
-   for (i = 0; i < program_size; i++)
-   lp55xx_write(chip, addr[idx] + i, pattern[i]);
 
-   return 0;
+   mutex_lock(&chip->lock);
+
+   for (i = 0; i < program_size; i++) {
+   ret = lp55xx_write(chip, addr[idx] + i, pattern[i]);
+   if (ret) {
+   mutex_unlock(&chip->lock);
+   return -EINVAL;
+   }
+   }
+
+   mutex_unlock(&chip->lock);
+
+   return size;
 
 err:
dev_err(&chip->cl->dev, "wrong pattern format\n");
@@ -365,6 +375,80 @@ static void lp5521_led_brightness_work(struct work_struct 
*work)
mutex_unlock(&chip->lock);
 }
 
+static ssize_t show_engine_mode(struct device *dev,
+   struct device_attribute *attr,
+   char *buf, int nr)
+{
+   struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
+   struct lp55xx_chip *chip = led->chip;
+   enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode;
+
+   switch (mode) {
+   case LP55XX_ENGINE_RUN:
+   return sprintf(buf, "run\n");
+   case LP55XX_ENGINE_LOAD:
+   return sprintf(buf, "load\n");
+   case LP55XX_ENGINE_DISABLED:
+   default:
+   return sprintf(buf, "disabled\n");
+   }
+}
+show_mode(1)
+show_mode(2)
+show_mode(3)
+
+static ssize_t store_engine_mode(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t len, int nr)
+{
+   struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
+   struct lp55xx_chip *chip = led->chip;
+   struct lp55xx_engine *engine = &chip->engines[nr - 1];
+
+   mutex_lock(&chip->lock);
+
+   chip->engine_idx = nr;
+
+   if (!strncmp(buf, "run", 3)) {
+   lp5521_run_engine(chip, true);
+   engine->mode = LP55XX_ENGINE_RUN;
+   } else if (!strncmp(buf, "load", 4)) {
+   lp5521_stop_engine(chip);
+   lp5521_load_engine(chip);
+   engine->mode = LP55XX_ENGINE_LOAD;
+   } else if (!strncmp(buf, "disabled", 8)) {
+   lp5521_stop_engine(chip);
+   engine->mode = LP55XX_ENGINE_DISABLED;
+   }
+
+   mutex_unlock(&chip->lock);
+
+   return len;
+}
+store_mode(1)
+store_mode(2)
+store_mode(3)
+
+static ssize_t store_engine_load(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t len, int nr)
+{
+   struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
+   struct lp55xx_chip *chip = led->chip;
+
+   mutex_lock(&chip->lock);
+
+   chip->engine_idx = nr;
+   lp5521_load_engine(chip);
+
+   mutex_unlock(&chip->lock);
+
+   return lp5521_update_program_memory(chip, buf, len);
+}
+store_load(1)
+store_load(2)
+store_load(3)
+
 static ssize_t lp5521_selftest(struct device *dev,
   struct device_attribute *attr,
   char *buf)
@@ -381,9 +465,21 @@ static ssize_t lp5521_selftest(struct device *d

[PATCH 01/10] leds: lp55xx: add common data structure for program

2013-08-08 Thread Milo Kim
LP55xx family devices have internal three program engines which are used for
loading LED patterns.
To maintain legacy device attributes, specific data structure is used, 'mode'
and 'led_mux'.
The mode is used for showing/storing current engine mode such like disabled,
load and run.
Then led_mux is used for showing/storing current output LED selection.
This is only for LP5523/55231.

Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp55xx-common.h |   19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/leds/leds-lp55xx-common.h 
b/drivers/leds/leds-lp55xx-common.h
index dbbf86d..04c1d4f 100644
--- a/drivers/leds/leds-lp55xx-common.h
+++ b/drivers/leds/leds-lp55xx-common.h
@@ -20,6 +20,13 @@ enum lp55xx_engine_index {
LP55XX_ENGINE_1,
LP55XX_ENGINE_2,
LP55XX_ENGINE_3,
+   LP55XX_ENGINE_MAX = LP55XX_ENGINE_3,
+};
+
+enum lp55xx_engine_mode {
+   LP55XX_ENGINE_DISABLED,
+   LP55XX_ENGINE_LOAD,
+   LP55XX_ENGINE_RUN,
 };
 
 struct lp55xx_led;
@@ -72,6 +79,16 @@ struct lp55xx_device_config {
 };
 
 /*
+ * struct lp55xx_engine
+ * @mode   : Engine mode
+ * @led_mux: Mux bits for LED selection. Only used in LP5523
+ */
+struct lp55xx_engine {
+   enum lp55xx_engine_mode mode;
+   u16 led_mux;
+};
+
+/*
  * struct lp55xx_chip
  * @cl : I2C communication for access registers
  * @pdata  : Platform specific data
@@ -79,6 +96,7 @@ struct lp55xx_device_config {
  * @num_leds   : Number of registered LEDs
  * @cfg: Device specific configuration data
  * @engine_idx : Selected engine number
+ * @engines: Engine structure for the device attribute R/W interface
  * @fw : Firmware data for running a LED pattern
  */
 struct lp55xx_chip {
@@ -89,6 +107,7 @@ struct lp55xx_chip {
int num_leds;
struct lp55xx_device_config *cfg;
enum lp55xx_engine_index engine_idx;
+   struct lp55xx_engine engines[LP55XX_ENGINE_MAX];
const struct firmware *fw;
 };
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4] ARM: dts: exynos: Enable HDMI for Arndale Octa board

2016-08-30 Thread Milo Kim
* GPIO for HDMI hot plug detect
  GPX3_7 is used. The HPD awareness is done when the GPIO is active high.

* Enable HDMI block in Exynos5420
  HDMI VDD and PLL consume 1.0V LDO6 (PVDD_ANAIP_1V0) and HDMI oscillator
  requires 1.8V LDO7 (PVDD_ANAIP_1V8).

* Support HDMI display data channel
  I2C #2 is assigned for the HDMI DDC. It enables the EDID access.

Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: Rob Herring 
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 arch/arm/boot/dts/exynos5420-arndale-octa.dts | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts 
b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index 39a3b81..d2ad48e 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -70,6 +70,15 @@
status = "disabled";
 };
 
+&hdmi {
+   hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+   vdd_osc-supply = <&ldo7_reg>;
+   vdd_pll-supply = <&ldo6_reg>;
+   vdd-supply = <&ldo6_reg>;
+   ddc = <&i2c_2>;
+   status = "okay";
+};
+
 &hsi2c_4 {
status = "okay";
 
@@ -347,6 +356,10 @@
};
 };
 
+&i2c_2 {
+   status = "okay";
+};
+
 &mmc_0 {
status = "okay";
broken-cd;
-- 
2.9.3



[PATCH v4 1/3] gpu: drm: exynos_hdmi: Move DDC logic into single function

2016-08-30 Thread Milo Kim
Paring DT properties and getting the I2C adapter in one function.

Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: dri-de...@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 46 
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 2275efe..1440dfd 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1760,16 +1760,34 @@ static const struct component_ops hdmi_component_ops = {
.unbind = hdmi_unbind,
 };
 
-static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
+static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
 {
const char *compatible_str = "samsung,exynos4210-hdmiddc";
struct device_node *np;
+   struct i2c_adapter *adpt;
 
np = of_find_compatible_node(NULL, NULL, compatible_str);
if (np)
-   return of_get_next_parent(np);
+   np = of_get_next_parent(np);
+   else
+   np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
+
+   if (!np) {
+   DRM_ERROR("Failed to find ddc node in device tree\n");
+   return -ENODEV;
+   }
+
+   adpt = of_find_i2c_adapter_by_node(np);
+   of_node_put(np);
 
-   return NULL;
+   if (!adpt) {
+   DRM_INFO("Failed to get ddc i2c adapter by node\n");
+   return -EPROBE_DEFER;
+   }
+
+   hdata->ddc_adpt = adpt;
+
+   return 0;
 }
 
 static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
@@ -1781,7 +1799,7 @@ static struct device_node 
*hdmi_legacy_phy_dt_binding(struct device *dev)
 
 static int hdmi_probe(struct platform_device *pdev)
 {
-   struct device_node *ddc_node, *phy_node;
+   struct device_node *phy_node;
struct device *dev = &pdev->dev;
struct hdmi_context *hdata;
struct resource *res;
@@ -1811,23 +1829,9 @@ static int hdmi_probe(struct platform_device *pdev)
return ret;
}
 
-   ddc_node = hdmi_legacy_ddc_dt_binding(dev);
-   if (ddc_node)
-   goto out_get_ddc_adpt;
-
-   ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
-   if (!ddc_node) {
-   DRM_ERROR("Failed to find ddc node in device tree\n");
-   return -ENODEV;
-   }
-   of_node_put(dev->of_node);
-
-out_get_ddc_adpt:
-   hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
-   if (!hdata->ddc_adpt) {
-   DRM_ERROR("Failed to get ddc i2c adapter by node\n");
-   return -EPROBE_DEFER;
-   }
+   ret = hdmi_get_ddc_adapter(hdata);
+   if (ret)
+   return ret;
 
phy_node = hdmi_legacy_phy_dt_binding(dev);
if (phy_node)
-- 
2.9.3



[PATCH v4 0/3] gpu: drm: exynos_hdmi: Code refactoring on hdmi ddc and phy

2016-08-30 Thread Milo Kim
v4:
  Only DRM patchset is sent, DTS patch was sent separately.

Milo Kim (3):
  gpu: drm: exynos_hdmi: Move DDC logic into single function
  gpu: drm: exynos_hdmi: Move PHY logic into single function
  gpu: drm: exynos_hdmi: Remove duplicate initialization of regulator
bulk consumer

 drivers/gpu/drm/exynos/exynos_hdmi.c | 112 ++-
 1 file changed, 59 insertions(+), 53 deletions(-)

-- 
2.9.3



[PATCH v4 3/3] gpu: drm: exynos_hdmi: Remove duplicate initialization of regulator bulk consumer

2016-08-30 Thread Milo Kim
The helper, devm_regulator_bulk_get() initializes the consumer as NULL,
so this code can be ignored.

Reviewed-by: Andrzej Hajda 
Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: dri-de...@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 42b0b98..e8fb6ef 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1669,10 +1669,9 @@ static int hdmi_resources_init(struct hdmi_context 
*hdata)
if (ret)
return ret;
 
-   for (i = 0; i < ARRAY_SIZE(supply); ++i) {
+   for (i = 0; i < ARRAY_SIZE(supply); ++i)
hdata->regul_bulk[i].supply = supply[i];
-   hdata->regul_bulk[i].consumer = NULL;
-   }
+
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), 
hdata->regul_bulk);
if (ret) {
if (ret != -EPROBE_DEFER)
-- 
2.9.3



[PATCH v4 2/3] gpu: drm: exynos_hdmi: Move PHY logic into single function

2016-08-30 Thread Milo Kim
Paring DT properties and getting PHY IO (memory mapped or I2C) in one
function.

Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: dri-de...@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 63 +++-
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 1440dfd..42b0b98 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1790,16 +1790,44 @@ static int hdmi_get_ddc_adapter(struct hdmi_context 
*hdata)
return 0;
 }
 
-static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
+static int hdmi_get_phy_io(struct hdmi_context *hdata)
 {
const char *compatible_str = "samsung,exynos4212-hdmiphy";
+   struct device_node *np;
+   int ret = 0;
+
+   np = of_find_compatible_node(NULL, NULL, compatible_str);
+   if (!np) {
+   np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
+   if (!np) {
+   DRM_ERROR("Failed to find hdmiphy node in device 
tree\n");
+   return -ENODEV;
+   }
+   }
+
+   if (hdata->drv_data->is_apb_phy) {
+   hdata->regs_hdmiphy = of_iomap(np, 0);
+   if (!hdata->regs_hdmiphy) {
+   DRM_ERROR("failed to ioremap hdmi phy\n");
+   ret = -ENOMEM;
+   goto out;
+   }
+   } else {
+   hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
+   if (!hdata->hdmiphy_port) {
+   DRM_INFO("Failed to get hdmi phy i2c client\n");
+   ret = -EPROBE_DEFER;
+   goto out;
+   }
+   }
 
-   return of_find_compatible_node(NULL, NULL, compatible_str);
+out:
+   of_node_put(np);
+   return ret;
 }
 
 static int hdmi_probe(struct platform_device *pdev)
 {
-   struct device_node *phy_node;
struct device *dev = &pdev->dev;
struct hdmi_context *hdata;
struct resource *res;
@@ -1833,34 +1861,9 @@ static int hdmi_probe(struct platform_device *pdev)
if (ret)
return ret;
 
-   phy_node = hdmi_legacy_phy_dt_binding(dev);
-   if (phy_node)
-   goto out_get_phy_port;
-
-   phy_node = of_parse_phandle(dev->of_node, "phy", 0);
-   if (!phy_node) {
-   DRM_ERROR("Failed to find hdmiphy node in device tree\n");
-   ret = -ENODEV;
+   ret = hdmi_get_phy_io(hdata);
+   if (ret)
goto err_ddc;
-   }
-   of_node_put(dev->of_node);
-
-out_get_phy_port:
-   if (hdata->drv_data->is_apb_phy) {
-   hdata->regs_hdmiphy = of_iomap(phy_node, 0);
-   if (!hdata->regs_hdmiphy) {
-   DRM_ERROR("failed to ioremap hdmi phy\n");
-   ret = -ENOMEM;
-   goto err_ddc;
-   }
-   } else {
-   hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
-   if (!hdata->hdmiphy_port) {
-   DRM_ERROR("Failed to get hdmi phy i2c client\n");
-   ret = -EPROBE_DEFER;
-   goto err_ddc;
-   }
-   }
 
INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
 
-- 
2.9.3



Re: [PATCH v3 1/5] ARM: dts: exynos: Enable HDMI for Arndale Octa board

2016-08-30 Thread Milo Kim

Hi Krzysztof,

On 08/25/2016 04:05 AM, Krzysztof Kozlowski wrote:

First of all - it looks like these DTS patches do not depend on DRM
part, do they?


I just sent the v4 patch for DTS. DRM patch-set was sent separately. 
Thanks for your advise.


Best regards,
Milo


[PATCH v2 1/4] ARM: dts: sun8i: Add PWM pin in H3

2016-08-31 Thread Milo Kim
H3 PA5 pin is assigned for single PWM channel.

Cc: Rob Herring 
Cc: Maxime Ripard 
Cc: Chen-Yu Tsai 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index fdf9fdb..05d0c4b 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -360,6 +360,13 @@
allwinner,pull = ;
};
 
+   pwm0_pin_a: pwm0@0 {
+   allwinner,pins = "PA5";
+   allwinner,function = "pwm0";
+   allwinner,drive = ;
+   allwinner,pull = ;
+   };
+
uart0_pins_a: uart0@0 {
allwinner,pins = "PA4", "PA5";
allwinner,function = "uart0";
-- 
2.9.3



[PATCH v2 4/4] pwm: sunxi: Add H3 support

2016-08-31 Thread Milo Kim
H3 PWM controller has same register layout as sun4i driver, so it works
by adding H3 specific data.

Cc: Thierry Reding 
Cc: Rob Herring 
Cc: Maxime Ripard 
Cc: Alexandre Belloni 
Cc: Chen-Yu Tsai 
Cc: linux-...@vger.kernel.org
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 Documentation/devicetree/bindings/pwm/pwm-sun4i.txt | 1 +
 drivers/pwm/pwm-sun4i.c | 9 +
 2 files changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt 
b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
index cf6068b..f1cbeef 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
@@ -6,6 +6,7 @@ Required properties:
 - "allwinner,sun5i-a10s-pwm"
 - "allwinner,sun5i-a13-pwm"
 - "allwinner,sun7i-a20-pwm"
+- "allwinner,sun8i-h3-pwm"
   - reg: physical base address and length of the controller's registers
   - #pwm-cells: should be 3. See pwm.txt in this directory for a description of
 the cells format.
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 03a99a5..b0803f6 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -284,6 +284,12 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
.npwm = 2,
 };
 
+static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
+   .has_prescaler_bypass = true,
+   .has_rdy = true,
+   .npwm = 1,
+};
+
 static const struct of_device_id sun4i_pwm_dt_ids[] = {
{
.compatible = "allwinner,sun4i-a10-pwm",
@@ -298,6 +304,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
.compatible = "allwinner,sun7i-a20-pwm",
.data = &sun4i_pwm_data_a20,
}, {
+   .compatible = "allwinner,sun8i-h3-pwm",
+   .data = &sun4i_pwm_data_h3,
+   }, {
/* sentinel */
},
 };
-- 
2.9.3



[PATCH v2 2/4] ARM: dts: sun8i: Add PWM controller node in H3

2016-08-31 Thread Milo Kim
Cc: Rob Herring 
Cc: Maxime Ripard 
Cc: Chen-Yu Tsai 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 05d0c4b..860e355 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -396,6 +396,14 @@
interrupts = ;
};
 
+   pwm: pwm@01c21400 {
+   compatible = "allwinner,sun8i-h3-pwm";
+   reg = <0x01c21400 0x8>;
+   clocks = <&osc24M>;
+   #pwm-cells = <3>;
+   status = "disabled";
+   };
+
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
-- 
2.9.3



[PATCH v2 3/4] pinctrl: sunxi: Remove unsupported PWM channel pinmux in H3

2016-08-31 Thread Milo Kim
H3 has single PWM channel. The second PWM channel is not supported,
so the pinctrl function should be removed.

Cc: Linus Walleij 
Cc: Maxime Ripard 
Cc: Chen-Yu Tsai 
Cc: Icenowy Zheng 
Cc: Jens Kuske 
Cc: Krzysztof Adamski 
Cc: linux-g...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c 
b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
index 26a2ad3..518a92d 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
@@ -60,7 +60,6 @@ static const struct sunxi_desc_pin sun8i_h3_pins[] = {
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
  SUNXI_FUNCTION(0x2, "sim"),   /* PWREN */
- SUNXI_FUNCTION(0x3, "pwm1"),
  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),  /* PA_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
  SUNXI_FUNCTION(0x0, "gpio_in"),
-- 
2.9.3



Re: [PATCH 2/2] ARM: dts: sun8i-h3: Add UART1 pinctrl

2016-08-31 Thread Milo Kim

Hi Maxime,

On 08/26/2016 04:10 PM, Maxime Ripard wrote:

Hi Milo,

On Thu, Aug 25, 2016 at 03:44:54PM +0900, Milo Kim wrote:

In H3, PA5 can be used as PWM and UART0. If the PWM is used, the console
UART should be moved to other port.
This patch enables UART1 pinctrl to support this case.

PA5: PWM
PG6, PG7: debug console

Cc: Chen-Yu Tsai 
Cc: Maxime Ripard 
Cc: Rob Herring 
Signed-off-by: Milo Kim 
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 3a965fb..fdb6801 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -526,6 +526,13 @@
allwinner,pull = ;
};

+   uart1_pins_a: uart1@0 {
+   allwinner,pins = "PG6", "PG7";
+   allwinner,function = "uart1";
+   allwinner,drive = ;
+   allwinner,pull = ;
+   };
+


Our policy is that we don't introduce new pinctrl nodes that are not
used by any board to avoid bloating the DT too much with unused nodes.

If you have a board using it, please submit that change as well.


UART1 was already added in sun8i-h3.dtsi, so I drop this change in v2.

Commit-ID: 966c11a3b5e4

Best regards,
Milo


[PATCH v2 0/4] Add PWM feature in Allwinner H3

2016-08-31 Thread Milo Kim
According to the latest datasheet, H3 has single PWM channel.
H3 PWM controller has same register layout as sun4i driver, so it works 
by adding H3 specific data.
And the second PWM channel is not supported, so the pinctrl function is removed.

Datasheet:
  http://linux-sunxi.org/File:Allwinner_H3_Datasheet_V1.2.pdf

Test environment:
  Tested on Nano Pi M1 board, but PA5 pin is assigned for UART0.
  So the debug console should be changed to other port like UART1.

  Ex)
aliases {
serial0 = &uart1;
};

&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins_a>;
status = "okay";
};

v2:
  Split v1 patch-set into several patches

Milo Kim (4):
  ARM: dts: sun8i: Add PWM pin in H3
  ARM: dts: sun8i: Add PWM controller node in H3
  pinctrl: sunxi: Remove unsupported PWM channel pinmux in H3
  pwm: sunxi: Add H3 support

 Documentation/devicetree/bindings/pwm/pwm-sun4i.txt |  1 +
 arch/arm/boot/dts/sun8i-h3.dtsi | 15 +++
 drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c|  1 -
 drivers/pwm/pwm-sun4i.c |  9 +
 4 files changed, 25 insertions(+), 1 deletion(-)

-- 
2.9.3



Re: [PATCH v2 1/4] ARM: dts: sun8i: Add PWM pin in H3

2016-09-01 Thread Milo Kim

On 08/31/2016 05:33 PM, Chen-Yu Tsai wrote:

+   pwm0_pin_a: pwm0@0 {

This is the only possible configuration. You can drop the _a suffix
from the label, and @0 from the node name.


OK, thanks for your review.

Best regards,
Milo


Re: [PATCH v2 1/4] ARM: dts: sun8i: Add PWM pin in H3

2016-09-01 Thread Milo Kim

On 09/01/2016 01:20 AM, Maxime Ripard wrote:

Hi Milo,

On Wed, Aug 31, 2016 at 05:25:17PM +0900, Milo Kim wrote:

H3 PA5 pin is assigned for single PWM channel.

Cc: Rob Herring 
Cc: Maxime Ripard 
Cc: Chen-Yu Tsai 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index fdf9fdb..05d0c4b 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -360,6 +360,13 @@
allwinner,pull = ;
};

+   pwm0_pin_a: pwm0@0 {
+   allwinner,pins = "PA5";
+   allwinner,function = "pwm0";
+   allwinner,drive = ;
+   allwinner,pull = ;
+   };
+


Is it used on any boards?

If not, we have the policy of not merging the pinctrl nodes that are
not used by anyone to avoid bloating the DT for no particular reason.


Yes, I have. It's Nano Pi M1 which was derived from Orange Pi PC.
The board DTS is ready to be sent out, but I'm not sure which is better.

a) Send new board DTS file in other patch thread

[PATCH v3 0/4] Add PWM feature in Allwinner H3
[PATCH v3 1/4] ARM: dts: sun8i: Add PWM pin in H3
..
[PATCH v3 4/4] pwm: sunxi: Add H3 support

[PATCH] ARM: dts: sun8i: Add Nano Pi M1 support

Or

b) Include the DTS in next patch-set v3
[PATCH v3 0/4] Add PWM feature in Allwinner H3
[PATCH v3 1/4] ARM: dts: sun8i: Add PWM pin in H3
[PATCH v3 2/4] ARM: dts: sun8i: Add PWM controller node in H3
[PATCH v3 3/4] ARM: dts: sun8i: Add Nano Pi M1 support
...

I'd like to have your opinion.

Best regards,
Milo


[PATCH v2 1/4] ARM: dts: exynos: Enable HDMI for Arndale Octa board

2016-08-23 Thread Milo Kim
* Support HDMI display data channel
  I2C #2 is assigned for the HDMI DDC. It enables the EDID access.

* GPIO for HDMI hot plug detect
  GPX3_7 is used. The HPD awareness is done when the GPIO is active high and
  single ended.

* Enable HDMI block in Exynos5420
  HDMI PLL consumes 1.0V LDO6 (PVDD_ANAIP_1V0) and HDMI oscillator requires
  1.8V LDO7 (PVDD_ANAIP_1V8).

Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: David Airlie 
Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Rob Herring 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: Milo Kim 
---
 arch/arm/boot/dts/exynos5420-arndale-octa.dts | 17 +
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts 
b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index 39a3b81..df362a2 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -70,6 +70,23 @@
status = "disabled";
 };
 
+&i2c_2 {
+   samsung,i2c-slave-addr = <0x50>;
+   status = "okay";
+
+   hdmiddc@50 {
+   compatible = "samsung,exynos4210-hdmiddc";
+   reg = <0x50>;
+   };
+};
+
+&hdmi {
+   hpd-gpios = <&gpx3 7 GPIO_OPEN_SOURCE>;
+   vdd_osc-supply = <&ldo7_reg>;
+   vdd_pll-supply = <&ldo6_reg>;
+   status = "okay";
+};
+
 &hsi2c_4 {
status = "okay";
 
-- 
1.9.1



[PATCH v2 3/4] gpu: drm: exynos_hdmi: Use consolidated function on binding DDC DT property

2016-08-23 Thread Milo Kim
Handle legacy and raw 'ddc' parsing in single function.
And it also removes goto condition.

Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: David Airlie 
Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Rob Herring 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: Milo Kim 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 2275efe..6a636f2 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1760,7 +1760,7 @@ static const struct component_ops hdmi_component_ops = {
.unbind = hdmi_unbind,
 };
 
-static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
+static struct device_node *hdmi_ddc_dt_binding(struct device *dev)
 {
const char *compatible_str = "samsung,exynos4210-hdmiddc";
struct device_node *np;
@@ -1769,7 +1769,13 @@ static struct device_node 
*hdmi_legacy_ddc_dt_binding(struct device *dev)
if (np)
return of_get_next_parent(np);
 
-   return NULL;
+   np = of_parse_phandle(dev->of_node, "ddc", 0);
+   if (!np)
+   return NULL;
+
+   of_node_put(dev->of_node);
+
+   return np;
 }
 
 static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
@@ -1811,18 +1817,12 @@ static int hdmi_probe(struct platform_device *pdev)
return ret;
}
 
-   ddc_node = hdmi_legacy_ddc_dt_binding(dev);
-   if (ddc_node)
-   goto out_get_ddc_adpt;
-
-   ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
+   ddc_node = hdmi_ddc_dt_binding(dev);
if (!ddc_node) {
DRM_ERROR("Failed to find ddc node in device tree\n");
return -ENODEV;
}
-   of_node_put(dev->of_node);
 
-out_get_ddc_adpt:
hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
if (!hdata->ddc_adpt) {
DRM_ERROR("Failed to get ddc i2c adapter by node\n");
-- 
1.9.1



[PATCH v2 4/4] gpu: drm: exynos_hdmi: Use consolidated function on binding PHY DT property

2016-08-23 Thread Milo Kim
Handle legacy and raw 'phy' parsing in single function.
And it also removes goto condition.

Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: David Airlie 
Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Rob Herring 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: Milo Kim 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 6a636f2..bb2d6d4 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1778,11 +1778,22 @@ static struct device_node *hdmi_ddc_dt_binding(struct 
device *dev)
return np;
 }
 
-static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
+static struct device_node *hdmi_phy_dt_binding(struct device *dev)
 {
const char *compatible_str = "samsung,exynos4212-hdmiphy";
+   struct device_node *np;
+
+   np = of_find_compatible_node(NULL, NULL, compatible_str);
+   if (np)
+   return np;
+
+   np = of_parse_phandle(dev->of_node, "phy", 0);
+   if (!np)
+   return NULL;
+
+   of_node_put(dev->of_node);
 
-   return of_find_compatible_node(NULL, NULL, compatible_str);
+   return np;
 }
 
 static int hdmi_probe(struct platform_device *pdev)
@@ -1829,19 +1840,13 @@ static int hdmi_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}
 
-   phy_node = hdmi_legacy_phy_dt_binding(dev);
-   if (phy_node)
-   goto out_get_phy_port;
-
-   phy_node = of_parse_phandle(dev->of_node, "phy", 0);
+   phy_node = hdmi_phy_dt_binding(dev);
if (!phy_node) {
DRM_ERROR("Failed to find hdmiphy node in device tree\n");
ret = -ENODEV;
goto err_ddc;
}
-   of_node_put(dev->of_node);
 
-out_get_phy_port:
if (hdata->drv_data->is_apb_phy) {
hdata->regs_hdmiphy = of_iomap(phy_node, 0);
if (!hdata->regs_hdmiphy) {
-- 
1.9.1



[PATCH v2 2/4] ARM: dts: exynos: Use 'hpd-gpios' instead of 'hpd-gpio'

2016-08-23 Thread Milo Kim
This patch enables getting a HPD GPIO descriptor quickly.
The exynos-hdmi driver uses "hpd" for HDMI hot plug detection.

static int hdmi_resources_init(struct hdmi_context *hdata)
{
...
hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
...
}

This calls 'of_find_gpio()' and it generates the GPIO consumer ID by referring
GPIO suffix. So 'hpd-gpios' is preferred on getting a GPIO descriptor.

However, if the device tree uses 'hpd-gpio', then the exynos-hdmi driver
always retries to get a GPIO descriptor because the first GPIO suffix is not
'gpio' but 'gpios'. So you always see the debug message below.

of_get_named_gpiod_flags: can't parse 'hpd-gpios' property of node 
'/soc/hdmi@1453[0]'

Use the preferred property, 'hpd-gpios' instead of 'hpd-gpio'.

Acked-by: Rob Herring 
Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: David Airlie 
Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: Milo Kim 
---
 Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt | 4 ++--
 arch/arm/boot/dts/exynos4210-universal_c210.dts  | 2 +-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi  | 2 +-
 arch/arm/boot/dts/exynos5250-arndale.dts | 2 +-
 arch/arm/boot/dts/exynos5250-smdk5250.dts| 2 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi| 2 +-
 arch/arm/boot/dts/exynos5250-spring.dts  | 2 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts   | 2 +-
 arch/arm/boot/dts/exynos5420-smdk5420.dts| 2 +-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi   | 2 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts| 2 +-
 11 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt 
b/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
index a2ec4c1..6394ea9 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
@@ -9,7 +9,7 @@ Required properties:
 - reg: physical base address of the hdmi and length of memory mapped
region.
 - interrupts: interrupt number to the cpu.
-- hpd-gpio: following information about the hotplug gpio pin.
+- hpd-gpios: following information about the hotplug gpio pin.
a) phandle of the gpio controller node.
b) pin number within the gpio controller.
c) optional flags and pull up/down.
@@ -56,7 +56,7 @@ Example:
compatible = "samsung,exynos4212-hdmi";
reg = <0x1453 0x10>;
interrupts = <0 95 0>;
-   hpd-gpio = <&gpx3 7 1>;
+   hpd-gpios = <&gpx3 7 1>;
ddc = <&hdmi_ddc_node>;
phy = <&hdmi_phy_node>;
samsung,syscon-phandle = <&pmu_system_controller>;
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts 
b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 9a75e3e..cf95202 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -269,7 +269,7 @@
 };
 
 &hdmi {
-   hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+   hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_hpd>;
hdmi-en-supply = <&hdmi_en>;
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi 
b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 58ad48e7..be644fe 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -227,7 +227,7 @@
 };
 
 &hdmi {
-   hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+   hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_hpd>;
vdd-supply = <&ldo8_reg>;
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts 
b/arch/arm/boot/dts/exynos5250-arndale.dts
index ea70603..3d981f3 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -152,7 +152,7 @@
 };
 
 &hdmi {
-   hpd-gpio = <&gpx3 7 GPIO_ACTIVE_LOW>;
+   hpd-gpios = <&gpx3 7 GPIO_ACTIVE_LOW>;
vdd_osc-supply = <&ldo10_reg>;
vdd_pll-supply = <&ldo8_reg>;
vdd-supply = <&am

[PATCH v2 0/4] ARM: dts: exynos: Enable HDMI in Arndale Octa board

2016-08-23 Thread Milo Kim
This patch-set enables HDMI in Arndale Octa board and fixes HPD DT property.
It also includes code refactoring on ddc and phy.

v2:
  Include DRM and Exynos maintainers and resend the patch-set.
  Add Rob's ack for the patch,
[PATCH 2/4] ARM: dts: exynos: Use 'hpd-gpios' instead of 'hpd-gpio'

Milo Kim (4):
  ARM: dts: exynos: Enable HDMI for Arndale Octa board
  ARM: dts: exynos: Use 'hpd-gpios' instead of 'hpd-gpio'
  gpu: drm: exynos_hdmi: Use consolidated function on binding DDC DT
property
  gpu: drm: exynos_hdmi: Use consolidated function on binding PHY DT
property

 .../bindings/display/exynos/exynos_hdmi.txt|  4 +--
 arch/arm/boot/dts/exynos4210-universal_c210.dts|  2 +-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi|  2 +-
 arch/arm/boot/dts/exynos5250-arndale.dts   |  2 +-
 arch/arm/boot/dts/exynos5250-smdk5250.dts  |  2 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi  |  2 +-
 arch/arm/boot/dts/exynos5250-spring.dts|  2 +-
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  | 17 +
 arch/arm/boot/dts/exynos5420-peach-pit.dts |  2 +-
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |  2 +-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  2 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts  |  2 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c   | 41 --
 13 files changed, 52 insertions(+), 30 deletions(-)

-- 
1.9.1



Re: [PATCH 0/4] ARM: dts: exynos: Enable HDMI in Arndale Octa board

2016-08-23 Thread Milo Kim

On 08/24/2016 04:55 AM, Krzysztof Kozlowski wrote:

I saw DTS patches on linux-samsung-soc patchwork but still I would
appreciate if you send them to appropriate maintainers pointed by
get_maintainers.pl script. DTS stuff goes through samsung-soc tree.


Thanks for your tip. I've just sent out the v2.

Best regards,
Milo


Re: [PATCH v2 1/4] ARM: dts: exynos: Enable HDMI for Arndale Octa board

2016-08-24 Thread Milo Kim

Hi Andrzej,

On 08/24/2016 02:28 PM, Andrzej Hajda wrote:

Please use ddc property in hdmi node, instead of this legacy binding.
See exynos4210-universal_c210.dts or exynos4412-odroid-common.dtsi for
reference.


Cool! I prefer this simple property. Thanks for the review.

Best regards,
Milo


Re: [PATCH v2 3/4] gpu: drm: exynos_hdmi: Use consolidated function on binding DDC DT property

2016-08-24 Thread Milo Kim

Hi Andrzej,

On 08/24/2016 02:55 PM, Andrzej Hajda wrote:

This is mistake introduced  by other patch, of_node_put should be called on
np, after calling of_find_i2c_adapter_by_node. You can fix it in your
patch as well.
I think you can move of_find_i2c_adapter_by_node also to this function and
rename it to sth like hdmi_get_ddc_adapter, this way you will enclose
whole logic
of getting resource into one function.


Agree, let me prepare next patch-set. Thanks!

Best regards,
Milo


[PATCH v3 2/5] ARM: dts: exynos: Use 'hpd-gpios' instead of 'hpd-gpio'

2016-08-24 Thread Milo Kim
This patch enables getting a HPD GPIO descriptor quickly.
The exynos-hdmi driver uses "hpd" for HDMI hot plug detection.

static int hdmi_resources_init(struct hdmi_context *hdata)
{
...
hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
...
}

This calls 'of_find_gpio()' and it generates the GPIO consumer ID by referring
GPIO suffix. So 'hpd-gpios' is preferred on getting a GPIO descriptor.

However, if the device tree uses 'hpd-gpio', then the exynos-hdmi driver
always retries to get a GPIO descriptor because the first GPIO suffix is not
'gpio' but 'gpios'. So you always see the debug message below.

of_get_named_gpiod_flags: can't parse 'hpd-gpios' property of node 
'/soc/hdmi@1453[0]'

Use the preferred property, 'hpd-gpios' instead of 'hpd-gpio'.

Acked-by: Rob Herring 
Reviewed-by: Andrzej Hajda 
Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt | 4 ++--
 arch/arm/boot/dts/exynos4210-universal_c210.dts  | 2 +-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi  | 2 +-
 arch/arm/boot/dts/exynos5250-arndale.dts | 2 +-
 arch/arm/boot/dts/exynos5250-smdk5250.dts| 2 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi| 2 +-
 arch/arm/boot/dts/exynos5250-spring.dts  | 2 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts   | 2 +-
 arch/arm/boot/dts/exynos5420-smdk5420.dts| 2 +-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi   | 2 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts| 2 +-
 11 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt 
b/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
index a2ec4c1..6394ea9 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos_hdmi.txt
@@ -9,7 +9,7 @@ Required properties:
 - reg: physical base address of the hdmi and length of memory mapped
region.
 - interrupts: interrupt number to the cpu.
-- hpd-gpio: following information about the hotplug gpio pin.
+- hpd-gpios: following information about the hotplug gpio pin.
a) phandle of the gpio controller node.
b) pin number within the gpio controller.
c) optional flags and pull up/down.
@@ -56,7 +56,7 @@ Example:
compatible = "samsung,exynos4212-hdmi";
reg = <0x1453 0x10>;
interrupts = <0 95 0>;
-   hpd-gpio = <&gpx3 7 1>;
+   hpd-gpios = <&gpx3 7 1>;
ddc = <&hdmi_ddc_node>;
phy = <&hdmi_phy_node>;
samsung,syscon-phandle = <&pmu_system_controller>;
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts 
b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 9a75e3e..cf95202 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -269,7 +269,7 @@
 };
 
 &hdmi {
-   hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+   hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_hpd>;
hdmi-en-supply = <&hdmi_en>;
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi 
b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 58ad48e7..be644fe 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -227,7 +227,7 @@
 };
 
 &hdmi {
-   hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>;
+   hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&hdmi_hpd>;
vdd-supply = <&ldo8_reg>;
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts 
b/arch/arm/boot/dts/exynos5250-arndale.dts
index ea70603..3d981f3 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -152,7 +152,7 @@
 };
 
 &hdmi {
-   hpd-gpio = <&gpx3 7 GPIO_ACTIVE_LOW>;
+   hpd-gpios = <&gpx3 7 GPIO_ACTIVE_LOW>;
vdd_osc-supply = <&ldo10_reg>;
vdd_pll-supply = <&ldo8_reg>;
vdd-supply = <&ldo8_reg>;
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts 
b/arch/arm/boot/dts/exynos5250-smd

[PATCH v3 3/5] gpu: drm: exynos_hdmi: Move DDC logic into single function

2016-08-24 Thread Milo Kim
Paring DT properties and getting the I2C adapter in one function.

Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: David Airlie 
Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Rob Herring 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: Milo Kim 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 46 
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 2275efe..8d99b5d 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1760,16 +1760,34 @@ static const struct component_ops hdmi_component_ops = {
.unbind = hdmi_unbind,
 };
 
-static struct device_node *hdmi_legacy_ddc_dt_binding(struct device *dev)
+static int hdmi_get_ddc_adapter(struct hdmi_context *hdata)
 {
const char *compatible_str = "samsung,exynos4210-hdmiddc";
struct device_node *np;
+   struct i2c_adapter *adpt;
 
np = of_find_compatible_node(NULL, NULL, compatible_str);
if (np)
-   return of_get_next_parent(np);
+   np = of_get_next_parent(np);
+   else
+   np = of_parse_phandle(hdata->dev->of_node, "ddc", 0);
+
+   if (!np) {
+   DRM_ERROR("Failed to find ddc node in device tree\n");
+   return -ENODEV;
+   }
 
-   return NULL;
+   adpt = of_find_i2c_adapter_by_node(np);
+   if (!adpt) {
+   DRM_ERROR("Failed to get ddc i2c adapter by node\n");
+   of_node_put(np);
+   return -EPROBE_DEFER;
+   }
+
+   hdata->ddc_adpt = adpt;
+   of_node_put(np);
+
+   return 0;
 }
 
 static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
@@ -1781,7 +1799,7 @@ static struct device_node 
*hdmi_legacy_phy_dt_binding(struct device *dev)
 
 static int hdmi_probe(struct platform_device *pdev)
 {
-   struct device_node *ddc_node, *phy_node;
+   struct device_node *phy_node;
struct device *dev = &pdev->dev;
struct hdmi_context *hdata;
struct resource *res;
@@ -1811,23 +1829,9 @@ static int hdmi_probe(struct platform_device *pdev)
return ret;
}
 
-   ddc_node = hdmi_legacy_ddc_dt_binding(dev);
-   if (ddc_node)
-   goto out_get_ddc_adpt;
-
-   ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
-   if (!ddc_node) {
-   DRM_ERROR("Failed to find ddc node in device tree\n");
-   return -ENODEV;
-   }
-   of_node_put(dev->of_node);
-
-out_get_ddc_adpt:
-   hdata->ddc_adpt = of_find_i2c_adapter_by_node(ddc_node);
-   if (!hdata->ddc_adpt) {
-   DRM_ERROR("Failed to get ddc i2c adapter by node\n");
-   return -EPROBE_DEFER;
-   }
+   ret = hdmi_get_ddc_adapter(hdata);
+   if (ret)
+   return ret;
 
phy_node = hdmi_legacy_phy_dt_binding(dev);
if (phy_node)
-- 
1.9.1



[PATCH v3 1/5] ARM: dts: exynos: Enable HDMI for Arndale Octa board

2016-08-24 Thread Milo Kim
* GPIO for HDMI hot plug detect
  GPX3_7 is used. The HPD awareness is done when the GPIO is active high and
  single ended.

* Enable HDMI block in Exynos5420
  HDMI VDD and PLL consume 1.0V LDO6 (PVDD_ANAIP_1V0) and HDMI oscillator
  requires 1.8V LDO7 (PVDD_ANAIP_1V8).

* Support HDMI display data channel
  I2C #2 is assigned for the HDMI DDC. It enables the EDID access.

Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: Rob Herring 
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 arch/arm/boot/dts/exynos5420-arndale-octa.dts | 13 +
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts 
b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index 39a3b81..2fb5708 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -70,6 +70,19 @@
status = "disabled";
 };
 
+&hdmi {
+   hpd-gpios = <&gpx3 7 GPIO_OPEN_SOURCE>;
+   vdd_osc-supply = <&ldo7_reg>;
+   vdd_pll-supply = <&ldo6_reg>;
+   vdd-supply = <&ldo6_reg>;
+   ddc = <&i2c_2>;
+   status = "okay";
+};
+
+&i2c_2 {
+   status = "okay";
+};
+
 &hsi2c_4 {
status = "okay";
 
-- 
1.9.1



[PATCH v3 5/5] gpu: drm: exynos_hdmi: Remove duplicate initialization of regulator bulk consumer

2016-08-24 Thread Milo Kim
The helper, devm_regulator_bulk_get() initializes the consumer as NULL,
so this code can be ignored.

Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: David Airlie 
Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: Milo Kim 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 249cb23..4e17877f 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1669,10 +1669,9 @@ static int hdmi_resources_init(struct hdmi_context 
*hdata)
if (ret)
return ret;
 
-   for (i = 0; i < ARRAY_SIZE(supply); ++i) {
+   for (i = 0; i < ARRAY_SIZE(supply); ++i)
hdata->regul_bulk[i].supply = supply[i];
-   hdata->regul_bulk[i].consumer = NULL;
-   }
+
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), 
hdata->regul_bulk);
if (ret) {
if (ret != -EPROBE_DEFER)
-- 
1.9.1



[PATCH v3 4/5] gpu: drm: exynos_hdmi: Move PHY logic into single function

2016-08-24 Thread Milo Kim
Paring DT properties and getting PHY IO (memory mapped or I2C) in one function.

Cc: Kukjin Kim 
Cc: Krzysztof Kozlowski 
Cc: David Airlie 
Cc: Inki Dae 
Cc: Joonyoung Shim 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Rob Herring 
Cc: devicet...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Signed-off-by: Milo Kim 
---
 drivers/gpu/drm/exynos/exynos_hdmi.c | 63 +++-
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c 
b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 8d99b5d..249cb23 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1790,16 +1790,44 @@ static int hdmi_get_ddc_adapter(struct hdmi_context 
*hdata)
return 0;
 }
 
-static struct device_node *hdmi_legacy_phy_dt_binding(struct device *dev)
+static int hdmi_get_phy_io(struct hdmi_context *hdata)
 {
const char *compatible_str = "samsung,exynos4212-hdmiphy";
+   struct device_node *np;
+   int ret = 0;
+
+   np = of_find_compatible_node(NULL, NULL, compatible_str);
+   if (!np) {
+   np = of_parse_phandle(hdata->dev->of_node, "phy", 0);
+   if (!np) {
+   DRM_ERROR("Failed to find hdmiphy node in device 
tree\n");
+   return -ENODEV;
+   }
+   }
+
+   if (hdata->drv_data->is_apb_phy) {
+   hdata->regs_hdmiphy = of_iomap(np, 0);
+   if (!hdata->regs_hdmiphy) {
+   DRM_ERROR("failed to ioremap hdmi phy\n");
+   ret = -ENOMEM;
+   goto out;
+   }
+   } else {
+   hdata->hdmiphy_port = of_find_i2c_device_by_node(np);
+   if (!hdata->hdmiphy_port) {
+   DRM_ERROR("Failed to get hdmi phy i2c client\n");
+   ret = -EPROBE_DEFER;
+   goto out;
+   }
+   }
 
-   return of_find_compatible_node(NULL, NULL, compatible_str);
+out:
+   of_node_put(np);
+   return ret;
 }
 
 static int hdmi_probe(struct platform_device *pdev)
 {
-   struct device_node *phy_node;
struct device *dev = &pdev->dev;
struct hdmi_context *hdata;
struct resource *res;
@@ -1833,34 +1861,9 @@ static int hdmi_probe(struct platform_device *pdev)
if (ret)
return ret;
 
-   phy_node = hdmi_legacy_phy_dt_binding(dev);
-   if (phy_node)
-   goto out_get_phy_port;
-
-   phy_node = of_parse_phandle(dev->of_node, "phy", 0);
-   if (!phy_node) {
-   DRM_ERROR("Failed to find hdmiphy node in device tree\n");
-   ret = -ENODEV;
+   ret = hdmi_get_phy_io(hdata);
+   if (ret)
goto err_ddc;
-   }
-   of_node_put(dev->of_node);
-
-out_get_phy_port:
-   if (hdata->drv_data->is_apb_phy) {
-   hdata->regs_hdmiphy = of_iomap(phy_node, 0);
-   if (!hdata->regs_hdmiphy) {
-   DRM_ERROR("failed to ioremap hdmi phy\n");
-   ret = -ENOMEM;
-   goto err_ddc;
-   }
-   } else {
-   hdata->hdmiphy_port = of_find_i2c_device_by_node(phy_node);
-   if (!hdata->hdmiphy_port) {
-   DRM_ERROR("Failed to get hdmi phy i2c client\n");
-   ret = -EPROBE_DEFER;
-   goto err_ddc;
-   }
-   }
 
INIT_DELAYED_WORK(&hdata->hotplug_work, hdmi_hotplug_work_func);
 
-- 
1.9.1



[PATCH v3 0/5] ARM: dts: exynos: Enable HDMI in Arndale Octa board

2016-08-24 Thread Milo Kim
This patch-set enables HDMI in Arndale Octa board and fixes HPD DT property.
It also includes code refactoring on ddc and phy.

v3:
  Add 'vdd-supply' property in dts.
  Use generic 'ddc' property instead of legacy property.
  Clean up DDC and PHY logic in _probe().
  Remove duplicate code of regulator consumer initialization.

v2:
  Include DRM and Exynos maintainers and resend the patch-set.
  Add Rob's ack for the patch,
[PATCH 2/4] ARM: dts: exynos: Use 'hpd-gpios' instead of 'hpd-gpio'

Milo Kim (5):
  ARM: dts: exynos: Enable HDMI for Arndale Octa board
  ARM: dts: exynos: Use 'hpd-gpios' instead of 'hpd-gpio'
  gpu: drm: exynos_hdmi: Move DDC logic into single function
  gpu: drm: exynos_hdmi: Move PHY logic into single function
  gpu: drm: exynos_hdmi: Remove duplicate initialization of regulator
bulk consumer

 .../bindings/display/exynos/exynos_hdmi.txt|   4 +-
 arch/arm/boot/dts/exynos4210-universal_c210.dts|   2 +-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi|   2 +-
 arch/arm/boot/dts/exynos5250-arndale.dts   |   2 +-
 arch/arm/boot/dts/exynos5250-smdk5250.dts  |   2 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi  |   2 +-
 arch/arm/boot/dts/exynos5250-spring.dts|   2 +-
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  |  13 +++
 arch/arm/boot/dts/exynos5420-peach-pit.dts |   2 +-
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |   2 +-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |   2 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts  |   2 +-
 drivers/gpu/drm/exynos/exynos_hdmi.c   | 112 +++--
 13 files changed, 84 insertions(+), 65 deletions(-)

-- 
1.9.1



[PATCH 1/2] pwm: sun4i: Add Allwinner H3 support

2016-08-24 Thread Milo Kim
According to the latest datasheet (v1.2), H3 has single PWM channel.
H3 PWM controller has same register layout as sun4i driver, so it works 
by adding H3 specific data.
And the second PWM channel is not supported, so the pinctrl function is removed.

Datasheet:
  http://linux-sunxi.org/File:Allwinner_H3_Datasheet_V1.2.pdf

Test environment:
  Tested on Nano Pi M1 board, but PA5 pin is assigned for UART0.
  So the debug console should be changed to other port like UART1.

  Ex)
aliases {
serial0 = &uart1;
};

&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins_a>;
status = "okay";
};

Cc: Chen-Yu Tsai 
Cc: Maxime Ripard 
Cc: Rob Herring 
Cc: Thierry Reding 
Signed-off-by: Milo Kim 
---
 Documentation/devicetree/bindings/pwm/pwm-sun4i.txt |  1 +
 arch/arm/boot/dts/sun8i-h3.dtsi | 15 +++
 drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c|  1 -
 drivers/pwm/pwm-sun4i.c |  9 +
 4 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt 
b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
index cf6068b..f1cbeef 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
@@ -6,6 +6,7 @@ Required properties:
 - "allwinner,sun5i-a10s-pwm"
 - "allwinner,sun5i-a13-pwm"
 - "allwinner,sun7i-a20-pwm"
+- "allwinner,sun8i-h3-pwm"
   - reg: physical base address and length of the controller's registers
   - #pwm-cells: should be 3. See pwm.txt in this directory for a description of
 the cells format.
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index b44bc48..3a965fb 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -512,6 +512,13 @@
allwinner,pull = ;
};
 
+   pwm0_pin_a: pwm0@0 {
+   allwinner,pins = "PA5";
+   allwinner,function = "pwm0";
+   allwinner,drive = ;
+   allwinner,pull = ;
+   };
+
uart0_pins_a: uart0@0 {
allwinner,pins = "PA4", "PA5";
allwinner,function = "uart0";
@@ -585,6 +592,14 @@
interrupts = ;
};
 
+   pwm: pwm@01c21400 {
+   compatible = "allwinner,sun8i-h3-pwm";
+   reg = <0x01c21400 0x8>;
+   clocks = <&osc24M>;
+   #pwm-cells = <3>;
+   status = "disabled";
+   };
+
uart0: serial@01c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c 
b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
index 11760bb..087f231 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c
@@ -60,7 +60,6 @@ static const struct sunxi_desc_pin sun8i_h3_pins[] = {
  SUNXI_FUNCTION(0x0, "gpio_in"),
  SUNXI_FUNCTION(0x1, "gpio_out"),
  SUNXI_FUNCTION(0x2, "sim"),   /* PWREN */
- SUNXI_FUNCTION(0x3, "pwm1"),
  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),  /* PA_EINT6 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(A, 7),
  SUNXI_FUNCTION(0x0, "gpio_in"),
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index 03a99a5..b0803f6 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -284,6 +284,12 @@ static const struct sun4i_pwm_data sun4i_pwm_data_a20 = {
.npwm = 2,
 };
 
+static const struct sun4i_pwm_data sun4i_pwm_data_h3 = {
+   .has_prescaler_bypass = true,
+   .has_rdy = true,
+   .npwm = 1,
+};
+
 static const struct of_device_id sun4i_pwm_dt_ids[] = {
{
.compatible = "allwinner,sun4i-a10-pwm",
@@ -298,6 +304,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
.compatible = "allwinner,sun7i-a20-pwm",
.data = &sun4i_pwm_data_a20,
}, {
+   .compatible = "allwinner,sun8i-h3-pwm",
+   .data = &sun4i_pwm_data_h3,
+   }, {
/* sentinel */
},
 };
-- 
1.9.1



[PATCH 2/2] ARM: dts: sun8i-h3: Add UART1 pinctrl

2016-08-24 Thread Milo Kim
In H3, PA5 can be used as PWM and UART0. If the PWM is used, the console
UART should be moved to other port.
This patch enables UART1 pinctrl to support this case.

PA5: PWM
PG6, PG7: debug console

Cc: Chen-Yu Tsai 
Cc: Maxime Ripard 
Cc: Rob Herring 
Signed-off-by: Milo Kim 
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 3a965fb..fdb6801 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -526,6 +526,13 @@
allwinner,pull = ;
};
 
+   uart1_pins_a: uart1@0 {
+   allwinner,pins = "PG6", "PG7";
+   allwinner,function = "uart1";
+   allwinner,drive = ;
+   allwinner,pull = ;
+   };
+
mmc0_pins_a: mmc0@0 {
allwinner,pins = "PF0", "PF1", "PF2", "PF3",
 "PF4", "PF5";
-- 
1.9.1



Re: [PATCH 1/2] pwm: sun4i: Add Allwinner H3 support

2016-08-26 Thread Milo Kim

Hi Maxime,

On 08/26/2016 05:51 AM, Maxime Ripard wrote:

Remember to use get_maintainers to send your patches, you missed a few
mailing lists (linux-arm-kernel, for example), developpers (Alexandre
Belloni, the original author of the driver) and maintainers (Linus
Walleij for the pinctrl changes).


Thanks for this tip and your review regarding splitting pinctrl patch. 
Let me prepare the 2nd patch-set.


Best regards,
Milo


Re: [PATCH 2/2] ARM: dts: sun8i-h3: Add UART1 pinctrl

2016-08-26 Thread Milo Kim

On 08/26/2016 04:10 PM, Maxime Ripard wrote:

+   uart1_pins_a: uart1@0 {
> +  allwinner,pins = "PG6", "PG7";
> +  allwinner,function = "uart1";
> +  allwinner,drive = ;
> +  allwinner,pull = ;
> +  };
> +

Our policy is that we don't introduce new pinctrl nodes that are not
used by any board to avoid bloating the DT too much with unused nodes.

If you have a board using it, please submit that change as well.


OK, I agree.

However, this pinmux is only useful in case PA5 is assigned for PWM.
PA5 is commonly used for UART0_RX, so I'd like to add UART1 node into 
*.dts and disable it (status = "disabled"). Does it make sense?


Best regards,
Milo


[RFC 1/4] of: add of_dev_get_platdata()

2015-08-28 Thread Milo Kim
of_dev_get_platdata()
  - provides unified handling of getting device platform data
  - supports DT and non-DT(legacy) cases
if CONFIG_OF is not defined, then returns legacy function,
'dev_get_platdata()'.
  - removes duplicated code from each driver
  - keeps driver specific code simple in each driver

Parser function - of_parse_dt_fn()
  Caller(aka driver) gets allocated platform data and optional private
  data. Then, it will parse the DT and copy properties into allocated
  platform data and use the private data if needed.

Cc: Dmitry Torokhov 
Cc: Felipe Balbi 
Cc: Grant Likely 
Cc: Greg Kroah-Hartman 
Cc: Lee Jones 
Cc: Rob Herring 
Cc: Samuel Ortiz 
Cc: Tony Lindgren 
Cc: devicet...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 drivers/of/device.c   | 46 ++
 include/linux/of_device.h | 12 
 2 files changed, 58 insertions(+)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 8b91ea2..5793ba0 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -286,3 +286,49 @@ int of_device_uevent_modalias(struct device *dev, struct 
kobj_uevent_env *env)
 
return 0;
 }
+
+/**
+ * of_dev_get_platdata - get the platform data.
+ * @dev: device to get the platform data.
+ * @size: size of the platform data.
+ * @of_parse_dt_fn: device specific function to parse the device tree.
+ * @priv: driver private data to be passed to of_parse_dt_fn.
+ *
+ * This routine provides unified way of getting device platform data.
+ * If the platform data exists, just return it. It's exactly same as
+ * how to get device platform data by using dev_get_platdata().
+ * If the platform data is null, checks the device node. If the device tree is
+ * is supported, then allocates the device platform data and call back to
+ * driver specific 'of_parse_dt_fn'. The caller driver should handle data
+ * manipulation inside this function.
+ *
+ * of_parse_dt_fn() has three arguments. The first is device structure.
+ * The second is the pointer of allocated device platform data.
+ * The last one is private data pointer which is used in of_parse_dt_fn().
+ *
+ * Return value is a pointer of device platform data.
+ * Caller should check IS_ERR(pdata) and return PTR_ERR(pdata).
+ */
+void *of_dev_get_platdata(struct device *dev, size_t size,
+ of_parse_dt_t of_parse_dt_fn, void *priv)
+{
+   void *pdata = dev_get_platdata(dev);
+   int err;
+
+   if (pdata)
+   return pdata;
+
+   if (!dev_of_node(dev) || !of_parse_dt_fn)
+   return NULL;
+
+   pdata = devm_kzalloc(dev, size, GFP_KERNEL);
+   if (!pdata)
+   return ERR_PTR(-ENOMEM);
+
+   err = of_parse_dt_fn(dev, pdata, priv);
+   if (err)
+   return ERR_PTR(err);
+
+   return pdata;
+}
+EXPORT_SYMBOL_GPL(of_dev_get_platdata);
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index cc7dd687..b24b3d8 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -10,6 +10,9 @@
 
 struct device;
 
+/* Device specific DT parser function */
+typedef int (*of_parse_dt_t)(struct device *, void *, void *);
+
 #ifdef CONFIG_OF
 extern const struct of_device_id *of_match_device(
const struct of_device_id *matches, const struct device *dev);
@@ -56,6 +59,9 @@ static inline struct device_node *of_cpu_device_node_get(int 
cpu)
 }
 
 void of_dma_configure(struct device *dev, struct device_node *np);
+
+extern void *of_dev_get_platdata(struct device *dev, size_t size,
+of_parse_dt_t of_parse_dt_fn, void *priv);
 #else /* CONFIG_OF */
 
 static inline int of_driver_match_device(struct device *dev,
@@ -100,6 +106,12 @@ static inline struct device_node 
*of_cpu_device_node_get(int cpu)
 }
 static inline void of_dma_configure(struct device *dev, struct device_node *np)
 {}
+
+static inline void *of_dev_get_platdata(struct device *dev, size_t size,
+   of_parse_dt_t of_parse_dt_fn, void *priv)
+{
+   return dev_get_platdata(dev);
+}
 #endif /* CONFIG_OF */
 
 #endif /* _LINUX_OF_DEVICE_H */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 2/4] input: touchscree: mms114: use of_dev_get_platdata()

2015-08-28 Thread Milo Kim
Driver calls of_dev_get_platdata(). Error handler is added - IS_ERR() and
PTR_ERR() if an error is found.
Return type of mms114_parse_dt() is changed to integer. So return values
are modified.

Cc: Dmitry Torokhov 
Cc: Felipe Balbi 
Cc: Grant Likely 
Cc: Greg Kroah-Hartman 
Cc: Lee Jones 
Cc: Rob Herring 
Cc: Samuel Ortiz 
Cc: Tony Lindgren 
Cc: devicet...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 drivers/input/touchscreen/mms114.c | 34 ++
 1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/drivers/input/touchscreen/mms114.c 
b/drivers/input/touchscreen/mms114.c
index 67c0d31..555e326 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -376,29 +377,19 @@ static void mms114_input_close(struct input_dev *dev)
mms114_stop(data);
 }
 
-#ifdef CONFIG_OF
-static struct mms114_platform_data *mms114_parse_dt(struct device *dev)
+static int mms114_parse_dt(struct device *dev, void *data, void *priv)
 {
-   struct mms114_platform_data *pdata;
+   struct mms114_platform_data *pdata = data;
struct device_node *np = dev->of_node;
 
-   if (!np)
-   return NULL;
-
-   pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
-   if (!pdata) {
-   dev_err(dev, "failed to allocate platform data\n");
-   return NULL;
-   }
-
if (of_property_read_u32(np, "x-size", &pdata->x_size)) {
dev_err(dev, "failed to get x-size property\n");
-   return NULL;
+   return -EINVAL;
};
 
if (of_property_read_u32(np, "y-size", &pdata->y_size)) {
dev_err(dev, "failed to get y-size property\n");
-   return NULL;
+   return -EINVAL;
};
 
of_property_read_u32(np, "contact-threshold",
@@ -411,14 +402,8 @@ static struct mms114_platform_data *mms114_parse_dt(struct 
device *dev)
if (of_find_property(np, "y-invert", NULL))
pdata->y_invert = true;
 
-   return pdata;
-}
-#else
-static inline struct mms114_platform_data *mms114_parse_dt(struct device *dev)
-{
-   return NULL;
+   return 0;
 }
-#endif
 
 static int mms114_probe(struct i2c_client *client,
  const struct i2c_device_id *id)
@@ -428,9 +413,10 @@ static int mms114_probe(struct i2c_client *client,
struct input_dev *input_dev;
int error;
 
-   pdata = dev_get_platdata(&client->dev);
-   if (!pdata)
-   pdata = mms114_parse_dt(&client->dev);
+   pdata = of_dev_get_platdata(&client->dev, sizeof(*pdata),
+   mms114_parse_dt, NULL);
+   if (IS_ERR(pdata))
+   return PTR_ERR(pdata);
 
if (!pdata) {
dev_err(&client->dev, "Need platform data\n");
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 4/4] usb: musb: use of_dev_get_platdata()

2015-08-28 Thread Milo Kim
'of_dev_get_platdata()' makes if-statements simple.

Cc: Dmitry Torokhov 
Cc: Felipe Balbi 
Cc: Grant Likely 
Cc: Greg Kroah-Hartman 
Cc: Lee Jones 
Cc: Rob Herring 
Cc: Samuel Ortiz 
Cc: Tony Lindgren 
Cc: devicet...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 drivers/usb/musb/ux500.c | 40 
 1 file changed, 16 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c
index 39168fe..851cf4a 100644
--- a/drivers/usb/musb/ux500.c
+++ b/drivers/usb/musb/ux500.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -200,21 +201,16 @@ static const struct musb_platform_ops ux500_ops = {
.set_vbus   = ux500_musb_set_vbus,
 };
 
-static struct musb_hdrc_platform_data *
-ux500_of_probe(struct platform_device *pdev, struct device_node *np)
+static int ux500_of_probe(struct device *dev, void *data, void *priv)
 {
-   struct musb_hdrc_platform_data *pdata;
+   struct musb_hdrc_platform_data *pdata = data;
const char *mode;
int strlen;
 
-   pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-   if (!pdata)
-   return NULL;
-
-   mode = of_get_property(np, "dr_mode", &strlen);
+   mode = of_get_property(dev->of_node, "dr_mode", &strlen);
if (!mode) {
-   dev_err(&pdev->dev, "No 'dr_mode' property found\n");
-   return NULL;
+   dev_err(dev, "No 'dr_mode' property found\n");
+   return -EINVAL;
}
 
if (strlen > 0) {
@@ -226,31 +222,27 @@ ux500_of_probe(struct platform_device *pdev, struct 
device_node *np)
pdata->mode = MUSB_PERIPHERAL;
}
 
-   return pdata;
+   return 0;
 }
 
 static int ux500_probe(struct platform_device *pdev)
 {
struct resource musb_resources[2];
-   struct musb_hdrc_platform_data  *pdata = dev_get_platdata(&pdev->dev);
-   struct device_node  *np = pdev->dev.of_node;
+   struct musb_hdrc_platform_data  *pdata;
struct platform_device  *musb;
struct ux500_glue   *glue;
struct clk  *clk;
int ret = -ENOMEM;
 
-   if (!pdata) {
-   if (np) {
-   pdata = ux500_of_probe(pdev, np);
-   if (!pdata)
-   goto err0;
+   pdata = of_dev_get_platdata(&pdev->dev, sizeof(*pdata),
+   ux500_of_probe, NULL);
+   if (IS_ERR(pdata))
+   return PTR_ERR(pdata);
 
-   pdev->dev.platform_data = pdata;
-   } else {
-   dev_err(&pdev->dev, "no pdata or device tree found\n");
-   goto err0;
-   }
-   }
+   if (!pdata)
+   goto err0;
+
+   pdev->dev.platform_data = pdata;
 
glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
if (!glue)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC 3/4] mfd: tps65910: use of_dev_get_platdata()

2015-08-28 Thread Milo Kim
Platform data allocation, CONFIG_OF and condition statements are supported
in of_dev_get_platdata().
This patch shows how to use private data in each parser function.
tps65910 calls of_dev_get_platdata() with driver private data, 'chip_id'.
This data is used in tps65910_parse_dt().

'of_pmic_plat_data' is unnecessary any more. IRQ number is updated after
parsing the DT.

Cc: Dmitry Torokhov 
Cc: Felipe Balbi 
Cc: Grant Likely 
Cc: Greg Kroah-Hartman 
Cc: Lee Jones 
Cc: Rob Herring 
Cc: Samuel Ortiz 
Cc: Tony Lindgren 
Cc: devicet...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Milo Kim 
---
 drivers/mfd/tps65910.c | 49 -
 1 file changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index 7612d89..2a068d7 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -378,7 +378,6 @@ err_sleep_init:
return ret;
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id tps65910_of_match[] = {
{ .compatible = "ti,tps65910", .data = (void *)TPS65910},
{ .compatible = "ti,tps65911", .data = (void *)TPS65911},
@@ -386,30 +385,23 @@ static const struct of_device_id tps65910_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tps65910_of_match);
 
-static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
-   unsigned long *chip_id)
+static int tps65910_parse_dt(struct device *dev, void *data, void *priv)
 {
-   struct device_node *np = client->dev.of_node;
-   struct tps65910_board *board_info;
+   struct device_node *np = dev->of_node;
+   struct tps65910_board *board_info = data;
+   unsigned long *chip_id = priv;
unsigned int prop;
const struct of_device_id *match;
int ret = 0;
 
-   match = of_match_device(tps65910_of_match, &client->dev);
+   match = of_match_device(tps65910_of_match, dev);
if (!match) {
-   dev_err(&client->dev, "Failed to find matching dt id\n");
-   return NULL;
+   dev_err(dev, "Failed to find matching dt id\n");
+   return -EINVAL;
}
 
*chip_id  = (unsigned long)match->data;
 
-   board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
-   GFP_KERNEL);
-   if (!board_info) {
-   dev_err(&client->dev, "Failed to allocate pdata\n");
-   return NULL;
-   }
-
ret = of_property_read_u32(np, "ti,vmbch-threshold", &prop);
if (!ret)
board_info->vmbch_threshold = prop;
@@ -421,21 +413,12 @@ static struct tps65910_board *tps65910_parse_dt(struct 
i2c_client *client,
prop = of_property_read_bool(np, "ti,en-ck32k-xtal");
board_info->en_ck32k_xtal = prop;
 
-   board_info->irq = client->irq;
board_info->irq_base = -1;
board_info->pm_off = of_property_read_bool(np,
"ti,system-power-controller");
 
-   return board_info;
-}
-#else
-static inline
-struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
-unsigned long *chip_id)
-{
-   return NULL;
+   return 0;
 }
-#endif
 
 static struct i2c_client *tps65910_i2c_client;
 static void tps65910_power_off(void)
@@ -457,21 +440,21 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
 {
struct tps65910 *tps65910;
struct tps65910_board *pmic_plat_data;
-   struct tps65910_board *of_pmic_plat_data = NULL;
struct tps65910_platform_data *init_data;
unsigned long chip_id = id->driver_data;
int ret = 0;
 
-   pmic_plat_data = dev_get_platdata(&i2c->dev);
-
-   if (!pmic_plat_data && i2c->dev.of_node) {
-   pmic_plat_data = tps65910_parse_dt(i2c, &chip_id);
-   of_pmic_plat_data = pmic_plat_data;
-   }
+   pmic_plat_data = of_dev_get_platdata(&i2c->dev,
+sizeof(*pmic_plat_data),
+tps65910_parse_dt, &chip_id);
+   if (IS_ERR(pmic_plat_data))
+   return PTR_ERR(pmic_plat_data);
 
if (!pmic_plat_data)
return -EINVAL;
 
+   pmic_plat_data->irq = i2c->irq;
+
init_data = devm_kzalloc(&i2c->dev, sizeof(*init_data), GFP_KERNEL);
if (init_data == NULL)
return -ENOMEM;
@@ -480,7 +463,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
if (tps65910 == NULL)
return -ENOMEM;
 
-   tps65910->of_plat_data = of_pmic_plat_data;
+   tps65910->of_plat_data = pmic_plat_data;
i2c_set_clientdata(i2c, tps65910);
tps65910->dev 

[RFC 0/4] of: introduce of_dev_get_platdata()

2015-08-28 Thread Milo Kim
c
  drivers/video/backlight/lp855x_bl.c
  drivers/video/backlight/pwm_bl.c
  drivers/video/backlight/sky81452-backlight.c
  drivers/video/backlight/tps65217_bl.c

This is the RFC, so I would like to get some feedback prior to patching all
drivers. Any comments are welcome.

Cc: Dmitry Torokhov 
Cc: Felipe Balbi 
Cc: Grant Likely 
Cc: Greg Kroah-Hartman 
Cc: Lee Jones 
Cc: Rob Herring 
Cc: Samuel Ortiz 
Cc: Tony Lindgren 
Cc: devicet...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

Milo Kim (4):
  of: introduce of_dev_get_platdata()
  input: touchscree: mms114: use of_dev_get_platdata()
  mfd: tps65910: use of_dev_get_platdata()
  usb: musb: use of_dev_get_platdata()

 drivers/input/touchscreen/mms114.c | 34 --
 drivers/mfd/tps65910.c | 49 +-
 drivers/of/device.c| 46 +++
 drivers/usb/musb/ux500.c   | 40 +--
 include/linux/of_device.h  | 12 ++
 5 files changed, 100 insertions(+), 81 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 01/10] mfd: Add TI LMU driver

2014-02-18 Thread Milo Kim

Hi Lee,

On 02/18/2014 05:21 PM, Lee Jones wrote:

+   pdata->en_gpio = of_get_named_gpio(node, "ti,enable-gpio", 0);


There is a global DT property for this already.


I've not found it yet, but I agree it looks like general property.
So I'll replace "ti,enable-gpio" with "ti,lmu-en-gpio".


Just re-use "gpio-enable". No need for it to be vendor specific.



Got it. Thanks!

This GPIO is used for enabling the device. So, "enable-gpio" is more 
appropriate name, isn't it?


Best regards,
Milo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 00/10] leds: lp5521,5523: restore device attributes for running LED patterns

2013-11-07 Thread Milo Kim

Hi Pali,

Sorry for the late reply.

On 10/26/2013 03:21 AM, Pali Rohár wrote:

On Friday 25 October 2013 19:10:07 Bryan Wu wrote:

On Fri, Oct 25, 2013 at 9:38 AM, Pali Rohár

 wrote:

On Tuesday 13 August 2013 23:04:14 Bryan Wu wrote:

On Thu, Aug 8, 2013 at 12:59 AM, Milo Kim

 wrote:

This patch-set resolves the application conflict by
restoring sysfs files.

For LP5521

   engine1/2/3_mode
   engine1/2/3_load

For LP5523

   engine1/2/3_mode
   engine1/2/3_load
   engine1/2/3_leds

Those attributes are accessed when LED pattern is run by
custom application. Those were removed when LED pattern
interface was changed to generic firmware interface.
Please refer to commits below.

   git commit 9ce7cb170f97f83a78dc948bf7d25690f15e1328
   (leds-lp5521: use generic firmware interface)

   git commit db6eaf8388a413a5ee1b4547ce78506b9c6456b0
   (leds-lp5523: use generic firmware interface)

Necessary attributes are restored in this patch-set.

(Other changes)
New data structure is added for handling values from/to
an application. Few code fixes for reducing writing I2C
commands.
Add LP55xx common macros for code refactoring.
Documentation updates.

You can also pull from the location below
This branch is based on 'for-next' of linux-leds.

   https://github.com/milokim/lp55xx.git
   resolve-missing-sysfs


Thanks, I've already merged the whole patchset in my -devel
branch [1].

Pali, could you please help to test it on your hardware?
Just grab my -devel branch and build then run.

Thanks,
-Bryan


Hi, I see that all your patches are part of 3.12-rc5 kernel.

Now I tested this example led program:
 # Clearing LED-state to be sure
 echo "disabled" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode echo
 "disabled" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode echo 0
 > /sys/class/leds/lp5523:r/brightness
 echo 0 > /sys/class/leds/lp5523:g/brightness
 echo 0 > /sys/class/leds/lp5523:b/brightness

 # Setting yellow light pattern and running it
 echo "load" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode echo
 "01100" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine1_leds echo
 "9d804000427f0d7f7f007f004200" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine1_load echo
 "load" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode echo
 "0" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine2_leds echo
 "9d80" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine2_load echo
 "run" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode echo
 "run" >
 /sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode echo
 20 > /sys/class/leds/lp5523:r/led_current
 echo 2 > /sys/class/leds/lp5523:g/led_current
 echo 0 > /sys/class/leds/lp5523:b/led_current


In the latest LP5523 driver, I just found wrong operation mode setting 
in case of multiple engine used. (please find a patch below)




All sysfs entries exists and every echo returned 0.

But led does not start blinking that yellow ligh pattern.
So it not working on 3.12-rc5 kernel :-(


OK, great! Do you still remember which kernel version works on
you system? Milo, do you have time to take a look? I bet it's
a regression somewhere.

Thanks,
-Bryan


I do not know which version. Now I tried pattern example from
Documentation/leds/leds-lp55xx.txt which using new API.

echo 2 > /sys/class/i2c-adapter/i2c-2/2-0032/select_engine
echo 1 > /sys/class/firmware/lp5523/loading
echo "9d8044ff05ff437f" > /sys/class/firmware/lp5523/data
echo 0 > /sys/class/firmware/lp5523/loading
echo 1 > /sys/class/i2c-adapter/i2c-2/2-0032/run_engine

But it failed at second command. In directory /sys/class/firmware/
I have only one file with name timeout. Nothing more, no lp5523
folder.


I can't reproduce this issue but I found some duplicated mutex problem.
But in my case, I could found /sys/class/firmware/lp5523 directory.
Is any permission issue? Anyway, I've added fixed mutex code below.

Could you check this patch below?
If it's resolved, then I'll send official patch-set.

 8<  8< ---

From dad27e0d834a5635232116569aaa1fa471ac46bf Mon Sep 17 00:00:00 2001
From: Milo Kim 
Date: Fri, 8 Nov 2013 13:43:33 +0900
Subject: [PATCH] leds: lp5523: Fix multiple engine usage bug and remove
 duplicated mutex

Fix multiple engine usage bug:
  Whenever the engine is loaded by the user-application, the operation 
mode is

  reset first. But it has a problem in case of multiple engine used because
  previous engine settings are cleared.
  The driver should update not whole 8bits but each engine bits by masking.

Remove duplicate mutex:
  It can be a problem when a pattern is loaded via the firmware interface.
  LP55xx

Re: [PATCH 00/10] leds: lp5521,5523: restore device attributes for running LED patterns

2013-11-19 Thread Milo Kim

Hi Bryan,

On 11/20/2013 04:20 AM, Bryan Wu wrote:

On Tue, Nov 19, 2013 at 2:35 AM, Pali Rohár  wrote:

>Hello,
>
>now I tested that patch on top of 3.12-rc5 with this led example:
>
> # Clearing LED-state to be sure
> echo "disabled" > /sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode
> echo "disabled" > /sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode
> echo 0 > /sys/class/leds/lp5523:r/brightness
> echo 0 > /sys/class/leds/lp5523:g/brightness
> echo 0 > /sys/class/leds/lp5523:b/brightness
>
> # Setting yellow light pattern and running it
> echo "load" > /sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode
> echo "01100" > /sys/class/i2c-adapter/i2c-2/2-0032/engine1_leds
> echo "9d804000427f0d7f7f007f004200" > 
/sys/class/i2c-adapter/i2c-2/2-0032/engine1_load
> echo "load" > /sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode
> echo "0" > /sys/class/i2c-adapter/i2c-2/2-0032/engine2_leds
> echo "9d80" > /sys/class/i2c-adapter/i2c-2/2-0032/engine2_load
> echo "run" > /sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode
> echo "run" > /sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode
> echo 20 > /sys/class/leds/lp5523:r/led_current
> echo 2 > /sys/class/leds/lp5523:g/led_current
> echo 0 > /sys/class/leds/lp5523:b/led_current
>
>And now it working, led blinks :-) I also tested Maemo
>application for managing lp5523 led and now it working too.
>

That's good. We can post this fixing patch to stable tree as well as
latest upstream kernel.

Milo, do you need to update your patch, if not I'm going to take it
into my tree and for stable tree.


I'll send the patch-set again because LP5521 is also required to be fixed.
And _remove() also needs to be updated.
I can send it by tomorrow.

Thanks,
- Milo


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] leds: lp5521/5523: Fix multiple engine usage bug

2013-11-20 Thread Milo Kim
Whenever the engine is loaded by the user-application, the operation mode is
reset first. But it has a problem in case of multiple engine used because
previous engine settings are cleared.
The driver should update not whole 8bits but each engine bit by masking.

On the other hands, whole engines should be reset when the driver is unloaded
and on initializing the LP5523 driver.
So, new functions are used for this handling - lp5521/5523_stop_all_engines().

Cc: Pali Rohár 
Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp5521.c |   18 --
 drivers/leds/leds-lp5523.c |   20 +---
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 0518835..26f89ac 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -152,12 +152,26 @@ static void lp5521_load_engine(struct lp55xx_chip *chip)
lp5521_wait_opmode_done();
 }
 
-static void lp5521_stop_engine(struct lp55xx_chip *chip)
+static void lp5521_stop_all_engines(struct lp55xx_chip *chip)
 {
lp55xx_write(chip, LP5521_REG_OP_MODE, 0);
lp5521_wait_opmode_done();
 }
 
+static void lp5521_stop_engine(struct lp55xx_chip *chip)
+{
+   enum lp55xx_engine_index idx = chip->engine_idx;
+   u8 mask[] = {
+   [LP55XX_ENGINE_1] = LP5521_MODE_R_M,
+   [LP55XX_ENGINE_2] = LP5521_MODE_G_M,
+   [LP55XX_ENGINE_3] = LP5521_MODE_B_M,
+   };
+
+   lp55xx_update_bits(chip, LP5521_REG_OP_MODE, mask[idx], 0);
+
+   lp5521_wait_opmode_done();
+}
+
 static void lp5521_run_engine(struct lp55xx_chip *chip, bool start)
 {
int ret;
@@ -568,7 +582,7 @@ static int lp5521_remove(struct i2c_client *client)
struct lp55xx_led *led = i2c_get_clientdata(client);
struct lp55xx_chip *chip = led->chip;
 
-   lp5521_stop_engine(chip);
+   lp5521_stop_all_engines(chip);
lp55xx_unregister_sysfs(chip);
lp55xx_unregister_leds(led, chip);
lp55xx_deinit_device(chip);
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 6b553d9..2ce1723 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -187,12 +187,26 @@ static void lp5523_load_engine_and_select_page(struct 
lp55xx_chip *chip)
lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, page_sel[idx]);
 }
 
-static void lp5523_stop_engine(struct lp55xx_chip *chip)
+static void lp5523_stop_all_engines(struct lp55xx_chip *chip)
 {
lp55xx_write(chip, LP5523_REG_OP_MODE, 0);
lp5523_wait_opmode_done();
 }
 
+static void lp5523_stop_engine(struct lp55xx_chip *chip)
+{
+   enum lp55xx_engine_index idx = chip->engine_idx;
+   u8 mask[] = {
+   [LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M,
+   [LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M,
+   [LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M,
+   };
+
+   lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], 0);
+
+   lp5523_wait_opmode_done();
+}
+
 static void lp5523_turn_off_channels(struct lp55xx_chip *chip)
 {
int i;
@@ -303,7 +317,7 @@ static int lp5523_init_program_engine(struct lp55xx_chip 
*chip)
}
 
 out:
-   lp5523_stop_engine(chip);
+   lp5523_stop_all_engines(chip);
return ret;
 }
 
@@ -778,7 +792,7 @@ static int lp5523_remove(struct i2c_client *client)
struct lp55xx_led *led = i2c_get_clientdata(client);
struct lp55xx_chip *chip = led->chip;
 
-   lp5523_stop_engine(chip);
+   lp5523_stop_all_engines(chip);
lp55xx_unregister_sysfs(chip);
lp55xx_unregister_leds(led, chip);
lp55xx_deinit_device(chip);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] leds: lp5521/5523: Remove duplicate mutex

2013-12-02 Thread Milo Kim
It can be a problem when a pattern is loaded via the firmware interface.
LP55xx common driver has already locked the mutex in 'lp55xx_firmware_loaded()'.
So it should be deleted.

On the other hand, locks are required in store_engine_load()
on updating program memory.

Cc: Pali Rohár 
Signed-off-by: Milo Kim 
---
 drivers/leds/leds-lp5521.c |   12 
 drivers/leds/leds-lp5523.c |   12 
 2 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 26f89ac..2ec34cf 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -258,18 +258,12 @@ static int lp5521_update_program_memory(struct 
lp55xx_chip *chip,
if (i % 2)
goto err;
 
-   mutex_lock(&chip->lock);
-
for (i = 0; i < LP5521_PROGRAM_LENGTH; i++) {
ret = lp55xx_write(chip, addr[idx] + i, pattern[i]);
-   if (ret) {
-   mutex_unlock(&chip->lock);
+   if (ret)
return -EINVAL;
-   }
}
 
-   mutex_unlock(&chip->lock);
-
return size;
 
 err:
@@ -441,15 +435,17 @@ static ssize_t store_engine_load(struct device *dev,
 {
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
struct lp55xx_chip *chip = led->chip;
+   int ret;
 
mutex_lock(&chip->lock);
 
chip->engine_idx = nr;
lp5521_load_engine(chip);
+   ret = lp5521_update_program_memory(chip, buf, len);
 
mutex_unlock(&chip->lock);
 
-   return lp5521_update_program_memory(chip, buf, len);
+   return ret;
 }
 store_load(1)
 store_load(2)
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 2ce1723..bf21852 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -351,18 +351,12 @@ static int lp5523_update_program_memory(struct 
lp55xx_chip *chip,
if (i % 2)
goto err;
 
-   mutex_lock(&chip->lock);
-
for (i = 0; i < LP5523_PROGRAM_LENGTH; i++) {
ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + i, pattern[i]);
-   if (ret) {
-   mutex_unlock(&chip->lock);
+   if (ret)
return -EINVAL;
-   }
}
 
-   mutex_unlock(&chip->lock);
-
return size;
 
 err:
@@ -562,15 +556,17 @@ static ssize_t store_engine_load(struct device *dev,
 {
struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
struct lp55xx_chip *chip = led->chip;
+   int ret;
 
mutex_lock(&chip->lock);
 
chip->engine_idx = nr;
lp5523_load_engine_and_select_page(chip);
+   ret = lp5523_update_program_memory(chip, buf, len);
 
mutex_unlock(&chip->lock);
 
-   return lp5523_update_program_memory(chip, buf, len);
+   return ret;
 }
 store_load(1)
 store_load(2)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] leds: lp5521/5523: Remove duplicate mutex

2013-12-02 Thread Milo Kim

Hi Bryan,

On 12/03/2013 04:40 AM, Bryan Wu wrote:

On Wed, Nov 20, 2013 at 10:14 PM, Milo Kim  wrote:

It can be a problem when a pattern is loaded via the firmware interface.
LP55xx common driver has already locked the mutex in 'lp55xx_firmware_loaded()'.
So it should be deleted.



Looks like lp5521_update_program_memory() will be called by
store_engine_load() without holding a lock after this change, is this
correct? I think you need also update store_engine_load() to hold the
lock when calling lp5521_update_program_memory().


Thanks, good point! I've just sent the patch-v2.

Best regards,
  Milo

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 3/4] pwm: add LP3943 PWM driver

2013-12-03 Thread Milo Kim

Hi Thierry,

On 12/03/2013 07:24 PM, Thierry Reding wrote:

On Thu, Sep 12, 2013 at 10:33:50AM +0900, Milo Kim wrote:

This is the other of the LP3943 MFD driver.
LP3943 can be used as a PWM generator, up to 2 channels.

* Two PWM generators supported

* Supported PWM operations
   request, free, config, enable and disable

* Pin assignment
   A driver data, 'pin_used' is checked when a PWM is requested.
   If the output pin is already assigned, then returns as failure.
   If the pin is available, 'pin_used' is set.
   When the PWM is not used anymore, then it is cleared.
   It is defined as unsigned long type for atomic bit operation APIs,
   but only LSB 16bits are used because LP3943 has 16 outputs.

Cc: Thierry Reding 
Signed-off-by: Milo Kim 
---
* Patch v3
   Manual polarity not supported any more.
   Add encapsulation functions for accessing internal data structure.
   Use pwm_set_chip_data() and pwm_get_chip_data().
   And other code fixes based on Thierry's feedback.

  drivers/pwm/Kconfig  |   10 ++
  drivers/pwm/Makefile |1 +
  drivers/pwm/pwm-lp3943.c |  314 ++
  3 files changed, 325 insertions(+)
  create mode 100644 drivers/pwm/pwm-lp3943.c


Hi Milo,

Is this patchset still the latest version? I've tried to remember the
status of this series, but I could only draw a blank.


Thanks a lot for this reminder.
I forgot to check the status.

The latest one is the v4, but LP3943 PWM driver code is same as v3.

  Update from v3 to v4:
Move the driver description from the documentation to the MFD 
driver file.


There are two things to be ACKed for v4.
One is the PWM driver. (https://lkml.org/lkml/2013/9/25/11)
The other is the documentation. (https://lkml.org/lkml/2013/9/25/10)

Thanks,
  Milo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 0/4] LP3943 MFD driver for a GPIO expander and a PWM generator

2013-12-03 Thread Milo Kim

Hello Guys,

Could you check this patchset?
Driver documentation was moved from 'Documentation' to 
'drivers/mfd/lp3943.c'.


Thanks,
  Milo

On 09/25/2013 01:22 PM, Milo Kim wrote:

LP3943 is an integrated device capable of driving 16 output channels.
It can be used for GPIO expander and PWM generators.
LP3493 registers are controlled via the I2C interface.

This patch-set consists of four parts - MFD, GPIO, PWM and documents.

Update from v3 to v4:
   Move the driver description from the documentation to the MFD driver file.

Milo Kim (4):
   mfd: add LP3943 MFD driver
   gpio: add LP3943 I2C GPIO expander driver
   pwm: add LP3943 PWM driver
   Documentation: add LP3943 DT bindings and document

  .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 +++
  Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 ++
  .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 
  drivers/gpio/Kconfig   |8 +
  drivers/gpio/Makefile  |1 +
  drivers/gpio/gpio-lp3943.c |  242 +++
  drivers/mfd/Kconfig|   11 +
  drivers/mfd/Makefile   |1 +
  drivers/mfd/lp3943.c   |  167 +++
  drivers/pwm/Kconfig|   10 +
  drivers/pwm/Makefile   |1 +
  drivers/pwm/pwm-lp3943.c   |  314 
  include/linux/mfd/lp3943.h |  114 +++
  13 files changed, 997 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
  create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
  create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
  create mode 100644 drivers/gpio/gpio-lp3943.c
  create mode 100644 drivers/mfd/lp3943.c
  create mode 100644 drivers/pwm/pwm-lp3943.c
  create mode 100644 include/linux/mfd/lp3943.h



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 09/13] video/backlight: LP8788 needs PWM

2014-04-24 Thread Milo Kim

On 04/24/2014 09:28 PM, Peter Griffin wrote:

The LP8788 driver cannot be successfully built if we don't
enable the PWM subsystem. This patch makes that dependency
explicit in Kconfig and prevents broken randconfig builds.

Based on Arnd Bergmann patch but split out into seperate
commits per driver based on feedback.

Signed-off-by: Arnd Bergmann 
Signed-off-by: Peter Griffin 


Thanks!

Acked-by: Milo Kim 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 12/13] video/backlight: LP855X needs PWM

2014-04-24 Thread Milo Kim

On 04/24/2014 09:28 PM, Peter Griffin wrote:

From: Arnd Bergmann 

The LP855X driver cannot be successfully built if we don't
enable the PWM subsystem. This patch makes that dependency
explicit in Kconfig and prevents broken randconfig builds.



Thanks!

Acked-by: Milo Kim 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 00/10] Support TI Light Management Unit devices

2014-02-13 Thread Milo Kim
TI LMU (Lighting Management Unit) driver supports lighting devices such like
LM3532, LM3631, LM3633, LM3695 and LM3697.

 Enable pin  Backlights  PWM control  Light effects  Others
 --  --  ---  -  --
LM3532   Yes Yes Yes  ramp up/down
LM3631   Yes Yes Yes  slope  5 regulators
LM3633   Yes Yes Yes  ramp up/down   LEDs
  /pattern
LM3695   Yes Yes No
LM3697   Yes Yes Yes  ramp up/down

This patch-set consists of several parts below.

  TI LMU: HW enable pin control. I2C register access
  TI LMU effect : Light effect support for backlight and LED
  TI LMU backlight  : Backlight subsystem, PWM, control bank assignment
  Each backlight driver : Chip dependent code
  LM3633 LED: LED subsystem, pattern generation
  LM3631 regulator  : Regulator drivers for the display bias

Device tree documentation is also included.

Milo Kim (10):
  mfd: Add TI LMU driver
  backlight: Add TI LMU backlight common driver
  backlight: ti-lmu-backlight: Add LM3532 driver
  backlight: ti-lmu-backlight: Add LM3631 driver
  backlight: ti-lmu-backlight: Add LM3633 driver
  backlight: ti-lmu-backlight: Add LM3695 driver
  backlight: ti-lmu-backlight: Add LM3697 driver
  leds: Add LM3633 driver
  regulator: Add LM3631 driver
  Documentation: Add device tree bindings for TI LMU devices

 .../devicetree/bindings/leds/leds-lm3633.txt   |   39 ++
 Documentation/devicetree/bindings/mfd/ti-lmu.txt   |  182 ++
 .../bindings/regulator/lm3631-regulator.txt|   49 ++
 .../bindings/video/backlight/ti-lmu-backlight.txt  |  127 
 Documentation/leds/leds-lm3633.txt |   38 ++
 drivers/leds/Kconfig   |   10 +
 drivers/leds/Makefile  |1 +
 drivers/leds/leds-lm3633.c |  661 
 drivers/mfd/Kconfig|   12 +
 drivers/mfd/Makefile   |1 +
 drivers/mfd/ti-lmu-effect.c|  328 ++
 drivers/mfd/ti-lmu.c   |  464 ++
 drivers/regulator/Kconfig  |8 +
 drivers/regulator/Makefile |1 +
 drivers/regulator/lm3631-regulator.c   |  285 +
 drivers/video/backlight/Kconfig|   51 ++
 drivers/video/backlight/Makefile   |6 +
 drivers/video/backlight/lm3532_bl.c|  240 +++
 drivers/video/backlight/lm3631_bl.c|  186 ++
 drivers/video/backlight/lm3633_bl.c|  244 
 drivers/video/backlight/lm3695_bl.c|  143 +
 drivers/video/backlight/lm3697_bl.c|  224 +++
 drivers/video/backlight/ti-lmu-backlight.c |  369 +++
 drivers/video/backlight/ti-lmu-backlight.h |   78 +++
 include/linux/mfd/ti-lmu-effect.h  |  109 
 include/linux/mfd/ti-lmu-register.h|  269 
 include/linux/mfd/ti-lmu.h |  150 +
 27 files changed, 4275 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-lm3633.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/ti-lmu.txt
 create mode 100644 
Documentation/devicetree/bindings/regulator/lm3631-regulator.txt
 create mode 100644 
Documentation/devicetree/bindings/video/backlight/ti-lmu-backlight.txt
 create mode 100644 Documentation/leds/leds-lm3633.txt
 create mode 100644 drivers/leds/leds-lm3633.c
 create mode 100644 drivers/mfd/ti-lmu-effect.c
 create mode 100644 drivers/mfd/ti-lmu.c
 create mode 100644 drivers/regulator/lm3631-regulator.c
 create mode 100644 drivers/video/backlight/lm3532_bl.c
 create mode 100644 drivers/video/backlight/lm3631_bl.c
 create mode 100644 drivers/video/backlight/lm3633_bl.c
 create mode 100644 drivers/video/backlight/lm3695_bl.c
 create mode 100644 drivers/video/backlight/lm3697_bl.c
 create mode 100644 drivers/video/backlight/ti-lmu-backlight.c
 create mode 100644 drivers/video/backlight/ti-lmu-backlight.h
 create mode 100644 include/linux/mfd/ti-lmu-effect.h
 create mode 100644 include/linux/mfd/ti-lmu-register.h
 create mode 100644 include/linux/mfd/ti-lmu.h

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 03/10] backlight: ti-lmu-backlight: Add LM3532 driver

2014-02-13 Thread Milo Kim
LM3532 has 3 backlight strings and 8 bit dimming is supported.
PWM brightness control is also supported.

Common backlight driver is controlled by TI LMU backlight driver.
Only LM3532 specific code is implemented here.

Cc: Jingoo Han 
Cc: Bryan Wu 
Cc: Lee Jones 
Signed-off-by: Milo Kim 
---
 drivers/video/backlight/Kconfig |9 ++
 drivers/video/backlight/Makefile|1 +
 drivers/video/backlight/lm3532_bl.c |  240 +++
 3 files changed, 250 insertions(+)
 create mode 100644 drivers/video/backlight/lm3532_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 3641698..d841057 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -384,6 +384,15 @@ config BACKLIGHT_LM3639
help
  This supports TI LM3639 Backlight + 1.5A Flash LED Driver
 
+config BACKLIGHT_LM3532
+   tristate "Backlight driver for TI LM3532"
+   depends on BACKLIGHT_CLASS_DEVICE && MFD_TI_LMU
+   select TI_LMU_BACKLIGHT
+   help
+ Say Y to enable the backlight driver for TI LM3532.
+ Up to 3 backlight strings and 8 bit dimming is supported.
+ PWM brightness control is also supported.
+
 config TI_LMU_BACKLIGHT
tristate "Backlight driver for TI LMU"
depends on BACKLIGHT_LM3532 || BACKLIGHT_LM3631 || BACKLIGHT_LM3633 || 
BACKLIGHT_LM3695 || BACKLIGHT_LM3697
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index f80e046..51354d1 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3630A)+= lm3630a_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3532) += lm3532_bl.o
 obj-$(CONFIG_TI_LMU_BACKLIGHT) += ti-lmu-backlight.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
 obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
diff --git a/drivers/video/backlight/lm3532_bl.c 
b/drivers/video/backlight/lm3532_bl.c
new file mode 100644
index 000..c4cf636
--- /dev/null
+++ b/drivers/video/backlight/lm3532_bl.c
@@ -0,0 +1,240 @@
+/*
+ * TI LM3532 Backlight Driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * LM3532 backlight driver consists of three parts
+ *
+ *   1) LM3532 chip specific part: this file
+ *  Define device specific operations
+ *  Register LMU backlight driver
+ *
+ *   2) LMU backlight common driver: ti-lmu-backlight
+ *  General backlight subsystem control
+ *
+ *   3) LMU effect driver
+ *  Backlight ramp time configuration
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ti-lmu-backlight.h"
+
+#define LM3532_PWM10
+#define LM3532_PWM21
+#define LM3532_BL_MAX_STRINGS  3
+#define LM3532_MAX_ZONE_CFG3
+#define LM3532_MAX_BRIGHTNESS  255
+
+static int lm3532_bl_init(struct ti_lmu_bl_chip *chip)
+{
+   int i, ret;
+   u8 lm3532_regs[] = { LM3532_REG_ZONE_CFG_A, LM3532_REG_ZONE_CFG_B,
+LM3532_REG_ZONE_CFG_C, };
+
+   /*
+* Assign zone targets as below.
+*   Zone target 0 for control A
+*   Zone target 1 for control B
+*   Zone target 2 for control C
+*/
+
+   for (i = 0; i < LM3532_MAX_ZONE_CFG; i++) {
+   ret = ti_lmu_update_bits(chip->lmu, lm3532_regs[i],
+LM3532_ZONE_CFG_MASK,
+i << LM3532_ZONE_CFG_SHIFT);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static int lm3532_bl_enable(struct ti_lmu_bl *lmu_bl, int enable)
+{
+   return ti_lmu_update_bits(lmu_bl->chip->lmu, LM3532_REG_ENABLE,
+ BIT(lmu_bl->bank_id),
+ enable << lmu_bl->bank_id);
+}
+
+static int lm3532_bl_set_brightness(struct ti_lmu_bl *lmu_bl, int brightness)
+{
+   u8 reg[] = { LM3532_REG_BRT_A, LM3532_REG_BRT_B, LM3532_REG_BRT_C, };
+
+   return ti_lmu_write_byte(lmu_bl->chip->lmu, reg[lmu_bl->bank_id],
+brightness);
+}
+
+static int lm3532_bl_select_pwm_bank(struct ti_lmu_bl *lmu_bl, int bank_id)
+{
+   struct ti_lmu *lmu = lmu_bl->chip->lmu;
+   static int num_pwms;
+   u8 pwm_sel;
+   u8 mask[]  = { LM3532_PWM_SEL_A_MASK, LM3532_PWM_SEL_B_MASK,
+  LM3532_PWM_S

[PATCH 02/10] backlight: Add TI LMU backlight common driver

2014-02-13 Thread Milo Kim
TI LMU backlight driver provides common driver features.
Chip specific configuration is handled by each backlight driver such like
LM3532, LM3631, LM3633, LM3695 and LM3697.

It supports common features as below.
  - Consistent device control flow
  - Control bank assignment from the platform data
  - Backlight subsystem control
  - PWM brightness control
  - Shared device tree node

Cc: Jingoo Han 
Cc: Bryan Wu 
Cc: Lee Jones 
Signed-off-by: Milo Kim 
---
 drivers/video/backlight/Kconfig|7 +
 drivers/video/backlight/Makefile   |1 +
 drivers/video/backlight/ti-lmu-backlight.c |  369 
 drivers/video/backlight/ti-lmu-backlight.h |   78 ++
 4 files changed, 455 insertions(+)
 create mode 100644 drivers/video/backlight/ti-lmu-backlight.c
 create mode 100644 drivers/video/backlight/ti-lmu-backlight.h

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 5a3eb2e..3641698 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -384,6 +384,13 @@ config BACKLIGHT_LM3639
help
  This supports TI LM3639 Backlight + 1.5A Flash LED Driver
 
+config TI_LMU_BACKLIGHT
+   tristate "Backlight driver for TI LMU"
+   depends on BACKLIGHT_LM3532 || BACKLIGHT_LM3631 || BACKLIGHT_LM3633 || 
BACKLIGHT_LM3695 || BACKLIGHT_LM3697
+   help
+ TI LMU backlight driver provides common driver features.
+ Chip specific configuration is handled by each backlight driver.
+
 config BACKLIGHT_LP855X
tristate "Backlight driver for TI LP855X"
depends on BACKLIGHT_CLASS_DEVICE && I2C
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index bb82002..f80e046 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3630A)+= lm3630a_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
+obj-$(CONFIG_TI_LMU_BACKLIGHT) += ti-lmu-backlight.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
 obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
 obj-$(CONFIG_BACKLIGHT_LP8788) += lp8788_bl.o
diff --git a/drivers/video/backlight/ti-lmu-backlight.c 
b/drivers/video/backlight/ti-lmu-backlight.c
new file mode 100644
index 000..5ceb5e8
--- /dev/null
+++ b/drivers/video/backlight/ti-lmu-backlight.c
@@ -0,0 +1,369 @@
+/*
+ * TI LMU Backlight Common Driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * LMU backlight driver supports common features as below.
+ *
+ *   - Consistent device control flow by using ti_lmu_bl_ops
+ *   - Control bank assignment from the platform data
+ *   - Backlight subsystem control
+ *   - PWM brightness control
+ *   - Shared device tree node
+ *
+ * Sequence of LMU backlight control
+ *
+ *   (Chip dependent backlight driver)(TI LMU Backlight Common)
+ *
+ * Operation configuration
+ * ti_lmu_backlight_init_device()   --->
+ * Initialization   <---ops->init()
+ *
+ * ti_lmu_backlight_register()  --->
+ * Backlight configuration  <---ops->configure()
+ *
+ *  Runtime brightness control
+ * Enable register control  <---ops->bl_enable()
+ * Brightness register control  <---ops->update_brightness()
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ti-lmu-backlight.h"
+
+#define DEFAULT_BL_NAME"lcd-backlight"
+
+static int ti_lmu_backlight_enable(struct ti_lmu_bl *lmu_bl, int enable)
+{
+   const struct ti_lmu_bl_ops *ops = lmu_bl->chip->ops;
+
+   if (ops->bl_enable)
+   return ops->bl_enable(lmu_bl, enable);
+
+   return 0;
+}
+
+static void ti_lmu_backlight_pwm_ctrl(struct ti_lmu_bl *lmu_bl, int br,
+ int max_br)
+{
+   struct pwm_device *pwm;
+   unsigned int duty, period;
+
+   /* Request a PWM device with the consumer name */
+   if (!lmu_bl->pwm) {
+   pwm = devm_pwm_get(lmu_bl->chip->dev, lmu_bl->pwm_name);
+   if (IS_ERR(pwm)) {
+   dev_err(lmu_bl->chip->dev,
+   "Can not get PWM device: %s\n",
+   lmu_bl->pwm_name);
+   return;
+   }
+   lmu_bl->pwm = pwm;
+   }
+
+   period = lmu_bl-&

[PATCH 01/10] mfd: Add TI LMU driver

2014-02-13 Thread Milo Kim
TI LMU (Lighting Management Unit) driver supports lighting devices such like
LM3532, LM3631, LM3633, LM3695 and LM3697.

LMU devices has common features as below.
  - I2C interface for accessing device registers
  - Hardware enable pin control
  - Backlight brightness control
  - Light effect driver for backlight and LED patterns

It contains backlight, light effect, LED and regulator driver.

Backlight
-
  It's handled by TI LMU backlight common driver and chip dependent driver.
  Please refer to separate patches for ti-lmu-backlight.

Light effect

  LMU effect driver is used for setting any light effects.
  Each device has specific time value and register map.
  Backlight and LED driver can use consitent APIs for light effects.

  There are two lists for effect management. LMU effect list and pending list.
  Light effect list is added when ti-lmu-effect driver is loaded by referencing
  platform resource data.
  However, it can be a problem because some LMU device requests the effect
  in advance of loading ti-lmu-effect driver.

  For example, LM3532 backlight driver requests light ramp effects before
  ti-lmu-effect is loaded.
  Then, requested effect can not be handled because it doesn't exist in the 
list.
  To solve this situation, pending request list is used.
  If requested effect is not in the list, just insert it into the pending list.
  And then pending request is handled as soon as the effect is added.

LED indicator
-
  LM3633 has 6 indicator LEDs. Programmable pattern is supported.

Regulator
-
  LM3631 has 5 regulators for the display bias.

Cc: Samuel Ortiz 
Cc: Lee Jones 
Signed-off-by: Milo Kim 
---
 drivers/mfd/Kconfig |   12 +
 drivers/mfd/Makefile|1 +
 drivers/mfd/ti-lmu-effect.c |  328 +
 drivers/mfd/ti-lmu.c|  464 +++
 include/linux/mfd/ti-lmu-effect.h   |  109 
 include/linux/mfd/ti-lmu-register.h |  269 
 include/linux/mfd/ti-lmu.h  |  150 +++
 7 files changed, 1333 insertions(+)
 create mode 100644 drivers/mfd/ti-lmu-effect.c
 create mode 100644 drivers/mfd/ti-lmu.c
 create mode 100644 include/linux/mfd/ti-lmu-effect.h
 create mode 100644 include/linux/mfd/ti-lmu-register.h
 create mode 100644 include/linux/mfd/ti-lmu.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d4be491..e7e1e6b 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -784,6 +784,18 @@ config MFD_PALMAS
  If you say yes here you get support for the Palmas
  series of PMIC chips from Texas Instruments.
 
+config MFD_TI_LMU
+   tristate "TI Lighting Management Unit driver"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ Say yes here to enable support for TI LMU chips.
+
+ TI LMU MFD supports LM3532, LM3631, LM3633, LM3695 and LM3697.
+ It consists of backlight, light effect, LED and regulator driver.
+ It provides consistent device controls for lighting functions.
+
 config MFD_TI_SSP
tristate "TI Sequencer Serial Port support"
depends on ARCH_DAVINCI_TNETV107X
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 93c7cad..02dc65a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_HTC_I2CPLD)  += htc-i2cpld.o
 
 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC)   += davinci_voicecodec.o
 obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
+obj-$(CONFIG_MFD_TI_LMU)   += ti-lmu.o ti-lmu-effect.o
 obj-$(CONFIG_MFD_TI_SSP)   += ti-ssp.o
 obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o
 
diff --git a/drivers/mfd/ti-lmu-effect.c b/drivers/mfd/ti-lmu-effect.c
new file mode 100644
index 000..a4a3d26
--- /dev/null
+++ b/drivers/mfd/ti-lmu-effect.c
@@ -0,0 +1,328 @@
+/*
+ * TI LMU Effect Driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * LMU effect driver is used for setting any light effects.
+ * Each device has specific time value and register map.
+ * Light effect can be controlled with consistent APIs.
+ *
+ * Examples:
+ *   Backlight ramp time control - LM3532, LM3631, LM3633 and LM3697
+ *   LED pattern display - LM3633
+ *
+ * Flow:
+ *   1) LMU backlight and LED drivers request to the light effect driver
+ *  by using ti_lmu_effect_request().
+ *   2) Call ti_lmu_effect_set_* APIs in each callback function.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LMU_EFFECT_MAX_TIME_PERIOD 9700
+
+struct ti_lmu_effect_req {
+   struct list_head list;
+   const char *name;
+   ti_lmu_effect_cb_t *cbfunc;
+   int req_id;
+  

[PATCH 08/10] leds: Add LM3633 driver

2014-02-13 Thread Milo Kim
LM3633 LED driver supports generic LED functions and pattern generation.
Pattern is generated by using LMU effect driver APIs.
Sysfs documentation is added.

Cc: Bryan Wu 
Signed-off-by: Milo Kim 
---
 Documentation/leds/leds-lm3633.txt |   38 +++
 drivers/leds/Kconfig   |   10 +
 drivers/leds/Makefile  |1 +
 drivers/leds/leds-lm3633.c |  661 
 4 files changed, 710 insertions(+)
 create mode 100644 Documentation/leds/leds-lm3633.txt
 create mode 100644 drivers/leds/leds-lm3633.c

diff --git a/Documentation/leds/leds-lm3633.txt 
b/Documentation/leds/leds-lm3633.txt
new file mode 100644
index 000..a5a59c3
--- /dev/null
+++ b/Documentation/leds/leds-lm3633.txt
@@ -0,0 +1,38 @@
+LM3633 LED Driver
+=
+
+LM3633 LED driver supports not only LED functions but also programmable 
pattern.
+A pattern is generated via the sysfs.
+
+LED Pattern Generator
+
+(3)
+  (a) --->  ___
+   /   \
+  (2) / \ (4)
+  (b) > _/   \_  ...
+   (1)   (5)
+
+ |<-   period   -> |
+
+  Time dimension
+(1) delay : 0 ~ 10 sec
+(2) rise  : 0 ~ 16 sec
+(3) high  : 0 ~ 10 sec
+(4) fall  : 0 ~ 16 sec
+(5) low   : 0 ~ 16 sec
+
+  Level dimension - channel current
+(a) low   : 0 ~ 255
+(b) high  : 0 ~ 255
+
+Example)
+Time  : No delay, rise 500ms, high 1000ms, fall 400ms, low 2000ms
+Level : Brightness 0 and 255
+
+echo 0 500 1000 400 2000 > /sys/class/leds//pattern_times
+echo 0 255 >  /sys/class/leds//pattern_levels
+echo 1 >  /sys/class/leds//run_pattern
+
+To stop running pattern,
+echo 0 >  /sys/class/leds//run_pattern
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 72156c1..ed659be 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -63,6 +63,16 @@ config LEDS_LM3533
  hardware-accelerated blinking with maximum on and off periods of 9.8
  and 77 seconds respectively.
 
+config LEDS_LM3633
+   tristate "LED support for the TI LM3633 LMU"
+   depends on LEDS_CLASS
+   depends on MFD_TI_LMU
+   help
+ This option enables support for the LEDs on the LM3633.
+ LM3633 has 6 low voltage indicator LEDs.
+ All low voltage current sinks can have a programmable pattern
+ modulated onto LED output strings.
+
 config LEDS_LM3642
tristate "LED support for LM3642 Chip"
depends on LEDS_CLASS && I2C
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 3cd76db..96f55fe 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
 obj-$(CONFIG_LEDS_LOCOMO)  += leds-locomo.o
 obj-$(CONFIG_LEDS_LM3530)  += leds-lm3530.o
 obj-$(CONFIG_LEDS_LM3533)  += leds-lm3533.o
+obj-$(CONFIG_LEDS_LM3633)  += leds-lm3633.o
 obj-$(CONFIG_LEDS_LM3642)  += leds-lm3642.o
 obj-$(CONFIG_LEDS_MIKROTIK_RB532)  += leds-rb532.o
 obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
diff --git a/drivers/leds/leds-lm3633.c b/drivers/leds/leds-lm3633.c
new file mode 100644
index 000..13a43bf
--- /dev/null
+++ b/drivers/leds/leds-lm3633.c
@@ -0,0 +1,661 @@
+/*
+ * TI LM3633 LED driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * LM3633 LED driver has features below.
+ *
+ *   - Generic LED subsystem control
+ *   - LED string configuration
+ *   - Pattern programming via the sysfs
+ *   - Platform data configuration from the device tree nodes
+ *
+ * Pattern generated by using LMU effect driver APIs.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LM3633_LED_MAX_BRIGHTNESS  255
+#define LM3633_DEFAULT_LED_NAME"indicator"
+
+enum lm3633_led_bank_id {
+   LM3633_LED_BANK_C,
+   LM3633_LED_BANK_D,
+   LM3633_LED_BANK_E,
+   LM3633_LED_BANK_F,
+   LM3633_LED_BANK_G,
+   LM3633_LED_BANK_H,
+   LM3633_MAX_LEDS,
+};
+
+struct lm3633_pattern_time {
+   unsigned int delay;
+   unsigned int rise;
+   unsigned int high;
+   unsigned int fall;
+   unsigned int low;
+};
+
+struct lm3633_pattern_level {
+   u8 low;
+   u8 high;
+};
+
+/* One LED chip can have multiple LED strings (max: 6) */
+struct ti_lmu_led_chip {
+   struct device *dev;
+   struct ti_lmu *lmu;
+   struct mutex lock;
+   int num_leds;
+};
+
+/* LED string structure */
+struct ti_lmu_led {
+   enum 

[PATCH 06/10] backlight: ti-lmu-backlight: Add LM3695 driver

2014-02-13 Thread Milo Kim
LM3695 has 2 backlight strings and 11 bit dimming is supported.

Common backlight driver is controlled by TI LMU backlight driver.
Only LM3695 specific code is implemented here.

Cc: Jingoo Han 
Cc: Bryan Wu 
Cc: Lee Jones 
Signed-off-by: Milo Kim 
---
 drivers/video/backlight/Kconfig |8 ++
 drivers/video/backlight/Makefile|1 +
 drivers/video/backlight/lm3695_bl.c |  143 +++
 3 files changed, 152 insertions(+)
 create mode 100644 drivers/video/backlight/lm3695_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index aa012a3..b169c8d 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -411,6 +411,14 @@ config BACKLIGHT_LM3633
  Up to 3 backlight strings and 11 bit dimming is supported.
  PWM brightness control is also supported.
 
+config BACKLIGHT_LM3695
+   tristate "Backlight driver for TI LM3695"
+   depends on BACKLIGHT_CLASS_DEVICE && MFD_TI_LMU
+   select TI_LMU_BACKLIGHT
+   help
+ Say Y to enable the backlight driver for TI LM3695.
+ Up to 2 backlight strings and 11 bit dimming is supported.
+
 config TI_LMU_BACKLIGHT
tristate "Backlight driver for TI LMU"
depends on BACKLIGHT_LM3532 || BACKLIGHT_LM3631 || BACKLIGHT_LM3633 || 
BACKLIGHT_LM3695 || BACKLIGHT_LM3697
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 842a256..5427162 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_BACKLIGHT_LM3639)+= lm3639_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3532) += lm3532_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3631) += lm3631_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3633) += lm3633_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3695) += lm3695_bl.o
 obj-$(CONFIG_TI_LMU_BACKLIGHT) += ti-lmu-backlight.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
 obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
diff --git a/drivers/video/backlight/lm3695_bl.c 
b/drivers/video/backlight/lm3695_bl.c
new file mode 100644
index 000..959e72a
--- /dev/null
+++ b/drivers/video/backlight/lm3695_bl.c
@@ -0,0 +1,143 @@
+/*
+ * TI LM3695 Backlight Driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * LM3695 backlight driver consists of two parts
+ *
+ *   1) LM3695 chip specific part: this file
+ *  Define device specific operations
+ *  Register LMU backlight driver
+ *
+ *   2) LMU backlight common driver: ti-lmu-backlight
+ *  General backlight subsystem control
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ti-lmu-backlight.h"
+
+#define LM3695_FULL_STRINGS(LMU_HVLED1 | LMU_HVLED2)
+#define LM3695_MAX_BRIGHTNESS  2047
+
+static int lm3695_bl_enable(struct ti_lmu_bl *lmu_bl, int enable)
+{
+   int ret;
+
+   ret = ti_lmu_update_bits(lmu_bl->chip->lmu, LM3695_REG_GP,
+LM3695_BL_EN_MASK, enable);
+   if (ret)
+   return ret;
+
+   /* Wait time for brightness register wake up */
+   usleep_range(600, 700);
+
+   return 0;
+}
+
+static int lm3695_bl_set_brightness(struct ti_lmu_bl *lmu_bl, int brightness)
+{
+   u8 data;
+   int ret;
+
+   data = brightness & LM3695_BRT_LSB_MASK;
+   ret = ti_lmu_update_bits(lmu_bl->chip->lmu, LM3695_REG_BRT_LSB,
+LM3695_BRT_LSB_MASK, data);
+   if (ret)
+   return ret;
+
+   data = (brightness >> LM3695_BRT_MSB_SHIFT) & 0xFF;
+   return ti_lmu_write_byte(lmu_bl->chip->lmu, LM3695_REG_BRT_MSB,
+data);
+}
+
+static int lm3695_bl_init(struct ti_lmu_bl_chip *chip)
+{
+   return ti_lmu_update_bits(chip->lmu, LM3695_REG_GP,
+ LM3695_BRT_RW_MASK, LM3695_BRT_SET_RW);
+}
+
+static int lm3695_bl_configure(struct ti_lmu_bl *lmu_bl)
+{
+   u8 val;
+
+   if (lmu_bl->bl_pdata->bl_string == LM3695_FULL_STRINGS)
+   val = LM3695_BL_TWO_STRINGS;
+   else
+   val = LM3695_BL_ONE_STRING;
+
+   return ti_lmu_update_bits(lmu_bl->chip->lmu, LM3695_REG_GP,
+ LM3695_BL_STRING_MASK, val);
+}
+
+static const struct ti_lmu_bl_ops lm3695_lmu_ops = {
+   .init  = lm3695_bl_init,
+   .configure = lm3695_bl_configure,
+   .update_brightness = lm3695_bl_set_brightness,
+   .bl_enable = lm3695_bl_enable,
+   .max_brightness= LM3695_MAX_BRIGHTNESS,
+};
+
+static int lm3695_bl_probe(struct pl

[PATCH 05/10] backlight: ti-lmu-backlight: Add LM3633 driver

2014-02-13 Thread Milo Kim
LM3633 has 3 backlight strings and 11 bit dimming is supported.
PWM brightness control is also supported.

Common backlight driver is controlled by TI LMU backlight driver.
Only LM3633 specific code is implemented here.

Cc: Jingoo Han 
Cc: Bryan Wu 
Cc: Lee Jones 
Signed-off-by: Milo Kim 
---
 drivers/video/backlight/Kconfig |9 ++
 drivers/video/backlight/Makefile|1 +
 drivers/video/backlight/lm3633_bl.c |  244 +++
 3 files changed, 254 insertions(+)
 create mode 100644 drivers/video/backlight/lm3633_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index a43a015..aa012a3 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -402,6 +402,15 @@ config BACKLIGHT_LM3631
  Up to 2 backlight strings and 11 bit dimming is supported.
  PWM brightness control is also supported.
 
+config BACKLIGHT_LM3633
+   tristate "Backlight driver for TI LM3633"
+   depends on BACKLIGHT_CLASS_DEVICE && MFD_TI_LMU
+   select TI_LMU_BACKLIGHT
+   help
+ Say Y to enable the backlight driver for TI LM3633.
+ Up to 3 backlight strings and 11 bit dimming is supported.
+ PWM brightness control is also supported.
+
 config TI_LMU_BACKLIGHT
tristate "Backlight driver for TI LMU"
depends on BACKLIGHT_LM3532 || BACKLIGHT_LM3631 || BACKLIGHT_LM3633 || 
BACKLIGHT_LM3695 || BACKLIGHT_LM3697
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 2a17f8b..842a256 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_BACKLIGHT_LM3630A)   += lm3630a_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3532) += lm3532_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3631) += lm3631_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3633) += lm3633_bl.o
 obj-$(CONFIG_TI_LMU_BACKLIGHT) += ti-lmu-backlight.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
 obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
diff --git a/drivers/video/backlight/lm3633_bl.c 
b/drivers/video/backlight/lm3633_bl.c
new file mode 100644
index 000..c12fd42
--- /dev/null
+++ b/drivers/video/backlight/lm3633_bl.c
@@ -0,0 +1,244 @@
+/*
+ * TI LM3633 Backlight Driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * LM3633 backlight driver consists of two parts
+ *
+ *   1) LM3633 chip specific part: this file
+ *  Define device specific operations
+ *  Register LMU backlight driver
+ *
+ *   2) LMU backlight common driver: ti-lmu-backlight
+ *  General backlight subsystem control
+ *
+ *   3) LMU effect driver
+ *  Backlight slope time configuration
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ti-lmu-backlight.h"
+
+#define LM3633_BOOST_OVP_40V   0x6
+#define LM3633_BL_MAX_STRINGS  3
+#define LM3633_BL_MAX_BRIGHTNESS   2047
+
+static int lm3633_bl_init(struct ti_lmu_bl_chip *chip)
+{
+   /* Configure ramp selection for each bank */
+   return ti_lmu_update_bits(chip->lmu, LM3633_REG_BL_RAMP_CONF,
+ LM3633_BL_RAMP_MASK, LM3633_BL_RAMP_EACH);
+}
+
+static int lm3633_bl_enable(struct ti_lmu_bl *lmu_bl, int enable)
+{
+   return ti_lmu_update_bits(lmu_bl->chip->lmu, LM3633_REG_ENABLE,
+ BIT(lmu_bl->bank_id),
+ enable << lmu_bl->bank_id);
+}
+
+static int lm3633_bl_set_brightness(struct ti_lmu_bl *lmu_bl, int brightness)
+{
+   int ret;
+   u8 data;
+   u8 reg_lsb[] = { LM3633_REG_BRT_HVLED_A_LSB,
+LM3633_REG_BRT_HVLED_B_LSB, };
+   u8 reg_msb[] = { LM3633_REG_BRT_HVLED_A_MSB,
+LM3633_REG_BRT_HVLED_B_MSB, };
+
+   if (lmu_bl->mode == BL_PWM_BASED) {
+   /*
+* PWM can start from any non-zero code and dim down to zero.
+* So, brightness register should be updated even in PWM mode.
+*/
+   if (brightness > 0)
+   brightness = LM3633_BL_MAX_BRIGHTNESS;
+   else
+   brightness = 0;
+   }
+
+   data = brightness & LM3633_BRT_HVLED_LSB_MASK;
+   ret = ti_lmu_update_bits(lmu_bl->chip->lmu, reg_lsb[lmu_bl->bank_id],
+LM3633_BRT_HVLED_LSB_MASK, data);
+   if (ret)
+   return ret;
+
+   data = (brightness >> LM3633_BRT_HVLED_MSB_SHIFT) & 0xFF;
+   return ti_lmu_write_byte(lmu_bl-&g

[PATCH 07/10] backlight: ti-lmu-backlight: Add LM3697 driver

2014-02-13 Thread Milo Kim
LM3697 has 3 backlight strings and 11 bit dimming is supported.
PWM brightness control is also supported.

Common backlight driver is controlled by TI LMU backlight driver.
Only LM3697 specific code is implemented here.

Cc: Jingoo Han 
Cc: Bryan Wu 
Cc: Lee Jones 
Signed-off-by: Milo Kim 
---
 drivers/video/backlight/Kconfig |9 ++
 drivers/video/backlight/Makefile|1 +
 drivers/video/backlight/lm3697_bl.c |  224 +++
 3 files changed, 234 insertions(+)
 create mode 100644 drivers/video/backlight/lm3697_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index b169c8d..3c39b30 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -419,6 +419,15 @@ config BACKLIGHT_LM3695
  Say Y to enable the backlight driver for TI LM3695.
  Up to 2 backlight strings and 11 bit dimming is supported.
 
+config BACKLIGHT_LM3697
+   tristate "Backlight driver for TI LM3697"
+   depends on BACKLIGHT_CLASS_DEVICE && MFD_TI_LMU
+   select TI_LMU_BACKLIGHT
+   help
+ Say Y to enable the backlight driver for TI LM3697.
+ Up to 3 backlight strings and 11 bit dimming is supported.
+ PWM brightness control is also supported.
+
 config TI_LMU_BACKLIGHT
tristate "Backlight driver for TI LMU"
depends on BACKLIGHT_LM3532 || BACKLIGHT_LM3631 || BACKLIGHT_LM3633 || 
BACKLIGHT_LM3695 || BACKLIGHT_LM3697
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 5427162..16e6ad7 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_BACKLIGHT_LM3532)+= lm3532_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3631) += lm3631_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3633) += lm3633_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3695) += lm3695_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3697) += lm3697_bl.o
 obj-$(CONFIG_TI_LMU_BACKLIGHT) += ti-lmu-backlight.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
 obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
diff --git a/drivers/video/backlight/lm3697_bl.c 
b/drivers/video/backlight/lm3697_bl.c
new file mode 100644
index 000..18b866a
--- /dev/null
+++ b/drivers/video/backlight/lm3697_bl.c
@@ -0,0 +1,224 @@
+/*
+ * TI LM3697 Backlight Driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * LM3697 backlight driver consists of three parts
+ *
+ *   1) LM3697 chip specific part: this file
+ *  Define device specific operations
+ *  Register LMU backlight driver
+ *
+ *   2) LMU backlight common driver: ti-lmu-backlight
+ *  General backlight subsystem control
+ *
+ *   3) LMU effect driver
+ *  Backlight ramp time configuration
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ti-lmu-backlight.h"
+
+#define LM3697_BL_MAX_STRINGS  3
+#define LM3697_MAX_BRIGHTNESS  2047
+
+static int lm3697_bl_init(struct ti_lmu_bl_chip *chip)
+{
+   /* Configure ramp selection for each bank */
+   return ti_lmu_update_bits(chip->lmu, LM3697_REG_RAMP_CONF,
+ LM3697_RAMP_MASK, LM3697_RAMP_EACH);
+}
+
+static int lm3697_bl_enable(struct ti_lmu_bl *lmu_bl, int enable)
+{
+   return ti_lmu_update_bits(lmu_bl->chip->lmu, LM3697_REG_ENABLE,
+ BIT(lmu_bl->bank_id),
+ enable << lmu_bl->bank_id);
+}
+
+static int lm3697_bl_set_brightness(struct ti_lmu_bl *lmu_bl, int brightness)
+{
+   int ret;
+   u8 data;
+   u8 reg_lsb[] = { LM3697_REG_BRT_A_LSB, LM3697_REG_BRT_B_LSB, };
+   u8 reg_msb[] = { LM3697_REG_BRT_A_MSB, LM3697_REG_BRT_B_MSB, };
+
+   data = brightness & LM3697_BRT_LSB_MASK;
+   ret = ti_lmu_update_bits(lmu_bl->chip->lmu, reg_lsb[lmu_bl->bank_id],
+LM3697_BRT_LSB_MASK, data);
+   if (ret)
+   return ret;
+
+   data = (brightness >> LM3697_BRT_MSB_SHIFT) & 0xFF;
+   return ti_lmu_write_byte(lmu_bl->chip->lmu, reg_msb[lmu_bl->bank_id],
+data);
+}
+
+static int lm3697_bl_set_ctrl_mode(struct ti_lmu_bl *lmu_bl)
+{
+   int bank_id = lmu_bl->bank_id;
+
+   if (lmu_bl->mode == BL_PWM_BASED)
+   return ti_lmu_update_bits(lmu_bl->chip->lmu,
+ LM3697_REG_PWM_CFG,
+ BIT(bank_id), 1 << bank_id);
+
+   return 0;
+}
+
+static int lm3697_bl_string_configure(struct ti_lmu_bl *lmu_bl)
+{
+

[PATCH 04/10] backlight: ti-lmu-backlight: Add LM3631 driver

2014-02-13 Thread Milo Kim
LM3631 has 2 backlight strings and 11 bit dimming is supported.
PWM brightness control is also supported.

Common backlight driver is controlled by TI LMU backlight driver.
Only LM3631 specific code is implemented here.

Cc: Jingoo Han 
Cc: Bryan Wu 
Cc: Lee Jones 
Signed-off-by: Milo Kim 
---
 drivers/video/backlight/Kconfig |9 ++
 drivers/video/backlight/Makefile|1 +
 drivers/video/backlight/lm3631_bl.c |  186 +++
 3 files changed, 196 insertions(+)
 create mode 100644 drivers/video/backlight/lm3631_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index d841057..a43a015 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -393,6 +393,15 @@ config BACKLIGHT_LM3532
  Up to 3 backlight strings and 8 bit dimming is supported.
  PWM brightness control is also supported.
 
+config BACKLIGHT_LM3631
+   tristate "Backlight driver for TI LM3631"
+   depends on BACKLIGHT_CLASS_DEVICE && MFD_TI_LMU
+   select TI_LMU_BACKLIGHT
+   help
+ Say Y to enable the backlight driver for TI LM3631.
+ Up to 2 backlight strings and 11 bit dimming is supported.
+ PWM brightness control is also supported.
+
 config TI_LMU_BACKLIGHT
tristate "Backlight driver for TI LMU"
depends on BACKLIGHT_LM3532 || BACKLIGHT_LM3631 || BACKLIGHT_LM3633 || 
BACKLIGHT_LM3695 || BACKLIGHT_LM3697
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 51354d1..2a17f8b 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_BACKLIGHT_LM3533)+= lm3533_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3630A)+= lm3630a_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3532) += lm3532_bl.o
+obj-$(CONFIG_BACKLIGHT_LM3631) += lm3631_bl.o
 obj-$(CONFIG_TI_LMU_BACKLIGHT) += ti-lmu-backlight.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
 obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
diff --git a/drivers/video/backlight/lm3631_bl.c 
b/drivers/video/backlight/lm3631_bl.c
new file mode 100644
index 000..45693c0
--- /dev/null
+++ b/drivers/video/backlight/lm3631_bl.c
@@ -0,0 +1,186 @@
+/*
+ * TI LM3631 Backlight Driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * LM3631 backlight driver consists of three parts
+ *
+ *   1) LM3631 chip specific part: this file
+ *  Define device specific operations
+ *  Register LMU backlight driver
+ *
+ *   2) LMU backlight common driver: ti-lmu-backlight
+ *  General backlight subsystem control
+ *
+ *   3) LMU effect driver
+ *  Backlight slope time configuration
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ti-lmu-backlight.h"
+
+#define LM3631_FULL_STRINGS(LMU_HVLED1 | LMU_HVLED2)
+#define LM3631_DEFAULT_MODELM3631_MODE_COMB1
+#define LM3631_MAX_BRIGHTNESS  2047
+
+static int lm3631_bl_init(struct ti_lmu_bl_chip *chip)
+{
+   int ret;
+
+   /* Set OVP to 25V by default */
+   ret = ti_lmu_update_bits(chip->lmu, LM3631_REG_BL_BOOST,
+LM3631_BOOST_OVP_MASK, LM3631_BOOST_OVP_25V);
+   if (ret)
+   return ret;
+
+   /* Set the brightness mode to 'comb1' by default */
+   return ti_lmu_update_bits(chip->lmu, LM3631_REG_BRT_MODE,
+ LM3631_MODE_MASK, LM3631_DEFAULT_MODE);
+}
+
+static int lm3631_bl_enable(struct ti_lmu_bl *lmu_bl, int enable)
+{
+   return ti_lmu_update_bits(lmu_bl->chip->lmu, LM3631_REG_DEVCTRL,
+ LM3631_BL_EN_MASK,
+ enable << LM3631_BL_EN_SHIFT);
+}
+
+static int lm3631_bl_set_brightness(struct ti_lmu_bl *lmu_bl, int brightness)
+{
+   u8 data;
+   int ret;
+
+   if (lmu_bl->mode == BL_PWM_BASED)
+   return 0;
+
+   data = brightness & LM3631_BRT_LSB_MASK;
+   ret = ti_lmu_update_bits(lmu_bl->chip->lmu, LM3631_REG_BRT_LSB,
+LM3631_BRT_LSB_MASK, data);
+   if (ret)
+   return ret;
+
+   data = (brightness >> LM3631_BRT_MSB_SHIFT) & 0xFF;
+   return ti_lmu_write_byte(lmu_bl->chip->lmu, LM3631_REG_BRT_MSB,
+data);
+}
+
+static int lm3631_bl_string_configure(struct ti_lmu_bl *lmu_bl)
+{
+   u8 val;
+
+   if (lmu_bl->bl_pdata->bl_string == LM3631_FULL_STRINGS)
+   val = LM3631_BL_TWO_STRINGS;
+   

[PATCH 09/10] regulator: Add LM3631 driver

2014-02-13 Thread Milo Kim
LM3631 regulator driver has 5 regulators.
One boost output and four LDOs are used for the display module.
Boost voltage is configurable but always on.
Supported operations for LDOs are enabled/disabled and voltage change.

Cc: Mark Brown 
Signed-off-by: Milo Kim 
---
 drivers/regulator/Kconfig|8 +
 drivers/regulator/Makefile   |1 +
 drivers/regulator/lm3631-regulator.c |  285 ++
 3 files changed, 294 insertions(+)
 create mode 100644 drivers/regulator/lm3631-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 6a79328..9809d7b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -221,6 +221,14 @@ config REGULATOR_ISL6271A
help
  This driver supports ISL6271A voltage regulator chip.
 
+config REGULATOR_LM3631
+   tristate "TI LM3631 voltage regulators"
+   depends on MFD_TI_LMU
+   help
+ This driver supports LM3631 voltage regulators for the LCD bias.
+ One boost output voltage is configurable and always on.
+ Four LDOs are used for the display module.
+
 config REGULATOR_LP3971
tristate "National Semiconductors LP3971 PMIC regulator driver"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 979f9dd..b20070d 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
 obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
 obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
 obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
+obj-$(CONFIG_REGULATOR_LM3631) += lm3631-regulator.o
 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
 obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o
 obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o
diff --git a/drivers/regulator/lm3631-regulator.c 
b/drivers/regulator/lm3631-regulator.c
new file mode 100644
index 000..930bad4
--- /dev/null
+++ b/drivers/regulator/lm3631-regulator.c
@@ -0,0 +1,285 @@
+/*
+ * TI LM3631 Regulator Driver
+ *
+ * Copyright 2014 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define ENABLE_TIME_USEC   1000
+
+enum lm3631_regulator_id {
+   LM3631_BOOST,   /* Boost output */
+   LM3631_LDO_CONT,/* Display panel controller */
+   LM3631_LDO_OREF,/* Gamma reference */
+   LM3631_LDO_POS, /* Positive display bias output */
+   LM3631_LDO_NEG, /* Negative display bias output */
+};
+
+struct lm3631_regulator {
+   struct ti_lmu *lmu;
+   struct regulator_desc *desc;
+   struct regulator_dev *regulator;
+};
+
+static const int lm3631_boost_vtbl[] = {
+   450, 455, 460, 465, 470, 475, 480, 485,
+   490, 495, 500, 505, 510, 515, 520, 525,
+   530, 535, 540, 545, 550, 555, 560, 565,
+   570, 575, 580, 585, 590, 595, 600, 605,
+   610, 615, 620, 625, 630, 635,
+};
+
+static const int lm3631_ldo_cont_vtbl[] = {
+   180, 230, 280, 330,
+};
+
+static const int lm3631_ldo_target_vtbl[] = {
+   400, 405, 410, 415, 420, 425, 430, 435,
+   440, 445, 450, 455, 460, 465, 470, 475,
+   480, 485, 490, 495, 500, 505, 510, 515,
+   520, 525, 530, 535, 540, 545, 550, 555,
+   560, 565, 570, 575, 580, 585, 590, 595,
+   600,
+};
+
+const int ldo_cont_enable_time[] = {
+   0, 2000, 5000, 1, 2, 5, 10, 20,
+};
+
+static int lm3631_regulator_enable_time(struct regulator_dev *rdev)
+{
+   struct lm3631_regulator *lm3631_regulator = rdev_get_drvdata(rdev);
+   enum lm3631_regulator_id id = rdev_get_id(rdev);
+   u8 val, addr, mask;
+
+   switch (id) {
+   case LM3631_LDO_CONT:
+   addr = LM3631_REG_ENTIME_VCONT;
+   mask = LM3631_ENTIME_CONT_MASK;
+   break;
+   case LM3631_LDO_OREF:
+   addr = LM3631_REG_ENTIME_VOREF;
+   mask = LM3631_ENTIME_MASK;
+   break;
+   case LM3631_LDO_POS:
+   addr = LM3631_REG_ENTIME_VPOS;
+   mask = LM3631_ENTIME_MASK;
+   break;
+   case LM3631_LDO_NEG:
+   addr = LM3631_REG_ENTIME_VNEG;
+   mask = LM3631_ENTIME_MASK;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   

[PATCH 10/10] Documentation: Add device tree bindings for TI LMU devices

2014-02-13 Thread Milo Kim
Bindings for TI LMU, backlight, LM3631 regulator and LM3633 LED are added.

Cc: devicet...@vger.kernel.org
Cc: Bryan Wu 
Cc: Jingoo Han 
Cc: Lee Jones 
Cc: Mark Brown 
Cc: Samuel Ortiz 
Signed-off-by: Milo Kim 
---
 .../devicetree/bindings/leds/leds-lm3633.txt   |   39 +
 Documentation/devicetree/bindings/mfd/ti-lmu.txt   |  182 
 .../bindings/regulator/lm3631-regulator.txt|   49 ++
 .../bindings/video/backlight/ti-lmu-backlight.txt  |  127 ++
 4 files changed, 397 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-lm3633.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/ti-lmu.txt
 create mode 100644 
Documentation/devicetree/bindings/regulator/lm3631-regulator.txt
 create mode 100644 
Documentation/devicetree/bindings/video/backlight/ti-lmu-backlight.txt

diff --git a/Documentation/devicetree/bindings/leds/leds-lm3633.txt 
b/Documentation/devicetree/bindings/leds/leds-lm3633.txt
new file mode 100644
index 000..4adeb62
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-lm3633.txt
@@ -0,0 +1,39 @@
+TI LMU LM3633 LED device tree bindings
+
+Required properties:
+  - compatible: "ti,lm3633-leds"
+  - lvled1-used, lvled2-used, lvled3-used, lvled4-used, lvled5-used, 
lvled6-used
+: LED string configuration. Each child node should include this information
+  about which LED string is used.
+
+Optional properties:
+  - chan-name: LED channel name
+  - max-current-milliamp: Max current setting. Unit is mA.
+
+Example:
+
+lm3633@36 {
+   compatible = "ti,lm3633";
+   reg = <0x36>;
+
+   ti,enable-gpio = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+
+   leds {
+   compatible = "ti,lm3633-leds";
+
+   chan2 {
+   chan-name = "status";
+   lvled2-used;
+   max-current-milliamp = /bits/ 8 <6>;
+   };
+
+   chan456 {
+   chan-name = "rgb";
+   lvled4-used;
+   lvled5-used;
+   lvled6-used;
+
+   max-current-milliamp = /bits/ 8 <5>;
+   };
+   };
+};
diff --git a/Documentation/devicetree/bindings/mfd/ti-lmu.txt 
b/Documentation/devicetree/bindings/mfd/ti-lmu.txt
new file mode 100644
index 000..2b3ecca
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/ti-lmu.txt
@@ -0,0 +1,182 @@
+TI LMU(Lighting Management Unit) device tree bindings
+
+TI LMU driver supports lighting devices belows.
+
+   NameDevice tree properties
+  --  
+  LM3532   Backlight
+  LM3631   Backlight and regulator
+  LM3633   Backlight and LED
+  LM3695   Backlight
+  LM3697   Backlight
+
+Those have shared device tree properties.
+
+Required properties:
+  - compatible: "ti,lm3532", "ti,lm3631", "ti,lm3633", "ti,lm3695", "ti,lm3697"
+  - reg: I2C slave address.
+0x38 is LM3532
+0x29 is LM3631
+0x36 is LM3633, LM3697
+0x63 is LM3695
+  - ti,enable-gpio: GPIO number of hardware enable pin
+
+For the TI LMU backlight properties, please refer to:
+Documentation/devicetree/bindings/video/backlight/ti-lmu-backlight.txt
+
+For the LM3631 regulator properties, please refer to:
+Documentation/devicetree/bindings/regulator/lm3631-regulator.txt
+
+For the LM3633 LED properties, please refer to:
+Documentation/devicetree/bindings/leds/leds-lm3633.txt
+
+Examples:
+
+lm3532@38 {
+   compatible = "ti,lm3532";
+   reg = <0x38>;
+
+   /* GPIO134 for HWEN pin */
+   ti,enable-gpio = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+
+   backlight {
+   compatible = "ti,lmu-backlight", "ti,lm3532-backlight";
+
+   lcd {
+   hvled1-used;
+   hvled2-used;
+   hvled3-used;
+
+   max-current-milliamp = /bits/ 8 <20>;
+   ramp-up = <1>;
+   ramp-down = <1>;
+   };
+   };
+};
+
+lm3631@29 {
+   compatible = "ti,lm3631";
+   reg = <0x29>;
+
+   ti,enable-gpio = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+
+   /* Only Vpos and Vneg are used with LCD boost */
+   regulators {
+   compatible = "ti,lm3631-regulator";
+
+   vboost {
+   regulator-name = "lcd_boost";
+   regulator-min-microvolt = <450>;
+   regulator-max-microvolt = <635>;
+   regulator-always-on;
+   };
+
+   vpos {
+   regulator-name = "lcd_vpos";
+   regulator-min-microvolt = <40

Re: [PATCH 00/10] Support TI Light Management Unit devices

2014-02-16 Thread Milo Kim

Hi Lee,

On 02/14/2014 07:14 PM, Lee Jones wrote:

Milo Kim (10):
   mfd: Add TI LMU driver
   backlight: Add TI LMU backlight common driver
   backlight: ti-lmu-backlight: Add LM3532 driver
   backlight: ti-lmu-backlight: Add LM3631 driver
   backlight: ti-lmu-backlight: Add LM3633 driver
   backlight: ti-lmu-backlight: Add LM3695 driver
   backlight: ti-lmu-backlight: Add LM3697 driver
   leds: Add LM3633 driver
   regulator: Add LM3631 driver
   Documentation: Add device tree bindings for TI LMU devices


It makes it much easier to track if you send your patch set (shallow)
threaded i.e. all patches attached to [PATCH 0/x]. Having all of the
patches sent individually they will get split up and spread out all
over the reviewers INBOX, which becomes unwieldy very quickly.

Please see git send-email options:
   `--[no-]thread` and `--[no-]chain-reply-to`



Oh, sorry. I made a mistake.

I copied patch files from my working machine and sent them by using git 
send-email.


I should run
  git send-email --thread --no-chain-reply-to *.patch

but I did for each patch file, stupidly.
  git send-email --thread --no-chain-reply-to -cover.patch
  git send-email --thread --no-chain-reply-to 
0001-mfd-Add-TI-LMU-driver.patch

..
  git send-email --thread --no-chain-reply-to 
0010-Documentation-Add-device-tree-bindings-for-TI-LMU-de.patch


I'm so embarrassed..

Thanks for your advice.

Best regards,
Milo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 10/10] Documentation: Add device tree bindings for TI LMU devices

2014-02-16 Thread Milo Kim

Hi Mark,

On 02/15/2014 05:50 AM, Mark Brown wrote:

On Fri, Feb 14, 2014 at 03:32:44PM +0900, Milo Kim wrote:

Bindings for TI LMU, backlight, LM3631 regulator and LM3633 LED are added.


Ah, sorry - I didn't notice that there were several different binding
documents in the patch.


@@ -0,0 +1,49 @@
+TI LMU LM3631 regulator device tree bindings
+
+Required properties:
+  - compatible: "ti,lm3631-regulator"
+
+Optional properties:
+  - regulator-name
+  - regulator-min-microvolt
+  - regulator-max-microvolt
+  - regulator-always-on
+  - regulator-boot-on
+
+  For those properties, please refer to:
+  Documentation/devicetree/bindings/regulator/regulator.txt


This doesn't correspond to the example which says that there is an
optional property "regulators" which can contain regualators lcd_boost,
lcd_vpos and lcd_vneg.  It's also better to not enumerate all the
standard properties but just refer to the generic document (as you do).
That avoids confusion if new properties are added to the generic
regulator bindings.

The actual binding is fine, it's just the way it's documented.


Thank you. I've fixed things based on your comments.
Could you check the description below?
I'd like to get your feedback before sending patch-set v2.


From f0dcb9d8b21d38a6764c2e43cde4b41da3078c23 Mon Sep 17 00:00:00 2001
From: Milo Kim 
Date: Mon, 17 Feb 2014 14:33:15 +0900
Subject: [PATCH 2/2] Documentation: fix LM3631 regulator DT based on
 maintainer's feedback

Signed-off-by: Milo Kim 
---
 .../bindings/regulator/lm3631-regulator.txt|   63 


 1 file changed, 63 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/lm3631-regulator.txt


diff --git 
a/Documentation/devicetree/bindings/regulator/lm3631-regulator.txt 
b/Documentation/devicetree/bindings/regulator/lm3631-regulator.txt

new file mode 100644
index 000..272cdc1
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/lm3631-regulator.txt
@@ -0,0 +1,63 @@
+TI LMU LM3631 regulator device tree bindings
+
+Required properties:
+  - compatible: "ti,lm3631-regulator"
+
+Sub-nodes:
+  - vboost
+  - vcont
+  - voref
+  - vpos
+  - vneg
+
+  Optional properties of each node:
+  Please refer to Documentation/devicetree/bindings/regulator/regulator.txt
+
+LM3631 regulator is represented as a sub-node of the "ti,lm3631" device.
+Please refer to "ti,lm3631" in 
Documentation/devicetree/bindings/mfd/ti-lmu.txt

+
+Example:
+
+lm3631@29 {
+   compatible = "ti,lm3631";
+   reg = <0x29>;
+
+   ti,enable-gpio = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+
+   regulators {
+   compatible = "ti,lm3631-regulator";
+
+   vboost {
+   regulator-name = "lcd_boost";
+   regulator-min-microvolt = <450>;
+   regulator-max-microvolt = <635>;
+   regulator-always-on;
+   };
+
+   vcont {
+   regulator-name = "lcd_vcont";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <330>;
+   };
+
+   voref {
+   regulator-name = "lcd_voref";
+   regulator-min-microvolt = <400>;
+   regulator-max-microvolt = <600>;
+   };
+
+   vpos {
+   regulator-name = "lcd_vpos";
+   regulator-min-microvolt = <400>;
+   regulator-max-microvolt = <600>;
+   regulator-boot-on;
+   };
+
+   vneg {
+   regulator-name = "lcd_vneg";
+   regulator-min-microvolt = <400>;
+   regulator-max-microvolt = <600>;
+   regulator-boot-on;
+   };
+   };
+};
--
1.7.9.5


Best regards,
Milo


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 10/10] Documentation: Add device tree bindings for TI LMU devices

2014-02-16 Thread Milo Kim

Hello Mark,

Thanks for your detailed comments.
I've fixed the structure and description.
I'd like to have your feedback before submitting new patch-set.


From 33faeeed69fa064cd476b252c5a7326a541e12b3 Mon Sep 17 00:00:00 2001
From: Milo Kim 
Date: Mon, 17 Feb 2014 14:32:39 +0900
Subject: [PATCH 1/2] Documentation: TI LMU DT fix based on Maintainer's
 feedback


Signed-off-by: Milo Kim 
---
 .../devicetree/bindings/leds/leds-lm3633.txt   |   47 +
 Documentation/devicetree/bindings/mfd/ti-lmu.txt   |  200 


 .../bindings/video/backlight/ti-lmu-backlight.txt  |  153 +++
 3 files changed, 400 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-lm3633.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/ti-lmu.txt
 create mode 100644 
Documentation/devicetree/bindings/video/backlight/ti-lmu-backlight.txt


diff --git a/Documentation/devicetree/bindings/leds/leds-lm3633.txt 
b/Documentation/devicetree/bindings/leds/leds-lm3633.txt

new file mode 100644
index 000..10546cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-lm3633.txt
@@ -0,0 +1,47 @@
+TI LMU LM3633 LED device tree bindings
+
+Required properties:
+  - compatible: "ti,lm3633-leds"
+
+Sub-nodes:
+  Maximum 6 LED channels can be configured in each sub-node.
+
+  Required properties of sub-node:
+  - lvled1-used, lvled2-used, lvled3-used, lvled4-used, lvled5-used, 
lvled6-used

+: LED string configuration about which LED string is used.
+
+  Optional properties of sub-node:
+  - channel-name: Name string for LED channel identification
+  - max-current-milliamp: Max current setting. Type is . Unit is mA.
+  Range is from 5 to 30 mA.
+
+LM3633 LED is represented as a sub-node of the "ti,lm3633" device.
+Please refer to "ti,lm3633" in 
Documentation/devicetree/bindings/mfd/ti-lmu.txt

+
+Example:
+
+lm3633@36 {
+   compatible = "ti,lm3633";
+   reg = <0x36>;
+
+   ti,enable-gpio = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+
+   leds {
+   compatible = "ti,lm3633-leds";
+
+   chan2 {
+   channel-name = "status";
+   lvled2-used;
+   max-current-milliamp = /bits/ 8 <6>;
+   };
+
+   chan456 {
+   channel-name = "rgb";
+   lvled4-used;
+   lvled5-used;
+   lvled6-used;
+
+   max-current-milliamp = /bits/ 8 <5>;
+   };
+   };
+};
diff --git a/Documentation/devicetree/bindings/mfd/ti-lmu.txt 
b/Documentation/devicetree/bindings/mfd/ti-lmu.txt

new file mode 100644
index 000..5e21ce9
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/ti-lmu.txt
@@ -0,0 +1,200 @@
+TI LMU(Lighting Management Unit) device tree bindings
+
+TI LMU driver supports lighting devices belows.
+
+   NameDevice tree properties
+  --  
+  LM3532   Backlight
+  LM3631   Backlight and regulator
+  LM3633   Backlight and LED
+  LM3695   Backlight
+  LM3697   Backlight
+
+Those have shared device tree properties.
+
+Required properties:
+  - compatible: Should be one of lists below.
+"ti,lm3532"
+"ti,lm3631"
+"ti,lm3633"
+"ti,lm3695"
+"ti,lm3697"
+  - reg: I2C slave address.
+ 0x38 is LM3532
+ 0x29 is LM3631
+ 0x36 is LM3633, LM3697
+ 0x63 is LM3695
+  - ti,enable-gpio: GPIOs about hardware enable pin
+
+Sub-nodes:
+  Required sub-node:
+- backlight: Every TI LMU device has backlight sub-nodes. Please 
refer to
+ 
Documentation/devicetree/bindings/video/backlight/ti-lmu-backlight.txt

+
+  Optional sub-node:
+- regulators: Only for LM3631. Please refer to
+ 
Documentation/devicetree/bindings/regulator/lm3631-regulator.txt

+- leds: Only for LM3633. Please refer to
+Documentation/devicetree/bindings/leds/leds-lm3633.txt
+
+Examples:
+
+lm3532@38 {
+   compatible = "ti,lm3532";
+   reg = <0x38>;
+
+   /* GPIO134 for HWEN pin */
+   ti,enable-gpio = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+
+   backlight {
+   compatible = "ti,lm3532-backlight", "ti,lmu-backlight";
+
+   lcd {
+   hvled1-used;
+   hvled2-used;
+   hvled3-used;
+
+   max-current-milliamp = /bits/ 8 <20>;
+   };
+   };
+};
+
+lm3631@29 {
+   compatible = "ti,lm3631";
+   reg = <0x29>;
+
+   ti,enable-gpio = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+
+   regulators {
+   compatible = "ti,lm3631-re

Re: [PATCH 01/10] mfd: Add TI LMU driver

2014-02-17 Thread Milo Kim

Hi Lee,

On 02/17/2014 06:57 PM, Lee Jones wrote:

+static const struct resource lm3633_effect_resources[] = {
+   {
+   .name  = LM3633_EFFECT_BL0_RAMPUP,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(BL0_RAMPUP),
+   },
+   {
+   .name  = LM3633_EFFECT_BL0_RAMPDOWN,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(BL0_RAMPDN),
+   },
+   {
+   .name  = LM3633_EFFECT_BL1_RAMPUP,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(BL1_RAMPUP),
+   },
+   {
+   .name  = LM3633_EFFECT_BL1_RAMPDOWN,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(BL1_RAMPDN),
+   },
+   {
+   .name  = LM3633_EFFECT_PTN_DELAY,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(DELAY),
+   },
+   {
+   .name  = LM3633_EFFECT_PTN_HIGHTIME,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(HIGHTIME),
+   },
+   {
+   .name  = LM3633_EFFECT_PTN_LOWTIME,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(LOWTIME),
+   },
+   {
+   .name  = LM3633_EFFECT_PTN0_RAMPUP,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(PTN0_RAMPUP),
+   },
+   {
+   .name  = LM3633_EFFECT_PTN0_RAMPDOWN,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(PTN0_RAMPDN),
+   },
+   {
+   .name  = LM3633_EFFECT_PTN1_RAMPUP,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(PTN1_RAMPUP),
+   },
+   {
+   .name  = LM3633_EFFECT_PTN1_RAMPDOWN,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(PTN1_RAMPDN),
+   },
+   {
+   .name  = LM3633_EFFECT_PTN_LOWBRT,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(LOWBRT),
+   },
+   {
+   .name  = LM3633_EFFECT_PTN_HIGHBRT,
+   .flags = IORESOURCE_REG,
+   .start = LM3633_EFFECT_REGISTER(HIGHBRT),
+   },
+};


Can you define a MACRO to do all of these as one liners?


Yes, resource definitions will be replaced by simple macro, 
LMU_EFFECT_RESOURCE().


For example,

#define LMU_EFFECT_RESOURCE(chip, effect)   \
{   \
.name  = chip##_EFFECT_##effect,\
.flags = IORESOURCE_REG,\
.start = LMU_EFFECT_REGISTER(chip, effect), \
}

static const struct resource lm3633_effect_resources[] = {
LMU_EFFECT_RESOURCE(LM3633, BL0_RAMPUP),
LMU_EFFECT_RESOURCE(LM3633, BL0_RAMPDN),
LMU_EFFECT_RESOURCE(LM3633, BL1_RAMPUP),
LMU_EFFECT_RESOURCE(LM3633, BL1_RAMPDN),
LMU_EFFECT_RESOURCE(LM3633, PTN_DELAY),
LMU_EFFECT_RESOURCE(LM3633, PTN_HIGHTIME),
LMU_EFFECT_RESOURCE(LM3633, PTN_LOWTIME),
LMU_EFFECT_RESOURCE(LM3633, PTN0_RAMPUP),
LMU_EFFECT_RESOURCE(LM3633, PTN0_RAMPDN),
LMU_EFFECT_RESOURCE(LM3633, PTN1_RAMPUP),
LMU_EFFECT_RESOURCE(LM3633, PTN1_RAMPDN),
LMU_EFFECT_RESOURCE(LM3633, PTN_LOWBRT),
LMU_EFFECT_RESOURCE(LM3633, PTN_HIGHBRT),
};

static const struct resource lm3697_effect_resources[] = {
LMU_EFFECT_RESOURCE(LM3697, BL0_RAMPUP),
LMU_EFFECT_RESOURCE(LM3697, BL0_RAMPDN),
LMU_EFFECT_RESOURCE(LM3697, BL1_RAMPUP),
LMU_EFFECT_RESOURCE(LM3697, BL1_RAMPDN),
};

and so on.





+static int ti_lmu_parse_dt(struct device *dev, struct ti_lmu *lmu)
+{





+   pdata->en_gpio = of_get_named_gpio(node, "ti,enable-gpio", 0);


There is a global DT property for this already.


I've not found it yet, but I agree it looks like general property.
So I'll replace "ti,enable-gpio" with "ti,lmu-en-gpio".




+static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{





+   lmu->id = id->driver_data;
+   switch (lmu->id) {
+   case LM3532:
+   lmu_regmap_config.max_register = LM3532_MAX_REGISTERS;
+   break;
+   case LM3631:
+   lmu_regmap_config.max_register = LM3631_MAX_REGISTERS;
+   break;
+   case LM3633:
+   lmu_regmap_config.max_register = LM3633_MAX_REGISTERS;
+   break;
+   case LM3695:
+   lmu_regmap_config.max_register = LM3695_MAX_REGISTERS;
+   break;
+   case LM3697:
+   lmu_regmap_config.max_register = LM3697_MAX_REGISTERS;
+   break;
+   default:
+   break;
+   }


As there are so many of these, it might be nicer to pull these out
into a sepera

Re: [PATCH 06/16] mfd: lp3943: Make mfd_cell array const

2014-05-13 Thread Milo Kim

On 05/13/2014 07:58 PM, Krzysztof Kozlowski wrote:

mfd_add_devices() expects array of struct mfd_cell to be const.

Signed-off-by: Krzysztof Kozlowski 
Cc: Milo Kim 


Acked-by: Milo Kim 

Thanks!
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v5 0/4] LP3943 MFD driver for a GPIO expander and a PWM generator

2013-12-05 Thread Milo Kim
LP3943 is an integrated device capable of driving 16 output channels.
It can be used for GPIO expander and PWM generators.
LP3493 registers are controlled via the I2C interface.

This patch-set consists of four parts - MFD, GPIO, PWM and documents.

Update from v4 to v5:
  Add Thierry's ACK for the PWM driver and the DT documentation

Milo Kim (4):
  mfd: add LP3943 MFD driver
  gpio: add LP3943 I2C GPIO expander driver
  pwm: add LP3943 PWM driver
  Documentation: add LP3943 DT bindings and document

 .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 +++
 Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 ++
 .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 
 drivers/gpio/Kconfig   |8 +
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-lp3943.c |  242 +++
 drivers/mfd/Kconfig|   11 +
 drivers/mfd/Makefile   |1 +
 drivers/mfd/lp3943.c   |  167 +++
 drivers/pwm/Kconfig|   10 +
 drivers/pwm/Makefile   |1 +
 drivers/pwm/pwm-lp3943.c   |  314 
 include/linux/mfd/lp3943.h |  114 +++
 13 files changed, 997 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
 create mode 100644 drivers/gpio/gpio-lp3943.c
 create mode 100644 drivers/mfd/lp3943.c
 create mode 100644 drivers/pwm/pwm-lp3943.c
 create mode 100644 include/linux/mfd/lp3943.h

-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v5 1/4] mfd: add LP3943 MFD driver

2013-12-05 Thread Milo Kim
LP3943 has 16 output pins which can be used as GPIO expander and PWM generator.

* Regmap I2C interface for R/W LP3943 registers

* Atomic operations for output pin assignment
  The driver should check whether requested pin is available or not.
  If the pin is already used, pin request returns as a failure.
  A driver data, 'pin_used' is checked when gpio_request() and
  pwm_request() are called. If the pin is available, then pin_used is set.
  And it is cleared when gpio_free() and pwm_free().

* Device tree support
  Compatible strings for GPIO and PWM driver.
  LP3943 platform data is PWM related, so parsing the device tree is
  implemented in the PWM driver.

Signed-off-by: Milo Kim 
Acked-by: Lee Jones 
---
* Patch v5
  Same as v4

* Patch v4
  Driver description was moved from the documentation in patch v3.

* Patch v3
  Now, output pin number is exactly matched with enum value of '
  lp3943_pwm_output'.
  Use dev_get_platdata() helper function in probe().
  Use module_i2c_driver() for initcall.

* Patch v2
  Handle atomic operations for output pin assignment.

 drivers/mfd/Kconfig|   11 +++
 drivers/mfd/Makefile   |1 +
 drivers/mfd/lp3943.c   |  167 
 include/linux/mfd/lp3943.h |  114 ++
 4 files changed, 293 insertions(+)
 create mode 100644 drivers/mfd/lp3943.c
 create mode 100644 include/linux/mfd/lp3943.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b7c74a7..eb16bd8 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -725,6 +725,17 @@ config MFD_DM355EVM_MSP
  boards.  MSP430 firmware manages resets and power sequencing,
  inputs from buttons and the IR remote, LEDs, an RTC, and more.
 
+config MFD_LP3943
+   tristate "TI/National Semiconductor LP3943 MFD Driver"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ Support for the TI/National Semiconductor LP3943.
+ This driver consists of GPIO and PWM drivers.
+ With these functionalities, it can be used for LED string control or
+ general usage such like a GPIO controller and a PWM controller.
+
 config MFD_LP8788
bool "TI LP8788 Power Management Unit Driver"
depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8a28dc9..58554f1 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_PMIC_DA9052)   += da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)   += da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)   += da9052-i2c.o
 
+obj-$(CONFIG_MFD_LP3943)   += lp3943.o
 obj-$(CONFIG_MFD_LP8788)   += lp8788.o lp8788-irq.o
 
 da9055-objs:= da9055-core.o da9055-i2c.o
diff --git a/drivers/mfd/lp3943.c b/drivers/mfd/lp3943.c
new file mode 100644
index 000..e322268
--- /dev/null
+++ b/drivers/mfd/lp3943.c
@@ -0,0 +1,167 @@
+/*
+ * TI/National Semiconductor LP3943 MFD Core Driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver structure:
+ *   LP3943 is an integrated device capable of driving 16 output channels.
+ *   It can be used for a GPIO expander and PWM generators.
+ *
+ *   LED controlGeneral usage for a device
+ *   ___   
+ *
+ *   LP3943 MFD  GPIO expanderleds-gpioeg) HW enable pin
+ *   |
+ *   --- PWM generatorleds-pwm eg) PWM input
+ *
+ *   Internal two PWM channels are used for LED dimming effect.
+ *   And each output pin can be used as a GPIO as well.
+ *   The LED functionality can work with GPIOs or PWMs.
+ *   LEDs can be controlled with legacy leds-gpio(static brightness) or
+ *   leds-pwm drivers(dynamic brightness control).
+ *   Alternatively, it can be used for generic GPIO and PWM controller.
+ *   For example, a GPIO is HW enable pin of a device.
+ *   A PWM is input pin of a backlight device.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LP3943_MAX_REGISTERS   0x09
+
+/* Register configuration for pin MUX */
+static const struct lp3943_reg_cfg lp3943_mux_cfg[] = {
+   /* address, mask, shift */
+   { LP3943_REG_MUX0, 0x03, 0 },
+   { LP3943_REG_MUX0, 0x0C, 2 },
+   { LP3943_REG_MUX0, 0x30, 4 },
+   { LP3943_REG_MUX0, 0xC0, 6 },
+   { LP3943_REG_MUX1, 0x03, 0 },
+   { LP3943_REG_MUX1, 0x0C, 2 },
+   { LP3943_REG_MUX1, 0x30, 4 },
+   { LP3943_REG_MUX1, 0xC0, 6 },
+   { LP3943_REG_MUX2, 0x03, 0 },
+   { LP3943_REG_MUX2, 0x0C, 2 },
+   { LP3943_REG_MUX2, 0x30, 4 },
+   { LP3943_REG_MUX2, 0xC0,

[PATCH v5 2/4] gpio: add LP3943 I2C GPIO expander driver

2013-12-05 Thread Milo Kim
This is one of LP3943 MFD driver.
LP3943 is configurable as a GPIO expander, up to 16 GPIOs.

* Application note: how to configure LP3943 as a GPIO expander
  http://www.ti.com/lit/an/snva287a/snva287a.pdf

* Supported GPIO controller operations
  request, free, direction_input, direction_output, get and set

* GPIO direction register not supported
  LP3943 doesn't have the GPIO direction register. It only provides input and
  output status registers.
  So, private data for the direction should be handled manually.
  This variable is updated whenever the direction is changed and
  used in 'get' operation.

* Pin assignment
  A driver data, 'pin_used' is checked when a GPIO is requested.
  If the GPIO is already assigned, then returns as failure.
  If the GPIO is available, 'pin_used' is set.
  When the GPIO is not used anymore, then it is cleared.
  It is defined as unsigned long type for atomic bit operation APIs,
  but only LSB 16bits are used because LP3943 has 16 outputs.

Signed-off-by: Milo Kim 
Reviewed-by: Linus Walleij 
---
* Patch v5 and v4
  No update, same as v3

* Patch v3
  Use inline function instead of macro(), to_lp3943_gpio().
  Add 'lp3943_gpio_set_mode()' and use it in lp3943_gpio_direction_input() and
  lp3943_gpio_set().
  Few code cosmetic applied - indentations.

* Patch v2
  Use bitops macros for bit manipulations.
  Support device tree structure for the GPIO controller.
  Add request() and free() for the pin assignment.

 drivers/gpio/Kconfig   |8 ++
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-lp3943.c |  242 
 3 files changed, 251 insertions(+)
 create mode 100644 drivers/gpio/gpio-lp3943.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b6ed304..e8ee076 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -368,6 +368,14 @@ config GPIO_ARIZONA
help
  Support for GPIOs on Wolfson Arizona class devices.
 
+config GPIO_LP3943
+   tristate "TI/National Semiconductor LP3943 GPIO expander"
+   depends on MFD_LP3943
+   help
+ GPIO driver for LP3943 MFD.
+ LP3943 can be used as a GPIO expander which provides up to 16 GPIOs.
+ Open drain outputs are required for this usage.
+
 config GPIO_MAX7300
tristate "Maxim MAX7300 GPIO expander"
depends on I2C
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 98e23eb..e246962 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL)   += gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)  += gpio-kempld.o
 obj-$(CONFIG_ARCH_KS8695)  += gpio-ks8695.o
 obj-$(CONFIG_GPIO_LANGWELL)+= gpio-langwell.o
+obj-$(CONFIG_GPIO_LP3943)  += gpio-lp3943.o
 obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LYNXPOINT)   += gpio-lynxpoint.o
 obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
diff --git a/drivers/gpio/gpio-lp3943.c b/drivers/gpio/gpio-lp3943.c
new file mode 100644
index 000..7b8db88
--- /dev/null
+++ b/drivers/gpio/gpio-lp3943.c
@@ -0,0 +1,242 @@
+/*
+ * TI/National Semiconductor LP3943 GPIO driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * 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; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum lp3943_gpios {
+   LP3943_GPIO1,
+   LP3943_GPIO2,
+   LP3943_GPIO3,
+   LP3943_GPIO4,
+   LP3943_GPIO5,
+   LP3943_GPIO6,
+   LP3943_GPIO7,
+   LP3943_GPIO8,
+   LP3943_GPIO9,
+   LP3943_GPIO10,
+   LP3943_GPIO11,
+   LP3943_GPIO12,
+   LP3943_GPIO13,
+   LP3943_GPIO14,
+   LP3943_GPIO15,
+   LP3943_GPIO16,
+   LP3943_MAX_GPIO,
+};
+
+struct lp3943_gpio {
+   struct gpio_chip chip;
+   struct lp3943 *lp3943;
+   u16 input_mask; /* 1 = GPIO is input direction, 0 = output */
+};
+
+static inline struct lp3943_gpio *to_lp3943_gpio(struct gpio_chip *_chip)
+{
+   return container_of(_chip, struct lp3943_gpio, chip);
+}
+
+static int lp3943_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+   struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+   struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+   /* Return an error if the pin is already assigned */
+   if (test_and_set_bit(offset, &lp3943->pin_used))
+   return -EBUSY;
+
+   return 0;
+}
+
+static void lp3943_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+   struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+   struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+   clear_bit(offset, &lp3943->pin_used);
+}
+
+static int lp3943_gpio_set_mode(struct lp3943_gpio *lp3

[PATCH v5 3/4] pwm: add LP3943 PWM driver

2013-12-05 Thread Milo Kim
This is the other of the LP3943 MFD driver.
LP3943 can be used as a PWM generator, up to 2 channels.

* Two PWM generators supported

* Supported PWM operations
  request, free, config, enable and disable

* Pin assignment
  A driver data, 'pin_used' is checked when a PWM is requested.
  If the output pin is already assigned, then returns as failure.
  If the pin is available, 'pin_used' is set.
  When the PWM is not used anymore, then it is cleared.
  It is defined as unsigned long type for atomic bit operation APIs,
  but only LSB 16bits are used because LP3943 has 16 outputs.

Signed-off-by: Milo Kim 
Acked-by: Thierry Reding 
---
* Patch v5
  Add Thierry's acknowledgement.

* Patch v4
  No update, same as v3.

* Patch v3
  Manual polarity not supported any more.
  Add encapsulation functions for accessing internal data structure.
  Use pwm_set_chip_data() and pwm_get_chip_data().
  And other code fixes based on Thierry's feedback.

 drivers/pwm/Kconfig  |   10 ++
 drivers/pwm/Makefile |1 +
 drivers/pwm/pwm-lp3943.c |  314 ++
 3 files changed, 325 insertions(+)
 create mode 100644 drivers/pwm/pwm-lp3943.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 75840b5..9cf38bc 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -81,6 +81,16 @@ config PWM_JZ4740
  To compile this driver as a module, choose M here: the module
  will be called pwm-jz4740.
 
+config PWM_LP3943
+   tristate "TI/National Semiconductor LP3943 PWM support"
+   depends on MFD_LP3943
+   help
+ Generic PWM framework driver for LP3943 which supports two PWM
+ channels.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-lp3943.
+
 config PWM_LPC32XX
tristate "LPC32XX PWM support"
depends on ARCH_LPC32XX
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 77a8c18..db8e349 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
 obj-$(CONFIG_PWM_IMX)  += pwm-imx.o
 obj-$(CONFIG_PWM_JZ4740)   += pwm-jz4740.o
+obj-$(CONFIG_PWM_LP3943)   += pwm-lp3943.o
 obj-$(CONFIG_PWM_LPC32XX)  += pwm-lpc32xx.o
 obj-$(CONFIG_PWM_MXS)  += pwm-mxs.o
 obj-$(CONFIG_PWM_PCA9685)  += pwm-pca9685.o
diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c
new file mode 100644
index 000..8a843a0
--- /dev/null
+++ b/drivers/pwm/pwm-lp3943.c
@@ -0,0 +1,314 @@
+/*
+ * TI/National Semiconductor LP3943 PWM driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * 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; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LP3943_MAX_DUTY255
+#define LP3943_MIN_PERIOD  6250
+#define LP3943_MAX_PERIOD  160
+
+struct lp3943_pwm {
+   struct pwm_chip chip;
+   struct lp3943 *lp3943;
+   struct lp3943_platform_data *pdata;
+};
+
+static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *_chip)
+{
+   return container_of(_chip, struct lp3943_pwm, chip);
+}
+
+static struct lp3943_pwm_map *
+lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm)
+{
+   struct lp3943_platform_data *pdata = lp3943_pwm->pdata;
+   struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+   struct lp3943_pwm_map *pwm_map;
+   int i, offset;
+
+   pwm_map = kzalloc(sizeof(*pwm_map), GFP_KERNEL);
+   if (!pwm_map)
+   return ERR_PTR(-ENOMEM);
+
+   pwm_map->output = pdata->pwms[hwpwm]->output;
+   pwm_map->num_outputs = pdata->pwms[hwpwm]->num_outputs;
+
+   for (i = 0; i < pwm_map->num_outputs; i++) {
+   offset = pwm_map->output[i];
+
+   /* Return an error if the pin is already assigned */
+   if (test_and_set_bit(offset, &lp3943->pin_used))
+   return ERR_PTR(-EBUSY);
+   }
+
+   return pwm_map;
+}
+
+static int lp3943_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+   struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
+   struct lp3943_pwm_map *pwm_map;
+
+   pwm_map = lp3943_pwm_request_map(lp3943_pwm, pwm->hwpwm);
+   if (IS_ERR(pwm_map))
+   return PTR_ERR(pwm_map);
+
+   return pwm_set_chip_data(pwm, pwm_map);
+}
+
+static void lp3943_pwm_free_map(struct lp3943_pwm *lp3943_pwm,
+   struct lp3943_pwm_map *pwm_map)
+{
+   struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+   int i, offset;
+
+   for (i = 0; i < pwm_map->num_

[PATCH v5 4/4] Documentation: add LP3943 DT bindings and document

2013-12-05 Thread Milo Kim
Bindings for LP3943 MFD, GPIO and PWM controller are added.

Cc: devicet...@vger.kernel.org
Cc: Lee Jones 
Cc: Linus Walleij 
Cc: Samuel Ortiz 
Signed-off-by: Milo Kim 
Acked-by: Thierry Reding 
---
 .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 +
 Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 +++
 .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 
 3 files changed, 128 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt 
b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
new file mode 100644
index 000..80fcb7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
@@ -0,0 +1,37 @@
+TI/National Semiconductor LP3943 GPIO controller
+
+Required properties:
+  - compatible: "ti,lp3943-gpio"
+  - gpio-controller: Marks the device node as a GPIO controller.
+  - #gpio-cells: Should be 2. See gpio.txt in this directory for a
+ description of the cells format.
+
+Example:
+Simple LED controls with LP3943 GPIO controller
+
+&i2c4 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+   };
+};
+
+leds {
+   compatible = "gpio-leds";
+   indicator1 {
+   label = "indi1";
+   gpios = <&gpioex 9 GPIO_ACTIVE_LOW>;
+   };
+
+   indicator2 {
+   label = "indi2";
+   gpios = <&gpioex 10 GPIO_ACTIVE_LOW>;
+   default-state = "off";
+   };
+};
diff --git a/Documentation/devicetree/bindings/mfd/lp3943.txt 
b/Documentation/devicetree/bindings/mfd/lp3943.txt
new file mode 100644
index 000..e8591d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/lp3943.txt
@@ -0,0 +1,33 @@
+TI/National Semiconductor LP3943 MFD driver
+
+Required properties:
+  - compatible: "ti,lp3943"
+  - reg: I2C slave address. From 0x60 to 0x67.
+
+LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm.
+
+For the LP3943 GPIO properties please refer to:
+Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
+
+For the LP3943 PWM properties please refer to:
+Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
+
+Example:
+
+lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+
+   pwm3943: pwm {
+   compatible = "ti,lp3943-pwm";
+   #pwm-cells = <2>;
+   ti,pwm0 = <8 9 10>;
+   ti,pwm1 = <15>;
+   };
+};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt 
b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
new file mode 100644
index 000..7bd9d3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
@@ -0,0 +1,58 @@
+TI/National Semiconductor LP3943 PWM controller
+
+Required properties:
+  - compatible: "ti,lp3943-pwm"
+  - #pwm-cells: Should be 2. See pwm.txt in this directory for a
+description of the cells format.
+Note that this hardware limits the period length to the
+range 6250~160.
+  - ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1.
+0 = output 0
+1 = output 1
+.
+.
+15 = output 15
+
+Example:
+PWM 0 is for RGB LED brightness control
+PWM 1 is for brightness control of LP8557 backlight device
+
+&i2c3 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   /*
+* PWM 0 : output 8, 9 and 10
+* PWM 1 : output 15
+*/
+   pwm3943: pwm {
+   compatible = "ti,lp3943-pwm";
+   #pwm-cells = <2>;
+   ti,pwm0 = <8 9 10>;
+   ti,pwm1 = <15>;
+   };
+   };
+
+};
+
+/* LEDs control with PWM 0 of LP3943 */
+pwmleds {
+   compatible = "pwm-leds";
+   rgb {
+   label = "indi::rgb";
+   pwms = <&pwm3943 0 1>;
+   max-brightness = <255>;
+   };
+};
+
+&i2c4 {
+   /* Backlight control with PWM 1 of LP3943 */
+   backlight@2c {
+   compatible = "ti,lp8557";
+  

[PATCH RESEND v5 4/4] Documentation: add LP3943 DT bindings and document

2013-12-05 Thread Milo Kim
Bindings for LP3943 MFD, GPIO and PWM controller are added.

Cc: devicet...@vger.kernel.org
Cc: Lee Jones 
Cc: Linus Walleij 
Cc: Samuel Ortiz 
Signed-off-by: Milo Kim 
Acked-by: Thierry Reding 
---
 .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 +
 Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 +++
 .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 
 3 files changed, 128 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt 
b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
new file mode 100644
index 000..80fcb7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
@@ -0,0 +1,37 @@
+TI/National Semiconductor LP3943 GPIO controller
+
+Required properties:
+  - compatible: "ti,lp3943-gpio"
+  - gpio-controller: Marks the device node as a GPIO controller.
+  - #gpio-cells: Should be 2. See gpio.txt in this directory for a
+ description of the cells format.
+
+Example:
+Simple LED controls with LP3943 GPIO controller
+
+&i2c4 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+   };
+};
+
+leds {
+   compatible = "gpio-leds";
+   indicator1 {
+   label = "indi1";
+   gpios = <&gpioex 9 GPIO_ACTIVE_LOW>;
+   };
+
+   indicator2 {
+   label = "indi2";
+   gpios = <&gpioex 10 GPIO_ACTIVE_LOW>;
+   default-state = "off";
+   };
+};
diff --git a/Documentation/devicetree/bindings/mfd/lp3943.txt 
b/Documentation/devicetree/bindings/mfd/lp3943.txt
new file mode 100644
index 000..e8591d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/lp3943.txt
@@ -0,0 +1,33 @@
+TI/National Semiconductor LP3943 MFD driver
+
+Required properties:
+  - compatible: "ti,lp3943"
+  - reg: I2C slave address. From 0x60 to 0x67.
+
+LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm.
+
+For the LP3943 GPIO properties please refer to:
+Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
+
+For the LP3943 PWM properties please refer to:
+Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
+
+Example:
+
+lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   gpioex: gpio {
+   compatible = "ti,lp3943-gpio";
+   gpio-controller;
+   #gpio-cells = <2>;
+   };
+
+   pwm3943: pwm {
+   compatible = "ti,lp3943-pwm";
+   #pwm-cells = <2>;
+   ti,pwm0 = <8 9 10>;
+   ti,pwm1 = <15>;
+   };
+};
diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt 
b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
new file mode 100644
index 000..7bd9d3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
@@ -0,0 +1,58 @@
+TI/National Semiconductor LP3943 PWM controller
+
+Required properties:
+  - compatible: "ti,lp3943-pwm"
+  - #pwm-cells: Should be 2. See pwm.txt in this directory for a
+description of the cells format.
+Note that this hardware limits the period length to the
+range 6250~160.
+  - ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1.
+0 = output 0
+1 = output 1
+.
+.
+15 = output 15
+
+Example:
+PWM 0 is for RGB LED brightness control
+PWM 1 is for brightness control of LP8557 backlight device
+
+&i2c3 {
+   lp3943@60 {
+   compatible = "ti,lp3943";
+   reg = <0x60>;
+
+   /*
+* PWM 0 : output 8, 9 and 10
+* PWM 1 : output 15
+*/
+   pwm3943: pwm {
+   compatible = "ti,lp3943-pwm";
+   #pwm-cells = <2>;
+   ti,pwm0 = <8 9 10>;
+   ti,pwm1 = <15>;
+   };
+   };
+
+};
+
+/* LEDs control with PWM 0 of LP3943 */
+pwmleds {
+   compatible = "pwm-leds";
+   rgb {
+   label = "indi::rgb";
+   pwms = <&pwm3943 0 1>;
+   max-brightness = <255>;
+   };
+};
+
+&i2c4 {
+   /* Backlight control with PWM 1 of LP3943 */
+   backlight@2c {
+   compatible = "ti,lp8557";
+  

[PATCH RESEND v5 0/4] LP3943 MFD driver for a GPIO expander and a PWM generator

2013-12-05 Thread Milo Kim
LP3943 is an integrated device capable of driving 16 output channels.
It can be used for GPIO expander and PWM generators.
LP3493 registers are controlled via the I2C interface.

This patch-set consists of four parts - MFD, GPIO, PWM and documents.

Update from v4 to v5:
  Add Thierry's ACK for the PWM driver and the DT documentation

Milo Kim (4):
  mfd: add LP3943 MFD driver
  gpio: add LP3943 I2C GPIO expander driver
  pwm: add LP3943 PWM driver
  Documentation: add LP3943 DT bindings and document

 .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 +++
 Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 ++
 .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 
 drivers/gpio/Kconfig   |8 +
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-lp3943.c |  242 +++
 drivers/mfd/Kconfig|   11 +
 drivers/mfd/Makefile   |1 +
 drivers/mfd/lp3943.c   |  167 +++
 drivers/pwm/Kconfig|   10 +
 drivers/pwm/Makefile   |1 +
 drivers/pwm/pwm-lp3943.c   |  314 
 include/linux/mfd/lp3943.h |  114 +++
 13 files changed, 997 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
 create mode 100644 drivers/gpio/gpio-lp3943.c
 create mode 100644 drivers/mfd/lp3943.c
 create mode 100644 drivers/pwm/pwm-lp3943.c
 create mode 100644 include/linux/mfd/lp3943.h

-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND v5 1/4] mfd: add LP3943 MFD driver

2013-12-05 Thread Milo Kim
LP3943 has 16 output pins which can be used as GPIO expander and PWM generator.

* Regmap I2C interface for R/W LP3943 registers

* Atomic operations for output pin assignment
  The driver should check whether requested pin is available or not.
  If the pin is already used, pin request returns as a failure.
  A driver data, 'pin_used' is checked when gpio_request() and
  pwm_request() are called. If the pin is available, then pin_used is set.
  And it is cleared when gpio_free() and pwm_free().

* Device tree support
  Compatible strings for GPIO and PWM driver.
  LP3943 platform data is PWM related, so parsing the device tree is
  implemented in the PWM driver.

Signed-off-by: Milo Kim 
Acked-by: Lee Jones 
---
* Patch v5
  Same as v4

* Patch v4
  Driver description was moved from the documentation in patch v3.

* Patch v3
  Now, output pin number is exactly matched with enum value of '
  lp3943_pwm_output'.
  Use dev_get_platdata() helper function in probe().
  Use module_i2c_driver() for initcall.

* Patch v2
  Handle atomic operations for output pin assignment.

 drivers/mfd/Kconfig|   11 +++
 drivers/mfd/Makefile   |1 +
 drivers/mfd/lp3943.c   |  167 
 include/linux/mfd/lp3943.h |  114 ++
 4 files changed, 293 insertions(+)
 create mode 100644 drivers/mfd/lp3943.c
 create mode 100644 include/linux/mfd/lp3943.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b7c74a7..eb16bd8 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -725,6 +725,17 @@ config MFD_DM355EVM_MSP
  boards.  MSP430 firmware manages resets and power sequencing,
  inputs from buttons and the IR remote, LEDs, an RTC, and more.
 
+config MFD_LP3943
+   tristate "TI/National Semiconductor LP3943 MFD Driver"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ Support for the TI/National Semiconductor LP3943.
+ This driver consists of GPIO and PWM drivers.
+ With these functionalities, it can be used for LED string control or
+ general usage such like a GPIO controller and a PWM controller.
+
 config MFD_LP8788
bool "TI LP8788 Power Management Unit Driver"
depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8a28dc9..58554f1 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_PMIC_DA9052)   += da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)   += da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)   += da9052-i2c.o
 
+obj-$(CONFIG_MFD_LP3943)   += lp3943.o
 obj-$(CONFIG_MFD_LP8788)   += lp8788.o lp8788-irq.o
 
 da9055-objs:= da9055-core.o da9055-i2c.o
diff --git a/drivers/mfd/lp3943.c b/drivers/mfd/lp3943.c
new file mode 100644
index 000..e322268
--- /dev/null
+++ b/drivers/mfd/lp3943.c
@@ -0,0 +1,167 @@
+/*
+ * TI/National Semiconductor LP3943 MFD Core Driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver structure:
+ *   LP3943 is an integrated device capable of driving 16 output channels.
+ *   It can be used for a GPIO expander and PWM generators.
+ *
+ *   LED controlGeneral usage for a device
+ *   ___   
+ *
+ *   LP3943 MFD  GPIO expanderleds-gpioeg) HW enable pin
+ *   |
+ *   --- PWM generatorleds-pwm eg) PWM input
+ *
+ *   Internal two PWM channels are used for LED dimming effect.
+ *   And each output pin can be used as a GPIO as well.
+ *   The LED functionality can work with GPIOs or PWMs.
+ *   LEDs can be controlled with legacy leds-gpio(static brightness) or
+ *   leds-pwm drivers(dynamic brightness control).
+ *   Alternatively, it can be used for generic GPIO and PWM controller.
+ *   For example, a GPIO is HW enable pin of a device.
+ *   A PWM is input pin of a backlight device.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LP3943_MAX_REGISTERS   0x09
+
+/* Register configuration for pin MUX */
+static const struct lp3943_reg_cfg lp3943_mux_cfg[] = {
+   /* address, mask, shift */
+   { LP3943_REG_MUX0, 0x03, 0 },
+   { LP3943_REG_MUX0, 0x0C, 2 },
+   { LP3943_REG_MUX0, 0x30, 4 },
+   { LP3943_REG_MUX0, 0xC0, 6 },
+   { LP3943_REG_MUX1, 0x03, 0 },
+   { LP3943_REG_MUX1, 0x0C, 2 },
+   { LP3943_REG_MUX1, 0x30, 4 },
+   { LP3943_REG_MUX1, 0xC0, 6 },
+   { LP3943_REG_MUX2, 0x03, 0 },
+   { LP3943_REG_MUX2, 0x0C, 2 },
+   { LP3943_REG_MUX2, 0x30, 4 },
+   { LP3943_REG_MUX2, 0xC0,

[PATCH RESEND v5 3/4] pwm: add LP3943 PWM driver

2013-12-05 Thread Milo Kim
This is the other of the LP3943 MFD driver.
LP3943 can be used as a PWM generator, up to 2 channels.

* Two PWM generators supported

* Supported PWM operations
  request, free, config, enable and disable

* Pin assignment
  A driver data, 'pin_used' is checked when a PWM is requested.
  If the output pin is already assigned, then returns as failure.
  If the pin is available, 'pin_used' is set.
  When the PWM is not used anymore, then it is cleared.
  It is defined as unsigned long type for atomic bit operation APIs,
  but only LSB 16bits are used because LP3943 has 16 outputs.

Signed-off-by: Milo Kim 
Acked-by: Thierry Reding 
---
* Patch v5
  Add Thierry's acknowledgement.

* Patch v4
  No update, same as v3.

* Patch v3
  Manual polarity not supported any more.
  Add encapsulation functions for accessing internal data structure.
  Use pwm_set_chip_data() and pwm_get_chip_data().
  And other code fixes based on Thierry's feedback.

 drivers/pwm/Kconfig  |   10 ++
 drivers/pwm/Makefile |1 +
 drivers/pwm/pwm-lp3943.c |  314 ++
 3 files changed, 325 insertions(+)
 create mode 100644 drivers/pwm/pwm-lp3943.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 75840b5..9cf38bc 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -81,6 +81,16 @@ config PWM_JZ4740
  To compile this driver as a module, choose M here: the module
  will be called pwm-jz4740.
 
+config PWM_LP3943
+   tristate "TI/National Semiconductor LP3943 PWM support"
+   depends on MFD_LP3943
+   help
+ Generic PWM framework driver for LP3943 which supports two PWM
+ channels.
+
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-lp3943.
+
 config PWM_LPC32XX
tristate "LPC32XX PWM support"
depends on ARCH_LPC32XX
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 77a8c18..db8e349 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
 obj-$(CONFIG_PWM_IMX)  += pwm-imx.o
 obj-$(CONFIG_PWM_JZ4740)   += pwm-jz4740.o
+obj-$(CONFIG_PWM_LP3943)   += pwm-lp3943.o
 obj-$(CONFIG_PWM_LPC32XX)  += pwm-lpc32xx.o
 obj-$(CONFIG_PWM_MXS)  += pwm-mxs.o
 obj-$(CONFIG_PWM_PCA9685)  += pwm-pca9685.o
diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c
new file mode 100644
index 000..8a843a0
--- /dev/null
+++ b/drivers/pwm/pwm-lp3943.c
@@ -0,0 +1,314 @@
+/*
+ * TI/National Semiconductor LP3943 PWM driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * 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; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LP3943_MAX_DUTY255
+#define LP3943_MIN_PERIOD  6250
+#define LP3943_MAX_PERIOD  160
+
+struct lp3943_pwm {
+   struct pwm_chip chip;
+   struct lp3943 *lp3943;
+   struct lp3943_platform_data *pdata;
+};
+
+static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *_chip)
+{
+   return container_of(_chip, struct lp3943_pwm, chip);
+}
+
+static struct lp3943_pwm_map *
+lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm)
+{
+   struct lp3943_platform_data *pdata = lp3943_pwm->pdata;
+   struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+   struct lp3943_pwm_map *pwm_map;
+   int i, offset;
+
+   pwm_map = kzalloc(sizeof(*pwm_map), GFP_KERNEL);
+   if (!pwm_map)
+   return ERR_PTR(-ENOMEM);
+
+   pwm_map->output = pdata->pwms[hwpwm]->output;
+   pwm_map->num_outputs = pdata->pwms[hwpwm]->num_outputs;
+
+   for (i = 0; i < pwm_map->num_outputs; i++) {
+   offset = pwm_map->output[i];
+
+   /* Return an error if the pin is already assigned */
+   if (test_and_set_bit(offset, &lp3943->pin_used))
+   return ERR_PTR(-EBUSY);
+   }
+
+   return pwm_map;
+}
+
+static int lp3943_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+   struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
+   struct lp3943_pwm_map *pwm_map;
+
+   pwm_map = lp3943_pwm_request_map(lp3943_pwm, pwm->hwpwm);
+   if (IS_ERR(pwm_map))
+   return PTR_ERR(pwm_map);
+
+   return pwm_set_chip_data(pwm, pwm_map);
+}
+
+static void lp3943_pwm_free_map(struct lp3943_pwm *lp3943_pwm,
+   struct lp3943_pwm_map *pwm_map)
+{
+   struct lp3943 *lp3943 = lp3943_pwm->lp3943;
+   int i, offset;
+
+   for (i = 0; i < pwm_map->num_

[PATCH RESEND v5 2/4] gpio: add LP3943 I2C GPIO expander driver

2013-12-05 Thread Milo Kim
This is one of LP3943 MFD driver.
LP3943 is configurable as a GPIO expander, up to 16 GPIOs.

* Application note: how to configure LP3943 as a GPIO expander
  http://www.ti.com/lit/an/snva287a/snva287a.pdf

* Supported GPIO controller operations
  request, free, direction_input, direction_output, get and set

* GPIO direction register not supported
  LP3943 doesn't have the GPIO direction register. It only provides input and
  output status registers.
  So, private data for the direction should be handled manually.
  This variable is updated whenever the direction is changed and
  used in 'get' operation.

* Pin assignment
  A driver data, 'pin_used' is checked when a GPIO is requested.
  If the GPIO is already assigned, then returns as failure.
  If the GPIO is available, 'pin_used' is set.
  When the GPIO is not used anymore, then it is cleared.
  It is defined as unsigned long type for atomic bit operation APIs,
  but only LSB 16bits are used because LP3943 has 16 outputs.

Signed-off-by: Milo Kim 
Reviewed-by: Linus Walleij 
---
* Patch v5 and v4
  No update, same as v3

* Patch v3
  Use inline function instead of macro(), to_lp3943_gpio().
  Add 'lp3943_gpio_set_mode()' and use it in lp3943_gpio_direction_input() and
  lp3943_gpio_set().
  Few code cosmetic applied - indentations.

* Patch v2
  Use bitops macros for bit manipulations.
  Support device tree structure for the GPIO controller.
  Add request() and free() for the pin assignment.

 drivers/gpio/Kconfig   |8 ++
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-lp3943.c |  242 
 3 files changed, 251 insertions(+)
 create mode 100644 drivers/gpio/gpio-lp3943.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b6ed304..e8ee076 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -368,6 +368,14 @@ config GPIO_ARIZONA
help
  Support for GPIOs on Wolfson Arizona class devices.
 
+config GPIO_LP3943
+   tristate "TI/National Semiconductor LP3943 GPIO expander"
+   depends on MFD_LP3943
+   help
+ GPIO driver for LP3943 MFD.
+ LP3943 can be used as a GPIO expander which provides up to 16 GPIOs.
+ Open drain outputs are required for this usage.
+
 config GPIO_MAX7300
tristate "Maxim MAX7300 GPIO expander"
depends on I2C
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 98e23eb..e246962 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL)   += gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)  += gpio-kempld.o
 obj-$(CONFIG_ARCH_KS8695)  += gpio-ks8695.o
 obj-$(CONFIG_GPIO_LANGWELL)+= gpio-langwell.o
+obj-$(CONFIG_GPIO_LP3943)  += gpio-lp3943.o
 obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LYNXPOINT)   += gpio-lynxpoint.o
 obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
diff --git a/drivers/gpio/gpio-lp3943.c b/drivers/gpio/gpio-lp3943.c
new file mode 100644
index 000..7b8db88
--- /dev/null
+++ b/drivers/gpio/gpio-lp3943.c
@@ -0,0 +1,242 @@
+/*
+ * TI/National Semiconductor LP3943 GPIO driver
+ *
+ * Copyright 2013 Texas Instruments
+ *
+ * Author: Milo Kim 
+ *
+ * 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; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum lp3943_gpios {
+   LP3943_GPIO1,
+   LP3943_GPIO2,
+   LP3943_GPIO3,
+   LP3943_GPIO4,
+   LP3943_GPIO5,
+   LP3943_GPIO6,
+   LP3943_GPIO7,
+   LP3943_GPIO8,
+   LP3943_GPIO9,
+   LP3943_GPIO10,
+   LP3943_GPIO11,
+   LP3943_GPIO12,
+   LP3943_GPIO13,
+   LP3943_GPIO14,
+   LP3943_GPIO15,
+   LP3943_GPIO16,
+   LP3943_MAX_GPIO,
+};
+
+struct lp3943_gpio {
+   struct gpio_chip chip;
+   struct lp3943 *lp3943;
+   u16 input_mask; /* 1 = GPIO is input direction, 0 = output */
+};
+
+static inline struct lp3943_gpio *to_lp3943_gpio(struct gpio_chip *_chip)
+{
+   return container_of(_chip, struct lp3943_gpio, chip);
+}
+
+static int lp3943_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+   struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+   struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+   /* Return an error if the pin is already assigned */
+   if (test_and_set_bit(offset, &lp3943->pin_used))
+   return -EBUSY;
+
+   return 0;
+}
+
+static void lp3943_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+   struct lp3943_gpio *lp3943_gpio = to_lp3943_gpio(chip);
+   struct lp3943 *lp3943 = lp3943_gpio->lp3943;
+
+   clear_bit(offset, &lp3943->pin_used);
+}
+
+static int lp3943_gpio_set_mode(struct lp3943_gpio *lp3

Re: [PATCH v5 0/4] LP3943 MFD driver for a GPIO expander and a PWM generator

2013-12-05 Thread Milo Kim

Hello guys,

My apologies for too messy messages.
Would you please refer to the patch-set with 'PATCH RESEND v5'?
Thanks.

  Milo

On 12/06/2013 11:08 AM, Milo Kim wrote:

LP3943 is an integrated device capable of driving 16 output channels.
It can be used for GPIO expander and PWM generators.
LP3493 registers are controlled via the I2C interface.

This patch-set consists of four parts - MFD, GPIO, PWM and documents.

Update from v4 to v5:
   Add Thierry's ACK for the PWM driver and the DT documentation

Milo Kim (4):
   mfd: add LP3943 MFD driver
   gpio: add LP3943 I2C GPIO expander driver
   pwm: add LP3943 PWM driver
   Documentation: add LP3943 DT bindings and document

  .../devicetree/bindings/gpio/gpio-lp3943.txt   |   37 +++
  Documentation/devicetree/bindings/mfd/lp3943.txt   |   33 ++
  .../devicetree/bindings/pwm/pwm-lp3943.txt |   58 
  drivers/gpio/Kconfig   |8 +
  drivers/gpio/Makefile  |1 +
  drivers/gpio/gpio-lp3943.c |  242 +++
  drivers/mfd/Kconfig|   11 +
  drivers/mfd/Makefile   |1 +
  drivers/mfd/lp3943.c   |  167 +++
  drivers/pwm/Kconfig|   10 +
  drivers/pwm/Makefile   |1 +
  drivers/pwm/pwm-lp3943.c   |  314 
  include/linux/mfd/lp3943.h |  114 +++
  13 files changed, 997 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-lp3943.txt
  create mode 100644 Documentation/devicetree/bindings/mfd/lp3943.txt
  create mode 100644 Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
  create mode 100644 drivers/gpio/gpio-lp3943.c
  create mode 100644 drivers/mfd/lp3943.c
  create mode 100644 drivers/pwm/pwm-lp3943.c
  create mode 100644 include/linux/mfd/lp3943.h



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   3   4   >