gpio_common.go
1 /* code to generate common GPIO code for Intel 6/7/8 Series Chipset */ 2 3 package main 4 5 import ( 6 "fmt" 7 "os" 8 ) 9 10 func writeGPIOSet(ctx Context, sb *os.File, 11 val uint32, set uint, partno int, constraint uint32) { 12 13 max := uint(32) 14 if set == 3 { 15 max = 12 16 } 17 18 bits := [6][2]string{ 19 {"GPIO_MODE_NATIVE", "GPIO_MODE_GPIO"}, 20 {"GPIO_DIR_OUTPUT", "GPIO_DIR_INPUT"}, 21 {"GPIO_LEVEL_LOW", "GPIO_LEVEL_HIGH"}, 22 {"GPIO_RESET_PWROK", "GPIO_RESET_RSMRST"}, 23 {"GPIO_NO_INVERT", "GPIO_INVERT"}, 24 {"GPIO_NO_BLINK", "GPIO_BLINK"}, 25 } 26 27 for i := uint(0); i < max; i++ { 28 if (constraint>>i)&1 == 1 { 29 fmt.Fprintf(sb, " .gpio%d = %s,\n", 30 (set-1)*32+i, 31 bits[partno][(val>>i)&1]) 32 } 33 } 34 } 35 36 func GPIO(ctx Context, inteltool InteltoolData) { 37 var constraint uint32 38 gpio := Create(ctx, "gpio.c") 39 defer gpio.Close() 40 41 AddBootBlockFile("gpio.c", "") 42 AddROMStageFile("gpio.c", "") 43 44 Add_SPDX(gpio, C, GPL2_only) 45 gpio.WriteString("#include <southbridge/intel/common/gpio.h>\n\n") 46 47 addresses := [3][6]int{ 48 {0x00, 0x04, 0x0c, 0x60, 0x2c, 0x18}, 49 {0x30, 0x34, 0x38, 0x64, -1, -1}, 50 {0x40, 0x44, 0x48, 0x68, -1, -1}, 51 } 52 53 for set := 1; set <= 3; set++ { 54 for partno, part := range []string{"mode", "direction", "level", "reset", "invert", "blink"} { 55 addr := addresses[set-1][partno] 56 if addr < 0 { 57 continue 58 } 59 fmt.Fprintf(gpio, "static const struct pch_gpio_set%d pch_gpio_set%d_%s = {\n", 60 set, set, part) 61 62 constraint = 0xffffffff 63 switch part { 64 case "direction": 65 /* Ignored on native mode */ 66 constraint = inteltool.GPIO[uint16(addresses[set-1][0])] 67 case "level": 68 /* Level doesn't matter for input */ 69 constraint = inteltool.GPIO[uint16(addresses[set-1][0])] 70 constraint &^= inteltool.GPIO[uint16(addresses[set-1][1])] 71 case "reset": 72 /* Only show reset */ 73 constraint = inteltool.GPIO[uint16(addresses[set-1][3])] 74 case "invert": 75 /* Only on input and only show inverted GPIO */ 76 constraint = inteltool.GPIO[uint16(addresses[set-1][0])] 77 constraint &= inteltool.GPIO[uint16(addresses[set-1][1])] 78 constraint &= inteltool.GPIO[uint16(addresses[set-1][4])] 79 case "blink": 80 /* Only on output and only show blinking GPIO */ 81 constraint = inteltool.GPIO[uint16(addresses[set-1][0])] 82 constraint &^= inteltool.GPIO[uint16(addresses[set-1][1])] 83 constraint &= inteltool.GPIO[uint16(addresses[set-1][5])] 84 } 85 writeGPIOSet(ctx, gpio, inteltool.GPIO[uint16(addr)], uint(set), partno, constraint) 86 gpio.WriteString("};\n\n") 87 } 88 } 89 90 gpio.WriteString(`const struct pch_gpio_map mainboard_gpio_map = { 91 .set1 = { 92 .mode = &pch_gpio_set1_mode, 93 .direction = &pch_gpio_set1_direction, 94 .level = &pch_gpio_set1_level, 95 .blink = &pch_gpio_set1_blink, 96 .invert = &pch_gpio_set1_invert, 97 .reset = &pch_gpio_set1_reset, 98 }, 99 .set2 = { 100 .mode = &pch_gpio_set2_mode, 101 .direction = &pch_gpio_set2_direction, 102 .level = &pch_gpio_set2_level, 103 .reset = &pch_gpio_set2_reset, 104 }, 105 .set3 = { 106 .mode = &pch_gpio_set3_mode, 107 .direction = &pch_gpio_set3_direction, 108 .level = &pch_gpio_set3_level, 109 .reset = &pch_gpio_set3_reset, 110 }, 111 }; 112 `) 113 }