Ejemplo n.º 1
0
Archivo: core.c Proyecto: 020gzh/linux
static void sh_pfc_write_config_reg(struct sh_pfc *pfc,
				    const struct pinmux_cfg_reg *crp,
				    unsigned int field, u32 value)
{
	void __iomem *mapped_reg;
	unsigned int pos;
	u32 mask, data;

	sh_pfc_config_reg_helper(pfc, crp, field, &mapped_reg, &mask, &pos);

	dev_dbg(pfc->dev, "write_reg addr = %x, value = 0x%x, field = %u, "
		"r_width = %u, f_width = %u\n",
		crp->reg, value, field, crp->reg_width, crp->field_width);

	mask = ~(mask << pos);
	value = value << pos;

	data = sh_pfc_read_raw_reg(mapped_reg, crp->reg_width);
	data &= mask;
	data |= value;

	if (pfc->info->unlock_reg)
		sh_pfc_write_raw_reg(
			sh_pfc_phys_to_virt(pfc, pfc->info->unlock_reg), 32,
			~data);

	sh_pfc_write_raw_reg(mapped_reg, crp->reg_width, data);
}
Ejemplo n.º 2
0
void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data)
{
	void __iomem *unlock_reg =
		(void __iomem *)(uintptr_t)pfc->info->unlock_reg;

	if (pfc->info->unlock_reg)
		sh_pfc_write_raw_reg(unlock_reg, 32, ~data);

	sh_pfc_write_raw_reg((void __iomem *)(uintptr_t)reg, 32, data);
}
Ejemplo n.º 3
0
Archivo: gpio.c Proyecto: Lyude/linux
static void gpio_write_data_reg(struct sh_pfc_chip *chip,
				const struct pinmux_data_reg *dreg, u32 value)
{
	phys_addr_t address = dreg->reg;
	void __iomem *mem = address - chip->mem->phys + chip->mem->virt;

	sh_pfc_write_raw_reg(mem, dreg->reg_width, value);
}
Ejemplo n.º 4
0
static int sh_pfc_pinconf_set_drive_strength(struct sh_pfc *pfc,
					     unsigned int pin, u16 strength)
{
	unsigned int offset;
	unsigned int size;
	unsigned int step;
	void __iomem *reg;
	void __iomem *unlock_reg =
		(void __iomem *)(uintptr_t)pfc->info->unlock_reg;
	u32 val;

	reg = sh_pfc_pinconf_find_drive_strength_reg(pfc, pin, &offset, &size);
	if (!reg)
		return -EINVAL;

	step = size == 2 ? 6 : 3;

	if (strength < step || strength > 24)
		return -EINVAL;

	/* Convert the value from mA based on a full drive strength value of
	 * 24mA. We can make the full value configurable later if needed.
	 */
	strength = strength / step - 1;

	val = sh_pfc_read_raw_reg(reg, 32);
	val &= ~GENMASK(offset + size - 1, offset);
	val |= strength << offset;

	if (unlock_reg)
		sh_pfc_write_raw_reg(unlock_reg, 32, ~val);

	sh_pfc_write_raw_reg(reg, 32, val);

	return 0;
}
Ejemplo n.º 5
0
static int sh_pfc_pinconf_set(struct sh_pfc_pinctrl *pmx, unsigned _pin,
			      unsigned int param, unsigned int arg)
{
	struct sh_pfc *pfc = pmx->pfc;
	void __iomem *pocctrl;
	void __iomem *unlock_reg =
		(void __iomem *)(uintptr_t)pfc->info->unlock_reg;
	u32 addr, val;
	int bit, ret;

	if (!sh_pfc_pinconf_validate(pfc, _pin, param))
		return -ENOTSUPP;

	switch (param) {
	case PIN_CONFIG_BIAS_PULL_UP:
	case PIN_CONFIG_BIAS_PULL_DOWN:
	case PIN_CONFIG_BIAS_DISABLE:
		if (!pfc->info->ops || !pfc->info->ops->set_bias)
			return -ENOTSUPP;

		pfc->info->ops->set_bias(pfc, _pin, param);

		break;

	case PIN_CONFIG_DRIVE_STRENGTH:
		ret = sh_pfc_pinconf_set_drive_strength(pfc, _pin, arg);
		if (ret < 0)
			return ret;

		break;

	case PIN_CONFIG_POWER_SOURCE:
		if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl)
			return -ENOTSUPP;

		bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &addr);
		if (bit < 0) {
			printf("invalid pin %#x", _pin);
			return bit;
		}

		if (arg != 1800 && arg != 3300)
			return -EINVAL;

		pocctrl = (void __iomem *)(uintptr_t)addr;

		val = sh_pfc_read_raw_reg(pocctrl, 32);
		if (arg == 3300)
			val |= BIT(bit);
		else
			val &= ~BIT(bit);

		if (unlock_reg)
			sh_pfc_write_raw_reg(unlock_reg, 32, ~val);

		sh_pfc_write_raw_reg(pocctrl, 32, val);

		break;

	default:
		return -ENOTSUPP;
	}

	return 0;
}