Loading Documentation/devicetree/bindings/gpio/qpnp-pin.txt +6 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,12 @@ Optional configuration properties : QPNP_PIN_OUT_STRENGTH_MED = 2, (GPIO) QPNP_PIN_OUT_STRENGTH_HIGH = 3, (GPIO) - qcom,dtest-sel Route the pin internally to a DTEST line. QPNP_PIN_DIG_IN_CTL_DTEST1 = 1 (GPIO/MPP) QPNP_PIN_DIG_IN_CTL_DTEST2 = 2, (GPIO/MPP) QPNP_PIN_DIG_IN_CTL_DTEST3 = 3, (GPIO/MPP) QPNP_PIN_DIG_IN_CTL_DTEST4 = 4, (GPIO/MPP) - qcom,src-sel: select a function for the pin. Certain pins can be paired (shorted) with each other. Some gpio pins can act as alternate functions. Loading arch/arm/boot/dts/qcom/msm8937-cdp.dtsi +8 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,14 @@ qcom,master-en = <1>; qcom,out-strength = <2>; }; gpio@c100 { qcom,mode = <0>; qcom,vin-sel = <3>; qcom,dtest-sel = <1>; status = "okay"; }; gpio@c600 { status = "ok"; qcom,mode = <1>; Loading arch/arm/boot/dts/qcom/msm8937-mtp.dtsi +10 −0 Original line number Diff line number Diff line Loading @@ -203,3 +203,13 @@ &dsi_truly_1080_cmd { qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; }; /* PM8937 GPIO configuration */ &pm8937_gpios { gpio@c100 { qcom,mode = <0>; qcom,vin-sel = <3>; qcom,dtest-sel = <1>; status = "okay"; }; }; drivers/gpio/qpnp-pin.c +59 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,14 @@ #define Q_REG_OUT_TYPE_SHIFT 4 #define Q_REG_OUT_TYPE_MASK 0x30 /* control reg: dig_in_ctl */ #define Q_REG_DTEST_SEL_SHIFT 0 #define Q_REG_DTEST_SEL_MASK 0xF #define Q_REG_LV_MV_DTEST_SEL_CFG_SHIFT 0 #define Q_REG_LV_MV_DTEST_SEL_CFG_MASK 0x7 #define Q_REG_LV_MV_DTEST_SEL_EN_SHIFT 7 #define Q_REG_LV_MV_DTEST_SEL_EN_MASK 0x80 /* control reg: en */ #define Q_REG_MASTER_EN_SHIFT 7 #define Q_REG_MASTER_EN_MASK 0x80 Loading Loading @@ -154,6 +162,7 @@ enum qpnp_pin_param_type { Q_PIN_CFG_AIN_ROUTE, Q_PIN_CFG_CS_OUT, Q_PIN_CFG_APASS_SEL, Q_PIN_CFG_DTEST_SEL, Q_PIN_CFG_INVALID, }; Loading @@ -180,6 +189,7 @@ enum qpnp_pin_param_type { #define QPNP_PIN_AIN_ROUTE_INVALID 8 #define QPNP_PIN_CS_OUT_INVALID 8 #define QPNP_PIN_APASS_SEL_INVALID 4 #define QPNP_PIN_DTEST_SEL_INVALID 4 struct qpnp_pin_spec { uint8_t slave; /* 0-15 */ Loading Loading @@ -401,6 +411,10 @@ static int qpnp_pin_check_config(enum qpnp_pin_param_type idx, if (val >= QPNP_PIN_APASS_SEL_INVALID) return -EINVAL; break; case Q_PIN_CFG_DTEST_SEL: if (!val && val > QPNP_PIN_DTEST_SEL_INVALID) return -EINVAL; break; default: pr_err("invalid param type %u specified\n", idx); return -EINVAL; Loading Loading @@ -457,6 +471,9 @@ static int qpnp_pin_check_constraints(struct qpnp_pin_spec *q_spec, else if (Q_CHK_INVALID(Q_PIN_CFG_APASS_SEL, q_spec, param->apass_sel)) pr_err("invalid apass_sel value %d for %s %d\n", param->apass_sel, name, pin); else if (Q_CHK_INVALID(Q_PIN_CFG_DTEST_SEL, q_spec, param->dtest_sel)) pr_err("invalid dtest_sel value %d for %s %d\n", param->dtest_sel, name, pin); else return 0; Loading Loading @@ -630,6 +647,24 @@ static int _qpnp_pin_config(struct qpnp_pin_chip *q_chip, Q_REG_OUT_TYPE_SHIFT, Q_REG_OUT_TYPE_MASK, param->output_type); /* input config */ if (Q_HAVE_HW_SP(Q_PIN_CFG_DTEST_SEL, q_spec, param->dtest_sel)) { if (is_gpio_lv_mv(q_spec)) { q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_LV_MV_DTEST_SEL_CFG_SHIFT, Q_REG_LV_MV_DTEST_SEL_CFG_MASK, param->dtest_sel - 1); q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_LV_MV_DTEST_SEL_EN_SHIFT, Q_REG_LV_MV_DTEST_SEL_EN_MASK, 0x1); } else { q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_DTEST_SEL_SHIFT, Q_REG_DTEST_SEL_MASK, BIT(param->dtest_sel - 1)); } } /* config applicable for both input / output */ if (Q_HAVE_HW_SP(Q_PIN_CFG_VIN_SEL, q_spec, param->vin_sel)) q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_VIN_CTL], Loading Loading @@ -1035,6 +1070,15 @@ static int qpnp_pin_apply_config(struct qpnp_pin_chip *q_chip, param.apass_sel = q_reg_get(&q_spec->regs[Q_REG_I_APASS_SEL_CTL], Q_REG_APASS_SEL_SHIFT, Q_REG_APASS_SEL_MASK); if (is_gpio_lv_mv(q_spec)) { param.dtest_sel = q_reg_get(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_LV_MV_DTEST_SEL_CFG_SHIFT, Q_REG_LV_MV_DTEST_SEL_CFG_MASK); } else { param.dtest_sel = q_reg_get(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_DTEST_SEL_SHIFT, Q_REG_DTEST_SEL_MASK); } of_property_read_u32(node, "qcom,mode", ¶m.mode); Loading @@ -1060,6 +1104,9 @@ static int qpnp_pin_apply_config(struct qpnp_pin_chip *q_chip, ¶m.cs_out); of_property_read_u32(node, "qcom,apass-sel", ¶m.apass_sel); of_property_read_u32(node, "qcom,dtest-sel", ¶m.dtest_sel); rc = _qpnp_pin_config(q_chip, q_spec, ¶m); return rc; Loading Loading @@ -1192,6 +1239,17 @@ static int qpnp_pin_reg_attr(enum qpnp_pin_param_type type, cfg->shift = Q_REG_APASS_SEL_SHIFT; cfg->mask = Q_REG_APASS_SEL_MASK; break; case Q_PIN_CFG_DTEST_SEL: if (is_gpio_lv_mv(q_spec)) { cfg->shift = Q_REG_LV_MV_DTEST_SEL_SHIFT; cfg->mask = Q_REG_LV_MV_DTEST_SEL_MASK; } else { cfg->shift = Q_REG_DTEST_SEL_SHIFT; cfg->mask = Q_REG_DTEST_SEL_MASK; } cfg->addr = Q_REG_DIG_IN_CTL; cfg->idx = Q_REG_I_DIG_IN_CTL; break; default: return -EINVAL; } Loading Loading @@ -1264,6 +1322,7 @@ static struct qpnp_pin_debugfs_args dfs_args[] = { { Q_PIN_CFG_AIN_ROUTE, "ain_route" }, { Q_PIN_CFG_CS_OUT, "cs_out" }, { Q_PIN_CFG_APASS_SEL, "apass_sel" }, { Q_PIN_CFG_DTEST_SEL, "dtest-sel" }, }; static int qpnp_pin_debugfs_create(struct qpnp_pin_chip *q_chip) Loading include/linux/qpnp/pin.h +11 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,12 @@ #define QPNP_PIN_OUT_STRENGTH_MED 2 #define QPNP_PIN_OUT_STRENGTH_HIGH 3 /* Digital-in CTL (GPIO/MPP) */ #define QPNP_PIN_DIG_IN_CTL_DTEST1 1 #define QPNP_PIN_DIG_IN_CTL_DTEST2 2 #define QPNP_PIN_DIG_IN_CTL_DTEST3 3 #define QPNP_PIN_DIG_IN_CTL_DTEST4 4 /* Source Select (GPIO) / Enable Select (MPP) */ #define QPNP_PIN_SEL_FUNC_CONSTANT 0 #define QPNP_PIN_SEL_FUNC_PAIRED 1 Loading Loading @@ -175,6 +181,10 @@ * routed to. The parameter should be of type * QPNP_PIN_APASS_SEL_*. This * parameter only applies to GPIO LV/MV pins. * @dtest_sel: Select the DTEST line to which the signal needs * is routed to. The parameter should be of type * QPNP_PIN_DIG_IN_CTL_*. The parameter applies * to both gpio and mpp pins. */ struct qpnp_pin_cfg { int mode; Loading @@ -189,6 +199,7 @@ struct qpnp_pin_cfg { int ain_route; int cs_out; int apass_sel; int dtest_sel; }; /** Loading Loading
Documentation/devicetree/bindings/gpio/qpnp-pin.txt +6 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,12 @@ Optional configuration properties : QPNP_PIN_OUT_STRENGTH_MED = 2, (GPIO) QPNP_PIN_OUT_STRENGTH_HIGH = 3, (GPIO) - qcom,dtest-sel Route the pin internally to a DTEST line. QPNP_PIN_DIG_IN_CTL_DTEST1 = 1 (GPIO/MPP) QPNP_PIN_DIG_IN_CTL_DTEST2 = 2, (GPIO/MPP) QPNP_PIN_DIG_IN_CTL_DTEST3 = 3, (GPIO/MPP) QPNP_PIN_DIG_IN_CTL_DTEST4 = 4, (GPIO/MPP) - qcom,src-sel: select a function for the pin. Certain pins can be paired (shorted) with each other. Some gpio pins can act as alternate functions. Loading
arch/arm/boot/dts/qcom/msm8937-cdp.dtsi +8 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,14 @@ qcom,master-en = <1>; qcom,out-strength = <2>; }; gpio@c100 { qcom,mode = <0>; qcom,vin-sel = <3>; qcom,dtest-sel = <1>; status = "okay"; }; gpio@c600 { status = "ok"; qcom,mode = <1>; Loading
arch/arm/boot/dts/qcom/msm8937-mtp.dtsi +10 −0 Original line number Diff line number Diff line Loading @@ -203,3 +203,13 @@ &dsi_truly_1080_cmd { qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; }; /* PM8937 GPIO configuration */ &pm8937_gpios { gpio@c100 { qcom,mode = <0>; qcom,vin-sel = <3>; qcom,dtest-sel = <1>; status = "okay"; }; };
drivers/gpio/qpnp-pin.c +59 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,14 @@ #define Q_REG_OUT_TYPE_SHIFT 4 #define Q_REG_OUT_TYPE_MASK 0x30 /* control reg: dig_in_ctl */ #define Q_REG_DTEST_SEL_SHIFT 0 #define Q_REG_DTEST_SEL_MASK 0xF #define Q_REG_LV_MV_DTEST_SEL_CFG_SHIFT 0 #define Q_REG_LV_MV_DTEST_SEL_CFG_MASK 0x7 #define Q_REG_LV_MV_DTEST_SEL_EN_SHIFT 7 #define Q_REG_LV_MV_DTEST_SEL_EN_MASK 0x80 /* control reg: en */ #define Q_REG_MASTER_EN_SHIFT 7 #define Q_REG_MASTER_EN_MASK 0x80 Loading Loading @@ -154,6 +162,7 @@ enum qpnp_pin_param_type { Q_PIN_CFG_AIN_ROUTE, Q_PIN_CFG_CS_OUT, Q_PIN_CFG_APASS_SEL, Q_PIN_CFG_DTEST_SEL, Q_PIN_CFG_INVALID, }; Loading @@ -180,6 +189,7 @@ enum qpnp_pin_param_type { #define QPNP_PIN_AIN_ROUTE_INVALID 8 #define QPNP_PIN_CS_OUT_INVALID 8 #define QPNP_PIN_APASS_SEL_INVALID 4 #define QPNP_PIN_DTEST_SEL_INVALID 4 struct qpnp_pin_spec { uint8_t slave; /* 0-15 */ Loading Loading @@ -401,6 +411,10 @@ static int qpnp_pin_check_config(enum qpnp_pin_param_type idx, if (val >= QPNP_PIN_APASS_SEL_INVALID) return -EINVAL; break; case Q_PIN_CFG_DTEST_SEL: if (!val && val > QPNP_PIN_DTEST_SEL_INVALID) return -EINVAL; break; default: pr_err("invalid param type %u specified\n", idx); return -EINVAL; Loading Loading @@ -457,6 +471,9 @@ static int qpnp_pin_check_constraints(struct qpnp_pin_spec *q_spec, else if (Q_CHK_INVALID(Q_PIN_CFG_APASS_SEL, q_spec, param->apass_sel)) pr_err("invalid apass_sel value %d for %s %d\n", param->apass_sel, name, pin); else if (Q_CHK_INVALID(Q_PIN_CFG_DTEST_SEL, q_spec, param->dtest_sel)) pr_err("invalid dtest_sel value %d for %s %d\n", param->dtest_sel, name, pin); else return 0; Loading Loading @@ -630,6 +647,24 @@ static int _qpnp_pin_config(struct qpnp_pin_chip *q_chip, Q_REG_OUT_TYPE_SHIFT, Q_REG_OUT_TYPE_MASK, param->output_type); /* input config */ if (Q_HAVE_HW_SP(Q_PIN_CFG_DTEST_SEL, q_spec, param->dtest_sel)) { if (is_gpio_lv_mv(q_spec)) { q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_LV_MV_DTEST_SEL_CFG_SHIFT, Q_REG_LV_MV_DTEST_SEL_CFG_MASK, param->dtest_sel - 1); q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_LV_MV_DTEST_SEL_EN_SHIFT, Q_REG_LV_MV_DTEST_SEL_EN_MASK, 0x1); } else { q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_DTEST_SEL_SHIFT, Q_REG_DTEST_SEL_MASK, BIT(param->dtest_sel - 1)); } } /* config applicable for both input / output */ if (Q_HAVE_HW_SP(Q_PIN_CFG_VIN_SEL, q_spec, param->vin_sel)) q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_VIN_CTL], Loading Loading @@ -1035,6 +1070,15 @@ static int qpnp_pin_apply_config(struct qpnp_pin_chip *q_chip, param.apass_sel = q_reg_get(&q_spec->regs[Q_REG_I_APASS_SEL_CTL], Q_REG_APASS_SEL_SHIFT, Q_REG_APASS_SEL_MASK); if (is_gpio_lv_mv(q_spec)) { param.dtest_sel = q_reg_get(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_LV_MV_DTEST_SEL_CFG_SHIFT, Q_REG_LV_MV_DTEST_SEL_CFG_MASK); } else { param.dtest_sel = q_reg_get(&q_spec->regs[Q_REG_I_DIG_IN_CTL], Q_REG_DTEST_SEL_SHIFT, Q_REG_DTEST_SEL_MASK); } of_property_read_u32(node, "qcom,mode", ¶m.mode); Loading @@ -1060,6 +1104,9 @@ static int qpnp_pin_apply_config(struct qpnp_pin_chip *q_chip, ¶m.cs_out); of_property_read_u32(node, "qcom,apass-sel", ¶m.apass_sel); of_property_read_u32(node, "qcom,dtest-sel", ¶m.dtest_sel); rc = _qpnp_pin_config(q_chip, q_spec, ¶m); return rc; Loading Loading @@ -1192,6 +1239,17 @@ static int qpnp_pin_reg_attr(enum qpnp_pin_param_type type, cfg->shift = Q_REG_APASS_SEL_SHIFT; cfg->mask = Q_REG_APASS_SEL_MASK; break; case Q_PIN_CFG_DTEST_SEL: if (is_gpio_lv_mv(q_spec)) { cfg->shift = Q_REG_LV_MV_DTEST_SEL_SHIFT; cfg->mask = Q_REG_LV_MV_DTEST_SEL_MASK; } else { cfg->shift = Q_REG_DTEST_SEL_SHIFT; cfg->mask = Q_REG_DTEST_SEL_MASK; } cfg->addr = Q_REG_DIG_IN_CTL; cfg->idx = Q_REG_I_DIG_IN_CTL; break; default: return -EINVAL; } Loading Loading @@ -1264,6 +1322,7 @@ static struct qpnp_pin_debugfs_args dfs_args[] = { { Q_PIN_CFG_AIN_ROUTE, "ain_route" }, { Q_PIN_CFG_CS_OUT, "cs_out" }, { Q_PIN_CFG_APASS_SEL, "apass_sel" }, { Q_PIN_CFG_DTEST_SEL, "dtest-sel" }, }; static int qpnp_pin_debugfs_create(struct qpnp_pin_chip *q_chip) Loading
include/linux/qpnp/pin.h +11 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,12 @@ #define QPNP_PIN_OUT_STRENGTH_MED 2 #define QPNP_PIN_OUT_STRENGTH_HIGH 3 /* Digital-in CTL (GPIO/MPP) */ #define QPNP_PIN_DIG_IN_CTL_DTEST1 1 #define QPNP_PIN_DIG_IN_CTL_DTEST2 2 #define QPNP_PIN_DIG_IN_CTL_DTEST3 3 #define QPNP_PIN_DIG_IN_CTL_DTEST4 4 /* Source Select (GPIO) / Enable Select (MPP) */ #define QPNP_PIN_SEL_FUNC_CONSTANT 0 #define QPNP_PIN_SEL_FUNC_PAIRED 1 Loading Loading @@ -175,6 +181,10 @@ * routed to. The parameter should be of type * QPNP_PIN_APASS_SEL_*. This * parameter only applies to GPIO LV/MV pins. * @dtest_sel: Select the DTEST line to which the signal needs * is routed to. The parameter should be of type * QPNP_PIN_DIG_IN_CTL_*. The parameter applies * to both gpio and mpp pins. */ struct qpnp_pin_cfg { int mode; Loading @@ -189,6 +199,7 @@ struct qpnp_pin_cfg { int ain_route; int cs_out; int apass_sel; int dtest_sel; }; /** Loading