Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: qcom: spmi-mpp: Transpose pinmux function

The "function" of the MPP driver was inherited from the GPIO driver, but the
differences between the two hardware blocks makes both the driver and the
device tree binding to be awkward.

Instead of overloading the "normal" function with various modes this patch
transposes the pinmux function to represent the three operating modes of the
MPP (digital, analog and current sink). The properties of pin pairing and DTEST
routing is moved to separate properties.

Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Bjorn Andersson and committed by
Linus Walleij
eb5c144c 099f3e4a

+98 -86
+12 -17
Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.txt
··· 77 77 Value type: <string> 78 78 Definition: Specify the alternative function to be configured for the 79 79 specified pins. Valid values are: 80 - "normal", 81 - "paired", 82 - "dtest1", 83 - "dtest2", 84 - "dtest3", 85 - "dtest4" 80 + "digital", 81 + "analog", 82 + "sink" 86 83 87 84 - bias-disable: 88 85 Usage: optional ··· 131 134 defined in <dt-binding/pinctrl/qcom,pmic-mpp.h> 132 135 PMIC_MPP_AOUT_LVL_* 133 136 134 - - qcom,analog-mode: 137 + - qcom,dtest: 135 138 Usage: optional 136 - Value type: <none> 137 - Definition: Selects Analog mode of operation: combined with input-enable 138 - and/or output-high, output-low MPP could operate as 139 - Bidirectional Logic, Analog Input, Analog Output. 140 - 141 - - qcom,sink-mode: 142 - Usage: optional 143 - Value type: <u32> or <none> 144 - Definition: Selects sink mode of operation 139 + Value type: <u32> 140 + Definition: Selects which dtest rail to be routed in the various functions. 141 + Valid values are 1-4 145 142 146 143 - qcom,amux-route: 147 144 Usage: optional ··· 143 152 Definition: Selects the source for analog input. Valid values are 144 153 defined in <dt-bindings/pinctrl/qcom,pmic-mpp.h> 145 154 PMIC_MPP_AMUX_ROUTE_CH5, PMIC_MPP_AMUX_ROUTE_CH6... 155 + - qcom,paired: 156 + Usage: optional 157 + Value type: <none> 158 + Definition: Indicates that the pin should be operating in paired mode. 146 159 147 160 Example: 148 161 ··· 163 168 pm8841_default: default { 164 169 gpio { 165 170 pins = "mpp1", "mpp2", "mpp3", "mpp4"; 166 - function = "normal"; 171 + function = "digital"; 167 172 input-enable; 168 173 power-source = <PM8841_MPP_S3>; 169 174 };
+86 -69
drivers/pinctrl/qcom/pinctrl-spmi-mpp.c
··· 95 95 #define PMIC_MPP_MODE_ANALOG_OUTPUT 5 96 96 #define PMIC_MPP_MODE_CURRENT_SINK 6 97 97 98 + #define PMIC_MPP_SELECTOR_NORMAL 0 99 + #define PMIC_MPP_SELECTOR_PAIRED 1 100 + #define PMIC_MPP_SELECTOR_DTEST_FIRST 4 101 + 98 102 #define PMIC_MPP_PHYSICAL_OFFSET 1 99 103 100 104 /* Qualcomm specific pin configurations */ 101 105 #define PMIC_MPP_CONF_AMUX_ROUTE (PIN_CONFIG_END + 1) 102 - #define PMIC_MPP_CONF_ANALOG_MODE (PIN_CONFIG_END + 2) 103 - #define PMIC_MPP_CONF_SINK_MODE (PIN_CONFIG_END + 3) 104 - #define PMIC_MPP_CONF_ANALOG_LEVEL (PIN_CONFIG_END + 4) 106 + #define PMIC_MPP_CONF_ANALOG_LEVEL (PIN_CONFIG_END + 2) 107 + #define PMIC_MPP_CONF_DTEST_SELECTOR (PIN_CONFIG_END + 3) 108 + #define PMIC_MPP_CONF_PAIRED (PIN_CONFIG_END + 4) 105 109 106 110 /** 107 111 * struct pmic_mpp_pad - keep current MPP settings ··· 115 111 * @out_value: Cached pin output value. 116 112 * @output_enabled: Set to true if MPP output logic is enabled. 117 113 * @input_enabled: Set to true if MPP input buffer logic is enabled. 118 - * @analog_mode: Set to true when MPP should operate in Analog Input, Analog 119 - * Output or Bidirectional Analog mode. 120 - * @sink_mode: Boolean indicating if ink mode is slected 114 + * @paired: Pin operates in paired mode 121 115 * @num_sources: Number of power-sources supported by this MPP. 122 116 * @power_source: Current power-source used. 123 117 * @amux_input: Set the source for analog input. ··· 123 121 * @pullup: Pullup resistor value. Valid in Bidirectional mode only. 124 122 * @function: See pmic_mpp_functions[]. 125 123 * @drive_strength: Amount of current in sink mode 124 + * @dtest: DTEST route selector 126 125 */ 127 126 struct pmic_mpp_pad { 128 127 u16 base; ··· 132 129 bool out_value; 133 130 bool output_enabled; 134 131 bool input_enabled; 135 - bool analog_mode; 136 - bool sink_mode; 132 + bool paired; 137 133 unsigned int num_sources; 138 134 unsigned int power_source; 139 135 unsigned int amux_input; ··· 140 138 unsigned int pullup; 141 139 unsigned int function; 142 140 unsigned int drive_strength; 141 + unsigned int dtest; 143 142 }; 144 143 145 144 struct pmic_mpp_state { ··· 153 150 static const struct pinconf_generic_params pmic_mpp_bindings[] = { 154 151 {"qcom,amux-route", PMIC_MPP_CONF_AMUX_ROUTE, 0}, 155 152 {"qcom,analog-level", PMIC_MPP_CONF_ANALOG_LEVEL, 0}, 156 - {"qcom,analog-mode", PMIC_MPP_CONF_ANALOG_MODE, 0}, 157 - {"qcom,sink-mode", PMIC_MPP_CONF_SINK_MODE, 0}, 153 + {"qcom,dtest", PMIC_MPP_CONF_DTEST_SELECTOR, 0}, 154 + {"qcom,paired", PMIC_MPP_CONF_PAIRED, 0}, 158 155 }; 159 156 160 157 #ifdef CONFIG_DEBUG_FS 161 158 static const struct pin_config_item pmic_conf_items[] = { 162 159 PCONFDUMP(PMIC_MPP_CONF_AMUX_ROUTE, "analog mux", NULL, true), 163 160 PCONFDUMP(PMIC_MPP_CONF_ANALOG_LEVEL, "analog level", NULL, true), 164 - PCONFDUMP(PMIC_MPP_CONF_ANALOG_MODE, "analog output", NULL, false), 165 - PCONFDUMP(PMIC_MPP_CONF_SINK_MODE, "sink mode", NULL, false), 161 + PCONFDUMP(PMIC_MPP_CONF_DTEST_SELECTOR, "dtest", NULL, true), 162 + PCONFDUMP(PMIC_MPP_CONF_PAIRED, "paired", NULL, false), 166 163 }; 167 164 #endif 168 165 ··· 170 167 "mpp1", "mpp2", "mpp3", "mpp4", "mpp5", "mpp6", "mpp7", "mpp8", 171 168 }; 172 169 170 + #define PMIC_MPP_DIGITAL 0 171 + #define PMIC_MPP_ANALOG 1 172 + #define PMIC_MPP_SINK 2 173 + 173 174 static const char *const pmic_mpp_functions[] = { 174 - PMIC_MPP_FUNC_NORMAL, PMIC_MPP_FUNC_PAIRED, 175 - "reserved1", "reserved2", 176 - PMIC_MPP_FUNC_DTEST1, PMIC_MPP_FUNC_DTEST2, 177 - PMIC_MPP_FUNC_DTEST3, PMIC_MPP_FUNC_DTEST4, 175 + "digital", "analog", "sink" 178 176 }; 179 177 180 178 static inline struct pmic_mpp_state *to_mpp_state(struct gpio_chip *chip) ··· 264 260 static int pmic_mpp_write_mode_ctl(struct pmic_mpp_state *state, 265 261 struct pmic_mpp_pad *pad) 266 262 { 263 + unsigned int mode; 264 + unsigned int sel; 267 265 unsigned int val; 266 + unsigned int en; 268 267 269 - if (pad->analog_mode) { 270 - val = PMIC_MPP_MODE_ANALOG_INPUT; 271 - if (pad->output_enabled) { 272 - if (pad->input_enabled) 273 - val = PMIC_MPP_MODE_ANALOG_BIDIR; 274 - else 275 - val = PMIC_MPP_MODE_ANALOG_OUTPUT; 276 - } 277 - } else if (pad->sink_mode) { 278 - val = PMIC_MPP_MODE_CURRENT_SINK; 279 - } else { 280 - val = PMIC_MPP_MODE_DIGITAL_INPUT; 281 - if (pad->output_enabled) { 282 - if (pad->input_enabled) 283 - val = PMIC_MPP_MODE_DIGITAL_BIDIR; 284 - else 285 - val = PMIC_MPP_MODE_DIGITAL_OUTPUT; 286 - } 268 + switch (pad->function) { 269 + case PMIC_MPP_ANALOG: 270 + if (pad->input_enabled && pad->output_enabled) 271 + mode = PMIC_MPP_MODE_ANALOG_BIDIR; 272 + else if (pad->input_enabled) 273 + mode = PMIC_MPP_MODE_ANALOG_INPUT; 274 + else 275 + mode = PMIC_MPP_MODE_ANALOG_OUTPUT; 276 + break; 277 + case PMIC_MPP_DIGITAL: 278 + if (pad->input_enabled && pad->output_enabled) 279 + mode = PMIC_MPP_MODE_DIGITAL_BIDIR; 280 + else if (pad->input_enabled) 281 + mode = PMIC_MPP_MODE_DIGITAL_INPUT; 282 + else 283 + mode = PMIC_MPP_MODE_DIGITAL_OUTPUT; 284 + break; 285 + case PMIC_MPP_SINK: 286 + default: 287 + mode = PMIC_MPP_MODE_CURRENT_SINK; 288 + break; 287 289 } 288 290 289 - val = val << PMIC_MPP_REG_MODE_DIR_SHIFT; 290 - val |= pad->function << PMIC_MPP_REG_MODE_FUNCTION_SHIFT; 291 - val |= pad->out_value & PMIC_MPP_REG_MODE_VALUE_MASK; 291 + if (pad->dtest) 292 + sel = PMIC_MPP_SELECTOR_DTEST_FIRST + pad->dtest - 1; 293 + else if (pad->paired) 294 + sel = PMIC_MPP_SELECTOR_PAIRED; 295 + else 296 + sel = PMIC_MPP_SELECTOR_NORMAL; 297 + 298 + en = !!pad->out_value; 299 + 300 + val = mode << PMIC_MPP_REG_MODE_DIR_SHIFT | 301 + sel << PMIC_MPP_REG_MODE_FUNCTION_SHIFT | 302 + en; 292 303 293 304 return pmic_mpp_write(state, pad, PMIC_MPP_REG_MODE_CTL, val); 294 305 } ··· 377 358 case PIN_CONFIG_OUTPUT: 378 359 arg = pad->out_value; 379 360 break; 361 + case PMIC_MPP_CONF_DTEST_SELECTOR: 362 + arg = pad->dtest; 363 + break; 380 364 case PMIC_MPP_CONF_AMUX_ROUTE: 381 365 arg = pad->amux_input; 366 + break; 367 + case PMIC_MPP_CONF_PAIRED: 368 + arg = pad->paired; 382 369 break; 383 370 case PIN_CONFIG_DRIVE_STRENGTH: 384 371 arg = pad->drive_strength; 385 372 break; 386 373 case PMIC_MPP_CONF_ANALOG_LEVEL: 387 374 arg = pad->aout_level; 388 - break; 389 - case PMIC_MPP_CONF_ANALOG_MODE: 390 - arg = pad->analog_mode; 391 - break; 392 - case PMIC_MPP_CONF_SINK_MODE: 393 - arg = pad->sink_mode; 394 375 break; 395 376 default: 396 377 return -EINVAL; ··· 453 434 pad->output_enabled = true; 454 435 pad->out_value = arg; 455 436 break; 437 + case PMIC_MPP_CONF_DTEST_SELECTOR: 438 + pad->dtest = arg; 439 + break; 456 440 case PIN_CONFIG_DRIVE_STRENGTH: 457 441 arg = pad->drive_strength; 458 442 break; ··· 467 445 case PMIC_MPP_CONF_ANALOG_LEVEL: 468 446 pad->aout_level = arg; 469 447 break; 470 - case PMIC_MPP_CONF_ANALOG_MODE: 471 - pad->analog_mode = !!arg; 472 - break; 473 - case PMIC_MPP_CONF_SINK_MODE: 474 - pad->sink_mode = !!arg; 448 + case PMIC_MPP_CONF_PAIRED: 449 + pad->paired = !!arg; 475 450 break; 476 451 default: 477 452 return -EINVAL; ··· 517 498 "0.6kOhm", "10kOhm", "30kOhm", "Disabled" 518 499 }; 519 500 520 - static const char *const modes[] = { 521 - "digital", "analog", "sink" 522 - }; 523 - 524 501 pad = pctldev->desc->pins[pin].drv_data; 525 502 526 503 seq_printf(s, " mpp%-2d:", pin + PMIC_MPP_PHYSICAL_OFFSET); ··· 535 520 } 536 521 537 522 seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in"); 538 - seq_printf(s, " %-7s", modes[pad->analog_mode ? 1 : (pad->sink_mode ? 2 : 0)]); 539 523 seq_printf(s, " %-7s", pmic_mpp_functions[pad->function]); 540 524 seq_printf(s, " vin-%d", pad->power_source); 541 525 seq_printf(s, " %d", pad->aout_level); 542 526 seq_printf(s, " %-8s", biases[pad->pullup]); 543 527 seq_printf(s, " %-4s", pad->out_value ? "high" : "low"); 528 + if (pad->dtest) 529 + seq_printf(s, " dtest%d", pad->dtest); 530 + if (pad->paired) 531 + seq_puts(s, " paired"); 544 532 } 545 533 } 546 534 ··· 664 646 struct pmic_mpp_pad *pad) 665 647 { 666 648 int type, subtype, val, dir; 649 + unsigned int sel; 667 650 668 651 type = pmic_mpp_read(state, pad, PMIC_MPP_REG_TYPE); 669 652 if (type < 0) ··· 710 691 case PMIC_MPP_MODE_DIGITAL_INPUT: 711 692 pad->input_enabled = true; 712 693 pad->output_enabled = false; 713 - pad->analog_mode = false; 714 - pad->sink_mode = false; 694 + pad->function = PMIC_MPP_DIGITAL; 715 695 break; 716 696 case PMIC_MPP_MODE_DIGITAL_OUTPUT: 717 697 pad->input_enabled = false; 718 698 pad->output_enabled = true; 719 - pad->analog_mode = false; 720 - pad->sink_mode = false; 699 + pad->function = PMIC_MPP_DIGITAL; 721 700 break; 722 701 case PMIC_MPP_MODE_DIGITAL_BIDIR: 723 702 pad->input_enabled = true; 724 703 pad->output_enabled = true; 725 - pad->analog_mode = false; 726 - pad->sink_mode = false; 704 + pad->function = PMIC_MPP_DIGITAL; 727 705 break; 728 706 case PMIC_MPP_MODE_ANALOG_BIDIR: 729 707 pad->input_enabled = true; 730 708 pad->output_enabled = true; 731 - pad->analog_mode = true; 732 - pad->sink_mode = false; 709 + pad->function = PMIC_MPP_ANALOG; 733 710 break; 734 711 case PMIC_MPP_MODE_ANALOG_INPUT: 735 712 pad->input_enabled = true; 736 713 pad->output_enabled = false; 737 - pad->analog_mode = true; 738 - pad->sink_mode = false; 714 + pad->function = PMIC_MPP_ANALOG; 739 715 break; 740 716 case PMIC_MPP_MODE_ANALOG_OUTPUT: 741 717 pad->input_enabled = false; 742 718 pad->output_enabled = true; 743 - pad->analog_mode = true; 744 - pad->sink_mode = false; 719 + pad->function = PMIC_MPP_ANALOG; 745 720 break; 746 721 case PMIC_MPP_MODE_CURRENT_SINK: 747 722 pad->input_enabled = false; 748 723 pad->output_enabled = true; 749 - pad->analog_mode = false; 750 - pad->sink_mode = true; 724 + pad->function = PMIC_MPP_SINK; 751 725 break; 752 726 default: 753 727 dev_err(state->dev, "unknown MPP direction\n"); 754 728 return -ENODEV; 755 729 } 756 730 757 - pad->function = val >> PMIC_MPP_REG_MODE_FUNCTION_SHIFT; 758 - pad->function &= PMIC_MPP_REG_MODE_FUNCTION_MASK; 731 + sel = val >> PMIC_MPP_REG_MODE_FUNCTION_SHIFT; 732 + sel &= PMIC_MPP_REG_MODE_FUNCTION_MASK; 733 + 734 + if (sel >= PMIC_MPP_SELECTOR_DTEST_FIRST) 735 + pad->dtest = sel + 1; 736 + else if (sel == PMIC_MPP_SELECTOR_PAIRED) 737 + pad->paired = true; 759 738 760 739 val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_VIN_CTL); 761 740 if (val < 0)