static void gta02_bl_set_intensity(int intensity) { struct pcf50633 *pcf = gta02_pcf; int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); int ret; intensity >>= 2; /* * One code path that leads here is from a kernel panic. Trying to turn * the backlight on just gives us a nearly endless stream of complaints * and accomplishes nothing. We can't win. Just give up. * * In the unlikely event that there's another path leading here while * we're atomic, we print at least a warning. */ if (in_atomic()) { printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n"); return; } if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3)) old_intensity = 0; else old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); if (intensity == old_intensity) return; /* We can't do this anywhere else */ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5); /* * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60) * if seen, you have to re-enable the LED unit */ if (!intensity || !old_intensity) pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0); if (!intensity) /* illegal to set LEDOUT to 0 */ ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2); else ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, intensity); if (intensity) pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2); }
int pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val) { u8 reg; reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; return pcf50633_reg_set_bit_mask(pcf, reg, 0x07, val); }
static void gta02_bl_set_intensity(int intensity) { struct pcf50633 *pcf = gta02_pcf; int old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); /* We map 8-bit intensity to 6-bit intensity in hardware. */ intensity >>= 2; /* * This can happen during, eg, print of panic on blanked console, * but we can't service i2c without interrupts active, so abort. */ if (in_atomic()) { printk(KERN_ERR "gta02_bl_set_intensity called while atomic\n"); return; } old_intensity = pcf50633_reg_read(pcf, PCF50633_REG_LEDOUT); if (intensity == old_intensity) return; /* We can't do this anywhere else. */ pcf50633_reg_write(pcf, PCF50633_REG_LEDDIM, 5); if (!(pcf50633_reg_read(pcf, PCF50633_REG_LEDENA) & 3)) old_intensity = 0; /* * The PCF50633 cannot handle LEDOUT = 0 (datasheet p60) * if seen, you have to re-enable the LED unit. */ if (!intensity || !old_intensity) pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 0); /* Illegal to set LEDOUT to 0. */ if (!intensity) pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2); else pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, intensity); if (intensity) pcf50633_reg_write(pcf, PCF50633_REG_LEDENA, 2); }
int pcf50633_gpio_invert_set(struct pcf50633 *pcf, int gpio, int invert) { u8 val, reg; reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG; val = !!invert << 3; return pcf50633_reg_set_bit_mask(pcf, reg, 1 << 3, val); }
int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) { struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev); int ret = 0; u8 bits; int charging_start = 1; u8 mbcs2, chgmod; if (ma >= 1000) bits = PCF50633_MBCC7_USB_1000mA; else if (ma >= 500) bits = PCF50633_MBCC7_USB_500mA; else if (ma >= 100) bits = PCF50633_MBCC7_USB_100mA; else { bits = PCF50633_MBCC7_USB_SUSPEND; charging_start = 0; } ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7, PCF50633_MBCC7_USB_MASK, bits); if (ret) dev_err(pcf->dev, "error setting usb curlim to %d mA\n", ma); else dev_info(pcf->dev, "usb curlim to %d mA\n", ma); mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK); if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL) pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA); else pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME); mbc->usb_active = charging_start; power_supply_changed(&mbc->usb); return ret; }
int pcf50633_gpio_power_supply_set(struct pcf50633 *pcf, int gpio, int regulator, int on) { u8 reg, val, mask; reg = pcf50633_regulator_registers[regulator] + 1; val = !!on << (gpio - PCF50633_GPIO1); mask = 1 << (gpio - PCF50633_GPIO1); return pcf50633_reg_set_bit_mask(pcf, reg, mask, val); }
static int pcf50633_regulator_disable(struct regulator_dev *rdev) { struct pcf50633 *pcf = rdev_get_drvdata(rdev); int regulator_id; u8 regnr; regulator_id = rdev_get_id(rdev); if (regulator_id >= PCF50633_NUM_REGULATORS) return -EINVAL; /* the *ENA register is always one after the *OUT register */ regnr = pcf50633_regulator_registers[regulator_id] + 1; return pcf50633_reg_set_bit_mask(pcf, regnr, PCF50633_REGULATOR_ON, 0); }
static void pcf50633_mbc_charging_restart(struct work_struct *work) { struct pcf50633_mbc *mbc; u8 mbcs2, chgmod; mbc = container_of(work, struct pcf50633_mbc, charging_restart_work.work); mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2); chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK); if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL) return; pcf50633_reg_set_bit_mask(mbc->pcf, PCF50633_REG_MBCC1, PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME); mbc->usb_active = 1; power_supply_changed(&mbc->usb); dev_info(mbc->pcf->dev, "Charging restarted\n"); }
static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask) { u8 reg, bit; int ret = 0, idx; idx = irq >> 3; reg = PCF50633_REG_INT1M + idx; bit = 1 << (irq & 0x07); pcf50633_reg_set_bit_mask(pcf, reg, bit, mask ? bit : 0); mutex_lock(&pcf->lock); if (mask) pcf->mask_regs[idx] |= bit; else pcf->mask_regs[idx] &= ~bit; mutex_unlock(&pcf->lock); return ret; }
static irqreturn_t pcf50633_irq(int irq, void *data) { struct pcf50633 *pcf = data; int ret, i, j; u8 pcf_int[5], chgstat; /* Read the 5 INT regs in one transaction */ ret = pcf50633_read_block(pcf, PCF50633_REG_INT1, ARRAY_SIZE(pcf_int), pcf_int); if (ret != ARRAY_SIZE(pcf_int)) { dev_err(pcf->dev, "Error reading INT registers\n"); /* * If this doesn't ACK the interrupt to the chip, we'll be * called once again as we're level triggered. */ goto out; } /* defeat 8s death from lowsys on A5 */ pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04); /* We immediately read the usb and adapter status. We thus make sure * only of USBINS/USBREM IRQ handlers are called */ if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) { chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); if (chgstat & (0x3 << 4)) pcf_int[0] &= ~PCF50633_INT1_USBREM; else pcf_int[0] &= ~PCF50633_INT1_USBINS; } /* Make sure only one of ADPINS or ADPREM is set */ if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) { chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); if (chgstat & (0x3 << 4)) pcf_int[0] &= ~PCF50633_INT1_ADPREM; else pcf_int[0] &= ~PCF50633_INT1_ADPINS; } dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x " "INT4=0x%02x INT5=0x%02x\n", pcf_int[0], pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]); /* Some revisions of the chip don't have a 8s standby mode on * ONKEY1S press. We try to manually do it in such cases. */ if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) { dev_info(pcf->dev, "ONKEY1S held for %d secs\n", pcf->onkey1s_held); if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT) if (pcf->pdata->force_shutdown) pcf->pdata->force_shutdown(pcf); } if (pcf_int[2] & PCF50633_INT3_ONKEY1S) { dev_info(pcf->dev, "ONKEY1S held\n"); pcf->onkey1s_held = 1 ; /* Unmask IRQ_SECOND */ pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M, PCF50633_INT1_SECOND); /* Unmask IRQ_ONKEYR */ pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M, PCF50633_INT2_ONKEYR); } if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) { pcf->onkey1s_held = 0; /* Mask SECOND and ONKEYR interrupts */ if (pcf->mask_regs[0] & PCF50633_INT1_SECOND) pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_INT1M, PCF50633_INT1_SECOND, PCF50633_INT1_SECOND); if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR) pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_INT2M, PCF50633_INT2_ONKEYR, PCF50633_INT2_ONKEYR); } /* Have we just resumed ? */ if (pcf->is_suspended) { pcf->is_suspended = 0; /* Set the resume reason filtering out non resumers */ for (i = 0; i < ARRAY_SIZE(pcf_int); i++) pcf->resume_reason[i] = pcf_int[i] & pcf->pdata->resumers[i]; /* Make sure we don't pass on any ONKEY events to * userspace now */ pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF); } for (i = 0; i < ARRAY_SIZE(pcf_int); i++) { /* Unset masked interrupts */ pcf_int[i] &= ~pcf->mask_regs[i]; for (j = 0; j < 8 ; j++) if (pcf_int[i] & (1 << j)) pcf50633_irq_call_handler(pcf, (i * 8) + j); } out: return IRQ_HANDLED; }
static void gta02_pmu_force_shutdown(struct pcf50633 *pcf) { pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_OOCSHDWN, PCF50633_OOCSHDWN_GOSTDBY, PCF50633_OOCSHDWN_GOSTDBY); }
static void gta02_poweroff(void) { pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, PCF50633_OOCSHDWN_GOSTDBY, PCF50633_OOCSHDWN_GOSTDBY); }
int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma) { struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev); int ret = 0; u8 bits; u8 mbcs2, chgmod; unsigned int mbcc5; if (ma >= 1000) { bits = PCF50633_MBCC7_USB_1000mA; ma = 1000; } else if (ma >= 500) { bits = PCF50633_MBCC7_USB_500mA; ma = 500; } else if (ma >= 100) { bits = PCF50633_MBCC7_USB_100mA; ma = 100; } else { bits = PCF50633_MBCC7_USB_SUSPEND; ma = 0; } ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7, PCF50633_MBCC7_USB_MASK, bits); if (ret) dev_err(pcf->dev, "error setting usb curlim to %d mA\n", ma); else dev_info(pcf->dev, "usb curlim to %d mA\n", ma); /* * We limit the charging current to be the USB current limit. * The reason is that on pcf50633, when it enters PMU Standby mode, * which it does when the device goes "off", the USB current limit * reverts to the variant default. In at least one common case, that * default is 500mA. By setting the charging current to be the same * as the USB limit we set here before PMU standby, we enforce it only * using the correct amount of current even when the USB current limit * gets reset to the wrong thing */ if (mbc->pcf->pdata->charger_reference_current_ma) { mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma; if (mbcc5 > 255) mbcc5 = 255; pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5); } mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2); chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK); /* If chgmod == BATFULL, setting chgena has no effect. * Datasheet says we need to set resume instead but when autoresume is * used resume doesn't work. Clear and set chgena instead. */ if (chgmod != PCF50633_MBCS2_MBC_BAT_FULL) pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA); else { pcf50633_reg_clear_bits(pcf, PCF50633_REG_MBCC1, PCF50633_MBCC1_CHGENA); pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC1, PCF50633_MBCC1_CHGENA, PCF50633_MBCC1_CHGENA); } power_supply_changed(mbc->usb); return ret; }