Re: [PATCH V4 1/4] mfd: f81504-core: Add Fintek F81504/508/512 PCIE-to-UART/GPIO core support
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
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
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 ShevchenkoIntel Finland Oy
Re: [PATCH V4 1/4] mfd: f81504-core: Add Fintek F81504/508/512 PCIE-to-UART/GPIO core support
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
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 GnomesSuggested-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
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,