Re: [PATCH V4 1/4] mfd: f81504-core: Add Fintek F81504/508/512 PCIE-to-UART/GPIO core support

2016-03-01 Thread Peter Hung

Hi Andy,

Andy Shevchenko 於 2016/2/23 下午 07:05 寫道:

On Tue, 2016-02-23 at 14:30 +0800, Peter Hung wrote:

+config MFD_FINTEK_F81504_CORE
+tristate "Fintek F81504/508/512 PCIE-to-UART/GPIO MFD
support"
+depends on PCI
+select MFD_CORE
+default SERIAL_8250


SERIAL_8250_PCI ?


In my opinion, 8250_pci & f81504_core are independently drivers.
So I'll set the default to SERIAL_8250.


+static bool f81504_is_gpio(unsigned int idx, u8 gpio_en)
+{
+   unsigned int i;
+
+   /* Find every port to check is multi-function port */
+   for (i = 0; i < ARRAY_SIZE(fintek_gpio_mapping); i++) {




+   if (fintek_gpio_mapping[i] != idx || !(gpio_en &
BIT(i)))
+   continue;
+
+   /*
+* This port is multi-function and enabled as gpio
mode.
+* So we'll not configure it as serial port.
+*/
+   return true;


Perhaps

if (fintek_gpio_mapping[i] == idx && (gpio_en & BIT(i)))
  return true;


Your code is more simple and readable. I'll change it for V5

Thanks for your advices.
--
With Best Regards,
Peter Hung


Re: [PATCH V4 1/4] mfd: f81504-core: Add Fintek F81504/508/512 PCIE-to-UART/GPIO core support

2016-03-01 Thread Peter Hung

Hi Andy,

Andy Shevchenko 於 2016/2/23 下午 07:05 寫道:

On Tue, 2016-02-23 at 14:30 +0800, Peter Hung wrote:

+config MFD_FINTEK_F81504_CORE
+tristate "Fintek F81504/508/512 PCIE-to-UART/GPIO MFD
support"
+depends on PCI
+select MFD_CORE
+default SERIAL_8250


SERIAL_8250_PCI ?


In my opinion, 8250_pci & f81504_core are independently drivers.
So I'll set the default to SERIAL_8250.


+static bool f81504_is_gpio(unsigned int idx, u8 gpio_en)
+{
+   unsigned int i;
+
+   /* Find every port to check is multi-function port */
+   for (i = 0; i < ARRAY_SIZE(fintek_gpio_mapping); i++) {




+   if (fintek_gpio_mapping[i] != idx || !(gpio_en &
BIT(i)))
+   continue;
+
+   /*
+* This port is multi-function and enabled as gpio
mode.
+* So we'll not configure it as serial port.
+*/
+   return true;


Perhaps

if (fintek_gpio_mapping[i] == idx && (gpio_en & BIT(i)))
  return true;


Your code is more simple and readable. I'll change it for V5

Thanks for your advices.
--
With Best Regards,
Peter Hung


Re: [PATCH V4 1/4] mfd: f81504-core: Add Fintek F81504/508/512 PCIE-to-UART/GPIO core support

2016-02-23 Thread Andy Shevchenko
On Tue, 2016-02-23 at 14:30 +0800, Peter Hung wrote:
> The Fintek F81504/508/512 had implemented the basic serial port
> function in
> 8250_pci.c. We try to implement high baudrate & GPIOLIB with a spilt
> file
> 8250_f81504.c, but it seems too complex to add GPIOLIB.

[...]

> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -345,6 +345,18 @@ config HTC_I2CPLD
>     This device provides input and output GPIOs through an I2C
>     interface to one or more sub-chips.
>  
> +config MFD_FINTEK_F81504_CORE
> +tristate "Fintek F81504/508/512 PCIE-to-UART/GPIO MFD
> support"
> +depends on PCI
> +select MFD_CORE
> +default SERIAL_8250

SERIAL_8250_PCI ?

> +static bool f81504_is_gpio(unsigned int idx, u8 gpio_en)
> +{
> + unsigned int i;
> +
> + /* Find every port to check is multi-function port */
> + for (i = 0; i < ARRAY_SIZE(fintek_gpio_mapping); i++) {


> + if (fintek_gpio_mapping[i] != idx || !(gpio_en &
> BIT(i)))
> + continue;
> +
> + /*
> +  * This port is multi-function and enabled as gpio
> mode.
> +  * So we'll not configure it as serial port.
> +  */
> + return true;

Perhaps

if (fintek_gpio_mapping[i] == idx && (gpio_en & BIT(i)))
 return true;

?

> + }
> +
> + return false;
> +}

-- 
Andy Shevchenko 
Intel Finland Oy



Re: [PATCH V4 1/4] mfd: f81504-core: Add Fintek F81504/508/512 PCIE-to-UART/GPIO core support

2016-02-23 Thread Andy Shevchenko
On Tue, 2016-02-23 at 14:30 +0800, Peter Hung wrote:
> The Fintek F81504/508/512 had implemented the basic serial port
> function in
> 8250_pci.c. We try to implement high baudrate & GPIOLIB with a spilt
> file
> 8250_f81504.c, but it seems too complex to add GPIOLIB.

[...]

> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -345,6 +345,18 @@ config HTC_I2CPLD
>     This device provides input and output GPIOs through an I2C
>     interface to one or more sub-chips.
>  
> +config MFD_FINTEK_F81504_CORE
> +tristate "Fintek F81504/508/512 PCIE-to-UART/GPIO MFD
> support"
> +depends on PCI
> +select MFD_CORE
> +default SERIAL_8250

SERIAL_8250_PCI ?

> +static bool f81504_is_gpio(unsigned int idx, u8 gpio_en)
> +{
> + unsigned int i;
> +
> + /* Find every port to check is multi-function port */
> + for (i = 0; i < ARRAY_SIZE(fintek_gpio_mapping); i++) {


> + if (fintek_gpio_mapping[i] != idx || !(gpio_en &
> BIT(i)))
> + continue;
> +
> + /*
> +  * This port is multi-function and enabled as gpio
> mode.
> +  * So we'll not configure it as serial port.
> +  */
> + return true;

Perhaps

if (fintek_gpio_mapping[i] == idx && (gpio_en & BIT(i)))
 return true;

?

> + }
> +
> + return false;
> +}

-- 
Andy Shevchenko 
Intel Finland Oy



[PATCH V4 1/4] mfd: f81504-core: Add Fintek F81504/508/512 PCIE-to-UART/GPIO core support

2016-02-22 Thread Peter Hung
The Fintek F81504/508/512 had implemented the basic serial port function in
8250_pci.c. We try to implement high baudrate & GPIOLIB with a spilt file
8250_f81504.c, but it seems too complex to add GPIOLIB.

Alan & Andy recommend us to rewrite and spilt our driver with MFD
architecture.
https://lkml.org/lkml/2016/1/19/288

This driver is core driver for F81504/508/512, it'll handle the generation
of UART/GPIO platform device and initialize PCIE configuration space when
probe()/resume().

IC function list:
F81504: Max 2x8 GPIOs and max 4 serial ports
port2/3 are multi-function
F81508: Max 6x8 GPIOs and max 8 serial ports
port2/3 are multi-function, port8/9/10/11 are gpio only
F81512: Max 6x8 GPIOs and max 12 serial ports
port2/3/8/9/10/11 are multi-function

H/W provider could changes the PCI configure space F0/F3h
values in EEPROM or ASL code to change mode.

F0h bit0~5: Enable GPIO0~5
bit6~7: Reserve

F3h bit0~5: Multi-Functional Flag (0:GPIO/1:UART)
bit0: UART2 pin out for UART2 / GPIO0
bit1: UART3 pin out for UART3 / GPIO1
bit2: UART8 pin out for UART8 / GPIO2
bit3: UART9 pin out for UART9 / GPIO3
bit4: UART10 pin out for UART10 / GPIO4
bit5: UART11 pin out for UART11 / GPIO5
bit6~7: Reserve

Suggested-by: One Thousand Gnomes 
Suggested-by: Andy Shevchenko 
Signed-off-by: Peter Hung 
---
 drivers/mfd/Kconfig|  12 ++
 drivers/mfd/Makefile   |   2 +
 drivers/mfd/f81504-core.c  | 335 +
 include/linux/mfd/f81504.h |  52 +++
 4 files changed, 401 insertions(+)
 create mode 100644 drivers/mfd/f81504-core.c
 create mode 100644 include/linux/mfd/f81504.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index aa21dc5..775761f 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -345,6 +345,18 @@ config HTC_I2CPLD
  This device provides input and output GPIOs through an I2C
  interface to one or more sub-chips.
 
+config MFD_FINTEK_F81504_CORE
+tristate "Fintek F81504/508/512 PCIE-to-UART/GPIO MFD support"
+depends on PCI
+select MFD_CORE
+default SERIAL_8250
+help
+  This driver provides the F81504/508/512 UART & GPIO platform
+  devices. You should enable CONFIG_GPIO_F81504 to get GPIOLIB
+  support and CONFIG_8250_F81504 to get serial port support.
+  This driver needs to be built into the kernel to use early
+  console support.
+
 config MFD_INTEL_QUARK_I2C_GPIO
tristate "Intel Quark MFD I2C GPIO"
depends on PCI
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 5eaa6465d..8e581ad 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -22,6 +22,8 @@ obj-$(CONFIG_HTC_EGPIO)   += htc-egpio.o
 obj-$(CONFIG_HTC_PASIC3)   += htc-pasic3.o
 obj-$(CONFIG_HTC_I2CPLD)   += htc-i2cpld.o
 
+obj-$(CONFIG_MFD_FINTEK_F81504_CORE)   += f81504-core.o
+
 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC)   += davinci_voicecodec.o
 obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
 obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o
diff --git a/drivers/mfd/f81504-core.c b/drivers/mfd/f81504-core.c
new file mode 100644
index 000..c192250
--- /dev/null
+++ b/drivers/mfd/f81504-core.c
@@ -0,0 +1,335 @@
+/*
+ * Core operations for Fintek F81504/508/512 PCIE-to-UART/GPIO device
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define F81504_IO_REGION   8
+
+const u8 fintek_gpio_mapping[F81504_MAX_GPIO_CNT] = { 2, 3, 8, 9, 10, 11 };
+EXPORT_SYMBOL(fintek_gpio_mapping);
+
+static bool f81504_is_gpio(unsigned int idx, u8 gpio_en)
+{
+   unsigned int i;
+
+   /* Find every port to check is multi-function port */
+   for (i = 0; i < ARRAY_SIZE(fintek_gpio_mapping); i++) {
+   if (fintek_gpio_mapping[i] != idx || !(gpio_en & BIT(i)))
+   continue;
+
+   /*
+* This port is multi-function and enabled as gpio mode.
+* So we'll not configure it as serial port.
+*/
+   return true;
+   }
+
+   return false;
+}
+
+static int f81504_port_init(struct pci_dev *pdev)
+{
+   struct f81504_pci_private *priv = pci_get_drvdata(pdev);
+   unsigned int i;
+   u32 gpio_addr;
+   u8 gpio_en, f0h_data, f3h_data;
+   u32 max_port, iobase;
+   u32 bar_data[3];
+   u16 tmp;
+   u8 config_base;
+
+   /* Init GPIO IO Address */
+   gpio_addr = pci_resource_start(pdev, 2);
+
+   /*
+* Write GPIO IO Address LSB/MSB to corresponding register. Due to we
+* can't write once with pci_write_config_word() on x86 platform, we'll
+* write it with pci_write_config_byte().
+*/
+   pci_write_config_byte(pdev, 

[PATCH V4 1/4] mfd: f81504-core: Add Fintek F81504/508/512 PCIE-to-UART/GPIO core support

2016-02-22 Thread Peter Hung
The Fintek F81504/508/512 had implemented the basic serial port function in
8250_pci.c. We try to implement high baudrate & GPIOLIB with a spilt file
8250_f81504.c, but it seems too complex to add GPIOLIB.

Alan & Andy recommend us to rewrite and spilt our driver with MFD
architecture.
https://lkml.org/lkml/2016/1/19/288

This driver is core driver for F81504/508/512, it'll handle the generation
of UART/GPIO platform device and initialize PCIE configuration space when
probe()/resume().

IC function list:
F81504: Max 2x8 GPIOs and max 4 serial ports
port2/3 are multi-function
F81508: Max 6x8 GPIOs and max 8 serial ports
port2/3 are multi-function, port8/9/10/11 are gpio only
F81512: Max 6x8 GPIOs and max 12 serial ports
port2/3/8/9/10/11 are multi-function

H/W provider could changes the PCI configure space F0/F3h
values in EEPROM or ASL code to change mode.

F0h bit0~5: Enable GPIO0~5
bit6~7: Reserve

F3h bit0~5: Multi-Functional Flag (0:GPIO/1:UART)
bit0: UART2 pin out for UART2 / GPIO0
bit1: UART3 pin out for UART3 / GPIO1
bit2: UART8 pin out for UART8 / GPIO2
bit3: UART9 pin out for UART9 / GPIO3
bit4: UART10 pin out for UART10 / GPIO4
bit5: UART11 pin out for UART11 / GPIO5
bit6~7: Reserve

Suggested-by: One Thousand Gnomes 
Suggested-by: Andy Shevchenko 
Signed-off-by: Peter Hung 
---
 drivers/mfd/Kconfig|  12 ++
 drivers/mfd/Makefile   |   2 +
 drivers/mfd/f81504-core.c  | 335 +
 include/linux/mfd/f81504.h |  52 +++
 4 files changed, 401 insertions(+)
 create mode 100644 drivers/mfd/f81504-core.c
 create mode 100644 include/linux/mfd/f81504.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index aa21dc5..775761f 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -345,6 +345,18 @@ config HTC_I2CPLD
  This device provides input and output GPIOs through an I2C
  interface to one or more sub-chips.
 
+config MFD_FINTEK_F81504_CORE
+tristate "Fintek F81504/508/512 PCIE-to-UART/GPIO MFD support"
+depends on PCI
+select MFD_CORE
+default SERIAL_8250
+help
+  This driver provides the F81504/508/512 UART & GPIO platform
+  devices. You should enable CONFIG_GPIO_F81504 to get GPIOLIB
+  support and CONFIG_8250_F81504 to get serial port support.
+  This driver needs to be built into the kernel to use early
+  console support.
+
 config MFD_INTEL_QUARK_I2C_GPIO
tristate "Intel Quark MFD I2C GPIO"
depends on PCI
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 5eaa6465d..8e581ad 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -22,6 +22,8 @@ obj-$(CONFIG_HTC_EGPIO)   += htc-egpio.o
 obj-$(CONFIG_HTC_PASIC3)   += htc-pasic3.o
 obj-$(CONFIG_HTC_I2CPLD)   += htc-i2cpld.o
 
+obj-$(CONFIG_MFD_FINTEK_F81504_CORE)   += f81504-core.o
+
 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC)   += davinci_voicecodec.o
 obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
 obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o
diff --git a/drivers/mfd/f81504-core.c b/drivers/mfd/f81504-core.c
new file mode 100644
index 000..c192250
--- /dev/null
+++ b/drivers/mfd/f81504-core.c
@@ -0,0 +1,335 @@
+/*
+ * Core operations for Fintek F81504/508/512 PCIE-to-UART/GPIO device
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define F81504_IO_REGION   8
+
+const u8 fintek_gpio_mapping[F81504_MAX_GPIO_CNT] = { 2, 3, 8, 9, 10, 11 };
+EXPORT_SYMBOL(fintek_gpio_mapping);
+
+static bool f81504_is_gpio(unsigned int idx, u8 gpio_en)
+{
+   unsigned int i;
+
+   /* Find every port to check is multi-function port */
+   for (i = 0; i < ARRAY_SIZE(fintek_gpio_mapping); i++) {
+   if (fintek_gpio_mapping[i] != idx || !(gpio_en & BIT(i)))
+   continue;
+
+   /*
+* This port is multi-function and enabled as gpio mode.
+* So we'll not configure it as serial port.
+*/
+   return true;
+   }
+
+   return false;
+}
+
+static int f81504_port_init(struct pci_dev *pdev)
+{
+   struct f81504_pci_private *priv = pci_get_drvdata(pdev);
+   unsigned int i;
+   u32 gpio_addr;
+   u8 gpio_en, f0h_data, f3h_data;
+   u32 max_port, iobase;
+   u32 bar_data[3];
+   u16 tmp;
+   u8 config_base;
+
+   /* Init GPIO IO Address */
+   gpio_addr = pci_resource_start(pdev, 2);
+
+   /*
+* Write GPIO IO Address LSB/MSB to corresponding register. Due to we
+* can't write once with pci_write_config_word() on x86 platform, we'll
+* write it with pci_write_config_byte().
+*/
+   pci_write_config_byte(pdev, F81504_GPIO_IO_LSB_REG, gpio_addr & 0xff);
+   pci_write_config_byte(pdev,