コード例 #1
0
ファイル: pinctrl-mtk-common.c プロジェクト: coderkan/linux
static void mtk_pconf_set_ies_smt(struct mtk_pinctrl *pctl, unsigned pin,
                                  int value, enum pin_config_param param)
{
    unsigned int reg_addr, offset;
    unsigned int bit;
    int ret;

    /*
     * Due to some pins are irregular, their input enable and smt
     * control register are discontinuous, but they are mapping together.
     * So we need this special handle.
     */
    if (pctl->devdata->spec_ies_smt_set) {
        ret = pctl->devdata->spec_ies_smt_set(mtk_get_regmap(pctl, pin),
                                              pin, pctl->devdata->port_align, value);
        if (!ret)
            return;
    }

    bit = BIT(pin & 0xf);

    if (param == PIN_CONFIG_INPUT_ENABLE)
        offset = pctl->devdata->ies_offset;
    else
        offset = pctl->devdata->smt_offset;

    if (value)
        reg_addr = SET_ADDR(mtk_get_port(pctl, pin) + offset, pctl);
    else
        reg_addr = CLR_ADDR(mtk_get_port(pctl, pin) + offset, pctl);

    regmap_write(mtk_get_regmap(pctl, pin), reg_addr, bit);
}
コード例 #2
0
ファイル: pinctrl-mtk-common.c プロジェクト: coderkan/linux
static int mtk_pconf_set_driving(struct mtk_pinctrl *pctl,
                                 unsigned int pin, unsigned char driving)
{
    const struct mtk_pin_drv_grp *pin_drv;
    unsigned int val;
    unsigned int bits, mask, shift;
    const struct mtk_drv_group_desc *drv_grp;

    if (pin >= pctl->devdata->npins)
        return -EINVAL;

    pin_drv = mtk_find_pin_drv_grp_by_pin(pctl, pin);
    if (!pin_drv || pin_drv->grp > pctl->devdata->n_grp_cls)
        return -EINVAL;

    drv_grp = pctl->devdata->grp_desc + pin_drv->grp;
    if (driving >= drv_grp->min_drv && driving <= drv_grp->max_drv
            && !(driving % drv_grp->step)) {
        val = driving / drv_grp->step - 1;
        bits = drv_grp->high_bit - drv_grp->low_bit + 1;
        mask = BIT(bits) - 1;
        shift = pin_drv->bit + drv_grp->low_bit;
        mask <<= shift;
        val <<= shift;
        return regmap_update_bits(mtk_get_regmap(pctl, pin),
                                  pin_drv->offset, mask, val);
    }

    return -EINVAL;
}
コード例 #3
0
ファイル: pinctrl-mtk-common.c プロジェクト: coderkan/linux
static int mtk_pconf_set_pull_select(struct mtk_pinctrl *pctl,
                                     unsigned int pin, bool enable, bool isup, unsigned int arg)
{
    unsigned int bit;
    unsigned int reg_pullen, reg_pullsel;
    int ret;

    /* Some pins' pull setting are very different,
     * they have separate pull up/down bit, R0 and R1
     * resistor bit, so we need this special handle.
     */
    if (pctl->devdata->spec_pull_set) {
        ret = pctl->devdata->spec_pull_set(mtk_get_regmap(pctl, pin),
                                           pin, pctl->devdata->port_align, isup, arg);
        if (!ret)
            return 0;
    }

    /* For generic pull config, default arg value should be 0 or 1. */
    if (arg != 0 && arg != 1) {
        dev_err(pctl->dev, "invalid pull-up argument %d on pin %d .\n",
                arg, pin);
        return -EINVAL;
    }

    bit = BIT(pin & 0xf);
    if (enable)
        reg_pullen = SET_ADDR(mtk_get_port(pctl, pin) +
                              pctl->devdata->pullen_offset, pctl);
    else
        reg_pullen = CLR_ADDR(mtk_get_port(pctl, pin) +
                              pctl->devdata->pullen_offset, pctl);

    if (isup)
        reg_pullsel = SET_ADDR(mtk_get_port(pctl, pin) +
                               pctl->devdata->pullsel_offset, pctl);
    else
        reg_pullsel = CLR_ADDR(mtk_get_port(pctl, pin) +
                               pctl->devdata->pullsel_offset, pctl);

    regmap_write(mtk_get_regmap(pctl, pin), reg_pullen, bit);
    regmap_write(mtk_get_regmap(pctl, pin), reg_pullsel, bit);
    return 0;
}
コード例 #4
0
ファイル: pinctrl-mtk-common.c プロジェクト: infidel/linux
static int mtk_pconf_set_ies_smt(struct mtk_pinctrl *pctl, unsigned pin,
		int value, enum pin_config_param arg)
{
	unsigned int reg_addr, offset;
	unsigned int bit;

	/**
	 * Due to some soc are not support ies/smt config, add this special
	 * control to handle it.
	 */
	if (!pctl->devdata->spec_ies_smt_set &&
		pctl->devdata->ies_offset == MTK_PINCTRL_NOT_SUPPORT &&
			arg == PIN_CONFIG_INPUT_ENABLE)
		return -EINVAL;

	if (!pctl->devdata->spec_ies_smt_set &&
		pctl->devdata->smt_offset == MTK_PINCTRL_NOT_SUPPORT &&
			arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE)
		return -EINVAL;

	/*
	 * Due to some pins are irregular, their input enable and smt
	 * control register are discontinuous, so we need this special handle.
	 */
	if (pctl->devdata->spec_ies_smt_set) {
		return pctl->devdata->spec_ies_smt_set(mtk_get_regmap(pctl, pin),
			pin, pctl->devdata->port_align, value, arg);
	}

	bit = BIT(pin & 0xf);

	if (arg == PIN_CONFIG_INPUT_ENABLE)
		offset = pctl->devdata->ies_offset;
	else
		offset = pctl->devdata->smt_offset;

	if (value)
		reg_addr = SET_ADDR(mtk_get_port(pctl, pin) + offset, pctl);
	else
		reg_addr = CLR_ADDR(mtk_get_port(pctl, pin) + offset, pctl);

	regmap_write(mtk_get_regmap(pctl, pin), reg_addr, bit);
	return 0;
}
コード例 #5
0
ファイル: pinctrl-mtk-common.c プロジェクト: coderkan/linux
static void mtk_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
    unsigned int reg_addr;
    unsigned int bit;
    struct mtk_pinctrl *pctl = dev_get_drvdata(chip->dev);

    reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dout_offset;
    bit = BIT(offset & 0xf);

    if (value)
        reg_addr = SET_ADDR(reg_addr, pctl);
    else
        reg_addr = CLR_ADDR(reg_addr, pctl);

    regmap_write(mtk_get_regmap(pctl, offset), reg_addr, bit);
}
コード例 #6
0
ファイル: pinctrl-mtk-common.c プロジェクト: coderkan/linux
static int mtk_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
                                      struct pinctrl_gpio_range *range, unsigned offset,
                                      bool input)
{
    unsigned int reg_addr;
    unsigned int bit;
    struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);

    reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
    bit = BIT(offset & 0xf);

    if (input)
        /* Different SoC has different alignment offset. */
        reg_addr = CLR_ADDR(reg_addr, pctl);
    else
        reg_addr = SET_ADDR(reg_addr, pctl);

    regmap_write(mtk_get_regmap(pctl, offset), reg_addr, bit);
    return 0;
}