Message ID | 20231228151544.14408-3-larry.lai@yunjingtech.com |
---|---|
State | New |
Headers | show |
Series | Add support control UP board CPLD/FPGA pin control | expand |
On 28/12/2023 16:15, larry.lai wrote: > The UP Squared board <http://www.upboard.com> implements certain > features (pin control) through an on-board FPGA. > ... > +module_platform_driver_probe(upboard_pinctrl_driver, upboard_pinctrl_probe); > + > +MODULE_AUTHOR("Gary Wang <garywang@aaeon.com.tw>"); > +MODULE_DESCRIPTION("UP Board HAT pin controller driver"); > +MODULE_LICENSE("GPL v2"); > +MODULE_ALIAS("platform:upboard-pinctrl"); This is a friendly reminder during the review process. It seems my or other reviewer's previous comments were not fully addressed. Maybe the feedback got lost between the quotes, maybe you just forgot to apply it. Please go back to the previous discussion and either implement all requested changes or keep discussing them. Thank you. Best regards, Krzysztof
Hi larry.lai, kernel test robot noticed the following build warnings: [auto build test WARNING on 4fe89d07dcc2804c8b562f6c7896a45643d34b2f] url: https://github.com/intel-lab-lkp/linux/commits/larry-lai/mfd-Add-support-for-UP-board-CPLD-FPGA/20231228-231750 base: 4fe89d07dcc2804c8b562f6c7896a45643d34b2f patch link: https://lore.kernel.org/r/20231228151544.14408-3-larry.lai%40yunjingtech.com patch subject: [PATCH V8 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20231229/202312291646.wfn6dxdH-lkp@intel.com/config) compiler: ClangBuiltLinux clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231229/202312291646.wfn6dxdH-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202312291646.wfn6dxdH-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/pinctrl/pinctrl-upboard.c:709:13: warning: variable length array used [-Wvla] 709 | int offset[pctrl->pctldesc->npins]; | ^~~~~~~~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:1089:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1089 | .ident = BOARD_UP_APL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:46:27: note: expanded from macro 'BOARD_UP_APL01' 46 | #define BOARD_UP_APL01 1 | ^ drivers/pinctrl/pinctrl-upboard.c:1096:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1096 | .ident = BOARD_UP_APL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:46:27: note: expanded from macro 'BOARD_UP_APL01' 46 | #define BOARD_UP_APL01 1 | ^ drivers/pinctrl/pinctrl-upboard.c:1103:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1103 | .ident = BOARD_UP_APL03, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:53:27: note: expanded from macro 'BOARD_UP_APL03' 53 | #define BOARD_UP_APL03 9 | ^ drivers/pinctrl/pinctrl-upboard.c:1110:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1110 | .ident = BOARD_UP_WHL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:50:27: note: expanded from macro 'BOARD_UP_WHL01' 50 | #define BOARD_UP_WHL01 5 | ^ drivers/pinctrl/pinctrl-upboard.c:1117:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1117 | .ident = BOARD_UPX_TGL, | ^~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:55:26: note: expanded from macro 'BOARD_UPX_TGL' 55 | #define BOARD_UPX_TGL 11 | ^~ drivers/pinctrl/pinctrl-upboard.c:1124:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1124 | .ident = BOARD_UPN_EHL01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:57:28: note: expanded from macro 'BOARD_UPN_EHL01' 57 | #define BOARD_UPN_EHL01 13 | ^~ drivers/pinctrl/pinctrl-upboard.c:1131:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1131 | .ident = BOARD_UPS_EHL01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:58:28: note: expanded from macro 'BOARD_UPS_EHL01' 58 | #define BOARD_UPS_EHL01 BOARD_UPN_EHL01 | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:57:28: note: expanded from macro 'BOARD_UPN_EHL01' 57 | #define BOARD_UPN_EHL01 13 | ^~ drivers/pinctrl/pinctrl-upboard.c:1138:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1138 | .ident = BOARD_UPX_ADLP01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:59:28: note: expanded from macro 'BOARD_UPX_ADLP01' 59 | #define BOARD_UPX_ADLP01 15 | ^~ drivers/pinctrl/pinctrl-upboard.c:1145:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1145 | .ident = BOARD_UPN_ADLN01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:60:28: note: expanded from macro 'BOARD_UPN_ADLN01' 60 | #define BOARD_UPN_ADLN01 16 | ^~ drivers/pinctrl/pinctrl-upboard.c:1152:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1152 | .ident = BOARD_UPS_ADLP01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:61:28: note: expanded from macro 'BOARD_UPS_ADLP01' 61 | #define BOARD_UPS_ADLP01 BOARD_UPX_ADLP01 | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:59:28: note: expanded from macro 'BOARD_UPX_ADLP01' 59 | #define BOARD_UPX_ADLP01 15 | ^~ drivers/pinctrl/pinctrl-upboard.c:1159:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1159 | .ident = BOARD_UP_ADLN01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:62:28: note: expanded from macro 'BOARD_UP_ADLN01' 62 | #define BOARD_UP_ADLN01 18 | ^~ drivers/pinctrl/pinctrl-upboard.c:1185:12: error: incompatible pointer to integer conversion assigning to 'int' from 'const char *const' [-Wint-conversion] 1185 | board_id = system_id->ident; | ^ ~~~~~~~~~~~~~~~~ 1 warning and 12 errors generated. vim +709 drivers/pinctrl/pinctrl-upboard.c 705 706 static void upboard_alt_func_enable(struct gpio_chip *gc, const char *name, int id) 707 { 708 struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); > 709 int offset[pctrl->pctldesc->npins]; 710 int i, cnt; 711 bool input; 712 int mode; 713 unsigned int val; 714 715 /* find all pins */ 716 for (i = 0, cnt = 0; i < pctrl->pctldesc->npins; i++) { 717 if (strstr(pctrl->pctldesc->pins[i].name, name)) 718 offset[cnt++] = i; 719 } 720 721 /* change to alternate function */ 722 for (i = 0; i < cnt; i++) { 723 if (pctrl->pins[offset[i]].regs == NULL) 724 continue; 725 input = false; 726 mode = 0; /* default GPIO */ 727 val = readl(pctrl->pins[offset[i]].regs); 728 729 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2C") || 730 strstr(pctrl->pctldesc->pins[offset[i]].name, "PINMUX")) { 731 mode = 1; 732 switch (id) { 733 case BOARD_UPN_ADLN01: 734 case BOARD_UPX_ADLP01: 735 mode = 2; 736 break; 737 default: 738 break; 739 } 740 741 val |= mode<<PADCFG0_PMODE_SHIFT; 742 writel(val, pctrl->pins[offset[i]].regs); 743 upboard_fpga_request_free(pctrl->pctldev, offset[i]); 744 continue; 745 } 746 747 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "UART")) { 748 mode = 1; 749 switch (id) { 750 case BOARD_UPN_EHL01: 751 mode = 4; 752 break; 753 case BOARD_UP_ADLN01: 754 case BOARD_UPN_ADLN01: 755 case BOARD_UPX_ADLP01: 756 mode = 2; 757 break; 758 default: 759 break; 760 } 761 } 762 763 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SPI")) { 764 mode = 1; 765 switch (id) { 766 case BOARD_UP_WHL01: 767 mode = 3; 768 break; 769 case BOARD_UP_ADLN01: 770 case BOARD_UPN_ADLN01: 771 case BOARD_UPX_ADLP01: 772 mode = 7; 773 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MOSI")) { 774 val &= ~PADCFG0_GPIOTXDIS; 775 val |= PADCFG0_GPIORXDIS; 776 } 777 778 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO")) 779 val |= PADCFG0_GPIORXDIS; 780 781 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CLK")) { 782 val &= ~PADCFG0_GPIOTXDIS; 783 val |= PADCFG0_GPIORXDIS; 784 } 785 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS0")) 786 val |= PADCFG0_GPIORXDIS; 787 788 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS1")) 789 continue; 790 break; 791 default: 792 break; 793 } 794 } 795 796 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2S")) { 797 mode = 1; 798 switch (id) { 799 case BOARD_UPX_ADLP01: 800 mode = 4; 801 break; 802 default: 803 break; 804 } 805 } 806 807 val |= mode<<PADCFG0_PMODE_SHIFT; 808 writel(val, pctrl->pins[offset[i]].regs); 809 810 /* input pins */ 811 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "RX")) 812 input = true; 813 814 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CTS")) 815 input = true; 816 817 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "ADC")) { 818 input = true; 819 if (id == BOARD_UP_APL01) 820 upboard_fpga_request_enable(pctrl->pctldev, NULL, offset[i]); 821 else 822 upboard_fpga_request_free(pctrl->pctldev, offset[i]); 823 } 824 825 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO")) 826 input = true; 827 828 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "DIN")) 829 input = true; 830 831 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SDI")) 832 input = true; 833 834 upboard_fpga_set_direction(pctrl->pctldev, NULL, offset[i], input); 835 } 836 } 837
Hi larry.lai, kernel test robot noticed the following build warnings: [auto build test WARNING on 4fe89d07dcc2804c8b562f6c7896a45643d34b2f] url: https://github.com/intel-lab-lkp/linux/commits/larry-lai/mfd-Add-support-for-UP-board-CPLD-FPGA/20231228-231750 base: 4fe89d07dcc2804c8b562f6c7896a45643d34b2f patch link: https://lore.kernel.org/r/20231228151544.14408-3-larry.lai%40yunjingtech.com patch subject: [PATCH V8 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20231229/202312291634.yn0gCqZI-lkp@intel.com/config) compiler: m68k-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231229/202312291634.yn0gCqZI-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202312291634.yn0gCqZI-lkp@intel.com/ All warnings (new ones prefixed by >>): drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_alt_func_enable': >> drivers/pinctrl/pinctrl-upboard.c:709:9: warning: ISO C90 forbids variable length array 'offset' [-Wvla] 709 | int offset[pctrl->pctldesc->npins]; | ^~~ drivers/pinctrl/pinctrl-upboard.c: At top level: >> drivers/pinctrl/pinctrl-upboard.c:46:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 46 | #define BOARD_UP_APL01 1 | ^ drivers/pinctrl/pinctrl-upboard.c:1089:26: note: in expansion of macro 'BOARD_UP_APL01' 1089 | .ident = BOARD_UP_APL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:46:49: note: (near initialization for 'upboard_dmi_table[0].ident') 46 | #define BOARD_UP_APL01 1 | ^ drivers/pinctrl/pinctrl-upboard.c:1089:26: note: in expansion of macro 'BOARD_UP_APL01' 1089 | .ident = BOARD_UP_APL01, | ^~~~~~~~~~~~~~ >> drivers/pinctrl/pinctrl-upboard.c:46:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 46 | #define BOARD_UP_APL01 1 | ^ drivers/pinctrl/pinctrl-upboard.c:1096:26: note: in expansion of macro 'BOARD_UP_APL01' 1096 | .ident = BOARD_UP_APL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:46:49: note: (near initialization for 'upboard_dmi_table[1].ident') 46 | #define BOARD_UP_APL01 1 | ^ drivers/pinctrl/pinctrl-upboard.c:1096:26: note: in expansion of macro 'BOARD_UP_APL01' 1096 | .ident = BOARD_UP_APL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:53:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 53 | #define BOARD_UP_APL03 9 | ^ drivers/pinctrl/pinctrl-upboard.c:1103:26: note: in expansion of macro 'BOARD_UP_APL03' 1103 | .ident = BOARD_UP_APL03, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:53:49: note: (near initialization for 'upboard_dmi_table[2].ident') 53 | #define BOARD_UP_APL03 9 | ^ drivers/pinctrl/pinctrl-upboard.c:1103:26: note: in expansion of macro 'BOARD_UP_APL03' 1103 | .ident = BOARD_UP_APL03, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:50:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 50 | #define BOARD_UP_WHL01 5 | ^ drivers/pinctrl/pinctrl-upboard.c:1110:26: note: in expansion of macro 'BOARD_UP_WHL01' 1110 | .ident = BOARD_UP_WHL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:50:49: note: (near initialization for 'upboard_dmi_table[3].ident') 50 | #define BOARD_UP_WHL01 5 | ^ drivers/pinctrl/pinctrl-upboard.c:1110:26: note: in expansion of macro 'BOARD_UP_WHL01' 1110 | .ident = BOARD_UP_WHL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:55:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 55 | #define BOARD_UPX_TGL 11 | ^~ drivers/pinctrl/pinctrl-upboard.c:1117:26: note: in expansion of macro 'BOARD_UPX_TGL' 1117 | .ident = BOARD_UPX_TGL, | ^~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:55:49: note: (near initialization for 'upboard_dmi_table[4].ident') 55 | #define BOARD_UPX_TGL 11 | ^~ drivers/pinctrl/pinctrl-upboard.c:1117:26: note: in expansion of macro 'BOARD_UPX_TGL' 1117 | .ident = BOARD_UPX_TGL, | ^~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:57:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 57 | #define BOARD_UPN_EHL01 13 | ^~ drivers/pinctrl/pinctrl-upboard.c:1124:26: note: in expansion of macro 'BOARD_UPN_EHL01' 1124 | .ident = BOARD_UPN_EHL01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:57:49: note: (near initialization for 'upboard_dmi_table[5].ident') 57 | #define BOARD_UPN_EHL01 13 | ^~ drivers/pinctrl/pinctrl-upboard.c:1124:26: note: in expansion of macro 'BOARD_UPN_EHL01' 1124 | .ident = BOARD_UPN_EHL01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:57:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 57 | #define BOARD_UPN_EHL01 13 | ^~ drivers/pinctrl/pinctrl-upboard.c:58:49: note: in expansion of macro 'BOARD_UPN_EHL01' 58 | #define BOARD_UPS_EHL01 BOARD_UPN_EHL01 | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:1131:26: note: in expansion of macro 'BOARD_UPS_EHL01' 1131 | .ident = BOARD_UPS_EHL01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:57:49: note: (near initialization for 'upboard_dmi_table[6].ident') 57 | #define BOARD_UPN_EHL01 13 | ^~ drivers/pinctrl/pinctrl-upboard.c:58:49: note: in expansion of macro 'BOARD_UPN_EHL01' 58 | #define BOARD_UPS_EHL01 BOARD_UPN_EHL01 | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:1131:26: note: in expansion of macro 'BOARD_UPS_EHL01' 1131 | .ident = BOARD_UPS_EHL01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:59:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 59 | #define BOARD_UPX_ADLP01 15 | ^~ drivers/pinctrl/pinctrl-upboard.c:1138:26: note: in expansion of macro 'BOARD_UPX_ADLP01' 1138 | .ident = BOARD_UPX_ADLP01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:59:49: note: (near initialization for 'upboard_dmi_table[7].ident') 59 | #define BOARD_UPX_ADLP01 15 | ^~ drivers/pinctrl/pinctrl-upboard.c:1138:26: note: in expansion of macro 'BOARD_UPX_ADLP01' 1138 | .ident = BOARD_UPX_ADLP01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:60:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 60 | #define BOARD_UPN_ADLN01 16 | ^~ drivers/pinctrl/pinctrl-upboard.c:1145:26: note: in expansion of macro 'BOARD_UPN_ADLN01' 1145 | .ident = BOARD_UPN_ADLN01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:60:49: note: (near initialization for 'upboard_dmi_table[8].ident') 60 | #define BOARD_UPN_ADLN01 16 | ^~ drivers/pinctrl/pinctrl-upboard.c:1145:26: note: in expansion of macro 'BOARD_UPN_ADLN01' 1145 | .ident = BOARD_UPN_ADLN01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:59:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 59 | #define BOARD_UPX_ADLP01 15 | ^~ drivers/pinctrl/pinctrl-upboard.c:61:49: note: in expansion of macro 'BOARD_UPX_ADLP01' 61 | #define BOARD_UPS_ADLP01 BOARD_UPX_ADLP01 | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:1152:26: note: in expansion of macro 'BOARD_UPS_ADLP01' 1152 | .ident = BOARD_UPS_ADLP01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:59:49: note: (near initialization for 'upboard_dmi_table[9].ident') 59 | #define BOARD_UPX_ADLP01 15 | ^~ drivers/pinctrl/pinctrl-upboard.c:61:49: note: in expansion of macro 'BOARD_UPX_ADLP01' 61 | #define BOARD_UPS_ADLP01 BOARD_UPX_ADLP01 | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:1152:26: note: in expansion of macro 'BOARD_UPS_ADLP01' 1152 | .ident = BOARD_UPS_ADLP01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:62:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 62 | #define BOARD_UP_ADLN01 18 | ^~ drivers/pinctrl/pinctrl-upboard.c:1159:26: note: in expansion of macro 'BOARD_UP_ADLN01' 1159 | .ident = BOARD_UP_ADLN01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:62:49: note: (near initialization for 'upboard_dmi_table[10].ident') 62 | #define BOARD_UP_ADLN01 18 | ^~ drivers/pinctrl/pinctrl-upboard.c:1159:26: note: in expansion of macro 'BOARD_UP_ADLN01' 1159 | .ident = BOARD_UP_ADLN01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_pinctrl_probe': >> drivers/pinctrl/pinctrl-upboard.c:1185:26: warning: assignment to 'int' from 'const char *' makes integer from pointer without a cast [-Wint-conversion] 1185 | board_id = system_id->ident; | ^ vim +/offset +709 drivers/pinctrl/pinctrl-upboard.c 705 706 static void upboard_alt_func_enable(struct gpio_chip *gc, const char *name, int id) 707 { 708 struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); > 709 int offset[pctrl->pctldesc->npins]; 710 int i, cnt; 711 bool input; 712 int mode; 713 unsigned int val; 714 715 /* find all pins */ 716 for (i = 0, cnt = 0; i < pctrl->pctldesc->npins; i++) { 717 if (strstr(pctrl->pctldesc->pins[i].name, name)) 718 offset[cnt++] = i; 719 } 720 721 /* change to alternate function */ 722 for (i = 0; i < cnt; i++) { 723 if (pctrl->pins[offset[i]].regs == NULL) 724 continue; 725 input = false; 726 mode = 0; /* default GPIO */ 727 val = readl(pctrl->pins[offset[i]].regs); 728 729 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2C") || 730 strstr(pctrl->pctldesc->pins[offset[i]].name, "PINMUX")) { 731 mode = 1; 732 switch (id) { 733 case BOARD_UPN_ADLN01: 734 case BOARD_UPX_ADLP01: 735 mode = 2; 736 break; 737 default: 738 break; 739 } 740 741 val |= mode<<PADCFG0_PMODE_SHIFT; 742 writel(val, pctrl->pins[offset[i]].regs); 743 upboard_fpga_request_free(pctrl->pctldev, offset[i]); 744 continue; 745 } 746 747 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "UART")) { 748 mode = 1; 749 switch (id) { 750 case BOARD_UPN_EHL01: 751 mode = 4; 752 break; 753 case BOARD_UP_ADLN01: 754 case BOARD_UPN_ADLN01: 755 case BOARD_UPX_ADLP01: 756 mode = 2; 757 break; 758 default: 759 break; 760 } 761 } 762 763 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SPI")) { 764 mode = 1; 765 switch (id) { 766 case BOARD_UP_WHL01: 767 mode = 3; 768 break; 769 case BOARD_UP_ADLN01: 770 case BOARD_UPN_ADLN01: 771 case BOARD_UPX_ADLP01: 772 mode = 7; 773 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MOSI")) { 774 val &= ~PADCFG0_GPIOTXDIS; 775 val |= PADCFG0_GPIORXDIS; 776 } 777 778 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO")) 779 val |= PADCFG0_GPIORXDIS; 780 781 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CLK")) { 782 val &= ~PADCFG0_GPIOTXDIS; 783 val |= PADCFG0_GPIORXDIS; 784 } 785 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS0")) 786 val |= PADCFG0_GPIORXDIS; 787 788 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS1")) 789 continue; 790 break; 791 default: 792 break; 793 } 794 } 795 796 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2S")) { 797 mode = 1; 798 switch (id) { 799 case BOARD_UPX_ADLP01: 800 mode = 4; 801 break; 802 default: 803 break; 804 } 805 } 806 807 val |= mode<<PADCFG0_PMODE_SHIFT; 808 writel(val, pctrl->pins[offset[i]].regs); 809 810 /* input pins */ 811 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "RX")) 812 input = true; 813 814 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CTS")) 815 input = true; 816 817 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "ADC")) { 818 input = true; 819 if (id == BOARD_UP_APL01) 820 upboard_fpga_request_enable(pctrl->pctldev, NULL, offset[i]); 821 else 822 upboard_fpga_request_free(pctrl->pctldev, offset[i]); 823 } 824 825 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO")) 826 input = true; 827 828 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "DIN")) 829 input = true; 830 831 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SDI")) 832 input = true; 833 834 upboard_fpga_set_direction(pctrl->pctldev, NULL, offset[i], input); 835 } 836 } 837
On 2023/12/28 23:28, Krzysztof Kozlowski wrote: > On 28/12/2023 16:15, larry.lai wrote: >> The UP Squared board <http://www.upboard.com> implements certain >> features (pin control) through an on-board FPGA. ... >> +MODULE_ALIAS("platform:upboard-pinctrl"); > > This is a friendly reminder during the review process. > > It seems my or other reviewer's previous comments were not fully > addressed. Maybe the feedback got lost between the quotes, maybe you > just forgot to apply it. Please go back to the previous discussion and > either implement all requested changes or keep discussing them. add "platform:" for auto probe these two drivers when upboard-fpga has probe and register these 2 drivers.
Hi larry.lai, kernel test robot noticed the following build errors: [auto build test ERROR on 4fe89d07dcc2804c8b562f6c7896a45643d34b2f] url: https://github.com/intel-lab-lkp/linux/commits/larry-lai/mfd-Add-support-for-UP-board-CPLD-FPGA/20231228-231750 base: 4fe89d07dcc2804c8b562f6c7896a45643d34b2f patch link: https://lore.kernel.org/r/20231228151544.14408-3-larry.lai%40yunjingtech.com patch subject: [PATCH V8 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20231229/202312291907.7mgFSafz-lkp@intel.com/config) compiler: ClangBuiltLinux clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231229/202312291907.7mgFSafz-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202312291907.7mgFSafz-lkp@intel.com/ All errors (new ones prefixed by >>): drivers/pinctrl/pinctrl-upboard.c:709:13: warning: variable length array used [-Wvla] 709 | int offset[pctrl->pctldesc->npins]; | ^~~~~~~~~~~~~~~~~~~~~~ >> drivers/pinctrl/pinctrl-upboard.c:1089:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1089 | .ident = BOARD_UP_APL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:46:27: note: expanded from macro 'BOARD_UP_APL01' 46 | #define BOARD_UP_APL01 1 | ^ drivers/pinctrl/pinctrl-upboard.c:1096:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1096 | .ident = BOARD_UP_APL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:46:27: note: expanded from macro 'BOARD_UP_APL01' 46 | #define BOARD_UP_APL01 1 | ^ drivers/pinctrl/pinctrl-upboard.c:1103:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1103 | .ident = BOARD_UP_APL03, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:53:27: note: expanded from macro 'BOARD_UP_APL03' 53 | #define BOARD_UP_APL03 9 | ^ drivers/pinctrl/pinctrl-upboard.c:1110:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1110 | .ident = BOARD_UP_WHL01, | ^~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:50:27: note: expanded from macro 'BOARD_UP_WHL01' 50 | #define BOARD_UP_WHL01 5 | ^ drivers/pinctrl/pinctrl-upboard.c:1117:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1117 | .ident = BOARD_UPX_TGL, | ^~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:55:26: note: expanded from macro 'BOARD_UPX_TGL' 55 | #define BOARD_UPX_TGL 11 | ^~ drivers/pinctrl/pinctrl-upboard.c:1124:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1124 | .ident = BOARD_UPN_EHL01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:57:28: note: expanded from macro 'BOARD_UPN_EHL01' 57 | #define BOARD_UPN_EHL01 13 | ^~ drivers/pinctrl/pinctrl-upboard.c:1131:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1131 | .ident = BOARD_UPS_EHL01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:58:28: note: expanded from macro 'BOARD_UPS_EHL01' 58 | #define BOARD_UPS_EHL01 BOARD_UPN_EHL01 | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:57:28: note: expanded from macro 'BOARD_UPN_EHL01' 57 | #define BOARD_UPN_EHL01 13 | ^~ drivers/pinctrl/pinctrl-upboard.c:1138:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1138 | .ident = BOARD_UPX_ADLP01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:59:28: note: expanded from macro 'BOARD_UPX_ADLP01' 59 | #define BOARD_UPX_ADLP01 15 | ^~ drivers/pinctrl/pinctrl-upboard.c:1145:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1145 | .ident = BOARD_UPN_ADLN01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:60:28: note: expanded from macro 'BOARD_UPN_ADLN01' 60 | #define BOARD_UPN_ADLN01 16 | ^~ drivers/pinctrl/pinctrl-upboard.c:1152:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1152 | .ident = BOARD_UPS_ADLP01, | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:61:28: note: expanded from macro 'BOARD_UPS_ADLP01' 61 | #define BOARD_UPS_ADLP01 BOARD_UPX_ADLP01 | ^~~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:59:28: note: expanded from macro 'BOARD_UPX_ADLP01' 59 | #define BOARD_UPX_ADLP01 15 | ^~ drivers/pinctrl/pinctrl-upboard.c:1159:12: error: incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'int' [-Wint-conversion] 1159 | .ident = BOARD_UP_ADLN01, | ^~~~~~~~~~~~~~~ drivers/pinctrl/pinctrl-upboard.c:62:28: note: expanded from macro 'BOARD_UP_ADLN01' 62 | #define BOARD_UP_ADLN01 18 | ^~ >> drivers/pinctrl/pinctrl-upboard.c:1185:12: error: incompatible pointer to integer conversion assigning to 'int' from 'const char *const' [-Wint-conversion] 1185 | board_id = system_id->ident; | ^ ~~~~~~~~~~~~~~~~ 1 warning and 12 errors generated. vim +1089 drivers/pinctrl/pinctrl-upboard.c 1085 1086 /* DMI Matches to assign pin mapping driver data */ 1087 static const struct dmi_system_id upboard_dmi_table[] __initconst = { 1088 { > 1089 .ident = BOARD_UP_APL01, 1090 .matches = { /* UP SQUARED */ 1091 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1092 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-APL01"), 1093 }, 1094 }, 1095 { 1096 .ident = BOARD_UP_APL01, 1097 .matches = { /* UP SQUARED Pro*/ 1098 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1099 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPN-APL01"), 1100 }, 1101 }, 1102 { 1103 .ident = BOARD_UP_APL03, 1104 .matches = { /* UP 4000 */ 1105 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1106 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-APL03"), 1107 }, 1108 }, 1109 { 1110 .ident = BOARD_UP_WHL01, 1111 .matches = { /* UPX WHL */ 1112 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1113 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-WHL01"), 1114 }, 1115 }, 1116 { 1117 .ident = BOARD_UPX_TGL, 1118 .matches = { /* UP i11 */ 1119 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1120 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPX-TGL01"), 1121 }, 1122 }, 1123 { 1124 .ident = BOARD_UPN_EHL01, 1125 .matches = { /* UP 6000 */ 1126 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1127 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPN-EHL01"), 1128 }, 1129 }, 1130 { 1131 .ident = BOARD_UPS_EHL01, 1132 .matches = { /* UP squared v2 */ 1133 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1134 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPS-EHL01"), 1135 }, 1136 }, 1137 { 1138 .ident = BOARD_UPX_ADLP01, 1139 .matches = { /* UP Xtreme i12 */ 1140 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1141 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPX-ADLP01"), 1142 }, 1143 }, 1144 { 1145 .ident = BOARD_UPN_ADLN01, 1146 .matches = { /* UP 7000 */ 1147 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1148 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPN-ADLN01"), 1149 }, 1150 }, 1151 { 1152 .ident = BOARD_UPS_ADLP01, 1153 .matches = { /* UP Squared i12 */ 1154 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1155 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPS-ADLP01"), 1156 }, 1157 }, 1158 { 1159 .ident = BOARD_UP_ADLN01, 1160 .matches = { /* UP 7000 */ 1161 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), 1162 DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-ADLN01"), 1163 }, 1164 }, 1165 { } /* Terminating entry */ 1166 }; 1167 1168 static int upboard_pinctrl_probe(struct platform_device *pdev) 1169 { 1170 struct upboard_fpga * const fpga = dev_get_drvdata(pdev->dev.parent); 1171 struct pinctrl_desc *pctldesc; 1172 struct upboard_pinctrl *pctrl; 1173 struct upboard_pin *pins; 1174 const struct dmi_system_id *system_id; 1175 const unsigned int *rpi_mapping; 1176 unsigned int ngpio; 1177 int ret; 1178 int i; 1179 /* default */ 1180 int board_id = BOARD_UP_APL03; 1181 1182 /* check board id to arrange driver data */ 1183 system_id = dmi_first_match(upboard_dmi_table); 1184 if (system_id) > 1185 board_id = system_id->ident; 1186 dev_info(&pdev->dev, "Compatible Up Board ID %d", board_id); 1187 switch (board_id) { 1188 case BOARD_UP_APL01: 1189 pctldesc = &upboard_up2_pinctrl_desc; 1190 rpi_mapping = upboard_up2_rpi_mapping; 1191 ngpio = ARRAY_SIZE(upboard_up2_rpi_mapping); 1192 break; 1193 case BOARD_UP_UPCORE: 1194 pctldesc = &upboard_upcore_crex_pinctrl_desc; 1195 rpi_mapping = upboard_upcore_crex_rpi_mapping; 1196 ngpio = ARRAY_SIZE(upboard_upcore_crex_rpi_mapping); 1197 break; 1198 case BOARD_UP_CORE_PLUS: 1199 pctldesc = &upboard_upcore_crst02_pinctrl_desc; 1200 rpi_mapping = upboard_upcore_crst02_rpi_mapping; 1201 ngpio = ARRAY_SIZE(upboard_upcore_crst02_rpi_mapping); 1202 break; 1203 default: 1204 pctldesc = &upboard_up_pinctrl_desc; 1205 rpi_mapping = upboard_up_rpi_mapping; 1206 ngpio = ARRAY_SIZE(upboard_up_rpi_mapping); 1207 break; 1208 } 1209 1210 pctldesc->name = dev_name(&pdev->dev); 1211 1212 pins = devm_kcalloc(&pdev->dev, pctldesc->npins, sizeof(*pins), GFP_KERNEL); 1213 if (!pins) 1214 return -ENOMEM; 1215 1216 /* initialise pins */ 1217 for (i = 0; i < pctldesc->npins; i++) { 1218 struct upboard_pin *pin = &pins[i]; 1219 struct pinctrl_pin_desc *pd = (struct pinctrl_pin_desc *) &pctldesc->pins[i]; 1220 struct reg_field fldconf = {0}; 1221 unsigned int regoff = (pd->number / UPFPGA_REGISTER_SIZE); 1222 unsigned int lsb = pd->number % UPFPGA_REGISTER_SIZE; 1223 1224 pin->funcbit = NULL; 1225 1226 if (pd->drv_data) { 1227 fldconf = *(struct reg_field *)pd->drv_data; 1228 1229 pin->funcbit = devm_regmap_field_alloc(&pdev->dev, 1230 fpga->regmap, 1231 fldconf); 1232 if (IS_ERR(pin->funcbit)) 1233 return PTR_ERR(pin->funcbit); 1234 } 1235 1236 fldconf.reg = UPFPGA_REG_GPIO_EN0 + regoff; 1237 fldconf.lsb = lsb; 1238 fldconf.msb = lsb; 1239 1240 pin->enbit = devm_regmap_field_alloc(&pdev->dev, 1241 fpga->regmap, 1242 fldconf); 1243 if (IS_ERR(pin->enbit)) 1244 return PTR_ERR(pin->enbit); 1245 1246 fldconf.reg = UPFPGA_REG_GPIO_DIR0 + regoff; 1247 fldconf.lsb = lsb; 1248 fldconf.msb = lsb; 1249 1250 pin->dirbit = devm_regmap_field_alloc(&pdev->dev, 1251 fpga->regmap, 1252 fldconf); 1253 if (IS_ERR(pin->dirbit)) 1254 return PTR_ERR(pin->dirbit); 1255 1256 pd->drv_data = pin; 1257 } 1258 1259 /* create a new pinctrl device and register it */ 1260 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); 1261 if (!pctrl) 1262 return -ENOMEM; 1263 1264 pctrl->rpi_mapping = rpi_mapping; 1265 pctrl->chip = upboard_gpio_chip; 1266 pctrl->pctldesc = pctldesc; 1267 pctrl->chip.parent = &pdev->dev; 1268 pctrl->chip.ngpio = ngpio; 1269 pctrl->pins = pins; 1270 pctrl->ident = board_id; 1271 1272 ret = devm_gpiochip_add_data(&pdev->dev, &pctrl->chip, pctrl); 1273 if (ret) 1274 return ret; 1275 1276 pctrl->pctldev = devm_pinctrl_register(&pdev->dev, pctldesc, pctrl); 1277 if (IS_ERR(pctrl->pctldev)) 1278 return PTR_ERR(pctrl->pctldev); 1279 1280 /* add acpi pin mapping according to external-gpios key */ 1281 ret = upboard_acpi_node_pin_mapping(fpga, pctrl, 1282 "external", 1283 dev_name(&pdev->dev), 1284 0); 1285 if (ret) 1286 return ret; 1287 1288 upboard_alt_func_enable(&pctrl->chip, "I2C", pctrl->ident); 1289 upboard_alt_func_enable(&pctrl->chip, "SPI", pctrl->ident); 1290 upboard_alt_func_enable(&pctrl->chip, "UART", pctrl->ident); 1291 upboard_alt_func_enable(&pctrl->chip, "I2S", pctrl->ident); 1292 upboard_alt_func_enable(&pctrl->chip, "PWM", pctrl->ident); 1293 upboard_alt_func_enable(&pctrl->chip, "ADC", pctrl->ident); 1294 upboard_alt_func_enable(&pctrl->chip, "PINMUX", pctrl->ident); 1295 1296 return ret; 1297 } 1298
On 29/12/2023 10:18, Jack Chang wrote: > On 2023/12/28 23:28, Krzysztof Kozlowski wrote: >> On 28/12/2023 16:15, larry.lai wrote: >>> The UP Squared board <http://www.upboard.com> implements certain >>> features (pin control) through an on-board FPGA. > > ... > >>> +MODULE_ALIAS("platform:upboard-pinctrl"); >> >> This is a friendly reminder during the review process. >> >> It seems my or other reviewer's previous comments were not fully >> addressed. Maybe the feedback got lost between the quotes, maybe you >> just forgot to apply it. Please go back to the previous discussion and >> either implement all requested changes or keep discussing them. > > add "platform:" for auto probe these two drivers when upboard-fpga > has probe and register these 2 drivers. Why do you use alias instead of missing ID table? This scales poorly. Use ID table and if you disagree, then respond with proper comment. You just replied something obvious. Best regards, Krzysztof
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 1cf74b0c42e5..c114fc2b7cec 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -483,6 +483,21 @@ config PINCTRL_THUNDERBAY rate control and direction control. This module will be called as pinctrl-thunderbay. +config PINCTRL_UPBOARD + tristate "UP board FPGA pin controller" + depends on (X86 && ACPI) || COMPILE_TEST + depends on MFD_UPBOARD_FPGA + select GENERIC_PINCONF + select PINMUX + select PINCONF + help + Pin controller for the FPGA GPIO lines on UP boards. Due to the + hardware layout, these are meant to be controlled in tandem with their + corresponding Intel SoC GPIOs. + + To compile this driver as a module, choose M here: the module + will be called pinctrl-upboard. + config PINCTRL_ZYNQ bool "Pinctrl driver for Xilinx Zynq" depends on ARCH_ZYNQ diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index e76f5cdc64b0..c366706d36e7 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_THUNDERBAY) += pinctrl-thunderbay.o +obj-$(CONFIG_PINCTRL_UPBOARD) += pinctrl-upboard.o obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o diff --git a/drivers/pinctrl/pinctrl-upboard.c b/drivers/pinctrl/pinctrl-upboard.c new file mode 100644 index 000000000000..b9a65dcf6cc0 --- /dev/null +++ b/drivers/pinctrl/pinctrl-upboard.c @@ -0,0 +1,1309 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * UP Board HAT pin controller driver + * remapping native GPIO to RPI GPIO and set CPLD + * + * Copyright (c) AAEON. All rights reserved. + * + * Authors: Gary Wang <garywang@aaeon.com.tw> + */ + +#include <linux/dmi.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/driver.h> +#include <linux/mfd/upboard-fpga.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/interrupt.h> +#include <linux/seq_file.h> +#include <linux/string.h> + +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> + +#include "core.h" +#include "intel/pinctrl-intel.h" + +/* Offset from regs */ +#define REVID 0x000 +#define REVID_SHIFT 16 +#define REVID_MASK GENMASK(31, 16) +#define PADBAR 0x00c + +#define PADCFG0 0x000 +#define PADCFG1 0x004 +#define PADCFG2 0x008 +#define PADCFG0_GPIORXDIS BIT(9) +#define PADCFG0_GPIOTXDIS BIT(8) +#define PADCFG0_GPIORXSTATE BIT(1) +#define PADCFG0_GPIOTXSTATE BIT(0) +#define PADCFG0_PMODE_GPIO 0 +#define PADCFG0_PMODE_SHIFT 10 +#define PADCFG0_PMODE_MASK GENMASK(13, 10) + +#define BOARD_UP_CHT01 0 +#define BOARD_UP_APL01 1 +#define BOARD_UP_UPCORE 2 +#define BOARD_UP_CORE_PLUS 3 +#define BOARD_AIOT_IP6801 4 +#define BOARD_UP_WHL01 5 +#define BOARD_UP_ISH 7 +#define BOARD_UPN_APL 8 +#define BOARD_UP_APL03 9 +#define BOARD_UPX_WHLite 10 +#define BOARD_UPX_TGL 11 +#define BOARD_UPX_EDGE_WHL2 12 +#define BOARD_UPN_EHL01 13 +#define BOARD_UPS_EHL01 BOARD_UPN_EHL01 +#define BOARD_UPX_ADLP01 15 +#define BOARD_UPN_ADLN01 16 +#define BOARD_UPS_ADLP01 BOARD_UPX_ADLP01 +#define BOARD_UP_ADLN01 18 + +struct upboard_pin { + struct regmap_field *funcbit; + struct regmap_field *enbit; + struct regmap_field *dirbit; + /* native pin controllers: number, base, irq */ + unsigned int gpio; + unsigned int base; + int irq; + void __iomem *regs; +}; + +struct upboard_pinctrl { + struct gpio_chip chip; + struct device *dev; + struct pinctrl_dev *pctldev; + struct pinctrl_desc *pctldesc; + struct upboard_pin *pins; + struct regmap *regmap; + const unsigned int *rpi_mapping; + int ident; +}; + +enum upboard_func0_fpgabit { + UPFPGA_I2C0_EN = 8, + UPFPGA_I2C1_EN = 9, + UPFPGA_CEC0_EN = 12, + UPFPGA_ADC0_EN = 14 +}; + +static const struct reg_field upboard_i2c0_reg = + REG_FIELD(UPFPGA_REG_FUNC_EN0, UPFPGA_I2C0_EN, UPFPGA_I2C0_EN); + +static const struct reg_field upboard_i2c1_reg = + REG_FIELD(UPFPGA_REG_FUNC_EN0, UPFPGA_I2C1_EN, UPFPGA_I2C1_EN); + +static const struct reg_field upboard_adc0_reg = + REG_FIELD(UPFPGA_REG_FUNC_EN0, UPFPGA_ADC0_EN, UPFPGA_ADC0_EN); + +/* Pin group information */ +struct upboard_pingroup { + const char *name; + const unsigned int *pins; + size_t npins; +}; + +/* Pin function information */ +struct upboard_function { + const char *name; + const char * const *groups; + size_t ngroups; +}; + +#define UPBOARD_BIT_TO_PIN(r, bit) \ + ((r) * UPFPGA_REGISTER_SIZE + (bit)) + +/* + * UP board data + */ + +#define UPBOARD_UP_BIT_TO_PIN(r, id) (UPBOARD_BIT_TO_PIN(r, UPFPGA_UP_##id)) + +#define UPBOARD_UP_PIN_ANON(r, bit) \ + { \ + .number = UPBOARD_BIT_TO_PIN(r, bit), \ + } + +#define UPBOARD_UP_PIN_NAME(r, id) \ + { \ + .number = UPBOARD_UP_BIT_TO_PIN(r, id), \ + .name = #id, \ + } + +#define UPBOARD_UP_PIN_FUNC(r, id, data) \ + { \ + .number = UPBOARD_UP_BIT_TO_PIN(r, id), \ + .name = #id, \ + .drv_data = (void *)(data), \ + } + +#define UPBOARD_PIN_GROUP(n, p) \ + { \ + .name = (n), \ + .pins = (p), \ + .npins = ARRAY_SIZE((p)), \ + } + +#define FUNCTION(n, g) \ + { \ + .name = (n), \ + .groups = (g), \ + .ngroups = ARRAY_SIZE((g)), \ + } + +enum upboard_up_reg1_fpgabit { + UPFPGA_UP_I2C1_SDA, + UPFPGA_UP_I2C1_SCL, + UPFPGA_UP_ADC0, + UPFPGA_UP_GPIO17, + UPFPGA_UP_GPIO27, + UPFPGA_UP_GPIO22, + UPFPGA_UP_SPI_MOSI, + UPFPGA_UP_SPI_MISO, + UPFPGA_UP_SPI_CLK, + UPFPGA_UP_I2C0_SDA, + UPFPGA_UP_GPIO5, + UPFPGA_UP_GPIO6, + UPFPGA_UP_PWM1, + UPFPGA_UP_I2S_FRM, + UPFPGA_UP_GPIO26, + UPFPGA_UP_UART1_TX +}; + +enum upboard_up_reg2_fpgabit { + UPFPGA_UP_UART1_RX, + UPFPGA_UP_I2S_CLK, + UPFPGA_UP_GPIO23, + UPFPGA_UP_GPIO24, + UPFPGA_UP_GPIO25, + UPFPGA_UP_SPI_CS0, + UPFPGA_UP_SPI_CS1, + UPFPGA_UP_I2C0_SCL, + UPFPGA_UP_PWM0, + UPFPGA_UP_GPIO16, + UPFPGA_UP_I2S_DIN, + UPFPGA_UP_I2S_DOUT, +}; + +#define UPFPGA_UP_UART1_RTS UPFPGA_UP_GPIO17 +#define UPFPGA_UP_UART1_CTS UPFPGA_UP_GPIO16 + +static struct pinctrl_pin_desc upboard_up_pins[] = { + UPBOARD_UP_PIN_FUNC(0, I2C1_SDA, &upboard_i2c1_reg), + UPBOARD_UP_PIN_FUNC(0, I2C1_SCL, &upboard_i2c1_reg), + UPBOARD_UP_PIN_FUNC(0, ADC0, &upboard_adc0_reg), + UPBOARD_UP_PIN_NAME(0, UART1_RTS), + UPBOARD_UP_PIN_NAME(0, GPIO27), + UPBOARD_UP_PIN_NAME(0, GPIO22), + UPBOARD_UP_PIN_NAME(0, SPI_MOSI), + UPBOARD_UP_PIN_NAME(0, SPI_MISO), + UPBOARD_UP_PIN_NAME(0, SPI_CLK), + UPBOARD_UP_PIN_FUNC(0, I2C0_SDA, &upboard_i2c0_reg), + UPBOARD_UP_PIN_NAME(0, GPIO5), + UPBOARD_UP_PIN_NAME(0, GPIO6), + UPBOARD_UP_PIN_NAME(0, PWM1), + UPBOARD_UP_PIN_NAME(0, I2S_FRM), + UPBOARD_UP_PIN_NAME(0, GPIO26), + UPBOARD_UP_PIN_NAME(0, UART1_TX), + /* register 1 */ + UPBOARD_UP_PIN_NAME(1, UART1_RX), + UPBOARD_UP_PIN_NAME(1, I2S_CLK), + UPBOARD_UP_PIN_NAME(1, GPIO23), + UPBOARD_UP_PIN_NAME(1, GPIO24), + UPBOARD_UP_PIN_NAME(1, GPIO25), + UPBOARD_UP_PIN_NAME(1, SPI_CS0), + UPBOARD_UP_PIN_NAME(1, SPI_CS1), + UPBOARD_UP_PIN_FUNC(1, I2C0_SCL, &upboard_i2c0_reg), + UPBOARD_UP_PIN_NAME(1, PWM0), + UPBOARD_UP_PIN_NAME(1, UART1_CTS), + UPBOARD_UP_PIN_NAME(1, I2S_DIN), + UPBOARD_UP_PIN_NAME(1, I2S_DOUT), +}; + +static const unsigned int upboard_up_rpi_mapping[] = { + UPBOARD_UP_BIT_TO_PIN(0, I2C0_SDA), + UPBOARD_UP_BIT_TO_PIN(1, I2C0_SCL), + UPBOARD_UP_BIT_TO_PIN(0, I2C1_SDA), + UPBOARD_UP_BIT_TO_PIN(0, I2C1_SCL), + UPBOARD_UP_BIT_TO_PIN(0, ADC0), + UPBOARD_UP_BIT_TO_PIN(0, GPIO5), + UPBOARD_UP_BIT_TO_PIN(0, GPIO6), + UPBOARD_UP_BIT_TO_PIN(1, SPI_CS1), + UPBOARD_UP_BIT_TO_PIN(1, SPI_CS0), + UPBOARD_UP_BIT_TO_PIN(0, SPI_MISO), + UPBOARD_UP_BIT_TO_PIN(0, SPI_MOSI), + UPBOARD_UP_BIT_TO_PIN(0, SPI_CLK), + UPBOARD_UP_BIT_TO_PIN(1, PWM0), + UPBOARD_UP_BIT_TO_PIN(0, PWM1), + UPBOARD_UP_BIT_TO_PIN(0, UART1_TX), + UPBOARD_UP_BIT_TO_PIN(1, UART1_RX), + UPBOARD_UP_BIT_TO_PIN(1, GPIO16), + UPBOARD_UP_BIT_TO_PIN(0, GPIO17), + UPBOARD_UP_BIT_TO_PIN(1, I2S_CLK), + UPBOARD_UP_BIT_TO_PIN(0, I2S_FRM), + UPBOARD_UP_BIT_TO_PIN(1, I2S_DIN), + UPBOARD_UP_BIT_TO_PIN(1, I2S_DOUT), + UPBOARD_UP_BIT_TO_PIN(0, GPIO22), + UPBOARD_UP_BIT_TO_PIN(1, GPIO23), + UPBOARD_UP_BIT_TO_PIN(1, GPIO24), + UPBOARD_UP_BIT_TO_PIN(1, GPIO25), + UPBOARD_UP_BIT_TO_PIN(0, GPIO26), + UPBOARD_UP_BIT_TO_PIN(0, GPIO27), +}; + +/* + * UP^2 board data + */ + +#define UPBOARD_UP2_BIT_TO_PIN(r, id) (UPBOARD_BIT_TO_PIN(r, UPFPGA_UP2_##id)) + +#define UPBOARD_UP2_PIN_MUX(r, bit, data) \ + { \ + .number = UPBOARD_BIT_TO_PIN(r, bit), \ + .name = "PINMUX", \ + .drv_data = (void *)(data), \ + } + +#define UPBOARD_UP2_PIN_NAME(r, id) \ + { \ + .number = UPBOARD_UP2_BIT_TO_PIN(r, id), \ + .name = #id, \ + } + +#define UPBOARD_UP2_PIN_FUNC(r, id, data) \ + { \ + .number = UPBOARD_UP2_BIT_TO_PIN(r, id), \ + .name = #id, \ + .drv_data = (void *)(data), \ + } + +enum upboard_up2_reg0_fpgabit { + UPFPGA_UP2_UART1_TXD, + UPFPGA_UP2_UART1_RXD, + UPFPGA_UP2_UART1_RTS, + UPFPGA_UP2_UART1_CTS, + UPFPGA_UP2_GPIO3_ADC0, + UPFPGA_UP2_GPIO5_ADC2, + UPFPGA_UP2_GPIO6_ADC3, + UPFPGA_UP2_GPIO11, + UPFPGA_UP2_EXHAT_LVDS1n, + UPFPGA_UP2_EXHAT_LVDS1p, + UPFPGA_UP2_SPI2_TXD, + UPFPGA_UP2_SPI2_RXD, + UPFPGA_UP2_SPI2_FS1, + UPFPGA_UP2_SPI2_FS0, + UPFPGA_UP2_SPI2_CLK, + UPFPGA_UP2_SPI1_TXD, +}; + +enum upboard_up2_reg1_fpgabit { + UPFPGA_UP2_SPI1_RXD, + UPFPGA_UP2_SPI1_FS1, + UPFPGA_UP2_SPI1_FS0, + UPFPGA_UP2_SPI1_CLK, + UPFPGA_UP2_BIT20, + UPFPGA_UP2_BIT21, + UPFPGA_UP2_BIT22, + UPFPGA_UP2_BIT23, + UPFPGA_UP2_PWM1, + UPFPGA_UP2_PWM0, + UPFPGA_UP2_EXHAT_LVDS0n, + UPFPGA_UP2_EXHAT_LVDS0p, + UPFPGA_UP2_I2C0_SCL, + UPFPGA_UP2_I2C0_SDA, + UPFPGA_UP2_I2C1_SCL, + UPFPGA_UP2_I2C1_SDA, +}; + +enum upboard_up2_reg2_fpgabit { + UPFPGA_UP2_EXHAT_LVDS3n, + UPFPGA_UP2_EXHAT_LVDS3p, + UPFPGA_UP2_EXHAT_LVDS4n, + UPFPGA_UP2_EXHAT_LVDS4p, + UPFPGA_UP2_EXHAT_LVDS5n, + UPFPGA_UP2_EXHAT_LVDS5p, + UPFPGA_UP2_I2S_SDO, + UPFPGA_UP2_I2S_SDI, + UPFPGA_UP2_I2S_WS_SYNC, + UPFPGA_UP2_I2S_BCLK, + UPFPGA_UP2_EXHAT_LVDS6n, + UPFPGA_UP2_EXHAT_LVDS6p, + UPFPGA_UP2_EXHAT_LVDS7n, + UPFPGA_UP2_EXHAT_LVDS7p, + UPFPGA_UP2_EXHAT_LVDS2n, + UPFPGA_UP2_EXHAT_LVDS2p, +}; + +static struct pinctrl_pin_desc upboard_up2_pins[] = { + UPBOARD_UP2_PIN_NAME(0, UART1_TXD), + UPBOARD_UP2_PIN_NAME(0, UART1_RXD), + UPBOARD_UP2_PIN_NAME(0, UART1_RTS), + UPBOARD_UP2_PIN_NAME(0, UART1_CTS), + UPBOARD_UP2_PIN_NAME(0, GPIO3_ADC0), + UPBOARD_UP2_PIN_NAME(0, GPIO5_ADC2), + UPBOARD_UP2_PIN_NAME(0, GPIO6_ADC3), + UPBOARD_UP2_PIN_NAME(0, GPIO11), + UPBOARD_UP2_PIN_NAME(0, EXHAT_LVDS1n), + UPBOARD_UP2_PIN_NAME(0, EXHAT_LVDS1p), + UPBOARD_UP2_PIN_NAME(0, SPI2_TXD), + UPBOARD_UP2_PIN_NAME(0, SPI2_RXD), + UPBOARD_UP2_PIN_NAME(0, SPI2_FS1), + UPBOARD_UP2_PIN_NAME(0, SPI2_FS0), + UPBOARD_UP2_PIN_NAME(0, SPI2_CLK), + UPBOARD_UP2_PIN_NAME(0, SPI1_TXD), + UPBOARD_UP2_PIN_NAME(1, SPI1_RXD), + UPBOARD_UP2_PIN_NAME(1, SPI1_FS1), + UPBOARD_UP2_PIN_NAME(1, SPI1_FS0), + UPBOARD_UP2_PIN_NAME(1, SPI1_CLK), + UPBOARD_UP2_PIN_MUX(1, 4, &upboard_i2c0_reg), + UPBOARD_UP2_PIN_MUX(1, 5, &upboard_i2c0_reg), + UPBOARD_UP2_PIN_MUX(1, 6, &upboard_i2c1_reg), + UPBOARD_UP2_PIN_MUX(1, 7, &upboard_i2c1_reg), + UPBOARD_UP2_PIN_NAME(1, PWM1), + UPBOARD_UP2_PIN_NAME(1, PWM0), + UPBOARD_UP2_PIN_NAME(1, EXHAT_LVDS0n), + UPBOARD_UP2_PIN_NAME(1, EXHAT_LVDS0p), + UPBOARD_UP2_PIN_FUNC(1, I2C0_SCL, &upboard_i2c0_reg), + UPBOARD_UP2_PIN_FUNC(1, I2C0_SDA, &upboard_i2c0_reg), + UPBOARD_UP2_PIN_FUNC(1, I2C1_SCL, &upboard_i2c1_reg), + UPBOARD_UP2_PIN_FUNC(1, I2C1_SDA, &upboard_i2c1_reg), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS3n), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS3p), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS4n), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS4p), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS5n), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS5p), + UPBOARD_UP2_PIN_NAME(2, I2S_SDO), + UPBOARD_UP2_PIN_NAME(2, I2S_SDI), + UPBOARD_UP2_PIN_NAME(2, I2S_WS_SYNC), + UPBOARD_UP2_PIN_NAME(2, I2S_BCLK), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS6n), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS6p), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS7n), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS7p), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS2n), + UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS2p), +}; + +static const unsigned int upboard_up2_rpi_mapping[] = { + UPBOARD_UP2_BIT_TO_PIN(1, I2C0_SDA), + UPBOARD_UP2_BIT_TO_PIN(1, I2C0_SCL), + UPBOARD_UP2_BIT_TO_PIN(1, I2C1_SDA), + UPBOARD_UP2_BIT_TO_PIN(1, I2C1_SCL), + UPBOARD_UP2_BIT_TO_PIN(0, GPIO3_ADC0), + UPBOARD_UP2_BIT_TO_PIN(0, GPIO11), + UPBOARD_UP2_BIT_TO_PIN(0, SPI2_CLK), + UPBOARD_UP2_BIT_TO_PIN(1, SPI1_FS1), + UPBOARD_UP2_BIT_TO_PIN(1, SPI1_FS0), + UPBOARD_UP2_BIT_TO_PIN(1, SPI1_RXD), + UPBOARD_UP2_BIT_TO_PIN(0, SPI1_TXD), + UPBOARD_UP2_BIT_TO_PIN(1, SPI1_CLK), + UPBOARD_UP2_BIT_TO_PIN(1, PWM0), + UPBOARD_UP2_BIT_TO_PIN(1, PWM1), + UPBOARD_UP2_BIT_TO_PIN(0, UART1_TXD), + UPBOARD_UP2_BIT_TO_PIN(0, UART1_RXD), + UPBOARD_UP2_BIT_TO_PIN(0, UART1_CTS), + UPBOARD_UP2_BIT_TO_PIN(0, UART1_RTS), + UPBOARD_UP2_BIT_TO_PIN(2, I2S_BCLK), + UPBOARD_UP2_BIT_TO_PIN(2, I2S_WS_SYNC), + UPBOARD_UP2_BIT_TO_PIN(2, I2S_SDI), + UPBOARD_UP2_BIT_TO_PIN(2, I2S_SDO), + UPBOARD_UP2_BIT_TO_PIN(0, GPIO6_ADC3), + UPBOARD_UP2_BIT_TO_PIN(0, SPI2_FS1), + UPBOARD_UP2_BIT_TO_PIN(0, SPI2_RXD), + UPBOARD_UP2_BIT_TO_PIN(0, SPI2_TXD), + UPBOARD_UP2_BIT_TO_PIN(0, SPI2_FS0), + UPBOARD_UP2_BIT_TO_PIN(0, GPIO5_ADC2), +}; + +/* + * UP Core board + CREX carrier board data + */ + +#define UPBOARD_UPCORE_CREX_BIT_TO_PIN(r, id) \ + (UPBOARD_BIT_TO_PIN(r, UPFPGA_UPCORE_CREX_##id)) + +#define UPBOARD_UPCORE_CREX_PIN_ANON(r, bit) \ + { \ + .number = UPBOARD_BIT_TO_PIN(r, bit), \ + } + +#define UPBOARD_UPCORE_CREX_PIN_NAME(r, id) \ + { \ + .number = UPBOARD_UPCORE_CREX_BIT_TO_PIN(r, id), \ + .name = #id, \ + } + +#define UPBOARD_UPCORE_CREX_PIN_FUNC(r, id, data) \ + { \ + .number = UPBOARD_UPCORE_CREX_BIT_TO_PIN(r, id), \ + .name = #id, \ + .drv_data = (void *)(data), \ + } + +enum upboard_upcore_crex_reg1_fpgabit { + UPFPGA_UPCORE_CREX_I2C0_SDA, + UPFPGA_UPCORE_CREX_I2C0_SCL, + UPFPGA_UPCORE_CREX_I2C1_SDA, + UPFPGA_UPCORE_CREX_I2C1_SCL, + UPFPGA_UPCORE_CREX_SPI2_CS0, + UPFPGA_UPCORE_CREX_SPI2_CS1, + UPFPGA_UPCORE_CREX_SPI2_MOSI, + UPFPGA_UPCORE_CREX_SPI2_MISO, + UPFPGA_UPCORE_CREX_SPI2_CLK, + UPFPGA_UPCORE_CREX_UART1_TXD, + UPFPGA_UPCORE_CREX_UART1_RXD, + UPFPGA_UPCORE_CREX_PWM0, + UPFPGA_UPCORE_CREX_PWM1, + UPFPGA_UPCORE_CREX_I2S2_FRM, + UPFPGA_UPCORE_CREX_I2S2_CLK, + UPFPGA_UPCORE_CREX_I2S2_RX, +}; + +enum upboard_upcore_crex_reg2_fpgabit { + UPFPGA_UPCORE_CREX_I2S2_TX, + UPFPGA_UPCORE_CREX_GPIO0, + UPFPGA_UPCORE_CREX_GPIO2, + UPFPGA_UPCORE_CREX_GPIO3, + UPFPGA_UPCORE_CREX_GPIO4, + UPFPGA_UPCORE_CREX_GPIO9, +}; + +static struct pinctrl_pin_desc upboard_upcore_crex_pins[] = { + UPBOARD_UPCORE_CREX_PIN_FUNC(0, I2C0_SDA, &upboard_i2c0_reg), + UPBOARD_UPCORE_CREX_PIN_FUNC(0, I2C0_SCL, &upboard_i2c0_reg), + UPBOARD_UPCORE_CREX_PIN_FUNC(0, I2C1_SDA, &upboard_i2c1_reg), + UPBOARD_UPCORE_CREX_PIN_FUNC(0, I2C1_SCL, &upboard_i2c1_reg), + UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_CS0), + UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_CS1), + UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_MOSI), + UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_MISO), + UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_CLK), + UPBOARD_UPCORE_CREX_PIN_NAME(0, UART1_TXD), + UPBOARD_UPCORE_CREX_PIN_NAME(0, UART1_RXD), + UPBOARD_UPCORE_CREX_PIN_NAME(0, PWM0), + UPBOARD_UPCORE_CREX_PIN_NAME(0, PWM1), + UPBOARD_UPCORE_CREX_PIN_NAME(0, I2S2_FRM), + UPBOARD_UPCORE_CREX_PIN_NAME(0, I2S2_CLK), + UPBOARD_UPCORE_CREX_PIN_NAME(0, I2S2_RX), + /* register 1 */ + UPBOARD_UPCORE_CREX_PIN_NAME(1, I2S2_TX), + UPBOARD_UPCORE_CREX_PIN_NAME(1, GPIO0), + UPBOARD_UPCORE_CREX_PIN_FUNC(1, GPIO2, &upboard_adc0_reg), + UPBOARD_UPCORE_CREX_PIN_NAME(1, GPIO3), + UPBOARD_UPCORE_CREX_PIN_NAME(1, GPIO4), + UPBOARD_UPCORE_CREX_PIN_NAME(1, GPIO9), +}; + +static unsigned int upboard_upcore_crex_rpi_mapping[] = { + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2C0_SDA), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2C0_SCL), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2C1_SDA), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2C1_SCL), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO0), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO2), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO3), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_CS1), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_CS0), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_MISO), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_MOSI), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_CLK), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, PWM0), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, PWM1), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, UART1_TXD), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, UART1_RXD), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO9), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO4), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2S2_CLK), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2S2_FRM), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2S2_RX), + UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, I2S2_TX), +}; + +/* + * UP Core board + CRST02 carrier board data + */ + +#define upboard_upcore_crst02_pins upboard_upcore_crex_pins +#define upboard_upcore_crst02_rpi_mapping upboard_upcore_crex_rpi_mapping + +static int upboard_set_mux(struct pinctrl_dev *pctldev, unsigned int function, + unsigned int group) +{ + return 0; +} + +static int upboard_fpga_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + const struct pin_desc * const pd = pin_desc_get(pctldev, pin); + const struct upboard_pin *p; + int ret; + + p = pd->drv_data; + if (p->funcbit) { + ret = regmap_field_write(p->funcbit, 0); + if (ret) + return ret; + } + + if (p->enbit) { + ret = regmap_field_write(p->enbit, 1); + if (ret) + return ret; + } + + return 0; +} + +static int upboard_fpga_request_free(struct pinctrl_dev *pctldev, + unsigned int pin) +{ + const struct pin_desc * const pd = pin_desc_get(pctldev, pin); + const struct upboard_pin *p; + int ret; + + p = pd->drv_data; + if (p->funcbit) { + ret = regmap_field_write(p->funcbit, 1); + if (ret) + return ret; + } + + if (p->enbit) { + ret = regmap_field_write(p->enbit, 0); + if (ret) + return ret; + } + + return 0; +} + +static int upboard_fpga_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin, bool input) +{ + const struct pin_desc * const pd = pin_desc_get(pctldev, pin); + const struct upboard_pin *p; + + p = pd->drv_data; + + return regmap_field_write(p->dirbit, input); +} + +static int upboard_get_functions_count(struct pinctrl_dev *pctldev) +{ + return 0; +} + +static const char *upboard_get_function_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + return NULL; +} + +static int upboard_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int selector, + const char * const **groups, + unsigned int *num_groups) +{ + *groups = NULL; + *num_groups = 0; + return 0; +} + +static const struct pinmux_ops upboard_pinmux_ops = { + .get_functions_count = upboard_get_functions_count, + .get_function_groups = upboard_get_function_groups, + .get_function_name = upboard_get_function_name, + .set_mux = upboard_set_mux, + .gpio_request_enable = upboard_fpga_request_enable, + .gpio_set_direction = upboard_fpga_set_direction, +}; + +static int upboard_get_groups_count(struct pinctrl_dev *pctldev) +{ + return 0; +} + +static const char *upboard_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + return NULL; +} + +static void upboard_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned int pin) +{ + struct upboard_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + void __iomem *padcfg; + u32 cfg0, cfg1, mode; + + if (pctrl->pins[pin].regs == NULL) + return; + + cfg0 = readl(pctrl->pins[pin].regs); + cfg1 = readl(pctrl->pins[pin].regs + PADCFG1); + + mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; + if (mode == PADCFG0_PMODE_GPIO) + seq_puts(s, "GPIO "); + else + seq_printf(s, "mode %d ", mode); + + seq_printf(s, "0x%08x 0x%08x", cfg0, cfg1); + + /* Dump the additional PADCFG registers if available */ + padcfg = pctrl->pins[pin].regs + PADCFG2; + if (padcfg) + seq_printf(s, " 0x%08x", readl(padcfg)); + + seq_printf(s, " 0x%p", pctrl->pins[pin].regs); +} + +static const struct pinctrl_ops upboard_pinctrl_ops = { + .get_groups_count = upboard_get_groups_count, + .get_group_name = upboard_get_group_name, + .pin_dbg_show = upboard_pin_dbg_show, +}; + +static struct pinctrl_desc upboard_up_pinctrl_desc = { + .pins = upboard_up_pins, + .npins = ARRAY_SIZE(upboard_up_pins), + .pctlops = &upboard_pinctrl_ops, + .pmxops = &upboard_pinmux_ops, + .owner = THIS_MODULE, +}; + +static struct pinctrl_desc upboard_up2_pinctrl_desc = { + .pins = upboard_up2_pins, + .npins = ARRAY_SIZE(upboard_up2_pins), + .pctlops = &upboard_pinctrl_ops, + .pmxops = &upboard_pinmux_ops, + .owner = THIS_MODULE, +}; + +static struct pinctrl_desc upboard_upcore_crex_pinctrl_desc = { + .pins = upboard_upcore_crex_pins, + .npins = ARRAY_SIZE(upboard_upcore_crex_pins), + .pctlops = &upboard_pinctrl_ops, + .pmxops = &upboard_pinmux_ops, + .owner = THIS_MODULE, +}; + +static struct pinctrl_desc upboard_upcore_crst02_pinctrl_desc = { + .pins = upboard_upcore_crst02_pins, + .npins = ARRAY_SIZE(upboard_upcore_crst02_pins), + .pctlops = &upboard_pinctrl_ops, + .pmxops = &upboard_pinmux_ops, + .owner = THIS_MODULE, +}; + +static void upboard_alt_func_enable(struct gpio_chip *gc, const char *name, int id) +{ + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); + int offset[pctrl->pctldesc->npins]; + int i, cnt; + bool input; + int mode; + unsigned int val; + + /* find all pins */ + for (i = 0, cnt = 0; i < pctrl->pctldesc->npins; i++) { + if (strstr(pctrl->pctldesc->pins[i].name, name)) + offset[cnt++] = i; + } + + /* change to alternate function */ + for (i = 0; i < cnt; i++) { + if (pctrl->pins[offset[i]].regs == NULL) + continue; + input = false; + mode = 0; /* default GPIO */ + val = readl(pctrl->pins[offset[i]].regs); + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2C") || + strstr(pctrl->pctldesc->pins[offset[i]].name, "PINMUX")) { + mode = 1; + switch (id) { + case BOARD_UPN_ADLN01: + case BOARD_UPX_ADLP01: + mode = 2; + break; + default: + break; + } + + val |= mode<<PADCFG0_PMODE_SHIFT; + writel(val, pctrl->pins[offset[i]].regs); + upboard_fpga_request_free(pctrl->pctldev, offset[i]); + continue; + } + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "UART")) { + mode = 1; + switch (id) { + case BOARD_UPN_EHL01: + mode = 4; + break; + case BOARD_UP_ADLN01: + case BOARD_UPN_ADLN01: + case BOARD_UPX_ADLP01: + mode = 2; + break; + default: + break; + } + } + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SPI")) { + mode = 1; + switch (id) { + case BOARD_UP_WHL01: + mode = 3; + break; + case BOARD_UP_ADLN01: + case BOARD_UPN_ADLN01: + case BOARD_UPX_ADLP01: + mode = 7; + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MOSI")) { + val &= ~PADCFG0_GPIOTXDIS; + val |= PADCFG0_GPIORXDIS; + } + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO")) + val |= PADCFG0_GPIORXDIS; + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CLK")) { + val &= ~PADCFG0_GPIOTXDIS; + val |= PADCFG0_GPIORXDIS; + } + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS0")) + val |= PADCFG0_GPIORXDIS; + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS1")) + continue; + break; + default: + break; + } + } + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2S")) { + mode = 1; + switch (id) { + case BOARD_UPX_ADLP01: + mode = 4; + break; + default: + break; + } + } + + val |= mode<<PADCFG0_PMODE_SHIFT; + writel(val, pctrl->pins[offset[i]].regs); + + /* input pins */ + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "RX")) + input = true; + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CTS")) + input = true; + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "ADC")) { + input = true; + if (id == BOARD_UP_APL01) + upboard_fpga_request_enable(pctrl->pctldev, NULL, offset[i]); + else + upboard_fpga_request_free(pctrl->pctldev, offset[i]); + } + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO")) + input = true; + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "DIN")) + input = true; + + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SDI")) + input = true; + + upboard_fpga_set_direction(pctrl->pctldev, NULL, offset[i], input); + } +} + +static int upboard_rpi_to_native_gpio(struct gpio_chip *gc, unsigned int gpio) +{ + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); + unsigned int pin = pctrl->rpi_mapping[gpio]; + struct pinctrl_gpio_range *range; + + range = pinctrl_find_gpio_range_from_pin(pctrl->pctldev, pin); + if (!range) + return -ENODEV; + + return range->base; +} + +static int upboard_gpio_request(struct gpio_chip *gc, unsigned int offset) +{ + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); + unsigned int pin = pctrl->rpi_mapping[offset]; + int gpio = upboard_rpi_to_native_gpio(gc, offset); + + upboard_fpga_request_enable(pctrl->pctldev, NULL, pin); + return pinctrl_gpio_request(gpio); +} + +static void upboard_gpio_free(struct gpio_chip *gc, unsigned int offset) +{ + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); + int gpio = upboard_rpi_to_native_gpio(gc, offset); + unsigned int pin = pctrl->rpi_mapping[offset]; + + pinctrl_gpio_free(gpio); + + upboard_alt_func_enable(gc, pctrl->pctldesc->pins[pin].name, pctrl->ident); +} + +static int upboard_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); + unsigned int pin = pctrl->rpi_mapping[offset]; + unsigned int padcfg0; + + if (!pctrl->pins[pin].regs) + return -EINVAL; + + padcfg0 = readl(pctrl->pins[pin].regs); + if (padcfg0 & PADCFG0_GPIOTXDIS) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; +} + +static int upboard_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); + unsigned int pin = pctrl->rpi_mapping[offset]; + int gpio = upboard_rpi_to_native_gpio(gc, offset); + int reg_val = readl(pctrl->pins[pin].regs); + + if (gpio < 0) + return gpio; + + /* APL03 board open drain GPIO */ + if (pctrl->ident == BOARD_UP_APL03) { + switch (pin) { + case 0: + case 1: + case 9: + case 23: + return reg_val & 0x00000003; + default: + break; + } + } + + if (!(reg_val & PADCFG0_GPIOTXDIS)) + return !!(reg_val & PADCFG0_GPIOTXSTATE); + + return !!(reg_val & PADCFG0_GPIORXSTATE); +} + +static void upboard_gpio_set(struct gpio_chip *gc, unsigned int offset, + int value) +{ + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); + unsigned int pin = pctrl->rpi_mapping[offset]; + int gpio = upboard_rpi_to_native_gpio(gc, offset); + int reg_val = readl(pctrl->pins[pin].regs); + + if (gpio < 0) + return; + + /* APL03 board open drain GPIO */ + if (pctrl->ident == BOARD_UP_APL03) { + switch (pin) { + case 0: + case 1: + case 9: + case 23: + if (value) + reg_val |= PADCFG0_GPIOTXDIS; + else + reg_val &= ~PADCFG0_GPIOTXDIS; + + writel(reg_val, pctrl->pins[pin].regs); + return; + default: + break; + } + } + if (value) + reg_val |= PADCFG0_GPIOTXSTATE; + else + reg_val &= ~PADCFG0_GPIOTXSTATE; + writel(reg_val, pctrl->pins[pin].regs); +} + +static int upboard_gpio_direction_input(struct gpio_chip *gc, + unsigned int offset) +{ + int gpio = upboard_rpi_to_native_gpio(gc, offset); + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); + unsigned int pin = pctrl->rpi_mapping[offset]; + + upboard_fpga_set_direction(pctrl->pctldev, NULL, pin, true); + + return pinctrl_gpio_direction_input(gpio); +} + +static int upboard_gpio_direction_output(struct gpio_chip *gc, + unsigned int offset, int value) +{ + int gpio = upboard_rpi_to_native_gpio(gc, offset); + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip); + unsigned int pin = pctrl->rpi_mapping[offset]; + + upboard_fpga_set_direction(pctrl->pctldev, NULL, pin, false); + + return pinctrl_gpio_direction_output(gpio); +} + +static void __iomem *upboard_get_regs(struct gpio_chip *gc, unsigned int gpio, unsigned int reg) +{ + struct platform_device *pdev = to_platform_device(gc->parent); + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct intel_pinctrl *pctrl = gpiochip_get_data(gc); + size_t nregs; + void __iomem *base = NULL; + u32 offset, value; + int pin = gpio-gc->base; + + /* check Intel pin controller for all platform */ + if (pctrl->ncommunities > 1) { + int i, j, offset = 0; + + pin = -1; + for (i = 0; i < pctrl->ncommunities; i++) { + struct intel_community *community = &pctrl->communities[i]; + + for (j = 0; j < community->ngpps ; j++) { + struct intel_padgroup gpps = community->gpps[j]; + + if (gpio < gc->base + gpps.gpio_base + gpps.size) { + res = platform_get_resource(pdev, IORESOURCE_MEM, + community->barno); + pin = gpio-gc->base-gpps.gpio_base + + offset-community->pin_base; + break; + } + + offset += gpps.size; + } + + if (pin != -1) + break; + } + } + + base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (base == NULL) + return base; + + offset = readl(base + PADBAR); + value = readl(base + REVID); + + if (((value & REVID_MASK) >> REVID_SHIFT) >= 0x94) + nregs = 4; + else + nregs = 2; + + return base + offset + reg + pin * nregs * 4; +} + +static int upboard_acpi_node_pin_mapping(struct upboard_fpga *fpga, + struct upboard_pinctrl *pctrl, + const char *propname, + const char *pinctl_name, + unsigned int pin_offset) +{ + struct gpio_descs *descs; + int ret, i; + + descs = devm_gpiod_get_array(fpga->dev, propname, GPIOD_ASIS); + if (IS_ERR(descs)) { + ret = PTR_ERR(descs); + if (ret != -EPROBE_DEFER) + dev_err(fpga->dev, "Failed to get %s GPIOs", propname); + + return ret; + } + + for (i = 0; i < descs->ndescs; i++) { + struct gpio_desc *desc = descs->desc[i]; + struct gpio_chip *gc = gpiod_to_chip(desc); + + pctrl->pins[i].gpio = desc_to_gpio(desc); + pctrl->pins[i].base = gc->base; + pctrl->pins[i].irq = gpiod_to_irq(desc); + pctrl->pins[i].regs = + upboard_get_regs(gc, + desc_to_gpio(desc) - gc->base, + PADCFG0); + + /* The GPIOs may not be contiguous, so add them 1-by-1 */ + ret = gpiochip_add_pin_range(gpiod_to_chip(desc), pinctl_name, + desc_to_gpio(desc) - gc->base, + pin_offset + i, 1); + if (ret) + return ret; + } + + /* dispose acpi resource */ + devm_gpiod_put_array(fpga->dev, descs); + + return ret; +} + +static struct gpio_chip upboard_gpio_chip = { + .label = "Raspberry Pi compatible UP GPIO", + .base = 0, + .request = upboard_gpio_request, + .free = upboard_gpio_free, + .get = upboard_gpio_get, + .set = upboard_gpio_set, + .get_direction = upboard_gpio_get_direction, + .direction_input = upboard_gpio_direction_input, + .direction_output = upboard_gpio_direction_output, + .owner = THIS_MODULE, +}; + +/* DMI Matches to assign pin mapping driver data */ +static const struct dmi_system_id upboard_dmi_table[] __initconst = { + { + .ident = BOARD_UP_APL01, + .matches = { /* UP SQUARED */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-APL01"), + }, + }, + { + .ident = BOARD_UP_APL01, + .matches = { /* UP SQUARED Pro*/ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPN-APL01"), + }, + }, + { + .ident = BOARD_UP_APL03, + .matches = { /* UP 4000 */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-APL03"), + }, + }, + { + .ident = BOARD_UP_WHL01, + .matches = { /* UPX WHL */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-WHL01"), + }, + }, + { + .ident = BOARD_UPX_TGL, + .matches = { /* UP i11 */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPX-TGL01"), + }, + }, + { + .ident = BOARD_UPN_EHL01, + .matches = { /* UP 6000 */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPN-EHL01"), + }, + }, + { + .ident = BOARD_UPS_EHL01, + .matches = { /* UP squared v2 */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPS-EHL01"), + }, + }, + { + .ident = BOARD_UPX_ADLP01, + .matches = { /* UP Xtreme i12 */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPX-ADLP01"), + }, + }, + { + .ident = BOARD_UPN_ADLN01, + .matches = { /* UP 7000 */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPN-ADLN01"), + }, + }, + { + .ident = BOARD_UPS_ADLP01, + .matches = { /* UP Squared i12 */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPS-ADLP01"), + }, + }, + { + .ident = BOARD_UP_ADLN01, + .matches = { /* UP 7000 */ + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-ADLN01"), + }, + }, + { } /* Terminating entry */ +}; + +static int upboard_pinctrl_probe(struct platform_device *pdev) +{ + struct upboard_fpga * const fpga = dev_get_drvdata(pdev->dev.parent); + struct pinctrl_desc *pctldesc; + struct upboard_pinctrl *pctrl; + struct upboard_pin *pins; + const struct dmi_system_id *system_id; + const unsigned int *rpi_mapping; + unsigned int ngpio; + int ret; + int i; + /* default */ + int board_id = BOARD_UP_APL03; + + /* check board id to arrange driver data */ + system_id = dmi_first_match(upboard_dmi_table); + if (system_id) + board_id = system_id->ident; + dev_info(&pdev->dev, "Compatible Up Board ID %d", board_id); + switch (board_id) { + case BOARD_UP_APL01: + pctldesc = &upboard_up2_pinctrl_desc; + rpi_mapping = upboard_up2_rpi_mapping; + ngpio = ARRAY_SIZE(upboard_up2_rpi_mapping); + break; + case BOARD_UP_UPCORE: + pctldesc = &upboard_upcore_crex_pinctrl_desc; + rpi_mapping = upboard_upcore_crex_rpi_mapping; + ngpio = ARRAY_SIZE(upboard_upcore_crex_rpi_mapping); + break; + case BOARD_UP_CORE_PLUS: + pctldesc = &upboard_upcore_crst02_pinctrl_desc; + rpi_mapping = upboard_upcore_crst02_rpi_mapping; + ngpio = ARRAY_SIZE(upboard_upcore_crst02_rpi_mapping); + break; + default: + pctldesc = &upboard_up_pinctrl_desc; + rpi_mapping = upboard_up_rpi_mapping; + ngpio = ARRAY_SIZE(upboard_up_rpi_mapping); + break; + } + + pctldesc->name = dev_name(&pdev->dev); + + pins = devm_kcalloc(&pdev->dev, pctldesc->npins, sizeof(*pins), GFP_KERNEL); + if (!pins) + return -ENOMEM; + + /* initialise pins */ + for (i = 0; i < pctldesc->npins; i++) { + struct upboard_pin *pin = &pins[i]; + struct pinctrl_pin_desc *pd = (struct pinctrl_pin_desc *) &pctldesc->pins[i]; + struct reg_field fldconf = {0}; + unsigned int regoff = (pd->number / UPFPGA_REGISTER_SIZE); + unsigned int lsb = pd->number % UPFPGA_REGISTER_SIZE; + + pin->funcbit = NULL; + + if (pd->drv_data) { + fldconf = *(struct reg_field *)pd->drv_data; + + pin->funcbit = devm_regmap_field_alloc(&pdev->dev, + fpga->regmap, + fldconf); + if (IS_ERR(pin->funcbit)) + return PTR_ERR(pin->funcbit); + } + + fldconf.reg = UPFPGA_REG_GPIO_EN0 + regoff; + fldconf.lsb = lsb; + fldconf.msb = lsb; + + pin->enbit = devm_regmap_field_alloc(&pdev->dev, + fpga->regmap, + fldconf); + if (IS_ERR(pin->enbit)) + return PTR_ERR(pin->enbit); + + fldconf.reg = UPFPGA_REG_GPIO_DIR0 + regoff; + fldconf.lsb = lsb; + fldconf.msb = lsb; + + pin->dirbit = devm_regmap_field_alloc(&pdev->dev, + fpga->regmap, + fldconf); + if (IS_ERR(pin->dirbit)) + return PTR_ERR(pin->dirbit); + + pd->drv_data = pin; + } + + /* create a new pinctrl device and register it */ + pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + pctrl->rpi_mapping = rpi_mapping; + pctrl->chip = upboard_gpio_chip; + pctrl->pctldesc = pctldesc; + pctrl->chip.parent = &pdev->dev; + pctrl->chip.ngpio = ngpio; + pctrl->pins = pins; + pctrl->ident = board_id; + + ret = devm_gpiochip_add_data(&pdev->dev, &pctrl->chip, pctrl); + if (ret) + return ret; + + pctrl->pctldev = devm_pinctrl_register(&pdev->dev, pctldesc, pctrl); + if (IS_ERR(pctrl->pctldev)) + return PTR_ERR(pctrl->pctldev); + + /* add acpi pin mapping according to external-gpios key */ + ret = upboard_acpi_node_pin_mapping(fpga, pctrl, + "external", + dev_name(&pdev->dev), + 0); + if (ret) + return ret; + + upboard_alt_func_enable(&pctrl->chip, "I2C", pctrl->ident); + upboard_alt_func_enable(&pctrl->chip, "SPI", pctrl->ident); + upboard_alt_func_enable(&pctrl->chip, "UART", pctrl->ident); + upboard_alt_func_enable(&pctrl->chip, "I2S", pctrl->ident); + upboard_alt_func_enable(&pctrl->chip, "PWM", pctrl->ident); + upboard_alt_func_enable(&pctrl->chip, "ADC", pctrl->ident); + upboard_alt_func_enable(&pctrl->chip, "PINMUX", pctrl->ident); + + return ret; +} + +static struct platform_driver upboard_pinctrl_driver = { + .driver = { + .name = "upboard-pinctrl", + }, +}; +module_platform_driver_probe(upboard_pinctrl_driver, upboard_pinctrl_probe); + +MODULE_AUTHOR("Gary Wang <garywang@aaeon.com.tw>"); +MODULE_DESCRIPTION("UP Board HAT pin controller driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:upboard-pinctrl");