static int twlreg_enable(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int grp; int ret; grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) return grp; if (twl_class_is_4030()) grp |= P1_GRP_4030; else grp |= P1_GRP_6030; ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); if (!ret && twl_class_is_6030()) ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, grp << TWL6030_CFG_STATE_GRP_SHIFT | TWL6030_CFG_STATE_ON); udelay(info->delay); return ret; }
static int twlreg_disable(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int grp; int ret; grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) return grp; /* For 6030, set the off state for all grps enabled */ if (twl_class_is_6030()) { ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, (grp & (P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030)) << TWL6030_CFG_STATE_GRP_SHIFT | TWL6030_CFG_STATE_OFF); if (ret) return ret; } if (twl_class_is_4030()) grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); else grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030); ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); /* Next, associate cleared grp in state register */ if (!ret && twl_class_is_6030()) ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, grp << TWL6030_CFG_STATE_GRP_SHIFT | TWL6030_CFG_STATE_OFF); return ret; }
static void rtc_interrupt_bottom_half(struct work_struct *work) { unsigned long events = 0; int ret = IRQ_NONE; int res; u8 rd_reg; printk("rtc_interrupt_bottom_half \n"); void* rtc =(void *) rtc_ins.rtc ; #if 1 res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (res) goto out; /* * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG. * only one (ALARM or RTC) interrupt source may be enabled * at time, we also could check our results * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM] */ if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) events |= RTC_IRQF | RTC_AF; else events |= RTC_IRQF | RTC_UF; res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M, REG_RTC_STATUS_REG); if (res) goto out; if (twl_class_is_4030()) { /* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1 * needs 2 reads to clear the interrupt. One read is done in * do_twl_pwrirq(). Doing the second read, to clear * the bit. * * FIXME the reason PWR_ISR1 needs an extra read is that * RTC_IF retriggered until we cleared REG_ALARM_M above. * But re-reading like this is a bad hack; by doing so we * risk wrongly clearing status for some other IRQ (losing * the interrupt). Be smarter about handling RTC_UF ... */ res = twl_i2c_read_u8(TWL4030_MODULE_INT, &rd_reg, TWL4030_INT_PWR_ISR1); if (res) goto out; } /* Notify RTC core on event */ rtc_update_irq(rtc, 1, events); out: return ret; #endif }
static inline int twl_get_last_module(void) { if (twl_class_is_4030()) return TWL4030_MODULE_LAST; else return TWL6030_MODULE_LAST; }
static inline int twl_get_num_slaves(void) { if (twl_class_is_4030()) return 4; /* TWL4030 class have four slave address */ else return 3; /* TWL6030 class have three slave address */ }
static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) { unsigned long events = 0; int ret = IRQ_NONE; int res; u8 rd_reg; #ifdef CONFIG_LOCKDEP /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which * we don't want and can't tolerate. Although it might be * friendlier not to borrow this thread context... */ local_irq_enable(); #endif res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (res) goto out; /* * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG. * only one (ALARM or RTC) interrupt source may be enabled * at time, we also could check our results * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM] */ if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) events |= RTC_IRQF | RTC_AF; else events |= RTC_IRQF | RTC_UF; res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M, REG_RTC_STATUS_REG); if (res) goto out; if (twl_class_is_4030()) { /* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1 * needs 2 reads to clear the interrupt. One read is done in * do_twl_pwrirq(). Doing the second read, to clear * the bit. * * FIXME the reason PWR_ISR1 needs an extra read is that * RTC_IF retriggered until we cleared REG_ALARM_M above. * But re-reading like this is a bad hack; by doing so we * risk wrongly clearing status for some other IRQ (losing * the interrupt). Be smarter about handling RTC_UF ... */ res = twl_i2c_read_u8(TWL4030_MODULE_INT, &rd_reg, TWL4030_INT_PWR_ISR1); if (res) goto out; } /* Notify RTC core on event */ rtc_update_irq(rtc, 1, events); ret = IRQ_HANDLED; out: return ret; }
static int __init twl_rtc_init(void) { if (twl_class_is_4030()) rtc_reg_map = (u8 *) twl4030_rtc_reg_map; else rtc_reg_map = (u8 *) twl6030_rtc_reg_map; return platform_driver_register(&twl4030rtc_driver); }
static int twlreg_is_enabled(struct regulator_dev *rdev) { int state = twlreg_grp(rdev); if (state < 0) return state; if (twl_class_is_4030()) state &= P1_GRP_4030; else state &= P1_GRP_6030; return state; }
static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) { unsigned long events; int ret = IRQ_NONE; int res; u8 rd_reg; res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (res) goto out; /* */ if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) events = RTC_IRQF | RTC_AF; else events = RTC_IRQF | RTC_PF; res = twl_rtc_write_u8(BIT_RTC_STATUS_REG_ALARM_M, REG_RTC_STATUS_REG); if (res) goto out; if (twl_class_is_4030()) { /* */ res = twl_i2c_read_u8(TWL4030_MODULE_INT, &rd_reg, TWL4030_INT_PWR_ISR1); if (res) goto out; } /* */ rtc_update_irq(rtc, 1, events); ret = IRQ_HANDLED; out: return ret; }
static int twlreg_disable(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int grp; grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) return grp; if (twl_class_is_4030()) grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); else grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030); return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); }
static int twlreg_disable(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int grp; int ret; grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) return grp; if (twl_class_is_4030()) grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); else grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030); ret= twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); printk("%s : %s info->base=0x%x grp=0x%x \n",__func__,rdev->desc->name,info->base , grp); return ret; }
static int __devinit twlreg_probe(struct platform_device *pdev) { int i; struct twlreg_info *info; struct regulator_init_data *initdata; struct regulation_constraints *c; struct regulator_dev *rdev; for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) { if (twl_regs[i].desc.id != pdev->id) continue; info = twl_regs + i; break; } if (!info) return -ENODEV; initdata = pdev->dev.platform_data; if (!initdata) return -EINVAL; /* Constrain board-specific capabilities according to what * this driver and the chip itself can actually do. */ c = &initdata->constraints; c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS; switch (pdev->id) { case TWL4030_REG_VIO: case TWL4030_REG_VDD1: case TWL4030_REG_VDD2: case TWL4030_REG_VPLL1: case TWL4030_REG_VINTANA1: case TWL4030_REG_VINTANA2: case TWL4030_REG_VINTDIG: c->always_on = true; break; /* * TODO: This is needed for a Phoenix ES1.0 Errata. * Once, ES check for Phoenix is implemented. Make * this conditional only for ES1. */ case TWL6030_REG_VAUX3_6030: /* Set duty-cycle to 100% */ twl_i2c_write_u8(TWL6030_MODULE_ID1, 0, TWL6030_VIBCTRL); /* Enable the Vibrator driver */ twl_i2c_write_u8(TWL6030_MODULE_ID1, 128, TWL6030_TOGGLE2); break; default: break; } rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "can't register %s, %ld\n", info->desc.name, PTR_ERR(rdev)); return PTR_ERR(rdev); } platform_set_drvdata(pdev, rdev); if (twl_class_is_4030()) twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, info->remap); /* NOTE: many regulators support short-circuit IRQs (presentable * as REGULATOR_OVER_CURRENT notifications?) configured via: * - SC_CONFIG * - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4) * - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2) * - IT_CONFIG */ return 0; }
static int __devinit twlreg_probe(struct platform_device *pdev) { int i, id; struct twlreg_info *info; struct regulator_init_data *initdata; struct regulation_constraints *c; struct regulator_dev *rdev; struct twl_regulator_driver_data *drvdata; const struct of_device_id *match; u32 twl_errata = 0; match = of_match_device(twl_of_match, &pdev->dev); if (match) { info = match->data; id = info->desc.id; initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); drvdata = NULL; } else { id = pdev->id; initdata = pdev->dev.platform_data; for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) { info = twl_of_match[i].data; if (!info || info->desc.id != id) continue; break; } drvdata = initdata->driver_data; if (!drvdata) return -EINVAL; } if (!info) return -ENODEV; if (!initdata) return -EINVAL; if (drvdata) { /* copy the driver data into regulator data */ info->features = drvdata->features; twl_errata = drvdata->errata; info->data = drvdata->data; info->set_voltage = drvdata->set_voltage; info->get_voltage = drvdata->get_voltage; } /* Constrain board-specific capabilities according to what * this driver and the chip itself can actually do. */ c = &initdata->constraints; c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS; switch (id) { case TWL4030_REG_VIO: case TWL4030_REG_VDD1: case TWL4030_REG_VDD2: case TWL4030_REG_VPLL1: case TWL4030_REG_VINTANA1: case TWL4030_REG_VINTANA2: case TWL4030_REG_VINTDIG: c->always_on = true; break; default: break; } switch (id) { case TWL6032_REG_SMPS3: if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3) info->flags |= SMPS_EXTENDED_EN; if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3) info->flags |= SMPS_OFFSET_EN; break; case TWL6032_REG_SMPS4: if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4) info->flags |= SMPS_EXTENDED_EN; if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4) info->flags |= SMPS_OFFSET_EN; break; case TWL6032_REG_VIO: if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO) info->flags |= SMPS_EXTENDED_EN; if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO) info->flags |= SMPS_OFFSET_EN; break; case TWL6030_REG_SYSEN: case TWL6032_REG_LDO6: case TWL6032_REG_LDOLN: if (twl_errata & TWL6032_ERRATA_LDO_MUST_BE_ALWAYS_ON) { c->state_mem.enabled = true; c->state_mem.disabled = false; } break; } rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, pdev->dev.of_node); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "can't register %s, %ld\n", info->desc.name, PTR_ERR(rdev)); return PTR_ERR(rdev); } platform_set_drvdata(pdev, rdev); if (twl_class_is_4030()) twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, info->remap); /* NOTE: many regulators support short-circuit IRQs (presentable * as REGULATOR_OVER_CURRENT notifications?) configured via: * - SC_CONFIG * - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4) * - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2) * - IT_CONFIG */ return 0; }
static int __devinit twlreg_probe(struct platform_device *pdev) { int i; struct twlreg_info *info; struct regulator_init_data *initdata; struct regulation_constraints *c; struct regulator_dev *rdev; for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) { if (twl_regs[i].desc.id != pdev->id) continue; info = twl_regs + i; break; } if (!info) return -ENODEV; initdata = pdev->dev.platform_data; if (!initdata) return -EINVAL; /* copy the features into regulator data */ info->features = (unsigned long)initdata->driver_data; /* Constrain board-specific capabilities according to what * this driver and the chip itself can actually do. */ c = &initdata->constraints; c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS; switch (pdev->id) { case TWL4030_REG_VIO: case TWL4030_REG_VDD1: case TWL4030_REG_VDD2: case TWL4030_REG_VPLL1: case TWL4030_REG_VINTANA1: case TWL4030_REG_VINTANA2: case TWL4030_REG_VINTDIG: c->always_on = true; break; default: break; } switch (pdev->id) { case TWL6025_REG_SMPS3: if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3) info->flags |= SMPS_EXTENDED_EN; if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3) info->flags |= SMPS_OFFSET_EN; break; case TWL6025_REG_SMPS4: if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4) info->flags |= SMPS_EXTENDED_EN; if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4) info->flags |= SMPS_OFFSET_EN; break; case TWL6025_REG_VIO: if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO) info->flags |= SMPS_EXTENDED_EN; if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO) info->flags |= SMPS_OFFSET_EN; break; } rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "can't register %s, %ld\n", info->desc.name, PTR_ERR(rdev)); return PTR_ERR(rdev); } platform_set_drvdata(pdev, rdev); if (twl_class_is_4030()) twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, info->remap); /* NOTE: many regulators support short-circuit IRQs (presentable * as REGULATOR_OVER_CURRENT notifications?) configured via: * - SC_CONFIG * - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4) * - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2) * - IT_CONFIG */ return 0; }
static int __devinit twlreg_probe(struct platform_device *pdev) { int i, id; struct twlreg_info *info; struct regulator_init_data *initdata; struct regulation_constraints *c; struct regulator_dev *rdev; struct twl_regulator_driver_data *drvdata; const struct of_device_id *match; match = of_match_device(twl_of_match, &pdev->dev); if (match) { info = match->data; id = info->desc.id; initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); drvdata = NULL; } else { id = pdev->id; initdata = pdev->dev.platform_data; for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) { info = twl_of_match[i].data; if (!info || info->desc.id != id) continue; break; } drvdata = initdata->driver_data; if (!drvdata) return -EINVAL; } if (!info) return -ENODEV; if (!initdata) return -EINVAL; if (drvdata) { info->features = drvdata->features; info->data = drvdata->data; info->set_voltage = drvdata->set_voltage; info->get_voltage = drvdata->get_voltage; } c = &initdata->constraints; c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY; c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS; switch (id) { case TWL4030_REG_VIO: case TWL4030_REG_VDD1: case TWL4030_REG_VDD2: case TWL4030_REG_VPLL1: case TWL4030_REG_VINTANA1: case TWL4030_REG_VINTANA2: case TWL4030_REG_VINTDIG: c->always_on = true; break; default: break; } switch (id) { case TWL6025_REG_SMPS3: if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3) info->flags |= SMPS_EXTENDED_EN; if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3) info->flags |= SMPS_OFFSET_EN; break; case TWL6025_REG_SMPS4: if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4) info->flags |= SMPS_EXTENDED_EN; if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4) info->flags |= SMPS_OFFSET_EN; break; case TWL6025_REG_VIO: if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO) info->flags |= SMPS_EXTENDED_EN; if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO) info->flags |= SMPS_OFFSET_EN; break; } rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, pdev->dev.of_node); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "can't register %s, %ld\n", info->desc.name, PTR_ERR(rdev)); return PTR_ERR(rdev); } platform_set_drvdata(pdev, rdev); if (twl_class_is_4030()) twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, info->remap); return 0; }
static int twl_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; int ret = -EINVAL; int irq = platform_get_irq(pdev, 0); u8 rd_reg; if (irq <= 0) return ret; /* Initialize the register map */ if (twl_class_is_4030()) rtc_reg_map = (u8 *)twl4030_rtc_reg_map; else rtc_reg_map = (u8 *)twl6030_rtc_reg_map; ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (ret < 0) return ret; if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M) dev_warn(&pdev->dev, "Power up reset detected.\n"); if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M) dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n"); /* Clear RTC Power up reset and pending alarm interrupts */ ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG); if (ret < 0) return ret; if (twl_class_is_6030()) { twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK, REG_INT_MSK_LINE_A); twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK, REG_INT_MSK_STS_A); } dev_info(&pdev->dev, "Enabling TWL-RTC\n"); ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG); if (ret < 0) return ret; /* ensure interrupts are disabled, bootloaders can be strange */ ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG); if (ret < 0) dev_warn(&pdev->dev, "unable to disable interrupt\n"); /* init cached IRQ enable bits */ ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); if (ret < 0) return ret; device_init_wakeup(&pdev->dev, 1); rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &twl_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { dev_err(&pdev->dev, "can't register RTC device, err %ld\n", PTR_ERR(rtc)); return PTR_ERR(rtc); } ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, twl_rtc_interrupt, IRQF_TRIGGER_RISING | IRQF_ONESHOT, dev_name(&rtc->dev), rtc); if (ret < 0) { dev_err(&pdev->dev, "IRQ is not free.\n"); return ret; } platform_set_drvdata(pdev, rtc); return 0; }