static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev)
{
	struct device *parent = pdev->dev.parent;
	struct regulator_init_data *p = pdev->dev.platform_data;
	struct tps6586x_settings *setting = p->driver_data;
	uint8_t reg;

	if (setting == NULL)
		return 0;

	if (!(setting->slew_rate & TPS6586X_SLEW_RATE_SET))
		return 0;

	/* only SM0 and SM1 can have the slew rate settings */
	switch (pdev->id) {
	case TPS6586X_ID_SM_0:
		reg = TPS6586X_SM0SL;
		break;
	case TPS6586X_ID_SM_1:
		reg = TPS6586X_SM1SL;
		break;
	default:
		dev_warn(&pdev->dev, "Only SM0/SM1 can set slew rate\n");
		return -EINVAL;
	}

	return tps6586x_write(parent, reg,
			setting->slew_rate & TPS6586X_SLEW_RATE_MASK);
}
Example #2
0
/*
 * TPS6586X has 2 enable bits that are OR'ed to determine the actual
 * regulator state. Clearing one of this bits allows switching
 * regulator on and of with single register write.
 */
static inline int tps6586x_regulator_preinit(struct device *parent,
					     struct tps6586x_regulator *ri)
{
	uint8_t val1, val2;
	int ret;

#ifdef CONFIG_MACH_SAMSUNG_VARIATION_TEGRA
	/*
	 * set SM0V1 : 1.325V --> 1.2V
	 * because the default TPS6586X SM0V1[0x26]:1.325V,
	 * SM0V2:1.2V, but SM0 voltage selector points SM0V1
	 * our spec of v_core : 1.2V
	 */

	if (ri->desc.id == TPS6586X_ID_SM_0) {
		int ret;
		ret = tps6586x_write(parent, TPS6586X_SM0V1, 0x13);
		if (ret)
			return ret;
	}
#endif

	if (ri->enable_reg[0] == ri->enable_reg[1] &&
	    ri->enable_bit[0] == ri->enable_bit[1])
			return 0;

	ret = tps6586x_read(parent, ri->enable_reg[0], &val1);
	if (ret)
		return ret;

	ret = tps6586x_read(parent, ri->enable_reg[1], &val2);
	if (ret)
		return ret;

	if (!(val2 & (1 << ri->enable_bit[1])))
		return 0;

	/*
	 * The regulator is on, but it's enabled with the bit we don't
	 * want to use, so we switch the enable bits
	 */
	if (!(val1 & (1 << ri->enable_bit[0]))) {
		ret = tps6586x_set_bits(parent, ri->enable_reg[0],
					1 << ri->enable_bit[0]);
		if (ret)
			return ret;
	}

	return tps6586x_clr_bits(parent, ri->enable_reg[1],
				 1 << ri->enable_bit[1]);
}
static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
				       int irq_base)
{
	int i, ret;
	u8 tmp[4];

	if (!irq_base) {
		dev_warn(tps6586x->dev, "No interrupt support on IRQ base\n");
		return -EINVAL;
	}

	mutex_init(&tps6586x->irq_lock);
	for (i = 0; i < 5; i++) {
		tps6586x->mask_cache[i] = 0xff;
		tps6586x->mask_reg[i] = 0xff;
		tps6586x_write(tps6586x->dev, TPS6586X_INT_MASK1 + i, 0xff);
	}

	tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, sizeof(tmp), tmp);

	tps6586x->irq_base = irq_base;

	tps6586x->irq_chip.name = "tps6586x";
	tps6586x->irq_chip.irq_enable = tps6586x_irq_enable;
	tps6586x->irq_chip.irq_disable = tps6586x_irq_disable;
	tps6586x->irq_chip.irq_bus_lock = tps6586x_irq_lock;
	tps6586x->irq_chip.irq_bus_sync_unlock = tps6586x_irq_sync_unlock;

	for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) {
		int __irq = i + tps6586x->irq_base;
		irq_set_chip_data(__irq, tps6586x);
		irq_set_chip_and_handler(__irq, &tps6586x->irq_chip,
					 handle_simple_irq);
		irq_set_nested_thread(__irq, 1);
#ifdef CONFIG_ARM
		set_irq_flags(__irq, IRQF_VALID);
#endif
	}

	ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT,
				   "tps6586x", tps6586x);

	if (!ret) {
		device_init_wakeup(tps6586x->dev, 1);
		enable_irq_wake(irq);
	}

	return ret;
}
Example #4
0
static int set_voltage(int reg, int data, int rate)
{
	uchar control_bit;
	uchar buff[3];

	control_bit = (reg == SM0_VOLTAGE_V1 ? CTRL_SM0_RAMP : CTRL_SM1_RAMP);

	/*
	 * Only one supply is needed in u-boot. set both v1 and v2 to
	 * same value.
	 *
	 * When both v1 and v2 are set to same value, we just need to set
	 * control1 reg to trigger the supply selection.
	 */
	buff[0] = buff[1] = (uchar)data;
	buff[2] = rate;

	/* write v1, v2 and rate, then trigger */
	if (tps6586x_write(reg, buff, 3) ||
	    tps6586x_write(SUPPLY_CONTROL1, &control_bit, 1))
		return -1;

	return 0;
}
static void tps6586x_irq_sync_unlock(struct irq_data *data)
{
	struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data);
	int i;

	for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) {
		if (tps6586x->mask_reg[i] != tps6586x->mask_cache[i]) {
			if (!WARN_ON(tps6586x_write(tps6586x->dev,
						    TPS6586X_INT_MASK1 + i,
						    tps6586x->mask_reg[i])))
				tps6586x->mask_cache[i] = tps6586x->mask_reg[i];
		}
	}

	mutex_unlock(&tps6586x->irq_lock);
}
Example #6
0
int tps6586x_set_pwm_mode(int mask)
{
	uchar val;
	int ret;

	assert(tps6586x_dev);
	ret = tps6586x_read(PFM_MODE);
	if (ret != -1) {
		val = (uchar)ret;
		val |= mask;

		ret = tps6586x_write(PFM_MODE, &val, 1);
	}

	if (ret == -1)
		debug("%s: Failed to read/write PWM mode reg\n", __func__);

	return ret;
}
Example #7
0
static inline int tps6586x_regulator_set_slew_rate(struct platform_device *pdev)
{
	struct device *parent = pdev->dev.parent;
	struct regulator_init_data *p = pdev->dev.platform_data;
	struct tps6586x_settings *setting = p->driver_data;
	uint8_t reg;

	if (setting == NULL)
		return 0;

	/* only SM0 and SM1 can have the slew rate settings */
	switch (pdev->id) {
	case TPS6586X_ID_SM_0:
		reg = TPS6586X_SM0SL;
		break;
	case TPS6586X_ID_SM_1:
		reg = TPS6586X_SM1SL;
		break;
	default:
		return 0;
	}
	return tps6586x_write(parent, reg, setting->slew_rate);
}