void pm8xxx_atc_led_ctrl(struct device *dev, unsigned on) { u8 val; if (on) { pm8xxx_readb(dev, ATC_LED_SRC, &val); val |= ATC_LED_SRC_MASK; pm8xxx_writeb(dev, ATC_LED_SRC, val); } else { pm8xxx_readb(dev, ATC_LED_SRC, &val); val &= ~ATC_LED_SRC_MASK; pm8xxx_writeb(dev, ATC_LED_SRC, val); } }
static int pm8xxx_read_config_irq(struct pm_irq_chip *chip, u8 bp, u8 cp, u8 *r) { int rc; spin_lock(&chip->pm_irq_lock); rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL(chip->base_addr), bp); if (rc) { pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); goto bail; } rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG(chip->base_addr), cp); if (rc) pr_err("Failed Configuring IRQ rc=%d\n", rc); rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG(chip->base_addr), r); if (rc) pr_err("Failed reading IRQ rc=%d\n", rc); bail: spin_unlock(&chip->pm_irq_lock); return rc; }
static void long_press_delay(int mode) { const struct pm8xxx_pwrkey_platform_data *pdata = dev_get_platdata(&long_press_pdev->dev); unsigned int new_delay = (mode ? 2000000 : orig_delay); unsigned int delay; u8 pon_cntl; int err; delay = (new_delay << 6) / USEC_PER_SEC; delay = ilog2(delay); err = pm8xxx_readb(long_press_pdev->dev.parent, PON_CNTL_1, &pon_cntl); if (err < 0) { dev_err(&long_press_pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err); return; } pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK; pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK); if (pdata->pull_up) pon_cntl |= PON_CNTL_PULL_UP; else pon_cntl &= ~PON_CNTL_PULL_UP; err = pm8xxx_writeb(long_press_pdev->dev.parent, PON_CNTL_1, pon_cntl); if (err < 0) { dev_err(&long_press_pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err); return; } return; }
/** * pm8821_get_irq_stat - get the status of the irq line * @chip: pointer to identify a pmic irq controller * @irq: the irq number * * The pm8821 gpio and mpp rely on the interrupt block to read * the values on their pins. This function is to facilitate reading * the status of a gpio or an mpp line. The caller has to convert the * gpio number to irq number. * * RETURNS: * an int indicating the value read on that line */ int pm8821_get_irq_stat(struct pm_irq_chip *chip, int irq) { int pmirq, rc; u8 block, bits, bit, master; unsigned long flags; if (chip == NULL || irq < chip->irq_base || irq >= chip->irq_base + chip->num_irqs) return -EINVAL; pmirq = irq - chip->irq_base; block = pmirq >> 3; master = block / PM8821_BLOCKS_PER_MASTER; bit = pmirq % 8; block %= PM8821_BLOCKS_PER_MASTER; spin_lock_irqsave(&chip->pm_irq_lock, flags); rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS(chip->masters[master], block), &bits); if (rc) { pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n", irq, pmirq, block, rc); goto bail_out; } rc = (bits & BIT(bit)) ? 1 : 0; bail_out: spin_unlock_irqrestore(&chip->pm_irq_lock, flags); return rc; }
static int __devinit get_init_value(struct pm8xxx_led_data *led, u8 *val) { int rc = -1 , offset = 0; u16 addr = 0; switch (led->id) { case PM8XXX_ID_LED_KB_LIGHT: addr = SSBI_REG_ADDR_DRV_KEYPAD; break; case PM8XXX_ID_LED_0: case PM8XXX_ID_LED_1: case PM8XXX_ID_LED_2: offset = PM8XXX_LED_OFFSET(led->id); addr = SSBI_REG_ADDR_LED_CTRL(offset); break; case PM8XXX_ID_FLASH_LED_0: addr = SSBI_REG_ADDR_FLASH_DRV0; break; case PM8XXX_ID_FLASH_LED_1: addr = SSBI_REG_ADDR_FLASH_DRV1; break; default: return rc; } rc = pm8xxx_readb(led->dev->parent, addr, val); if (rc) dev_err(led->cdev.dev, "can't get led(%d) level rc=%d\n", led->id, rc); return rc; }
/* REVISIT: just for debugging, will be removed in final working version */ static void __dump_vib_regs(struct pm8xxx_vib *vib, char *msg) { u8 temp; VIB_DBG_LOG("%s\n", msg); pm8xxx_readb(vib->dev->parent, VIB_DRV, &temp); VIB_DBG_LOG("VIB_DRV - %X\n", temp); }
/* REVISIT: just for debugging, will be removed in final working version */ static void __dump_vib_regs(struct pm8xxx_vib *vib, char *msg) { u8 temp; VIB_DEBUG_LOG(KERN_INFO, "called.\n"); VIB_DEBUG_LOG(KERN_INFO, "%s\n", msg); pm8xxx_readb(vib->dev->parent, VIB_DRV, &temp); VIB_DEBUG_LOG(KERN_INFO, "VIB_DRV - %X\n", temp); }
static int pm_chg_get_fsm_state(struct pm8921_chg_chip *chip) { u8 temp; int err, ret = 0; temp = CAPTURE_FSM_STATE_CMD; err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp); if (err) { pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST); return err; } temp = READ_BANK_7; err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp); if (err) { pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST); return err; } err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp); if (err) { pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err); return err; } /* get the lower 4 bits */ ret = temp & 0xF; temp = READ_BANK_4; err = pm8xxx_writeb(chip->dev->parent, CHG_TEST, temp); if (err) { pr_err("Error %d writing %d to addr %d\n", err, temp, CHG_TEST); return err; } err = pm8xxx_readb(chip->dev->parent, CHG_TEST, &temp); if (err) { pr_err("pm8xxx_readb fail: addr=%03X, rc=%d\n", CHG_TEST, err); return err; } /* get the upper 1 bit */ ret |= (temp & 0x1) << 4; return ret; }
static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib, u8 *data, u16 reg) { int rc; rc = pm8xxx_readb(vib->dev->parent, reg, data); if (rc < 0) dev_warn(vib->dev, "Error reading pm8xxx reg 0x%x(0x%x)\n", reg, rc); return rc; }
static int pm8058_init_xo_buffer(struct pm8058_xo_buffer *xo) { int rc; /* Save the current control register state */ rc = pm8xxx_readb(xo->dev->parent, xo->ctrl_addr, &xo->ctrl_reg); if (rc) pr_err("FAIL: pm8xxx_read: rc=%d\n", rc); return rc; }
static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib, u8 *data, u16 reg) { int rc; rc = pm8xxx_readb(vib->dev->parent, reg, data); if (rc < 0) VIB_ERR_LOG("Error reading pm8xxx: %X - ret %X\n", reg, rc); return rc; }
static inline int pm8xxx_tm_read_ctrl(struct pm8xxx_tm_chip *chip, u8 *reg) { int rc; rc = pm8xxx_readb(chip->dev->parent, chip->cdata.reg_addr_temp_alarm_ctrl, reg); if (rc) pr_err("%s: pm8xxx_readb(0x%03X) failed, rc=%d\n", chip->cdata.tm_name, chip->cdata.reg_addr_temp_alarm_ctrl, rc); return rc; }
static int pm8821_read_block_irq(struct pm_irq_chip *chip, int master, u8 block, u8 *bits) { int rc; spin_lock(&chip->pm_irq_lock); rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS(chip->masters[master], block), bits); if (rc) pr_err("Failed Reading Status rc=%d\n", rc); spin_unlock(&chip->pm_irq_lock); return rc; }
static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib, u8 *data, u16 reg) { int rc; VIB_DEBUG_LOG(KERN_INFO, "called. reg=0x%02X\n", reg); rc = pm8xxx_readb(vib->dev->parent, reg, data); VIB_DEBUG_LOG(KERN_INFO, "pm8xxx_readb() called. rc=%d,reg=0x%02X,data=0x%02X\n", rc, reg, *data); if (rc < 0) VIB_LOG(KERN_ERR, "Error reading pm8xxx: %X - ret %X\n", reg, rc); VIB_DEBUG_LOG(KERN_INFO, "end.rc=%d\n", rc); return rc; }
/* * The RTC registers need to be read/written one byte at a time. This is a * hardware limitation. */ static int pm8xxx_read_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val, int base, int count) { int i, rc; struct device *parent = rtc_dd->rtc_dev->parent; for (i = 0; i < count; i++) { rc = pm8xxx_readb(parent, base + i, &rtc_val[i]); if (rc < 0) { dev_err(rtc_dd->rtc_dev, "PMIC read failed\n"); return rc; } } return 0; }
static int pm8xxx_spk_read(u16 addr) { int rc = 0; u8 val = 0; mutex_lock(&the_spk_chip->spk_mutex); rc = pm8xxx_readb(the_spk_chip->dev->parent, the_spk_chip->base + addr, &val); if (rc) { pr_err("pm8xxx_spk_readb() failed: rc=%d\n", rc); val = rc; } mutex_unlock(&the_spk_chip->spk_mutex); return val; }
static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip) { int rc; spin_lock(&chip->pm_irq_lock); rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); if (rc) { pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); goto bail; } rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip); if (rc) pr_err("Failed Reading Status rc=%d\n", rc); bail: spin_unlock(&chip->pm_irq_lock); return rc; }
static int pm8xxx_misc_masked_write(struct pm8xxx_misc_chip *chip, u16 addr, u8 mask, u8 val) { int rc; u8 reg; rc = pm8xxx_readb(chip->dev->parent, addr, ®); if (rc) { pr_err("pm8xxx_readb(0x%03X) failed, rc=%d\n", addr, rc); return rc; } reg &= ~mask; reg |= val & mask; rc = pm8xxx_writeb(chip->dev->parent, addr, reg); if (rc) pr_err("pm8xxx_writeb(0x%03X)=0x%02X failed, rc=%d\n", addr, reg, rc); return rc; }
static int pm_chg_masked_write(struct pm8921_chg_chip *chip, u16 addr, u8 mask, u8 val) { int rc; u8 reg; rc = pm8xxx_readb(chip->dev->parent, addr, ®); if (rc) { pr_err("pm8xxx_readb failed: addr=%03X, rc=%d\n", addr, rc); return rc; } reg &= ~mask; reg |= val & mask; rc = pm8xxx_writeb(chip->dev->parent, addr, reg); if (rc) { pr_err("pm8xxx_writeb failed: addr=%03X, rc=%d\n", addr, rc); return rc; } return 0; }
static int pm8xxx_debug_data_get(void *data, u64 *val) { struct pm8xxx_debug_device *debugdev = data; int rc; u8 reg; mutex_lock(&debugdev->debug_mutex); if (pm8xxx_debug_addr_is_valid(debugdev->addr)) { rc = pm8xxx_readb(debugdev->parent, debugdev->addr, ®); if (rc) pr_err("pm8xxx_readb(0x%03X) failed: rc=%d\n", debugdev->addr, rc); else *val = reg; } mutex_unlock(&debugdev->debug_mutex); return 0; }
/** * pm8xxx_get_irq_stat - get the status of the irq line * @chip: pointer to identify a pmic irq controller * @irq: the irq number * * The pm8xxx gpio and mpp rely on the interrupt block to read * the values on their pins. This function is to facilitate reading * the status of a gpio or an mpp line. The caller has to convert the * gpio number to irq number. * * RETURNS: * an int indicating the value read on that line */ int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq) { int pmirq, rc; u8 block, bits, bit; unsigned long flags; if (chip == NULL || irq < chip->irq_base || irq >= chip->irq_base + chip->num_irqs) return -EINVAL; pmirq = irq - chip->irq_base; block = pmirq / 8; bit = pmirq % 8; spin_lock_irqsave(&chip->pm_irq_lock, flags); rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL(chip->base_addr), block); if (rc) { pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n", irq, pmirq, block, rc); goto bail_out; } rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS(chip->base_addr), &bits); if (rc) { pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n", irq, pmirq, block, rc); goto bail_out; } rc = (bits & (1 << bit)) ? 1 : 0; bail_out: spin_unlock_irqrestore(&chip->pm_irq_lock, flags); return rc; }
static int pmic8xxx_set_pon1(struct device *dev, u32 debounce_us, bool pull_up) { int err; u32 delay; u8 pon_cntl; if (debounce_us > USEC_PER_SEC * 2 || debounce_us < USEC_PER_SEC / 64) { dev_err(dev, "invalid power key trigger delay\n"); return -EINVAL; } delay = (debounce_us << 6) / USEC_PER_SEC; delay = ilog2(delay); err = pm8xxx_readb(dev->parent, PON_CNTL_1, &pon_cntl); if (err < 0) { dev_err(dev, "failed reading PON_CNTL_1 err=%d\n", err); return err; } pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK; pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK); if (pull_up) pon_cntl |= PON_CNTL_PULL_UP; else pon_cntl &= ~PON_CNTL_PULL_UP; err = pm8xxx_writeb(dev->parent, PON_CNTL_1, pon_cntl); if (err < 0) { dev_err(dev, "failed writing PON_CNTL_1 err=%d\n", err); return err; } return 0; }
static int pm8821_irq_masked_write(struct pm_irq_chip *chip, u16 addr, u8 mask, u8 val) { int rc; u8 reg; rc = pm8xxx_readb(chip->dev, addr, ®); if (rc) { pr_err("read failed addr = %03X, rc = %d\n", addr, rc); return rc; } reg &= ~mask; reg |= val & mask; rc = pm8xxx_writeb(chip->dev, addr, reg); if (rc) { pr_err("write failed addr = %03X, rc = %d\n", addr, rc); return rc; } return 0; }
static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev) { struct input_dev *pwr; int key_release_irq = platform_get_irq(pdev, 0); int key_press_irq = platform_get_irq(pdev, 1); int err; unsigned int delay; u8 pon_cntl; struct pmic8xxx_pwrkey *pwrkey; const struct pm8xxx_pwrkey_platform_data *pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "power key platform data not supplied\n"); return -EINVAL; } /* Valid range of pwr key trigger delay is 1/64 sec to 2 seconds. */ if (pdata->kpd_trigger_delay_us > USEC_PER_SEC * 2 || pdata->kpd_trigger_delay_us < USEC_PER_SEC / 64) { dev_err(&pdev->dev, "invalid power key trigger delay\n"); return -EINVAL; } pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL); if (!pwrkey) return -ENOMEM; init_timer(&pwrkey->hibernate_timer); pwrkey->hibernate_timer.data = (unsigned long)pwrkey; pwrkey->hibernate_timer.function = hibernate_timer_handle; pwrkey->pdata = pdata; pwr = input_allocate_device(); if (!pwr) { dev_dbg(&pdev->dev, "Can't allocate power button\n"); err = -ENOMEM; goto free_pwrkey; } input_set_capability(pwr, EV_KEY, KEY_POWER); pwr->name = "pmic8xxx_pwrkey"; pwr->phys = "pmic8xxx_pwrkey/input0"; pwr->dev.parent = &pdev->dev; delay = (pdata->kpd_trigger_delay_us << 6) / USEC_PER_SEC; delay = ilog2(delay); err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err); goto free_input_dev; } pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK; pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK); if (pdata->pull_up) pon_cntl |= PON_CNTL_PULL_UP; else pon_cntl &= ~PON_CNTL_PULL_UP; err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err); goto free_input_dev; } err = input_register_device(pwr); if (err) { dev_dbg(&pdev->dev, "Can't register power key: %d\n", err); goto free_input_dev; } pwrkey->key_press_irq = key_press_irq; pwrkey->pwr = pwr; platform_set_drvdata(pdev, pwrkey); the_pwrkey = pwrkey; err = request_any_context_irq(key_press_irq, pwrkey_press_irq, IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey); if (err < 0) { dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", key_press_irq, err); goto unreg_input_dev; } err = request_any_context_irq(key_release_irq, pwrkey_release_irq, IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwrkey); if (err < 0) { dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", key_release_irq, err); goto free_press_irq; } device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; free_press_irq: free_irq(key_press_irq, NULL); unreg_input_dev: platform_set_drvdata(pdev, NULL); input_unregister_device(pwr); pwr = NULL; free_input_dev: input_free_device(pwr); free_pwrkey: kfree(pwrkey); return err; }
int pm8058_mic_bias_enable(bool enable) { int rc = 0; u8 reg; u16 mic_bias_addr = loc_dat->mic_bias_pf->mic_bias_addr; dev_dbg(loc_dat->dev, "%s - %s MIC Bias\n", __func__, enable ? "Enabling" : "Disabling"); LOCK(&loc_dat->lock); if (enable) { if (!loc_dat->mic_bias_enable_counter) { rc = pm8xxx_readb(loc_dat->dev->parent, mic_bias_addr, ®); if (rc < 0) { dev_err(loc_dat->dev, "pm8058 read failed\n"); goto error; } reg &= PM8058_OTHC_EN_SIG_MASK; reg |= (OTHC_SIGNAL_ALWAYS_ON << PM8058_OTHC_EN_SIG_SHIFT); rc = pm8xxx_writeb(loc_dat->dev->parent, mic_bias_addr, reg); if (rc < 0) { dev_err(loc_dat->dev, "pm8058 write failed\n"); goto error; } /*Wait a bit to get basicly stable ADC value*/ msleep(WAIT_MIC_BIAS_VOLTAGE_STABLE_DELAY); } loc_dat->mic_bias_enable_counter++; dev_vdbg(loc_dat->dev, "%s - Increasing MIC_BIAS_COUNTER %u\n", __func__, loc_dat->mic_bias_enable_counter); } else { if (1 <= loc_dat->mic_bias_enable_counter) { if (1 == loc_dat->mic_bias_enable_counter) { rc = pm8xxx_readb(loc_dat->dev->parent, mic_bias_addr, ®); if (rc < 0) { dev_err(loc_dat->dev, "pm8058 read failed\n"); goto error; } reg &= PM8058_OTHC_EN_SIG_MASK; reg |= (OTHC_SIGNAL_OFF << PM8058_OTHC_EN_SIG_SHIFT); rc = pm8xxx_writeb(loc_dat->dev->parent, mic_bias_addr, reg); if (rc < 0) { dev_err(loc_dat->dev, "pm8058 write failed\n"); goto error; } if (!rc) dev_dbg(loc_dat->dev, "%s - MIC Bias disabled\n", __func__); } loc_dat->mic_bias_enable_counter--; dev_vdbg(loc_dat->dev, "%s - Decreasing MIC_BIAS_COUNTER %u\n", __func__, loc_dat->mic_bias_enable_counter); } else { dev_vdbg(loc_dat->dev, "%s - No need to decrease " "MIC_BIAS_COUNTER\n", __func__); } } error: UNLOCK(&loc_dat->lock); if (rc) dev_err(loc_dat->dev, "Unable to toggle MIC Bias\n"); return rc; }
static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev) { struct input_dev *pwr; int key_release_irq = platform_get_irq(pdev, 0); int key_press_irq = platform_get_irq(pdev, 1); int err; unsigned int delay; u8 pon_cntl; struct pmic8xxx_pwrkey *pwrkey; const struct pm8xxx_pwrkey_platform_data *pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "power key platform data not supplied\n"); return -EINVAL; } if (pdata->kpd_trigger_delay_us > 62500) { dev_err(&pdev->dev, "invalid power key trigger delay\n"); return -EINVAL; } pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL); if (!pwrkey) return -ENOMEM; pwr = input_allocate_device(); if (!pwr) { dev_dbg(&pdev->dev, "Can't allocate power button\n"); err = -ENOMEM; goto free_pwrkey; } input_set_capability(pwr, EV_KEY, KEY_POWER); pwr->name = "pmic8xxx_pwrkey"; pwr->phys = "pmic8xxx_pwrkey/input0"; pwr->dev.parent = &pdev->dev; delay = (pdata->kpd_trigger_delay_us << 10) / USEC_PER_SEC; delay = 1 + ilog2(delay); err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err); goto free_input_dev; } pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK; pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK); if (pdata->pull_up) pon_cntl |= PON_CNTL_PULL_UP; else pon_cntl &= ~PON_CNTL_PULL_UP; err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err); goto free_input_dev; } err = input_register_device(pwr); if (err) { dev_dbg(&pdev->dev, "Can't register power key: %d\n", err); goto free_input_dev; } pwrkey->key_press_irq = key_press_irq; pwrkey->pwr = pwr; #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE sweep2wake_setdev(pwr); #endif platform_set_drvdata(pdev, pwrkey); platform_set_drvdata(pdev, pwrkey); err = request_irq(key_press_irq, pwrkey_press_irq, IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey); if (err < 0) { dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", key_press_irq, err); goto unreg_input_dev; } err = request_irq(key_release_irq, pwrkey_release_irq, IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwrkey); if (err < 0) { dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", key_release_irq, err); goto free_press_irq; } device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; free_press_irq: free_irq(key_press_irq, NULL); unreg_input_dev: platform_set_drvdata(pdev, NULL); input_unregister_device(pwr); pwr = NULL; free_input_dev: input_free_device(pwr); free_pwrkey: kfree(pwrkey); return err; }
/* * Set an SMPS regulator to be disabled in its CTRL register, but enabled * in the master enable register. Also set it's pull down enable bit. * Take care to make sure that the output voltage doesn't change if switching * from advanced mode to legacy mode. */ static int __pm8058_disable_smps_locally_set_pull_down(struct pm8xxx_misc_chip *chip, u16 ctrl_addr, u16 test2_addr, u16 master_enable_addr, u8 master_enable_bit) { int rc = 0; u8 vref_sel, vlow_sel, band, vprog, bank, reg; bank = PM8058_REGULATOR_BANK_SEL(7); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: pm8xxx_writeb(0x%03X) failed: rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_readb(chip->dev->parent, test2_addr, ®); if (rc) { pr_err("%s: FAIL pm8xxx_readb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } /* Check if in advanced mode. */ if ((reg & PM8058_SMPS_ADVANCED_MODE_MASK) == PM8058_SMPS_ADVANCED_MODE) { /* Determine current output voltage. */ rc = pm8xxx_readb(chip->dev->parent, ctrl_addr, ®); if (rc) { pr_err("%s: FAIL pm8xxx_readb(0x%03X): rc=%d\n", __func__, ctrl_addr, rc); goto done; } band = (reg & PM8058_SMPS_ADVANCED_BAND_MASK) >> PM8058_SMPS_ADVANCED_BAND_SHIFT; switch (band) { case 3: vref_sel = 0; vlow_sel = 0; break; case 2: vref_sel = PM8058_SMPS_LEGACY_VREF_SEL; vlow_sel = 0; break; case 1: vref_sel = PM8058_SMPS_LEGACY_VREF_SEL; vlow_sel = PM8058_SMPS_LEGACY_VLOW_SEL; break; default: pr_err("%s: regulator already disabled\n", __func__); return -EPERM; } vprog = (reg & PM8058_SMPS_ADVANCED_VPROG_MASK); /* Round up if fine step is in use. */ vprog = (vprog + 1) >> 1; if (vprog > PM8058_SMPS_LEGACY_VPROG_MASK) vprog = PM8058_SMPS_LEGACY_VPROG_MASK; /* Set VLOW_SEL bit. */ bank = PM8058_REGULATOR_BANK_SEL(1); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: FAIL pm8xxx_writeb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_misc_masked_write(chip, test2_addr, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_MASK | PM8058_SMPS_LEGACY_VLOW_SEL, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_SEL(1) | vlow_sel); if (rc) goto done; /* Switch to legacy mode */ bank = PM8058_REGULATOR_BANK_SEL(7); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: FAIL pm8xxx_writeb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_misc_masked_write(chip, test2_addr, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_MASK | PM8058_SMPS_ADVANCED_MODE_MASK, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_SEL(7) | PM8058_SMPS_LEGACY_MODE); if (rc) goto done; /* Enable locally, enable pull down, keep voltage the same. */ rc = pm8xxx_misc_masked_write(chip, ctrl_addr, PM8058_REGULATOR_ENABLE_MASK | PM8058_REGULATOR_PULL_DOWN_MASK | PM8058_SMPS_LEGACY_VREF_SEL | PM8058_SMPS_LEGACY_VPROG_MASK, PM8058_REGULATOR_ENABLE | PM8058_REGULATOR_PULL_DOWN_EN | vref_sel | vprog); if (rc) goto done; }
static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev) { struct input_dev *pwr; int key_release_irq = platform_get_irq(pdev, 0); int key_press_irq = platform_get_irq(pdev, 1); int err; unsigned int delay; u8 pon_cntl; struct pmic8xxx_pwrkey *pwrkey; const struct pm8xxx_pwrkey_platform_data *pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(&pdev->dev, "power key platform data not supplied\n"); return -EINVAL; } /* Valid range of pwr key trigger delay is 1/64 sec to 2 seconds. */ if (pdata->kpd_trigger_delay_us > USEC_PER_SEC * 2 || pdata->kpd_trigger_delay_us < USEC_PER_SEC / 64) { dev_err(&pdev->dev, "invalid power key trigger delay\n"); return -EINVAL; } pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL); if (!pwrkey) return -ENOMEM; pwrkey->pdata = pdata; pwr = input_allocate_device(); if (!pwr) { dev_dbg(&pdev->dev, "Can't allocate power button\n"); err = -ENOMEM; goto free_pwrkey; } input_set_capability(pwr, EV_KEY, KEY_POWER); pwr->name = "pmic8xxx_pwrkey"; pwr->phys = "pmic8xxx_pwrkey/input0"; pwr->dev.parent = &pdev->dev; delay = (pdata->kpd_trigger_delay_us << 6) / USEC_PER_SEC; delay = ilog2(delay); err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err); goto free_input_dev; } pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK; pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK); if (pdata->pull_up) pon_cntl |= PON_CNTL_PULL_UP; else pon_cntl &= ~PON_CNTL_PULL_UP; err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err); goto free_input_dev; } err = input_register_device(pwr); if (err) { dev_dbg(&pdev->dev, "Can't register power key: %d\n", err); goto free_input_dev; } pwrkey->key_press_irq = key_press_irq; pwrkey->key_release_irq = key_release_irq; pwrkey->pwr = pwr; platform_set_drvdata(pdev, pwrkey); /* check power key status during boot */ err = pm8xxx_read_irq_stat(pdev->dev.parent, key_press_irq); if (err < 0) { dev_err(&pdev->dev, "reading irq status failed\n"); goto unreg_input_dev; } pwrkey->press = !!err; if (pwrkey->press) { input_report_key(pwrkey->pwr, KEY_POWER, 1); input_sync(pwrkey->pwr); } #ifdef CONFIG_TOUCHSCREEN_PREVENT_SLEEP #ifdef CONFIG_TOUCHSCREEN_SWEEP2WAKE pr_info("[wake_up_display]: set device %s\n", pwr->name); #else power_on_display_dt2w(pwr); pr_info("[wake_up_display]: set device %s\n", pwr->name); #endif #endif err = request_any_context_irq(key_press_irq, pwrkey_press_irq, IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey); if (err < 0) { dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", key_press_irq, err); goto unreg_input_dev; } err = request_any_context_irq(key_release_irq, pwrkey_release_irq, IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwrkey); if (err < 0) { dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", key_release_irq, err); goto free_press_irq; } device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; free_press_irq: free_irq(key_press_irq, NULL); unreg_input_dev: platform_set_drvdata(pdev, NULL); input_unregister_device(pwr); pwr = NULL; free_input_dev: input_free_device(pwr); free_pwrkey: kfree(pwrkey); return err; }
static int __pm8058_disable_smps_locally_set_pull_down(struct pm8xxx_misc_chip *chip, u16 ctrl_addr, u16 test2_addr, u16 master_enable_addr, u8 master_enable_bit) { int rc = 0; u8 vref_sel, vlow_sel, band, vprog, bank, reg; bank = PM8058_REGULATOR_BANK_SEL(7); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: pm8xxx_writeb(0x%03X) failed: rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_readb(chip->dev->parent, test2_addr, ®); if (rc) { pr_err("%s: FAIL pm8xxx_readb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } if ((reg & PM8058_SMPS_ADVANCED_MODE_MASK) == PM8058_SMPS_ADVANCED_MODE) { rc = pm8xxx_readb(chip->dev->parent, ctrl_addr, ®); if (rc) { pr_err("%s: FAIL pm8xxx_readb(0x%03X): rc=%d\n", __func__, ctrl_addr, rc); goto done; } band = (reg & PM8058_SMPS_ADVANCED_BAND_MASK) >> PM8058_SMPS_ADVANCED_BAND_SHIFT; switch (band) { case 3: vref_sel = 0; vlow_sel = 0; break; case 2: vref_sel = PM8058_SMPS_LEGACY_VREF_SEL; vlow_sel = 0; break; case 1: vref_sel = PM8058_SMPS_LEGACY_VREF_SEL; vlow_sel = PM8058_SMPS_LEGACY_VLOW_SEL; break; default: pr_err("%s: regulator already disabled\n", __func__); return -EPERM; } vprog = (reg & PM8058_SMPS_ADVANCED_VPROG_MASK); vprog = (vprog + 1) >> 1; if (vprog > PM8058_SMPS_LEGACY_VPROG_MASK) vprog = PM8058_SMPS_LEGACY_VPROG_MASK; bank = PM8058_REGULATOR_BANK_SEL(1); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: FAIL pm8xxx_writeb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_misc_masked_write(chip, test2_addr, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_MASK | PM8058_SMPS_LEGACY_VLOW_SEL, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_SEL(1) | vlow_sel); if (rc) goto done; bank = PM8058_REGULATOR_BANK_SEL(7); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: FAIL pm8xxx_writeb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_misc_masked_write(chip, test2_addr, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_MASK | PM8058_SMPS_ADVANCED_MODE_MASK, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_SEL(7) | PM8058_SMPS_LEGACY_MODE); if (rc) goto done; rc = pm8xxx_misc_masked_write(chip, ctrl_addr, PM8058_REGULATOR_ENABLE_MASK | PM8058_REGULATOR_PULL_DOWN_MASK | PM8058_SMPS_LEGACY_VREF_SEL | PM8058_SMPS_LEGACY_VPROG_MASK, PM8058_REGULATOR_ENABLE | PM8058_REGULATOR_PULL_DOWN_EN | vref_sel | vprog); if (rc) goto done; }
static int pm8821_read_master_irq(const struct pm_irq_chip *chip, int m, u8 *master) { return pm8xxx_readb(chip->dev, chip->masters[m], master); }