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); }
/* * 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; }
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); }
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; }
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); }