mfd: pm8058: Modify pm8058 subdevices to pm8xxx interface
Move the following subdevices to use the pm8xxx interface -
mpp, irq, gpio, keypad, power-key, leds, othc, vibrator,
rtc, batt-alarm, thermal, upl, nfc, pwm, xoadc, regulators,
xo-buffers, charger.
This allows usage of a common driver for modules which are same
across multiple PM8XXX PMICs. It also provides flexibility
to add/remove subdevices for multiple board configurations.
Change-Id: Id9795552fc9f4a2c920c070babfaef1f4cd6ca61
Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
diff --git a/drivers/gpio/pm8xxx-gpio.c b/drivers/gpio/pm8xxx-gpio.c
index 377510f..53305e3 100644
--- a/drivers/gpio/pm8xxx-gpio.c
+++ b/drivers/gpio/pm8xxx-gpio.c
@@ -432,7 +432,7 @@
return rc;
}
-EXPORT_SYMBOL_GPL(pm8xxx_gpio_config);
+EXPORT_SYMBOL(pm8xxx_gpio_config);
static struct platform_driver pm_gpio_driver = {
.probe = pm_gpio_probe,
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 0822866..6db0da1 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -401,17 +401,6 @@
Say Y here to enable the driver for the keypad matrix interface
on the Qualcomm PM8058 power management I/C device.
-config KEYBOARD_PMIC8XXX
- tristate "Qualcomm PMIC8XXX keypad support"
- depends on MFD_PM8XXX
- help
- Say Y here if you want to enable the driver for the PMIC8XXX
- keypad provided as a reference design from Qualcomm. This is intended
- to support upto 18x8 matrix based keypad design.
-
- To compile this driver as a module, choose M here: the module will
- be called pmic8xxx-keypad.
-
config KEYBOARD_PXA27x
tristate "PXA27x/PXA3xx keypad support"
depends on PXA27x || PXA3xx || ARCH_MMP
diff --git a/drivers/input/misc/pmic8058-othc.c b/drivers/input/misc/pmic8058-othc.c
index c6be119..a28e8e1 100644
--- a/drivers/input/misc/pmic8058-othc.c
+++ b/drivers/input/misc/pmic8058-othc.c
@@ -27,7 +27,7 @@
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
-#include <linux/mfd/pmic8058.h>
+#include <linux/mfd/pm8xxx/core.h>
#include <linux/pmic8058-othc.h>
#include <linux/msm_adc.h>
@@ -68,6 +68,7 @@
void *adc_handle;
void *accessory_adc_handle;
spinlock_t lock;
+ struct device *dev;
struct regulator *othc_vreg;
struct input_dev *othc_ipd;
struct switch_dev othc_sdev;
@@ -75,7 +76,6 @@
struct othc_accessory_info *accessory_info;
struct hrtimer timer;
struct othc_n_switch_config *switch_config;
- struct pm8058_chip *pm_chip;
struct work_struct switch_work;
struct delayed_work detect_work;
struct delayed_work hs_work;
@@ -149,7 +149,7 @@
return -EINVAL;
}
- rc = pm8058_read(dd->pm_chip, dd->othc_base + 1, ®, 1);
+ rc = pm8xxx_readb(dd->dev->parent, dd->othc_base + 1, ®);
if (rc < 0) {
pr_err("PM8058 read failed\n");
return rc;
@@ -158,7 +158,7 @@
reg &= PM8058_OTHC_EN_SIG_MASK;
reg |= (enable << PM8058_OTHC_EN_SIG_SHIFT);
- rc = pm8058_write(dd->pm_chip, dd->othc_base + 1, ®, 1);
+ rc = pm8xxx_writeb(dd->dev->parent, dd->othc_base + 1, reg);
if (rc < 0) {
pr_err("PM8058 write failed\n");
return rc;
@@ -446,7 +446,7 @@
if (dd->ir_gpio < 0) {
/* Check the MIC_BIAS status */
- rc = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_ir);
+ rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
if (rc < 0) {
pr_err("Unable to read IR status from PMIC\n");
goto fail_ir_accessory;
@@ -462,7 +462,7 @@
}
/* Check the switch status */
- rc = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_sw);
+ rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_sw);
if (rc < 0) {
pr_err("Unable to read SWITCH status\n");
goto fail_ir_accessory;
@@ -576,7 +576,7 @@
}
spin_unlock_irqrestore(&dd->lock, flags);
- level = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_sw);
+ level = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_sw);
if (level < 0) {
pr_err("Unable to read IRQ status register\n");
return IRQ_HANDLED;
@@ -641,7 +641,7 @@
disable_irq_nosync(dd->othc_irq_ir);
/* Check the MIC_BIAS status, to check if inserted or removed */
- rc = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_ir);
+ rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
if (rc < 0) {
pr_err("Unable to read IR status\n");
goto fail_ir;
@@ -666,7 +666,7 @@
/* Intialize the OTHC module */
/* Control Register 1*/
- rc = pm8058_read(dd->pm_chip, base_addr, ®, 1);
+ rc = pm8xxx_readb(dd->dev->parent, base_addr, ®);
if (rc < 0) {
pr_err("PM8058 read failed\n");
return rc;
@@ -676,14 +676,14 @@
value = (hsed_config->othc_highcurr_thresh_uA / 100) - 2;
reg = (reg & PM8058_OTHC_HIGH_CURR_MASK) | value;
- rc = pm8058_write(dd->pm_chip, base_addr, ®, 1);
+ rc = pm8xxx_writeb(dd->dev->parent, base_addr, reg);
if (rc < 0) {
pr_err("PM8058 read failed\n");
return rc;
}
/* Control register 2*/
- rc = pm8058_read(dd->pm_chip, base_addr + 1, ®, 1);
+ rc = pm8xxx_readb(dd->dev->parent, base_addr + 1, ®);
if (rc < 0) {
pr_err("PM8058 read failed\n");
return rc;
@@ -718,14 +718,14 @@
}
reg = (reg & PM8058_OTHC_CLK_PREDIV_MASK) | (value - 1);
- rc = pm8058_write(dd->pm_chip, base_addr + 1, ®, 1);
+ rc = pm8xxx_writeb(dd->dev->parent, base_addr + 1, reg);
if (rc < 0) {
pr_err("PM8058 read failed\n");
return rc;
}
/* Control register 3 */
- rc = pm8058_read(dd->pm_chip, base_addr + 2 , ®, 1);
+ rc = pm8xxx_readb(dd->dev->parent, base_addr + 2 , ®);
if (rc < 0) {
pr_err("PM8058 read failed\n");
return rc;
@@ -748,7 +748,7 @@
}
reg = (reg & PM8058_OTHC_PERIOD_CLK_MASK) | value;
- rc = pm8058_write(dd->pm_chip, base_addr + 2, ®, 1);
+ rc = pm8xxx_writeb(dd->dev->parent, base_addr + 2, reg);
if (rc < 0) {
pr_err("PM8058 read failed\n");
return rc;
@@ -1006,7 +1006,7 @@
/* Check if the accessory is already inserted during boot up */
if (dd->ir_gpio < 0) {
- rc = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_ir);
+ rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
if (rc < 0) {
pr_err("Unable to get accessory status at boot\n");
goto fail_ir_status;
@@ -1061,22 +1061,9 @@
{
int rc;
struct pm8058_othc *dd;
- struct pm8058_chip *chip;
struct resource *res;
struct pmic8058_othc_config_pdata *pdata = pd->dev.platform_data;
- chip = dev_get_drvdata(pd->dev.parent);
- if (chip == NULL) {
- pr_err("Invalid driver information\n");
- return -EINVAL;
- }
-
- /* Check PMIC8058 version. A0 version is not supported */
- if (pm8058_rev(chip) == PM_8058_REV_1p0) {
- pr_err("PMIC8058 version not supported\n");
- return -ENODEV;
- }
-
if (pdata == NULL) {
pr_err("Platform data not present\n");
return -EINVAL;
@@ -1101,8 +1088,8 @@
goto fail_get_res;
}
+ dd->dev = &pd->dev;
dd->othc_pdata = pdata;
- dd->pm_chip = chip;
dd->othc_base = res->start;
if (pdata->micbias_regulator == NULL) {
pr_err("OTHC regulator not specified\n");
diff --git a/drivers/leds/leds-pmic8058.c b/drivers/leds/leds-pmic8058.c
index d1aed3f..3b3a24a 100644
--- a/drivers/leds/leds-pmic8058.c
+++ b/drivers/leds/leds-pmic8058.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,7 +15,7 @@
#include <linux/leds.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
-#include <linux/mfd/pmic8058.h>
+#include <linux/mfd/pm8xxx/core.h>
#include <linux/leds-pmic8058.h>
#define SSBI_REG_ADDR_DRV_KEYPAD 0x48
@@ -41,11 +41,11 @@
#define PMIC8058_LED_OFFSET(id) ((id) - PMIC8058_ID_LED_0)
struct pmic8058_led_data {
+ struct device *dev;
struct led_classdev cdev;
int id;
enum led_brightness brightness;
u8 flags;
- struct pm8058_chip *pm_chip;
struct work_struct work;
struct mutex lock;
spinlock_t value_lock;
@@ -72,8 +72,8 @@
led->reg_kp |= level;
spin_unlock_irqrestore(&led->value_lock, flags);
- rc = pm8058_write(led->pm_chip, SSBI_REG_ADDR_DRV_KEYPAD,
- &led->reg_kp, 1);
+ rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_DRV_KEYPAD,
+ led->reg_kp);
if (rc)
pr_err("%s: can't set keypad backlight level\n", __func__);
}
@@ -105,8 +105,8 @@
tmp |= level;
spin_unlock_irqrestore(&led->value_lock, flags);
- rc = pm8058_write(led->pm_chip, SSBI_REG_ADDR_LED_CTRL(offset),
- &tmp, 1);
+ rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset),
+ tmp);
if (rc) {
dev_err(led->cdev.dev, "can't set (%d) led value\n",
led->id);
@@ -159,7 +159,7 @@
}
spin_unlock_irqrestore(&led->value_lock, flags);
- rc = pm8058_write(led->pm_chip, reg_addr, ®_flash_led, 1);
+ rc = pm8xxx_writeb(led->dev->parent, reg_addr, reg_flash_led);
if (rc)
pr_err("%s: can't set flash led%d level %d\n", __func__,
led->id, rc);
@@ -294,46 +294,38 @@
struct pmic8058_led_data *led_dat;
struct pmic8058_led *curr_led;
int rc, i = 0;
- struct pm8058_chip *pm_chip;
u8 reg_kp;
u8 reg_led_ctrl[3];
u8 reg_flash_led0;
u8 reg_flash_led1;
- pm_chip = dev_get_drvdata(pdev->dev.parent);
- if (pm_chip == NULL) {
- dev_err(&pdev->dev, "no parent data passed in\n");
- return -EFAULT;
- }
-
if (pdata == NULL) {
dev_err(&pdev->dev, "platform data not supplied\n");
return -EINVAL;
}
- rc = pm8058_read(pm_chip, SSBI_REG_ADDR_DRV_KEYPAD, ®_kp,
- 1);
+ rc = pm8xxx_readb(pdev->dev.parent, SSBI_REG_ADDR_DRV_KEYPAD, ®_kp);
if (rc) {
dev_err(&pdev->dev, "can't get keypad backlight level\n");
goto err_reg_read;
}
- rc = pm8058_read(pm_chip, SSBI_REG_ADDR_LED_CTRL_BASE,
- reg_led_ctrl, 3);
+ rc = pm8xxx_read_buf(pdev->dev.parent, SSBI_REG_ADDR_LED_CTRL_BASE,
+ reg_led_ctrl, 3);
if (rc) {
dev_err(&pdev->dev, "can't get led levels\n");
goto err_reg_read;
}
- rc = pm8058_read(pm_chip, SSBI_REG_ADDR_FLASH_DRV0,
- ®_flash_led0, 1);
+ rc = pm8xxx_readb(pdev->dev.parent, SSBI_REG_ADDR_FLASH_DRV0,
+ ®_flash_led0);
if (rc) {
dev_err(&pdev->dev, "can't read flash led0\n");
goto err_reg_read;
}
- rc = pm8058_read(pm_chip, SSBI_REG_ADDR_FLASH_DRV1,
- ®_flash_led1, 1);
+ rc = pm8xxx_readb(pdev->dev.parent, SSBI_REG_ADDR_FLASH_DRV1,
+ ®_flash_led1);
if (rc) {
dev_err(&pdev->dev, "can't get flash led1\n");
goto err_reg_read;
@@ -366,7 +358,7 @@
goto fail_id_check;
}
- led_dat->pm_chip = pm_chip;
+ led_dat->dev = &pdev->dev;
mutex_init(&led_dat->lock);
spin_lock_init(&led_dat->value_lock);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a4feb838..c27fea6 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -157,6 +157,7 @@
tristate "PMIC8058 Power Management chip"
depends on MSM_SSBI
select MFD_CORE
+ select MFD_PM8XXX
select MSM_SHOW_RESUME_IRQ
help
Say yes here for Qualcomm PM8058 chip.
diff --git a/drivers/mfd/pmic8058.c b/drivers/mfd/pmic8058.c
index 85c8a9d..77e393e 100644
--- a/drivers/mfd/pmic8058.c
+++ b/drivers/mfd/pmic8058.c
@@ -14,55 +14,32 @@
* Qualcomm PMIC8058 driver
*
*/
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/ratelimit.h>
-#include <linux/kthread.h>
+#include <linux/irq.h>
#include <linux/msm_ssbi.h>
#include <linux/mfd/core.h>
#include <linux/mfd/pmic8058.h>
-#include <linux/platform_device.h>
-#include <linux/ratelimit.h>
-#include <linux/slab.h>
-#include <linux/debugfs.h>
-#include <linux/irq.h>
-#include <linux/syscore_ops.h>
-#include <linux/gpio.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/msm_adc.h>
+
+#define REG_MPP_BASE 0x50
/* PMIC8058 Revision */
-#define SSBI_REG_REV 0x002 /* PMIC4 revision */
+#define PM8058_REG_REV 0x002 /* PMIC4 revision */
+#define PM8058_VERSION_MASK 0xF0
+#define PM8058_REVISION_MASK 0x0F
+#define PM8058_VERSION_VALUE 0xE0
-/* PMIC8058 IRQ */
-#define SSBI_REG_ADDR_IRQ_BASE 0x1BB
+/* PMIC 8058 Battery Alarm SSBI registers */
+#define REG_BATT_ALARM_THRESH 0x023
+#define REG_BATT_ALARM_CTRL1 0x024
+#define REG_BATT_ALARM_CTRL2 0x0AA
+#define REG_BATT_ALARM_PWM_CTRL 0x0A3
-#define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0)
-#define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1)
-#define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2)
-#define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3)
-#define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4)
-#define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5)
-#define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6)
-#define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7)
-#define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8)
-
-#define PM8058_IRQF_LVL_SEL 0x01 /* level select */
-#define PM8058_IRQF_MASK_FE 0x02 /* mask falling edge */
-#define PM8058_IRQF_MASK_RE 0x04 /* mask rising edge */
-#define PM8058_IRQF_CLR 0x08 /* clear interrupt */
-#define PM8058_IRQF_BITS_MASK 0x70
-#define PM8058_IRQF_BITS_SHIFT 4
-#define PM8058_IRQF_WRITE 0x80
-
-#define PM8058_IRQF_MASK_ALL (PM8058_IRQF_MASK_FE | \
- PM8058_IRQF_MASK_RE)
-#define PM8058_IRQF_W_C_M (PM8058_IRQF_WRITE | \
- PM8058_IRQF_CLR | \
- PM8058_IRQF_MASK_ALL)
-
-/* MISC register */
-#define SSBI_REG_ADDR_MISC 0x1CC
+#define REG_TEMP_ALRM_CTRL 0x1B
+#define REG_TEMP_ALRM_PWM 0x9B
/* PON CNTL 1 register */
#define SSBI_REG_ADDR_PON_CNTL_1 0x01C
@@ -138,53 +115,32 @@
/* GP_TEST1 register */
#define SSBI_REG_ADDR_GP_TEST_1 0x07A
-/* IRQ */
-#define MAX_PM_IRQ 256
-#define MAX_PM_BLOCKS (MAX_PM_IRQ / 8 + 1)
-#define MAX_PM_MASTERS (MAX_PM_BLOCKS / 8 + 1)
+#define PM8058_RTC_BASE 0x1E8
+#define PM8058_OTHC_CNTR_BASE0 0xA0
+#define PM8058_OTHC_CNTR_BASE1 0x134
+#define PM8058_OTHC_CNTR_BASE2 0x137
+
+#define SINGLE_IRQ_RESOURCE(_name, _irq) \
+{ \
+ .name = _name, \
+ .start = _irq, \
+ .end = _irq, \
+ .flags = IORESOURCE_IRQ, \
+}
struct pm8058_chip {
struct pm8058_platform_data pdata;
struct device *dev;
+ struct pm_irq_chip *irq_chip;
+ struct mfd_cell *mfd_regulators, *mfd_xo_buffers;
- u8 irqs_allowed[MAX_PM_BLOCKS];
- u8 blocks_allowed[MAX_PM_MASTERS];
- u8 masters_allowed;
- int pm_max_irq;
- int pm_max_blocks;
- int pm_max_masters;
-
- u8 config[MAX_PM_IRQ];
- u8 bus_unlock_config[MAX_PM_IRQ];
- u8 wake_enable[MAX_PM_IRQ];
- u16 count_wakeable;
-
- u8 revision;
+ u8 revision;
struct mutex pm_lock;
};
-#if defined(CONFIG_DEBUG_FS)
-struct pm8058_dbg_device {
- struct mutex dbg_mutex;
- struct pm8058_chip *pm_chip;
- struct dentry *dent;
- int addr;
-};
-
-static struct pm8058_dbg_device *pmic_dbg_device;
-#endif
-
static struct pm8058_chip *pmic_chip;
-/* Helper Functions */
-DEFINE_RATELIMIT_STATE(pm8058_msg_ratelimit, 60 * HZ, 10);
-
-static inline int pm8058_can_print(void)
-{
- return __ratelimit(&pm8058_msg_ratelimit);
-}
-
static inline int
ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
{
@@ -223,111 +179,6 @@
return rc;
}
-/* External APIs */
-int pm8058_rev(struct pm8058_chip *chip)
-{
- if (chip == NULL)
- return -EINVAL;
-
- return chip->revision;
-}
-EXPORT_SYMBOL(pm8058_rev);
-
-int pm8058_irq_get_rt_status(struct pm8058_chip *chip, int irq)
-{
- int rc;
- u8 block, bits, bit;
-
- if (chip == NULL || irq < chip->pdata.irq_base ||
- irq >= chip->pdata.irq_base + MAX_PM_IRQ)
- return -EINVAL;
-
- irq -= chip->pdata.irq_base;
-
- block = irq / 8;
- bit = irq % 8;
-
- mutex_lock(&chip->pm_lock);
-
- rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, &block, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
- __func__, rc);
- goto bail_out;
- }
-
- rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_read(): rc=%d (Read RT Status)\n",
- __func__, rc);
- goto bail_out;
- }
-
- rc = (bits & (1 << bit)) ? 1 : 0;
-
-bail_out:
- mutex_unlock(&chip->pm_lock);
-
- return rc;
-}
-EXPORT_SYMBOL(pm8058_irq_get_rt_status);
-
-int pm8058_read(struct pm8058_chip *chip, u16 addr, u8 *values,
- unsigned int len)
-{
- if (chip == NULL)
- return -EINVAL;
-
- return ssbi_read(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8058_read);
-
-int pm8058_write(struct pm8058_chip *chip, u16 addr, u8 *values,
- unsigned int len)
-{
- if (chip == NULL)
- return -EINVAL;
-
- return ssbi_write(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8058_write);
-
-int pm8058_misc_control(struct pm8058_chip *chip, int mask, int flag)
-{
- int rc;
- u8 misc;
-
- if (chip == NULL)
- chip = pmic_chip; /* for calls from non child */
- if (chip == NULL)
- return -ENODEV;
-
- mutex_lock(&chip->pm_lock);
-
- rc = ssbi_read(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
- __func__, SSBI_REG_ADDR_MISC, rc);
- goto get_out;
- }
-
- misc &= ~mask;
- misc |= flag;
-
- rc = ssbi_write(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
- __func__, SSBI_REG_ADDR_MISC, misc, rc);
- goto get_out;
- }
-
-get_out:
- mutex_unlock(&chip->pm_lock);
-
- return rc;
-}
-EXPORT_SYMBOL(pm8058_misc_control);
-
/**
* pm8058_smpl_control - enables/disables SMPL detection
* @enable: 0 = shutdown PMIC on power loss, 1 = reset PMIC on power loss
@@ -713,765 +564,694 @@
}
EXPORT_SYMBOL(pm8058_hard_reset_config);
-/* Internal functions */
-static inline int
-pm8058_config_irq(struct pm8058_chip *chip, u8 *bp, u8 *cp)
+static int pm8058_readb(const struct device *dev, u16 addr, u8 *val)
{
- int rc;
+ const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+ const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
- rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
- if (rc) {
- pr_err("%s: ssbi_write: rc=%d (Select block)\n",
- __func__, rc);
- goto bail_out;
- }
-
- rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp, 1);
- if (rc)
- pr_err("%s: ssbi_write: rc=%d (Configure IRQ)\n",
- __func__, rc);
-
-bail_out:
- return rc;
+ return msm_ssbi_read(pmic->dev->parent, addr, val, 1);
}
-static void pm8058_irq_mask(struct irq_data *data)
+static int pm8058_writeb(const struct device *dev, u16 addr, u8 val)
{
- int master, irq_bit;
- struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
- u8 block, config;
- unsigned int irq = data->irq;
+ const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+ const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
- irq -= chip->pdata.irq_base;
- block = irq / 8;
- master = block / 8;
- irq_bit = irq % 8;
-
- chip->irqs_allowed[block] &= ~(1 << irq_bit);
- if (!chip->irqs_allowed[block]) {
- chip->blocks_allowed[master] &= ~(1 << (block % 8));
-
- if (!chip->blocks_allowed[master])
- chip->masters_allowed &= ~(1 << master);
- }
-
- config = PM8058_IRQF_WRITE | chip->config[irq] |
- PM8058_IRQF_MASK_FE | PM8058_IRQF_MASK_RE;
- chip->bus_unlock_config[irq] = config;
+ return msm_ssbi_write(pmic->dev->parent, addr, &val, 1);
}
-static void pm8058_irq_unmask(struct irq_data *data)
+static int pm8058_read_buf(const struct device *dev, u16 addr, u8 *buf,
+ int cnt)
{
- int master, irq_bit;
- struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
- u8 block, config, old_irqs_allowed, old_blocks_allowed;
- unsigned int irq = data->irq;
+ const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+ const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
- irq -= chip->pdata.irq_base;
- block = irq / 8;
- master = block / 8;
- irq_bit = irq % 8;
-
- old_irqs_allowed = chip->irqs_allowed[block];
- if (old_irqs_allowed & (1 << irq_bit)) {
- pr_debug("%s: no need to enable an already enabled irq=%d\n",
- __func__, irq + chip->pdata.irq_base);
- return;
- }
-
- chip->irqs_allowed[block] |= 1 << irq_bit;
- if (!old_irqs_allowed) {
- master = block / 8;
-
- old_blocks_allowed = chip->blocks_allowed[master];
- chip->blocks_allowed[master] |= 1 << (block % 8);
-
- if (!old_blocks_allowed)
- chip->masters_allowed |= 1 << master;
- }
-
- config = PM8058_IRQF_WRITE | chip->config[irq];
- chip->bus_unlock_config[irq] = config;
+ return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt);
}
-static void pm8058_irq_ack(struct irq_data *data)
+static int pm8058_write_buf(const struct device *dev, u16 addr, u8 *buf,
+ int cnt)
{
- struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
- u8 block, config;
- unsigned int irq = data->irq;
+ const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+ const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
- irq -= chip->pdata.irq_base;
- block = irq / 8;
-
- config = PM8058_IRQF_WRITE | chip->config[irq] | PM8058_IRQF_CLR;
- /* Keep the mask */
- if (!(chip->irqs_allowed[block] & (1 << (irq % 8))))
- config |= PM8058_IRQF_MASK_FE | PM8058_IRQF_MASK_RE;
- chip->bus_unlock_config[irq] = config;
+ return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt);
}
-static int pm8058_irq_set_type(struct irq_data *data, unsigned int flow_type)
+static int pm8058_read_irq_stat(const struct device *dev, int irq)
{
- int master, irq_bit;
- struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
- u8 block, config;
- unsigned int irq = data->irq;
+ const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+ const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
- irq -= chip->pdata.irq_base;
- if (irq > chip->pm_max_irq) {
- chip->pm_max_irq = irq;
- chip->pm_max_blocks =
- chip->pm_max_irq / 8 + 1;
- chip->pm_max_masters =
- chip->pm_max_blocks / 8 + 1;
- }
- block = irq / 8;
- master = block / 8;
- irq_bit = irq % 8;
-
- chip->config[irq] = (irq_bit << PM8058_IRQF_BITS_SHIFT) |
- PM8058_IRQF_MASK_RE | PM8058_IRQF_MASK_FE;
- if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
- if (flow_type & IRQF_TRIGGER_RISING)
- chip->config[irq] &= ~PM8058_IRQF_MASK_RE;
- if (flow_type & IRQF_TRIGGER_FALLING)
- chip->config[irq] &= ~PM8058_IRQF_MASK_FE;
- } else {
- chip->config[irq] |= PM8058_IRQF_LVL_SEL;
-
- if (flow_type & IRQF_TRIGGER_HIGH)
- chip->config[irq] &= ~PM8058_IRQF_MASK_RE;
- else
- chip->config[irq] &= ~PM8058_IRQF_MASK_FE;
- }
-
- config = PM8058_IRQF_WRITE | chip->config[irq] | PM8058_IRQF_CLR;
- chip->bus_unlock_config[irq] = config;
- return 0;
-}
-
-static int pm8058_irq_set_wake(struct irq_data *data, unsigned int on)
-{
- struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
- unsigned int irq = data->irq;
-
- irq -= chip->pdata.irq_base;
- if (on) {
- if (!chip->wake_enable[irq]) {
- chip->wake_enable[irq] = 1;
- chip->count_wakeable++;
- }
- } else {
- if (chip->wake_enable[irq]) {
- chip->wake_enable[irq] = 0;
- chip->count_wakeable--;
- }
- }
+ return pm8xxx_get_irq_stat(pmic->irq_chip, irq);
return 0;
}
-static void pm8058_irq_bus_lock(struct irq_data *data)
+static enum pm8xxx_version pm8058_get_version(const struct device *dev)
{
- u8 block;
- struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
- unsigned int irq = data->irq;
+ const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+ const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
+ enum pm8xxx_version version = -ENODEV;
- irq -= chip->pdata.irq_base;
- block = irq / 8;
- chip->bus_unlock_config[irq] = 0;
+ if ((pmic->revision & PM8058_VERSION_MASK) == PM8058_VERSION_VALUE)
+ version = PM8XXX_VERSION_8058;
- mutex_lock(&chip->pm_lock);
+ return version;
}
-static void pm8058_irq_bus_sync_unlock(struct irq_data *data)
+static int pm8058_get_revision(const struct device *dev)
{
- u8 block, config;
- struct pm8058_chip *chip = irq_data_get_irq_chip_data(data);
- unsigned int irq = data->irq;
+ const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+ const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
- irq -= chip->pdata.irq_base;
- block = irq / 8;
- config = chip->bus_unlock_config[irq];
- /* dont waste cpu cycles if we dont have data to write */
- if (config)
- pm8058_config_irq(chip, &block, &config);
- mutex_unlock(&chip->pm_lock);
+ return pmic->revision & PM8058_REVISION_MASK;
}
-static inline int
-pm8058_read_root(struct pm8058_chip *chip, u8 *rp)
-{
- int rc;
-
- rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_read(): rc=%d (Read Root)\n",
- __func__, rc);
- *rp = 0;
- }
-
- return rc;
-}
-
-static inline int
-pm8058_read_master(struct pm8058_chip *chip, u8 m, u8 *bp)
-{
- int rc;
-
- rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_read(): rc=%d (Read Master)\n",
- __func__, rc);
- *bp = 0;
- }
-
- return rc;
-}
-
-static inline int
-pm8058_read_block(struct pm8058_chip *chip, u8 *bp, u8 *ip)
-{
- int rc;
-
- rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
- if (rc) {
- pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
- __func__, rc);
- *bp = 0;
- goto bail_out;
- }
-
- rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip, 1);
- if (rc)
- pr_err("%s: FAIL ssbi_read(): rc=%d (Read Status)\n",
- __func__, rc);
-
-bail_out:
- return rc;
-}
-
-static irqreturn_t pm8058_isr_thread(int irq_requested, void *data)
-{
- struct pm8058_chip *chip = data;
- int i, j, k;
- u8 root, block, config, bits;
- u8 blocks[MAX_PM_MASTERS];
- int masters = 0, irq, handled = 0, spurious = 0;
- u16 irqs_to_handle[MAX_PM_IRQ];
-
- mutex_lock(&chip->pm_lock);
-
- /* Read root for masters */
- if (pm8058_read_root(chip, &root))
- goto bail_out;
-
- masters = root >> 1;
-
- if (!(masters & chip->masters_allowed) ||
- (masters & ~chip->masters_allowed)) {
- spurious = 1000000;
- }
-
- /* Read allowed masters for blocks. */
- for (i = 0; i < chip->pm_max_masters; i++) {
- if (masters & (1 << i)) {
- if (pm8058_read_master(chip, i, &blocks[i]))
- goto bail_out;
-
- if (!blocks[i]) {
- if (pm8058_can_print())
- pr_err("%s: Spurious master: %d "
- "(blocks=0)", __func__, i);
- spurious += 10000;
- }
- } else
- blocks[i] = 0;
- }
-
- /* Select block, read status and call isr */
- for (i = 0; i < chip->pm_max_masters; i++) {
- if (!blocks[i])
- continue;
-
- for (j = 0; j < 8; j++) {
- if (!(blocks[i] & (1 << j)))
- continue;
-
- block = i * 8 + j; /* block # */
- if (pm8058_read_block(chip, &block, &bits))
- goto bail_out;
-
- if (!bits) {
- if (pm8058_can_print())
- pr_err("%s: Spurious block: "
- "[master, block]=[%d, %d] "
- "(bits=0)\n", __func__, i, j);
- spurious += 100;
- continue;
- }
-
- /* Check IRQ bits */
- for (k = 0; k < 8; k++) {
- if (!(bits & (1 << k)))
- continue;
-
- /* Check spurious interrupts */
- if (((1 << i) & chip->masters_allowed) &&
- (blocks[i] & chip->blocks_allowed[i]) &&
- (bits & chip->irqs_allowed[block])) {
-
- /* Found one */
- irq = block * 8 + k;
- irqs_to_handle[handled] = irq +
- chip->pdata.irq_base;
- handled++;
- } else {
- /* Clear and mask wrong one */
- config = PM8058_IRQF_W_C_M |
- (k << PM8058_IRQF_BITS_SHIFT);
-
- pm8058_config_irq(chip,
- &block, &config);
-
- if (pm8058_can_print())
- pr_err("%s: Spurious IRQ: "
- "[master, block, bit]="
- "[%d, %d (%d), %d]\n",
- __func__,
- i, j, block, k);
- spurious++;
- }
- }
- }
-
- }
-
-bail_out:
-
- mutex_unlock(&chip->pm_lock);
-
- for (i = 0; i < handled; i++) {
- int pmic_irq = irqs_to_handle[i] - chip->pdata.irq_base;
-
- /* ack the interrupt first */
- block = pmic_irq / 8 ;
- config = PM8058_IRQF_WRITE | chip->config[pmic_irq]
- | PM8058_IRQF_CLR;
- pm8058_config_irq(chip, &block, &config);
-
- /* calle the action handler */
- handle_nested_irq(irqs_to_handle[i]);
- }
-
- if (spurious) {
- if (!pm8058_can_print())
- return IRQ_HANDLED;
-
- pr_err("%s: spurious = %d (handled = %d)\n",
- __func__, spurious, handled);
- pr_err(" root = 0x%x (masters_allowed<<1 = 0x%x)\n",
- root, chip->masters_allowed << 1);
- for (i = 0; i < chip->pm_max_masters; i++) {
- if (masters & (1 << i))
- pr_err(" blocks[%d]=0x%x, "
- "allowed[%d]=0x%x\n",
- i, blocks[i],
- i, chip->blocks_allowed[i]);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-#if defined(CONFIG_DEBUG_FS)
-
-static int check_addr(int addr, const char *func_name)
-{
- if (addr < 0 || addr > 0x3FF) {
- pr_err("%s: PMIC 8058 register address is invalid: %d\n",
- func_name, addr);
- return -EINVAL;
- }
- return 0;
-}
-
-static int data_set(void *data, u64 val)
-{
- struct pm8058_dbg_device *dbgdev = data;
- u8 reg = val;
- int rc;
-
- mutex_lock(&dbgdev->dbg_mutex);
-
- rc = check_addr(dbgdev->addr, __func__);
- if (rc)
- goto done;
-
- rc = pm8058_write(dbgdev->pm_chip, dbgdev->addr, ®, 1);
-
- if (rc)
- pr_err("%s: FAIL pm8058_write(0x%03X)=0x%02X: rc=%d\n",
- __func__, dbgdev->addr, reg, rc);
-done:
- mutex_unlock(&dbgdev->dbg_mutex);
- return rc;
-}
-
-static int data_get(void *data, u64 *val)
-{
- struct pm8058_dbg_device *dbgdev = data;
- int rc;
- u8 reg;
-
- mutex_lock(&dbgdev->dbg_mutex);
-
- rc = check_addr(dbgdev->addr, __func__);
- if (rc)
- goto done;
-
- rc = pm8058_read(dbgdev->pm_chip, dbgdev->addr, ®, 1);
-
- if (rc) {
- pr_err("%s: FAIL pm8058_read(0x%03X)=0x%02X: rc=%d\n",
- __func__, dbgdev->addr, reg, rc);
- goto done;
- }
-
- *val = reg;
-done:
- mutex_unlock(&dbgdev->dbg_mutex);
- return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(dbg_data_fops, data_get, data_set, "0x%02llX\n");
-
-static int addr_set(void *data, u64 val)
-{
- struct pm8058_dbg_device *dbgdev = data;
- int rc;
-
- rc = check_addr(val, __func__);
- if (rc)
- return rc;
-
- mutex_lock(&dbgdev->dbg_mutex);
- dbgdev->addr = val;
- mutex_unlock(&dbgdev->dbg_mutex);
-
- return 0;
-}
-
-static int addr_get(void *data, u64 *val)
-{
- struct pm8058_dbg_device *dbgdev = data;
- int rc;
-
- mutex_lock(&dbgdev->dbg_mutex);
-
- rc = check_addr(dbgdev->addr, __func__);
- if (rc) {
- mutex_unlock(&dbgdev->dbg_mutex);
- return rc;
- }
- *val = dbgdev->addr;
-
- mutex_unlock(&dbgdev->dbg_mutex);
-
- return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(dbg_addr_fops, addr_get, addr_set, "0x%03llX\n");
-
-static int __devinit pmic8058_dbg_probe(struct pm8058_chip *chip)
-{
- struct pm8058_dbg_device *dbgdev;
- struct dentry *dent;
- struct dentry *temp;
- int rc;
-
- if (chip == NULL) {
- pr_err("%s: no parent data passed in.\n", __func__);
- return -EINVAL;
- }
-
- dbgdev = kzalloc(sizeof *dbgdev, GFP_KERNEL);
- if (dbgdev == NULL) {
- pr_err("%s: kzalloc() failed.\n", __func__);
- return -ENOMEM;
- }
-
- dbgdev->pm_chip = chip;
- dbgdev->addr = -1;
-
- dent = debugfs_create_dir("pm8058-dbg", NULL);
- if (dent == NULL || IS_ERR(dent)) {
- pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
- __func__, (unsigned)dent);
- rc = PTR_ERR(dent);
- goto dir_error;
- }
-
- temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, dent,
- dbgdev, &dbg_addr_fops);
- if (temp == NULL || IS_ERR(temp)) {
- pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
- __func__, (unsigned)temp);
- rc = PTR_ERR(temp);
- goto debug_error;
- }
-
- temp = debugfs_create_file("data", S_IRUSR | S_IWUSR, dent,
- dbgdev, &dbg_data_fops);
- if (temp == NULL || IS_ERR(temp)) {
- pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
- __func__, (unsigned)temp);
- rc = PTR_ERR(temp);
- goto debug_error;
- }
-
- mutex_init(&dbgdev->dbg_mutex);
-
- dbgdev->dent = dent;
-
- pmic_dbg_device = dbgdev;
-
- return 0;
-
-debug_error:
- debugfs_remove_recursive(dent);
-dir_error:
- kfree(dbgdev);
-
- return rc;
-}
-
-static int __devexit pmic8058_dbg_remove(void)
-{
- if (pmic_dbg_device) {
- debugfs_remove_recursive(pmic_dbg_device->dent);
- mutex_destroy(&pmic_dbg_device->dbg_mutex);
- kfree(pmic_dbg_device);
- }
- return 0;
-}
-
-#else
-
-static int __devinit pmic8058_dbg_probe(struct pm8058_chip *chip)
-{
- return 0;
-}
-
-static int __devexit pmic8058_dbg_remove(void)
-{
- return 0;
-}
-
-#endif
-
-static struct irq_chip pm8058_irq_chip = {
- .name = "pm8058",
- .irq_ack = pm8058_irq_ack,
- .irq_mask = pm8058_irq_mask,
- .irq_unmask = pm8058_irq_unmask,
- .irq_set_type = pm8058_irq_set_type,
- .irq_set_wake = pm8058_irq_set_wake,
- .irq_bus_lock = pm8058_irq_bus_lock,
- .irq_bus_sync_unlock = pm8058_irq_bus_sync_unlock,
+static struct pm8xxx_drvdata pm8058_drvdata = {
+ .pmic_readb = pm8058_readb,
+ .pmic_writeb = pm8058_writeb,
+ .pmic_read_buf = pm8058_read_buf,
+ .pmic_write_buf = pm8058_write_buf,
+ .pmic_read_irq_stat = pm8058_read_irq_stat,
+ .pmic_get_version = pm8058_get_version,
+ .pmic_get_revision = pm8058_get_revision,
};
-static int pm8058_suspend(void)
-{
- struct pm8058_chip *chip = pmic_chip;
- struct irq_data *data;
- int i;
-
- for (i = 0; i < MAX_PM_IRQ; i++) {
- if (chip->config[i] && !chip->wake_enable[i]) {
- if (!((chip->config[i] & PM8058_IRQF_MASK_ALL)
- == PM8058_IRQF_MASK_ALL)) {
- data = irq_get_irq_data(i +
- chip->pdata.irq_base);
- pm8058_irq_bus_lock(data);
- pm8058_irq_mask(data);
- pm8058_irq_bus_sync_unlock(data);
- }
- }
- }
-
- if (!chip->count_wakeable)
- disable_irq(chip->pdata.irq);
-
- return 0;
-}
-
-extern int msm_show_resume_irq_mask;
-
-static void pm8058_show_resume_irq(void)
-{
- u8 block, bits;
- int i;
- struct pm8058_chip *chip = pmic_chip;
-
- if (!msm_show_resume_irq_mask)
- return;
-
- for (i = 0; i < MAX_PM_IRQ; i++) {
- if (chip->wake_enable[i]) {
- block = i / 8;
- if (!pm8058_read_block(chip, &block, &bits)) {
- if (bits & (1 << (i & 0x7)))
- pr_warning("%s:%d triggered\n",
- __func__, i + chip->pdata.irq_base);
- }
- }
- }
-}
-
-static void pm8058_resume(void)
-{
- struct pm8058_chip *chip = pmic_chip;
- struct irq_data *data;
- int i;
-
- pm8058_show_resume_irq();
-
- for (i = 0; i < MAX_PM_IRQ; i++) {
- if (chip->config[i] && !chip->wake_enable[i]) {
- if (!((chip->config[i] & PM8058_IRQF_MASK_ALL)
- == PM8058_IRQF_MASK_ALL)) {
- data = irq_get_irq_data(i +
- chip->pdata.irq_base);
- pm8058_irq_bus_lock(data);
- pm8058_irq_unmask(data);
- pm8058_irq_bus_sync_unlock(data);
- }
- }
- }
-
- if (!chip->count_wakeable)
- enable_irq(chip->pdata.irq);
-}
-
-static struct syscore_ops pm8058_pm = {
- .suspend = pm8058_suspend,
- .resume = pm8058_resume,
+static const struct resource pm8058_charger_resources[] __devinitconst = {
+ SINGLE_IRQ_RESOURCE("CHGVAL", PM8058_CHGVAL_IRQ),
+ SINGLE_IRQ_RESOURCE("CHGINVAL", PM8058_CHGINVAL_IRQ),
+ SINGLE_IRQ_RESOURCE("CHGILIM", PM8058_CHGILIM_IRQ),
+ SINGLE_IRQ_RESOURCE("VCP", PM8058_VCP_IRQ),
+ SINGLE_IRQ_RESOURCE("ATC_DONE", PM8058_ATC_DONE_IRQ),
+ SINGLE_IRQ_RESOURCE("ATCFAIL", PM8058_ATCFAIL_IRQ),
+ SINGLE_IRQ_RESOURCE("AUTO_CHGDONE", PM8058_AUTO_CHGDONE_IRQ),
+ SINGLE_IRQ_RESOURCE("AUTO_CHGFAIL", PM8058_AUTO_CHGFAIL_IRQ),
+ SINGLE_IRQ_RESOURCE("CHGSTATE", PM8058_CHGSTATE_IRQ),
+ SINGLE_IRQ_RESOURCE("FASTCHG", PM8058_FASTCHG_IRQ),
+ SINGLE_IRQ_RESOURCE("CHG_END", PM8058_CHG_END_IRQ),
+ SINGLE_IRQ_RESOURCE("BATTTEMP", PM8058_BATTTEMP_IRQ),
+ SINGLE_IRQ_RESOURCE("CHGHOT", PM8058_CHGHOT_IRQ),
+ SINGLE_IRQ_RESOURCE("CHGTLIMIT", PM8058_CHGTLIMIT_IRQ),
+ SINGLE_IRQ_RESOURCE("CHG_GONE", PM8058_CHG_GONE_IRQ),
+ SINGLE_IRQ_RESOURCE("VCPMAJOR", PM8058_VCPMAJOR_IRQ),
+ SINGLE_IRQ_RESOURCE("VBATDET", PM8058_VBATDET_IRQ),
+ SINGLE_IRQ_RESOURCE("BATFET", PM8058_BATFET_IRQ),
+ SINGLE_IRQ_RESOURCE("BATT_REPLACE", PM8058_BATT_REPLACE_IRQ),
+ SINGLE_IRQ_RESOURCE("BATTCONNECT", PM8058_BATTCONNECT_IRQ),
+ SINGLE_IRQ_RESOURCE("VBATDET_LOW", PM8058_VBATDET_LOW_IRQ),
};
+static struct mfd_cell pm8058_charger_cell __devinitdata = {
+ .name = "pm8058-charger",
+ .id = -1,
+ .resources = pm8058_charger_resources,
+ .num_resources = ARRAY_SIZE(pm8058_charger_resources),
+};
+
+static const struct resource misc_cell_resources[] __devinitconst = {
+ SINGLE_IRQ_RESOURCE("pm8xxx_osc_halt_irq", PM8058_OSCHALT_IRQ),
+};
+
+static struct mfd_cell misc_cell __devinitdata = {
+ .name = PM8XXX_MISC_DEV_NAME,
+ .id = -1,
+ .resources = misc_cell_resources,
+ .num_resources = ARRAY_SIZE(misc_cell_resources),
+};
+
+static struct mfd_cell pm8058_pwm_cell __devinitdata = {
+ .name = "pm8058-pwm",
+ .id = -1,
+};
+
+static struct resource xoadc_resources[] = {
+ SINGLE_IRQ_RESOURCE(NULL, PM8058_ADC_IRQ),
+};
+
+static struct mfd_cell xoadc_cell __devinitdata = {
+ .name = "pm8058-xoadc",
+ .id = -1,
+ .resources = xoadc_resources,
+ .num_resources = ARRAY_SIZE(xoadc_resources),
+};
+
+static const struct resource thermal_alarm_cell_resources[] __devinitconst = {
+ SINGLE_IRQ_RESOURCE("pm8058_tempstat_irq", PM8058_TEMPSTAT_IRQ),
+ SINGLE_IRQ_RESOURCE("pm8058_overtemp_irq", PM8058_OVERTEMP_IRQ),
+};
+
+static struct pm8xxx_tm_core_data thermal_alarm_cdata = {
+ .adc_channel = CHANNEL_ADC_DIE_TEMP,
+ .adc_type = PM8XXX_TM_ADC_PM8058_ADC,
+ .reg_addr_temp_alarm_ctrl = REG_TEMP_ALRM_CTRL,
+ .reg_addr_temp_alarm_pwm = REG_TEMP_ALRM_PWM,
+ .tm_name = "pm8058_tz",
+ .irq_name_temp_stat = "pm8058_tempstat_irq",
+ .irq_name_over_temp = "pm8058_overtemp_irq",
+};
+
+static struct mfd_cell thermal_alarm_cell __devinitdata = {
+ .name = PM8XXX_TM_DEV_NAME,
+ .id = -1,
+ .resources = thermal_alarm_cell_resources,
+ .num_resources = ARRAY_SIZE(thermal_alarm_cell_resources),
+ .platform_data = &thermal_alarm_cdata,
+ .pdata_size = sizeof(struct pm8xxx_tm_core_data),
+};
+
+static struct mfd_cell debugfs_cell __devinitdata = {
+ .name = "pm8xxx-debug",
+ .id = -1,
+ .platform_data = "pm8058-dbg",
+ .pdata_size = sizeof("pm8058-dbg"),
+};
+
+static const struct resource othc0_cell_resources[] __devinitconst = {
+ {
+ .name = "othc_base",
+ .start = PM8058_OTHC_CNTR_BASE0,
+ .end = PM8058_OTHC_CNTR_BASE0,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static const struct resource othc1_cell_resources[] __devinitconst = {
+ SINGLE_IRQ_RESOURCE(NULL, PM8058_SW_1_IRQ),
+ SINGLE_IRQ_RESOURCE(NULL, PM8058_IR_1_IRQ),
+ {
+ .name = "othc_base",
+ .start = PM8058_OTHC_CNTR_BASE1,
+ .end = PM8058_OTHC_CNTR_BASE1,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static const struct resource othc2_cell_resources[] __devinitconst = {
+ {
+ .name = "othc_base",
+ .start = PM8058_OTHC_CNTR_BASE2,
+ .end = PM8058_OTHC_CNTR_BASE2,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static const struct resource batt_alarm_cell_resources[] __devinitconst = {
+ SINGLE_IRQ_RESOURCE("pm8058_batt_alarm_irq", PM8058_BATT_ALARM_IRQ),
+};
+
+static struct mfd_cell leds_cell __devinitdata = {
+ .name = "pm8058-led",
+ .id = -1,
+};
+
+static struct mfd_cell othc0_cell __devinitdata = {
+ .name = "pm8058-othc",
+ .id = 0,
+ .resources = othc0_cell_resources,
+ .num_resources = ARRAY_SIZE(othc0_cell_resources),
+};
+
+static struct mfd_cell othc1_cell __devinitdata = {
+ .name = "pm8058-othc",
+ .id = 1,
+ .resources = othc1_cell_resources,
+ .num_resources = ARRAY_SIZE(othc1_cell_resources),
+};
+
+static struct mfd_cell othc2_cell __devinitdata = {
+ .name = "pm8058-othc",
+ .id = 2,
+ .resources = othc2_cell_resources,
+ .num_resources = ARRAY_SIZE(othc2_cell_resources),
+};
+
+static struct pm8xxx_batt_alarm_core_data batt_alarm_cdata = {
+ .irq_name = "pm8058_batt_alarm_irq",
+ .reg_addr_threshold = REG_BATT_ALARM_THRESH,
+ .reg_addr_ctrl1 = REG_BATT_ALARM_CTRL1,
+ .reg_addr_ctrl2 = REG_BATT_ALARM_CTRL2,
+ .reg_addr_pwm_ctrl = REG_BATT_ALARM_PWM_CTRL,
+};
+
+static struct mfd_cell batt_alarm_cell __devinitdata = {
+ .name = PM8XXX_BATT_ALARM_DEV_NAME,
+ .id = -1,
+ .resources = batt_alarm_cell_resources,
+ .num_resources = ARRAY_SIZE(batt_alarm_cell_resources),
+ .platform_data = &batt_alarm_cdata,
+ .pdata_size = sizeof(struct pm8xxx_batt_alarm_core_data),
+};
+
+static struct mfd_cell upl_cell __devinitdata = {
+ .name = PM8XXX_UPL_DEV_NAME,
+ .id = -1,
+};
+
+static struct mfd_cell nfc_cell __devinitdata = {
+ .name = PM8XXX_NFC_DEV_NAME,
+ .id = -1,
+};
+
+static const struct resource rtc_cell_resources[] __devinitconst = {
+ [0] = SINGLE_IRQ_RESOURCE(NULL, PM8058_RTC_ALARM_IRQ),
+ [1] = {
+ .name = "pmic_rtc_base",
+ .start = PM8058_RTC_BASE,
+ .end = PM8058_RTC_BASE,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct mfd_cell rtc_cell __devinitdata = {
+ .name = PM8XXX_RTC_DEV_NAME,
+ .id = -1,
+ .resources = rtc_cell_resources,
+ .num_resources = ARRAY_SIZE(rtc_cell_resources),
+};
+
+static const struct resource resources_pwrkey[] __devinitconst = {
+ SINGLE_IRQ_RESOURCE(NULL, PM8058_PWRKEY_REL_IRQ),
+ SINGLE_IRQ_RESOURCE(NULL, PM8058_PWRKEY_PRESS_IRQ),
+};
+
+static struct mfd_cell vibrator_cell __devinitdata = {
+ .name = PM8XXX_VIBRATOR_DEV_NAME,
+ .id = -1,
+};
+
+static struct mfd_cell pwrkey_cell __devinitdata = {
+ .name = PM8XXX_PWRKEY_DEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_pwrkey),
+ .resources = resources_pwrkey,
+};
+
+static const struct resource resources_keypad[] = {
+ SINGLE_IRQ_RESOURCE(NULL, PM8058_KEYPAD_IRQ),
+ SINGLE_IRQ_RESOURCE(NULL, PM8058_KEYSTUCK_IRQ),
+};
+
+static struct mfd_cell keypad_cell __devinitdata = {
+ .name = PM8XXX_KEYPAD_DEV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_keypad),
+ .resources = resources_keypad,
+};
+
+static const struct resource mpp_cell_resources[] __devinitconst = {
+ {
+ .start = PM8058_IRQ_BLOCK_BIT(PM8058_MPP_BLOCK_START, 0),
+ .end = PM8058_IRQ_BLOCK_BIT(PM8058_MPP_BLOCK_START, 0)
+ + PM8058_MPPS - 1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell mpp_cell __devinitdata = {
+ .name = PM8XXX_MPP_DEV_NAME,
+ .id = 0,
+ .resources = mpp_cell_resources,
+ .num_resources = ARRAY_SIZE(mpp_cell_resources),
+};
+
+static const struct resource gpio_cell_resources[] __devinitconst = {
+ [0] = {
+ .start = PM8058_IRQ_BLOCK_BIT(PM8058_GPIO_BLOCK_START, 0),
+ .end = PM8058_IRQ_BLOCK_BIT(PM8058_GPIO_BLOCK_START, 0)
+ + PM8058_GPIOS - 1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mfd_cell gpio_cell __devinitdata = {
+ .name = PM8XXX_GPIO_DEV_NAME,
+ .id = -1,
+ .resources = gpio_cell_resources,
+ .num_resources = ARRAY_SIZE(gpio_cell_resources),
+};
+
+static int __devinit
+pm8058_add_subdevices(const struct pm8058_platform_data *pdata,
+ struct pm8058_chip *pmic)
+{
+ int rc = 0, irq_base = 0, i;
+ struct pm_irq_chip *irq_chip;
+ static struct mfd_cell *mfd_regulators, *mfd_xo_buffers;
+
+ if (pdata->irq_pdata) {
+ pdata->irq_pdata->irq_cdata.nirqs = PM8058_NR_IRQS;
+ irq_base = pdata->irq_pdata->irq_base;
+ irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata);
+
+ if (IS_ERR(irq_chip)) {
+ pr_err("Failed to init interrupts ret=%ld\n",
+ PTR_ERR(irq_chip));
+ return PTR_ERR(irq_chip);
+ }
+ pmic->irq_chip = irq_chip;
+ }
+
+ if (pdata->gpio_pdata) {
+ pdata->gpio_pdata->gpio_cdata.ngpios = PM8058_GPIOS;
+ gpio_cell.platform_data = pdata->gpio_pdata;
+ gpio_cell.pdata_size = sizeof(struct pm8xxx_gpio_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &gpio_cell, 1,
+ NULL, irq_base);
+ if (rc) {
+ pr_err("Failed to add gpio subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->mpp_pdata) {
+ pdata->mpp_pdata->core_data.nmpps = PM8058_MPPS;
+ pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE;
+ mpp_cell.platform_data = pdata->mpp_pdata;
+ mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add mpp subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->num_regulators > 0 && pdata->regulator_pdatas) {
+ mfd_regulators = kzalloc(sizeof(struct mfd_cell)
+ * (pdata->num_regulators), GFP_KERNEL);
+ if (!mfd_regulators) {
+ pr_err("Cannot allocate %d bytes for pm8058 regulator "
+ "mfd cells\n", sizeof(struct mfd_cell)
+ * (pdata->num_regulators));
+ rc = -ENOMEM;
+ goto bail;
+ }
+ for (i = 0; i < pdata->num_regulators; i++) {
+ mfd_regulators[i].name = "pm8058-regulator";
+ mfd_regulators[i].id = pdata->regulator_pdatas[i].id;
+ mfd_regulators[i].platform_data =
+ &(pdata->regulator_pdatas[i]);
+ mfd_regulators[i].pdata_size =
+ sizeof(struct pm8058_vreg_pdata);
+ }
+ rc = mfd_add_devices(pmic->dev, 0, mfd_regulators,
+ pdata->num_regulators, NULL, irq_base);
+ if (rc) {
+ pr_err("Failed to add regulator subdevices ret=%d\n",
+ rc);
+ kfree(mfd_regulators);
+ goto bail;
+ }
+ pmic->mfd_regulators = mfd_regulators;
+ }
+
+ if (pdata->num_xo_buffers > 0 && pdata->xo_buffer_pdata) {
+ mfd_xo_buffers = kzalloc(sizeof(struct mfd_cell)
+ * (pdata->num_xo_buffers), GFP_KERNEL);
+ if (!mfd_xo_buffers) {
+ pr_err("Cannot allocate %d bytes for pm8058 XO buffer "
+ "mfd cells\n", sizeof(struct mfd_cell)
+ * (pdata->num_xo_buffers));
+ rc = -ENOMEM;
+ goto bail;
+ }
+ for (i = 0; i < pdata->num_xo_buffers; i++) {
+ mfd_xo_buffers[i].name = PM8058_XO_BUFFER_DEV_NAME;
+ mfd_xo_buffers[i].id = pdata->xo_buffer_pdata[i].id;
+ mfd_xo_buffers[i].platform_data =
+ &(pdata->xo_buffer_pdata[i]);
+ mfd_xo_buffers[i].pdata_size =
+ sizeof(struct pm8058_xo_pdata);
+ }
+ rc = mfd_add_devices(pmic->dev, 0, mfd_xo_buffers,
+ pdata->num_xo_buffers, NULL, irq_base);
+ if (rc) {
+ pr_err("Failed to add XO buffer subdevices ret=%d\n",
+ rc);
+ kfree(mfd_xo_buffers);
+ goto bail;
+ }
+ pmic->mfd_xo_buffers = mfd_xo_buffers;
+ }
+
+ if (pdata->keypad_pdata) {
+ keypad_cell.platform_data = pdata->keypad_pdata;
+ keypad_cell.pdata_size =
+ sizeof(struct pm8xxx_keypad_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &keypad_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add keypad subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->rtc_pdata) {
+ rtc_cell.platform_data = pdata->rtc_pdata;
+ rtc_cell.pdata_size = sizeof(struct pm8xxx_rtc_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &rtc_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add rtc subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->pwrkey_pdata) {
+ pwrkey_cell.platform_data = pdata->pwrkey_pdata;
+ pwrkey_cell.pdata_size =
+ sizeof(struct pm8xxx_pwrkey_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &pwrkey_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add pwrkey subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->vibrator_pdata) {
+ vibrator_cell.platform_data = pdata->vibrator_pdata;
+ vibrator_cell.pdata_size =
+ sizeof(struct pm8xxx_vibrator_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &vibrator_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add vibrator subdevice ret=%d\n",
+ rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->leds_pdata) {
+ leds_cell.platform_data = pdata->leds_pdata;
+ leds_cell.pdata_size =
+ sizeof(struct pmic8058_leds_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &leds_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add leds subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->xoadc_pdata) {
+ xoadc_cell.platform_data = pdata->xoadc_pdata;
+ xoadc_cell.pdata_size =
+ sizeof(struct xoadc_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &xoadc_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add leds subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->othc0_pdata) {
+ othc0_cell.platform_data = pdata->othc0_pdata;
+ othc0_cell.pdata_size =
+ sizeof(struct pmic8058_othc_config_pdata);
+ rc = mfd_add_devices(pmic->dev, 0, &othc0_cell, 1, NULL, 0);
+ if (rc) {
+ pr_err("Failed to add othc0 subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->othc1_pdata) {
+ othc1_cell.platform_data = pdata->othc1_pdata;
+ othc1_cell.pdata_size =
+ sizeof(struct pmic8058_othc_config_pdata);
+ rc = mfd_add_devices(pmic->dev, 0, &othc1_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add othc1 subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->othc2_pdata) {
+ othc2_cell.platform_data = pdata->othc2_pdata;
+ othc2_cell.pdata_size =
+ sizeof(struct pmic8058_othc_config_pdata);
+ rc = mfd_add_devices(pmic->dev, 0, &othc2_cell, 1, NULL, 0);
+ if (rc) {
+ pr_err("Failed to add othc2 subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->pwm_pdata) {
+ pm8058_pwm_cell.platform_data = pdata->pwm_pdata;
+ pm8058_pwm_cell.pdata_size = sizeof(struct pm8058_pwm_pdata);
+ rc = mfd_add_devices(pmic->dev, 0, &pm8058_pwm_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add pwm subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ if (pdata->misc_pdata) {
+ misc_cell.platform_data = pdata->misc_pdata;
+ misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data);
+ rc = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add misc subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ rc = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add thermal alarm subdevice ret=%d\n",
+ rc);
+ goto bail;
+ }
+
+ rc = mfd_add_devices(pmic->dev, 0, &batt_alarm_cell, 1, NULL,
+ irq_base);
+ if (rc) {
+ pr_err("Failed to add battery alarm subdevice ret=%d\n",
+ rc);
+ goto bail;
+ }
+
+ rc = mfd_add_devices(pmic->dev, 0, &upl_cell, 1, NULL, 0);
+ if (rc) {
+ pr_err("Failed to add upl subdevice ret=%d\n", rc);
+ goto bail;
+ }
+
+ rc = mfd_add_devices(pmic->dev, 0, &nfc_cell, 1, NULL, 0);
+ if (rc) {
+ pr_err("Failed to add upl subdevice ret=%d\n", rc);
+ goto bail;
+ }
+
+ if (pdata->charger_pdata) {
+ pm8058_charger_cell.platform_data = pdata->charger_pdata;
+ pm8058_charger_cell.pdata_size = sizeof(struct
+ pmic8058_charger_data);
+ rc = mfd_add_devices(pmic->dev, 0, &pm8058_charger_cell,
+ 1, NULL, irq_base);
+ if (rc) {
+ pr_err("Failed to add charger subdevice ret=%d\n", rc);
+ goto bail;
+ }
+ }
+
+ rc = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base);
+ if (rc) {
+ pr_err("Failed to add debugfs subdevice ret=%d\n", rc);
+ goto bail;
+ }
+
+ return rc;
+bail:
+ if (pmic->irq_chip) {
+ pm8xxx_irq_exit(pmic->irq_chip);
+ pmic->irq_chip = NULL;
+ }
+ return rc;
+}
+
static int __devinit pm8058_probe(struct platform_device *pdev)
{
- int i, rc;
- struct pm8058_platform_data *pdata = pdev->dev.platform_data;
- struct pm8058_chip *chip;
+ int rc;
+ struct pm8058_platform_data *pdata = pdev->dev.platform_data;
+ struct pm8058_chip *pmic;
- if (pdata == NULL || !gpio_is_valid(pdata->irq)) {
+ if (pdata == NULL) {
pr_err("%s: No platform_data or IRQ.\n", __func__);
return -ENODEV;
}
- if (pdata->num_subdevs == 0) {
- pr_err("%s: No sub devices to support.\n", __func__);
- return -ENODEV;
- }
-
- chip = kzalloc(sizeof *chip, GFP_KERNEL);
- if (chip == NULL) {
+ pmic = kzalloc(sizeof *pmic, GFP_KERNEL);
+ if (pmic == NULL) {
pr_err("%s: kzalloc() failed.\n", __func__);
return -ENOMEM;
}
- chip->dev = &pdev->dev;
+ pmic->dev = &pdev->dev;
+
+ pm8058_drvdata.pm_chip_data = pmic;
+ platform_set_drvdata(pdev, &pm8058_drvdata);
+
+ mutex_init(&pmic->pm_lock);
+ pmic_chip = pmic;
/* Read PMIC chip revision */
- rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1);
+ rc = pm8058_readb(pmic->dev, PM8058_REG_REV, &pmic->revision);
if (rc)
- pr_err("%s: Failed on ssbi_read for revision: rc=%d.\n",
+ pr_err("%s: Failed on pm8058_readb for revision: rc=%d.\n",
__func__, rc);
- pr_info("%s: PMIC revision: %X\n", __func__, chip->revision);
- (void) memcpy((void *)&chip->pdata, (const void *)pdata,
- sizeof(chip->pdata));
+ pr_info("%s: PMIC revision: %X\n", __func__, pmic->revision);
- mutex_init(&chip->pm_lock);
- irq_set_handler_data(pdata->irq, (void *)chip);
- irq_set_irq_wake(pdata->irq, 1);
+ (void) memcpy((void *)&pmic->pdata, (const void *)pdata,
+ sizeof(pmic->pdata));
- chip->pm_max_irq = 0;
- chip->pm_max_blocks = 0;
- chip->pm_max_masters = 0;
-
- platform_set_drvdata(pdev, chip);
-
- pmic_chip = chip;
-
- /* Register for all reserved IRQs */
- for (i = pdata->irq_base; i < (pdata->irq_base + MAX_PM_IRQ); i++) {
- irq_set_chip(i, &pm8058_irq_chip);
- irq_set_chip_data(i, (void *)chip);
- irq_set_handler(i, handle_edge_irq);
- set_irq_flags(i, IRQF_VALID);
- irq_set_nested_thread(i, 1);
+ rc = pm8058_add_subdevices(pdata, pmic);
+ if (rc) {
+ pr_err("Cannot add subdevices rc=%d\n", rc);
+ goto err;
}
- rc = mfd_add_devices(chip->dev, 0, pdata->sub_devices,
- pdata->num_subdevs, NULL, 0);
-
- /* Add charger sub device with the chip parameter as driver data */
- if (pdata->charger_sub_device) {
- rc = mfd_add_devices(chip->dev, 0,
- pdata->charger_sub_device,
- 1, NULL, 0);
- }
-
- if (pdata->init) {
- rc = pdata->init(chip);
- if (rc != 0) {
- pr_err("%s: board init failed\n", __func__);
- chip->dev = NULL;
- kfree(chip);
- return -ENODEV;
- }
- }
-
- rc = request_threaded_irq(pdata->irq, NULL, pm8058_isr_thread,
- IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags,
- "pm8058-irq", chip);
- if (rc < 0)
- pr_err("%s: could not request irq %d: %d\n", __func__,
- pdata->irq, rc);
-
- rc = pmic8058_dbg_probe(chip);
- if (rc < 0)
- pr_err("%s: could not set up debugfs: %d\n", __func__, rc);
-
rc = pm8058_hard_reset_config(SHUTDOWN_ON_HARD_RESET);
if (rc < 0)
pr_err("%s: failed to config shutdown on hard reset: %d\n",
__func__, rc);
- register_syscore_ops(&pm8058_pm);
-
return 0;
+
+err:
+ mfd_remove_devices(pmic->dev);
+ platform_set_drvdata(pdev, NULL);
+ kfree(pmic);
+ return rc;
}
static int __devexit pm8058_remove(struct platform_device *pdev)
{
- struct pm8058_chip *chip;
+ struct pm8xxx_drvdata *drvdata;
+ struct pm8058_chip *pmic = NULL;
- chip = platform_get_drvdata(pdev);
- if (chip) {
- if (chip->pm_max_irq) {
- irq_set_irq_wake(chip->pdata.irq, 0);
- free_irq(chip->pdata.irq, chip);
- }
- mutex_destroy(&chip->pm_lock);
- chip->dev = NULL;
-
- kfree(chip);
+ drvdata = platform_get_drvdata(pdev);
+ if (drvdata)
+ pmic = drvdata->pm_chip_data;
+ if (pmic) {
+ if (pmic->dev)
+ mfd_remove_devices(pmic->dev);
+ if (pmic->irq_chip)
+ pm8xxx_irq_exit(pmic->irq_chip);
+ mutex_destroy(&pmic->pm_lock);
+ kfree(pmic->mfd_regulators);
+ kfree(pmic);
}
-
- pmic8058_dbg_remove();
+ platform_set_drvdata(pdev, NULL);
return 0;
}
@@ -1489,7 +1269,7 @@
{
return platform_driver_register(&pm8058_driver);
}
-arch_initcall(pm8058_init);
+postcore_initcall(pm8058_init);
static void __exit pm8058_exit(void)
{
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index dfbf345..3d7738e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -601,21 +601,19 @@
on the PM8XXX chips. The vibrator is controlled using the
timed output class.
-config PMIC8058_NFC
- tristate "Qualcomm PM8058 support for Near Field Communication"
- depends on PMIC8058
- default y
+config PMIC8XXX_NFC
+ tristate "Qualcomm PM8XXX support for Near Field Communication"
+ depends on MFD_PM8XXX
help
- Qualcomm PM8058 chip has a module to support NFC (Near Field
+ Qualcomm PM8XXX chips have a module to support NFC (Near Field
Communication). This option enables the driver to support it.
-config PMIC8058_UPL
- tristate "Qualcomm PM8058 support for User Programmable Logic"
- depends on PMIC8058
- default n
+config PMIC8XXX_UPL
+ tristate "Qualcomm PM8XXX support for User Programmable Logic"
+ depends on MFD_PM8XXX
help
This option enables device driver support for User Programmable Logic
- on Qualcomm PM8058 chip. The UPL module provides a means to implement
+ on Qualcomm PM8XXX chips. The UPL module provides a means to implement
simple truth table based logic via a set of control registers. I/O may
be routed in and out of the UPL module via GPIO or DTEST pins.
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a38ccfd..b7f23c8 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -59,8 +59,8 @@
obj-$(CONFIG_PMIC8058_PWM) += pmic8058-pwm.o
obj-$(CONFIG_PMIC8058_VIBRATOR) += pmic8058-vibrator.o
obj-$(CONFIG_PMIC8XXX_VIBRATOR) += pm8xxx-vibrator.o
-obj-$(CONFIG_PMIC8058_NFC) += pmic8058-nfc.o
-obj-$(CONFIG_PMIC8058_UPL) += pmic8058-upl.o
+obj-$(CONFIG_PMIC8XXX_NFC) += pm8xxx-nfc.o
+obj-$(CONFIG_PMIC8XXX_UPL) += pm8xxx-upl.o
obj-$(CONFIG_MSM_MEMORY_LOW_POWER_MODE_SUSPEND_DEEP_POWER_DOWN) \
+= msm_migrate_pages.o
obj-$(CONFIG_PMIC8058_XOADC) += pmic8058-xoadc.o
diff --git a/drivers/misc/pm8xxx-nfc.c b/drivers/misc/pm8xxx-nfc.c
new file mode 100644
index 0000000..1aaa3e3
--- /dev/null
+++ b/drivers/misc/pm8xxx-nfc.c
@@ -0,0 +1,311 @@
+/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+/*
+ * Qualcomm PMIC8XXX NFC driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pm8xxx/nfc.h>
+
+/* PM8XXX NFC */
+#define SSBI_REG_NFC_CTRL 0x14D
+#define SSBI_REG_NFC_TEST 0x14E
+
+/* NFC_CTRL */
+#define PM8XXX_NFC_SUPPORT_EN 0x80
+#define PM8XXX_NFC_LDO_EN 0x40
+#define PM8XXX_NFC_EN 0x20
+#define PM8XXX_NFC_EXT_VDDLDO_EN 0x10
+#define PM8XXX_NFC_VPH_PWR_EN 0x08
+#define PM8XXX_NFC_RESERVED 0x04
+#define PM8XXX_NFC_VDDLDO_LEVEL 0x03
+
+/* NFC_TEST */
+#define PM8XXX_NFC_VDDLDO_MON_EN 0x80
+#define PM8XXX_NFC_ATEST_EN 0x40
+#define PM8XXX_NFC_DTEST1_EN 0x20
+#define PM8XXX_NFC_RESERVED2 0x18
+#define PM8XXX_NFC_VDDLDO_OK_S 0x04
+#define PM8XXX_NFC_MBG_EN_S 0x02
+#define PM8XXX_NFC_EXT_EN_S 0x01
+
+struct pm8xxx_nfc_device {
+ struct device *dev;
+ struct mutex nfc_mutex;
+#if defined(CONFIG_DEBUG_FS)
+ struct dentry *dent;
+#endif
+};
+static struct pm8xxx_nfc_device *nfc_dev;
+
+/* APIs */
+/*
+ * pm8xxx_nfc_request - request a handle to access NFC device
+ */
+struct pm8xxx_nfc_device *pm8xxx_nfc_request(void)
+{
+ return nfc_dev;
+}
+EXPORT_SYMBOL(pm8xxx_nfc_request);
+
+/*
+ * pm8xxx_nfc_config - configure NFC signals
+ *
+ * @nfcdev: the NFC device
+ * @mask: signal mask to configure
+ * @flags: control flags
+ */
+int pm8xxx_nfc_config(struct pm8xxx_nfc_device *nfcdev, u32 mask, u32 flags)
+{
+ u8 nfc_ctrl, nfc_test, m, f;
+ int rc;
+
+ if (nfcdev == NULL || IS_ERR(nfcdev) || !mask)
+ return -EINVAL;
+
+ mutex_lock(&nfcdev->nfc_mutex);
+
+ if (!(mask & PM_NFC_CTRL_REQ))
+ goto config_test;
+
+ rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_CTRL, &nfc_ctrl);
+ if (rc) {
+ pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_ctrl=0x%x)\n",
+ __func__, rc, nfc_ctrl);
+ goto config_done;
+ }
+
+ m = mask & 0x00ff;
+ f = flags & 0x00ff;
+ nfc_ctrl &= ~m;
+ nfc_ctrl |= m & f;
+
+ rc = pm8xxx_writeb(nfcdev->dev->parent, SSBI_REG_NFC_CTRL, nfc_ctrl);
+ if (rc) {
+ pr_err("%s: FAIL pm8xxx_writeb(): rc=%d (nfc_ctrl=0x%x)\n",
+ __func__, rc, nfc_ctrl);
+ goto config_done;
+ }
+
+config_test:
+ if (!(mask & PM_NFC_TEST_REQ))
+ goto config_done;
+
+ rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_TEST, &nfc_test);
+ if (rc) {
+ pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_test=0x%x)\n",
+ __func__, rc, nfc_test);
+ goto config_done;
+ }
+
+ m = (mask >> 8) & 0x00ff;
+ f = (flags >> 8) & 0x00ff;
+ nfc_test &= ~m;
+ nfc_test |= m & f;
+
+ rc = pm8xxx_writeb(nfcdev->dev->parent, SSBI_REG_NFC_TEST, nfc_test);
+ if (rc) {
+ pr_err("%s: FAIL pm8xxx_writeb(): rc=%d (nfc_test=0x%x)\n",
+ __func__, rc, nfc_test);
+ goto config_done;
+ }
+
+config_done:
+ mutex_unlock(&nfcdev->nfc_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(pm8xxx_nfc_config);
+
+/*
+ * pm8xxx_nfc_get_status - get NFC status
+ *
+ * @nfcdev: the NFC device
+ * @mask: of status mask to read
+ * @status: pointer to the status variable
+ */
+int pm8xxx_nfc_get_status(struct pm8xxx_nfc_device *nfcdev,
+ u32 mask, u32 *status)
+{
+ u8 nfc_ctrl, nfc_test;
+ u32 st;
+ int rc;
+
+ if (nfcdev == NULL || IS_ERR(nfcdev) || status == NULL)
+ return -EINVAL;
+
+ st = 0;
+ mutex_lock(&nfcdev->nfc_mutex);
+
+ if (!(mask & PM_NFC_CTRL_REQ))
+ goto read_test;
+
+ rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_CTRL, &nfc_ctrl);
+ if (rc) {
+ pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_ctrl=0x%x)\n",
+ __func__, rc, nfc_ctrl);
+ goto get_status_done;
+ }
+
+read_test:
+ if (!(mask & (PM_NFC_TEST_REQ | PM_NFC_TEST_STATUS)))
+ goto get_status_done;
+
+ rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_TEST, &nfc_test);
+ if (rc)
+ pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_test=0x%x)\n",
+ __func__, rc, nfc_test);
+
+get_status_done:
+ st = nfc_ctrl;
+ st |= nfc_test << 8;
+ *status = st;
+
+ mutex_unlock(&nfcdev->nfc_mutex);
+ return 0;
+}
+EXPORT_SYMBOL(pm8xxx_nfc_get_status);
+
+/*
+ * pm8xxx_nfc_free - free the NFC device
+ */
+void pm8xxx_nfc_free(struct pm8xxx_nfc_device *nfcdev)
+{
+ /* Disable all signals */
+ pm8xxx_nfc_config(nfcdev, PM_NFC_CTRL_REQ, 0);
+}
+EXPORT_SYMBOL(pm8xxx_nfc_free);
+
+#if defined(CONFIG_DEBUG_FS)
+static int pm8xxx_nfc_debug_set(void *data, u64 val)
+{
+ struct pm8xxx_nfc_device *nfcdev;
+ u32 mask, control;
+ int rc;
+
+ nfcdev = (struct pm8xxx_nfc_device *)data;
+ control = (u32)val & 0xffff;
+ mask = ((u32)val >> 16) & 0xffff;
+ rc = pm8xxx_nfc_config(nfcdev, mask, control);
+ if (rc)
+ pr_err("%s: ERR pm8xxx_nfc_config: rc=%d, "
+ "[mask, control]=[0x%x, 0x%x]\n",
+ __func__, rc, mask, control);
+
+ return 0;
+}
+
+static int pm8xxx_nfc_debug_get(void *data, u64 *val)
+{
+ struct pm8xxx_nfc_device *nfcdev;
+ u32 status;
+ int rc;
+
+ nfcdev = (struct pm8xxx_nfc_device *)data;
+ rc = pm8xxx_nfc_get_status(nfcdev, (u32)-1, &status);
+ if (rc)
+ pr_err("%s: ERR pm8xxx_nfc_get_status: rc=%d, status=0x%x\n",
+ __func__, rc, status);
+
+ if (val)
+ *val = (u64)status;
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pm8xxx_nfc_fops, pm8xxx_nfc_debug_get,
+ pm8xxx_nfc_debug_set, "%llu\n");
+
+static int pm8xxx_nfc_debug_init(struct pm8xxx_nfc_device *nfcdev)
+{
+ struct dentry *dent;
+
+ dent = debugfs_create_file("pm8xxx-nfc", 0644, NULL,
+ (void *)nfcdev, &pm8xxx_nfc_fops);
+
+ if (dent == NULL || IS_ERR(dent))
+ pr_err("%s: ERR debugfs_create_file: dent=0x%x\n",
+ __func__, (unsigned)dent);
+
+ nfcdev->dent = dent;
+ return 0;
+}
+#endif
+
+static int __devinit pm8xxx_nfc_probe(struct platform_device *pdev)
+{
+ struct pm8xxx_nfc_device *nfcdev;
+
+ nfcdev = kzalloc(sizeof *nfcdev, GFP_KERNEL);
+ if (nfcdev == NULL) {
+ pr_err("%s: kzalloc() failed.\n", __func__);
+ return -ENOMEM;
+ }
+
+ mutex_init(&nfcdev->nfc_mutex);
+
+ nfcdev->dev = &pdev->dev;
+ nfc_dev = nfcdev;
+ platform_set_drvdata(pdev, nfcdev);
+
+#if defined(CONFIG_DEBUG_FS)
+ pm8xxx_nfc_debug_init(nfc_dev);
+#endif
+
+ pr_notice("%s: OK\n", __func__);
+ return 0;
+}
+
+static int __devexit pm8xxx_nfc_remove(struct platform_device *pdev)
+{
+ struct pm8xxx_nfc_device *nfcdev = platform_get_drvdata(pdev);
+
+#if defined(CONFIG_DEBUG_FS)
+ debugfs_remove(nfcdev->dent);
+#endif
+
+ platform_set_drvdata(pdev, NULL);
+ kfree(nfcdev);
+ return 0;
+}
+
+static struct platform_driver pm8xxx_nfc_driver = {
+ .probe = pm8xxx_nfc_probe,
+ .remove = __devexit_p(pm8xxx_nfc_remove),
+ .driver = {
+ .name = PM8XXX_NFC_DEV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init pm8xxx_nfc_init(void)
+{
+ return platform_driver_register(&pm8xxx_nfc_driver);
+}
+
+static void __exit pm8xxx_nfc_exit(void)
+{
+ platform_driver_unregister(&pm8xxx_nfc_driver);
+}
+
+module_init(pm8xxx_nfc_init);
+module_exit(pm8xxx_nfc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PM8XXX NFC driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:" PM8XXX_NFC_DEV_NAME);
diff --git a/drivers/misc/pm8xxx-upl.c b/drivers/misc/pm8xxx-upl.c
new file mode 100644
index 0000000..d3d9746f
--- /dev/null
+++ b/drivers/misc/pm8xxx-upl.c
@@ -0,0 +1,350 @@
+/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+/*
+ * Qualcomm PM8XXX UPL driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pm8xxx/upl.h>
+
+/* PMIC8XXX UPL registers */
+#define SSBI_REG_UPL_CTRL 0x17B
+#define SSBI_REG_UPL_TRUTHTABLE1 0x17C
+#define SSBI_REG_UPL_TRUTHTABLE2 0x17D
+
+struct pm8xxx_upl_device {
+ struct device *dev;
+ struct mutex upl_mutex;
+#if defined(CONFIG_DEBUG_FS)
+ struct dentry *dent;
+#endif
+};
+static struct pm8xxx_upl_device *upl_dev;
+
+/* APIs */
+
+/*
+ * pm8xxx_upl_request - request a handle to access UPL device
+ */
+struct pm8xxx_upl_device *pm8xxx_upl_request(void)
+{
+ return upl_dev;
+}
+EXPORT_SYMBOL(pm8xxx_upl_request);
+
+/*
+ * pm8xxx_upl_read_truthtable - read value currently stored in UPL truth table
+ *
+ * @upldev: the UPL device
+ * @truthtable: value read from UPL truth table
+ */
+int pm8xxx_upl_read_truthtable(struct pm8xxx_upl_device *upldev,
+ u16 *truthtable)
+{
+ int rc = 0;
+ u8 table[2];
+
+ if (upldev == NULL || IS_ERR(upldev))
+ return -EINVAL;
+
+ mutex_lock(&upldev->upl_mutex);
+
+ rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE1,
+ &(table[0]));
+ if (rc) {
+ pr_err("%s: FAIL pm8xxx_readb(0x%X)=0x%02X: rc=%d\n",
+ __func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
+ goto upl_read_done;
+ }
+
+ rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE2,
+ &(table[1]));
+ if (rc)
+ pr_err("%s: FAIL pm8xxx_readb(0x%X)=0x%02X: rc=%d\n",
+ __func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
+upl_read_done:
+ mutex_unlock(&upldev->upl_mutex);
+ *truthtable = (((u16)table[1]) << 8) | table[0];
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_upl_read_truthtable);
+
+/*
+ * pm8xxx_upl_writes_truthtable - write value into UPL truth table
+ *
+ * @upldev: the UPL device
+ * @truthtable: value written to UPL truth table
+ *
+ * Each bit in parameter "truthtable" corresponds to the UPL output for a given
+ * set of input pin values. For example, if the input pins have the following
+ * values: A=1, B=1, C=1, D=0, then the UPL would output the value of bit 14
+ * (0b1110) in parameter "truthtable".
+ */
+int pm8xxx_upl_write_truthtable(struct pm8xxx_upl_device *upldev,
+ u16 truthtable)
+{
+ int rc = 0;
+ u8 table[2];
+
+ if (upldev == NULL || IS_ERR(upldev))
+ return -EINVAL;
+
+ table[0] = truthtable & 0xFF;
+ table[1] = (truthtable >> 8) & 0xFF;
+
+ mutex_lock(&upldev->upl_mutex);
+
+ rc = pm8xxx_writeb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE1,
+ table[0]);
+ if (rc) {
+ pr_err("%s: FAIL pm8xxx_writeb(0x%X)=0x%04X: rc=%d\n",
+ __func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
+ goto upl_write_done;
+ }
+
+ rc = pm8xxx_writeb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE2,
+ table[1]);
+ if (rc)
+ pr_err("%s: FAIL pm8xxx_writeb(0x%X)=0x%04X: rc=%d\n",
+ __func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
+upl_write_done:
+ mutex_unlock(&upldev->upl_mutex);
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_upl_write_truthtable);
+
+/*
+ * pm8xxx_upl_config - configure UPL I/O settings and UPL enable/disable
+ *
+ * @upldev: the UPL device
+ * @mask: setting mask to configure
+ * @flags: setting flags
+ */
+int pm8xxx_upl_config(struct pm8xxx_upl_device *upldev, u32 mask, u32 flags)
+{
+ int rc;
+ u8 upl_ctrl, m, f;
+
+ if (upldev == NULL || IS_ERR(upldev))
+ return -EINVAL;
+
+ mutex_lock(&upldev->upl_mutex);
+
+ rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_CTRL, &upl_ctrl);
+ if (rc) {
+ pr_err("%s: FAIL pm8xxx_readb(0x%X)=0x%02X: rc=%d\n",
+ __func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
+ goto upl_config_done;
+ }
+
+ m = mask & 0x00ff;
+ f = flags & 0x00ff;
+ upl_ctrl &= ~m;
+ upl_ctrl |= m & f;
+
+ rc = pm8xxx_writeb(upldev->dev->parent, SSBI_REG_UPL_CTRL, upl_ctrl);
+ if (rc)
+ pr_err("%s: FAIL pm8xxx_writeb(0x%X)=0x%02X: rc=%d\n",
+ __func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
+upl_config_done:
+ mutex_unlock(&upldev->upl_mutex);
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_upl_config);
+
+#if defined(CONFIG_DEBUG_FS)
+
+static int truthtable_set(void *data, u64 val)
+{
+ int rc;
+
+ rc = pm8xxx_upl_write_truthtable(data, val);
+ if (rc)
+ pr_err("%s: pm8xxx_upl_write_truthtable: rc=%d, "
+ "truthtable=0x%llX\n", __func__, rc, val);
+ return rc;
+}
+
+static int truthtable_get(void *data, u64 *val)
+{
+ int rc;
+ u16 truthtable;
+
+ rc = pm8xxx_upl_read_truthtable(data, &truthtable);
+ if (rc)
+ pr_err("%s: pm8xxx_upl_read_truthtable: rc=%d, "
+ "truthtable=0x%X\n", __func__, rc, truthtable);
+ if (val)
+ *val = truthtable;
+
+ return rc;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(upl_truthtable_fops, truthtable_get,
+ truthtable_set, "0x%04llX\n");
+
+/* enter values as 0xMMMMFFFF where MMMM is the mask and FFFF is the flags */
+static int control_set(void *data, u64 val)
+{
+ u8 mask, flags;
+ int rc;
+
+ flags = val & 0xFFFF;
+ mask = (val >> 16) & 0xFFFF;
+
+ rc = pm8xxx_upl_config(data, mask, flags);
+ if (rc)
+ pr_err("%s: pm8xxx_upl_config: rc=%d, mask = 0x%X, "
+ "flags = 0x%X\n", __func__, rc, mask, flags);
+ return rc;
+}
+
+static int control_get(void *data, u64 *val)
+{
+ struct pm8xxx_upl_device *upldev;
+ int rc = 0;
+ u8 ctrl;
+
+ upldev = data;
+
+ mutex_lock(&upldev->upl_mutex);
+
+ rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_CTRL, &ctrl);
+ if (rc)
+ pr_err("%s: FAIL pm8xxx_readb(): rc=%d (ctrl=0x%02X)\n",
+ __func__, rc, ctrl);
+
+ mutex_unlock(&upldev->upl_mutex);
+
+ *val = ctrl;
+
+ return rc;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(upl_control_fops, control_get,
+ control_set, "0x%02llX\n");
+
+static int pm8xxx_upl_debug_init(struct pm8xxx_upl_device *upldev)
+{
+ struct dentry *dent;
+ struct dentry *temp;
+
+ dent = debugfs_create_dir("pm8xxx-upl", NULL);
+ if (dent == NULL || IS_ERR(dent)) {
+ pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
+ __func__, (unsigned)dent);
+ return -ENOMEM;
+ }
+
+ temp = debugfs_create_file("truthtable", S_IRUSR | S_IWUSR, dent,
+ upldev, &upl_truthtable_fops);
+ if (temp == NULL || IS_ERR(temp)) {
+ pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
+ __func__, (unsigned)dent);
+ goto debug_error;
+ }
+
+ temp = debugfs_create_file("control", S_IRUSR | S_IWUSR, dent,
+ upldev, &upl_control_fops);
+ if (temp == NULL || IS_ERR(temp)) {
+ pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
+ __func__, (unsigned)dent);
+ goto debug_error;
+ }
+
+ upldev->dent = dent;
+ return 0;
+
+debug_error:
+ debugfs_remove_recursive(dent);
+ return -ENOMEM;
+}
+
+static int __devexit pm8xxx_upl_debug_remove(struct pm8xxx_upl_device *upldev)
+{
+ debugfs_remove_recursive(upldev->dent);
+ return 0;
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __devinit pm8xxx_upl_probe(struct platform_device *pdev)
+{
+ struct pm8xxx_upl_device *upldev;
+
+ upldev = kzalloc(sizeof *upldev, GFP_KERNEL);
+ if (upldev == NULL) {
+ pr_err("%s: kzalloc() failed.\n", __func__);
+ return -ENOMEM;
+ }
+
+ mutex_init(&upldev->upl_mutex);
+
+ upl_dev = upldev;
+ upldev->dev = &pdev->dev;
+ platform_set_drvdata(pdev, upldev);
+
+#if defined(CONFIG_DEBUG_FS)
+ pm8xxx_upl_debug_init(upl_dev);
+#endif
+ pr_notice("%s: OK\n", __func__);
+ return 0;
+}
+
+static int __devexit pm8xxx_upl_remove(struct platform_device *pdev)
+{
+ struct pm8xxx_upl_device *upldev = platform_get_drvdata(pdev);
+
+#if defined(CONFIG_DEBUG_FS)
+ pm8xxx_upl_debug_remove(upldev);
+#endif
+
+ platform_set_drvdata(pdev, NULL);
+ kfree(upldev);
+ pr_notice("%s: OK\n", __func__);
+
+ return 0;
+}
+
+static struct platform_driver pm8xxx_upl_driver = {
+ .probe = pm8xxx_upl_probe,
+ .remove = __devexit_p(pm8xxx_upl_remove),
+ .driver = {
+ .name = PM8XXX_UPL_DEV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init pm8xxx_upl_init(void)
+{
+ return platform_driver_register(&pm8xxx_upl_driver);
+}
+
+static void __exit pm8xxx_upl_exit(void)
+{
+ platform_driver_unregister(&pm8xxx_upl_driver);
+}
+
+module_init(pm8xxx_upl_init);
+module_exit(pm8xxx_upl_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PM8XXX UPL driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:" PM8XXX_UPL_DEV_NAME);
diff --git a/drivers/misc/pm8xxx-vibrator.c b/drivers/misc/pm8xxx-vibrator.c
index 8aa7f72..4f22efe 100644
--- a/drivers/misc/pm8xxx-vibrator.c
+++ b/drivers/misc/pm8xxx-vibrator.c
@@ -27,6 +27,7 @@
#define VIB_DRV_SEL_MASK 0xf8
#define VIB_DRV_SEL_SHIFT 0x03
#define VIB_DRV_EN_MANUAL_MASK 0xfc
+#define VIB_DRV_LOGIC_SHIFT 0x2
#define VIB_MAX_LEVEL_mV 3100
#define VIB_MIN_LEVEL_mV 1200
@@ -43,6 +44,40 @@
u8 reg_vib_drv;
};
+static struct pm8xxx_vib *vib_dev;
+
+int pm8xxx_vibrator_config(struct pm8xxx_vib_config *vib_config)
+{
+ u8 reg = 0;
+ int rc;
+
+ if (vib_dev == NULL) {
+ pr_err("%s: vib_dev is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ if (vib_config->drive_mV) {
+ if ((vib_config->drive_mV < VIB_MIN_LEVEL_mV) ||
+ (vib_config->drive_mV > VIB_MAX_LEVEL_mV)) {
+ pr_err("Invalid vibrator drive strength\n");
+ return -EINVAL;
+ }
+ }
+
+ reg = (vib_config->drive_mV / 100) << VIB_DRV_SEL_SHIFT;
+
+ reg |= (!!vib_config->active_low) << VIB_DRV_LOGIC_SHIFT;
+
+ reg |= vib_config->enable_mode;
+
+ rc = pm8xxx_writeb(vib_dev->dev->parent, VIB_DRV, reg);
+ if (rc)
+ pr_err("%s: pm8xxx write failed: rc=%d\n", __func__, rc);
+
+ return rc;
+}
+EXPORT_SYMBOL(pm8xxx_vibrator_config);
+
/* REVISIT: just for debugging, will be removed in final working version */
static void __dump_vib_regs(struct pm8xxx_vib *vib, char *msg)
{
@@ -240,6 +275,8 @@
platform_set_drvdata(pdev, vib);
+ vib_dev = vib;
+
return 0;
err_read_vib:
diff --git a/drivers/misc/pmic8058-nfc.c b/drivers/misc/pmic8058-nfc.c
deleted file mode 100644
index 76a19f4..0000000
--- a/drivers/misc/pmic8058-nfc.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-/*
- * Qualcomm PMIC8058 NFC driver
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/mfd/pmic8058.h>
-#include <linux/pmic8058-nfc.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-
-/* PMIC8058 NFC */
-#define SSBI_REG_NFC_CTRL 0x14D
-#define SSBI_REG_NFC_TEST 0x14E
-
-/* NFC_CTRL */
-#define PM8058_NFC_SUPPORT_EN 0x80
-#define PM8058_NFC_LDO_EN 0x40
-#define PM8058_NFC_EN 0x20
-#define PM8058_NFC_EXT_VDDLDO_EN 0x10
-#define PM8058_NFC_VPH_PWR_EN 0x08
-#define PM8058_NFC_RESERVED 0x04
-#define PM8058_NFC_VDDLDO_LEVEL 0x03
-
-/* NFC_TEST */
-#define PM8058_NFC_VDDLDO_MON_EN 0x80
-#define PM8058_NFC_ATEST_EN 0x40
-#define PM8058_NFC_DTEST1_EN 0x20
-#define PM8058_NFC_RESERVED2 0x18
-#define PM8058_NFC_VDDLDO_OK_S 0x04
-#define PM8058_NFC_MBG_EN_S 0x02
-#define PM8058_NFC_EXT_EN_S 0x01
-
-struct pm8058_nfc_device {
- struct mutex nfc_mutex;
- struct pm8058_chip *pm_chip;
-#if defined(CONFIG_DEBUG_FS)
- struct dentry *dent;
-#endif
-};
-static struct pm8058_nfc_device *nfc_dev;
-
-/* APIs */
-/*
- * pm8058_nfc_request - request a handle to access NFC device
- */
-struct pm8058_nfc_device *pm8058_nfc_request(void)
-{
- return nfc_dev;
-}
-EXPORT_SYMBOL(pm8058_nfc_request);
-
-/*
- * pm8058_nfc_config - configure NFC signals
- *
- * @nfcdev: the NFC device
- * @mask: signal mask to configure
- * @flags: control flags
- */
-int pm8058_nfc_config(struct pm8058_nfc_device *nfcdev, u32 mask, u32 flags)
-{
- u8 nfc_ctrl, nfc_test, m, f;
- int rc;
-
- if (nfcdev == NULL || IS_ERR(nfcdev) || !mask)
- return -EINVAL;
- if (nfcdev->pm_chip == NULL)
- return -ENODEV;
-
- mutex_lock(&nfcdev->nfc_mutex);
-
- if (!(mask & PM_NFC_CTRL_REQ))
- goto config_test;
-
- rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_CTRL, &nfc_ctrl, 1);
- if (rc) {
- pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_ctrl=0x%x)\n",
- __func__, rc, nfc_ctrl);
- goto config_done;
- }
-
- m = mask & 0x00ff;
- f = flags & 0x00ff;
- nfc_ctrl &= ~m;
- nfc_ctrl |= m & f;
-
- rc = pm8058_write(nfcdev->pm_chip, SSBI_REG_NFC_CTRL, &nfc_ctrl, 1);
- if (rc) {
- pr_err("%s: FAIL pm8058_write(): rc=%d (nfc_ctrl=0x%x)\n",
- __func__, rc, nfc_ctrl);
- goto config_done;
- }
-
-config_test:
- if (!(mask & PM_NFC_TEST_REQ))
- goto config_done;
-
- rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_TEST, &nfc_test, 1);
- if (rc) {
- pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_test=0x%x)\n",
- __func__, rc, nfc_test);
- goto config_done;
- }
-
- m = (mask >> 8) & 0x00ff;
- f = (flags >> 8) & 0x00ff;
- nfc_test &= ~m;
- nfc_test |= m & f;
-
- rc = pm8058_write(nfcdev->pm_chip, SSBI_REG_NFC_TEST, &nfc_test, 1);
- if (rc) {
- pr_err("%s: FAIL pm8058_write(): rc=%d (nfc_test=0x%x)\n",
- __func__, rc, nfc_test);
- goto config_done;
- }
-
-config_done:
- mutex_unlock(&nfcdev->nfc_mutex);
- return 0;
-}
-EXPORT_SYMBOL(pm8058_nfc_config);
-
-/*
- * pm8058_nfc_get_status - get NFC status
- *
- * @nfcdev: the NFC device
- * @mask: of status mask to read
- * @status: pointer to the status variable
- */
-int pm8058_nfc_get_status(struct pm8058_nfc_device *nfcdev,
- u32 mask, u32 *status)
-{
- u8 nfc_ctrl, nfc_test;
- u32 st;
- int rc;
-
- if (nfcdev == NULL || IS_ERR(nfcdev) || status == NULL)
- return -EINVAL;
- if (nfcdev->pm_chip == NULL)
- return -ENODEV;
-
- st = 0;
- mutex_lock(&nfcdev->nfc_mutex);
-
- if (!(mask & PM_NFC_CTRL_REQ))
- goto read_test;
-
- rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_CTRL, &nfc_ctrl, 1);
- if (rc) {
- pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_ctrl=0x%x)\n",
- __func__, rc, nfc_ctrl);
- goto get_status_done;
- }
-
-read_test:
- if (!(mask & (PM_NFC_TEST_REQ | PM_NFC_TEST_STATUS)))
- goto get_status_done;
-
- rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_TEST, &nfc_test, 1);
- if (rc)
- pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_test=0x%x)\n",
- __func__, rc, nfc_test);
-
-get_status_done:
- st = nfc_ctrl;
- st |= nfc_test << 8;
- *status = st;
-
- mutex_unlock(&nfcdev->nfc_mutex);
- return 0;
-}
-EXPORT_SYMBOL(pm8058_nfc_get_status);
-
-/*
- * pm8058_nfc_free - free the NFC device
- */
-void pm8058_nfc_free(struct pm8058_nfc_device *nfcdev)
-{
- /* Disable all signals */
- pm8058_nfc_config(nfcdev, PM_NFC_CTRL_REQ, 0);
-}
-EXPORT_SYMBOL(pm8058_nfc_free);
-
-#if defined(CONFIG_DEBUG_FS)
-static int pm8058_nfc_debug_set(void *data, u64 val)
-{
- struct pm8058_nfc_device *nfcdev;
- u32 mask, control;
- int rc;
-
- nfcdev = (struct pm8058_nfc_device *)data;
- control = (u32)val & 0xffff;
- mask = ((u32)val >> 16) & 0xffff;
- rc = pm8058_nfc_config(nfcdev, mask, control);
- if (rc)
- pr_err("%s: ERR pm8058_nfc_config: rc=%d, "
- "[mask, control]=[0x%x, 0x%x]\n",
- __func__, rc, mask, control);
-
- return 0;
-}
-
-static int pm8058_nfc_debug_get(void *data, u64 *val)
-{
- struct pm8058_nfc_device *nfcdev;
- u32 status;
- int rc;
-
- nfcdev = (struct pm8058_nfc_device *)data;
- rc = pm8058_nfc_get_status(nfcdev, (u32)-1, &status);
- if (rc)
- pr_err("%s: ERR pm8058_nfc_get_status: rc=%d, status=0x%x\n",
- __func__, rc, status);
-
- if (val)
- *val = (u64)status;
- return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(pm8058_nfc_fops, pm8058_nfc_debug_get,
- pm8058_nfc_debug_set, "%llu\n");
-
-static int pm8058_nfc_debug_init(struct pm8058_nfc_device *nfcdev)
-{
- struct dentry *dent;
-
- dent = debugfs_create_file("pm8058-nfc", 0644, NULL,
- (void *)nfcdev, &pm8058_nfc_fops);
-
- if (dent == NULL || IS_ERR(dent))
- pr_err("%s: ERR debugfs_create_file: dent=0x%x\n",
- __func__, (unsigned)dent);
-
- nfcdev->dent = dent;
- return 0;
-}
-#endif
-
-static int __devinit pmic8058_nfc_probe(struct platform_device *pdev)
-{
- struct pm8058_chip *pm_chip;
- struct pm8058_nfc_device *nfcdev;
-
- pm_chip = dev_get_drvdata(pdev->dev.parent);
- if (pm_chip == NULL) {
- pr_err("%s: no parent data passed in.\n", __func__);
- return -EFAULT;
- }
-
- nfcdev = kzalloc(sizeof *nfcdev, GFP_KERNEL);
- if (nfcdev == NULL) {
- pr_err("%s: kzalloc() failed.\n", __func__);
- return -ENOMEM;
- }
-
- mutex_init(&nfcdev->nfc_mutex);
-
- nfcdev->pm_chip = pm_chip;
- nfc_dev = nfcdev;
- platform_set_drvdata(pdev, nfcdev);
-
-#if defined(CONFIG_DEBUG_FS)
- pm8058_nfc_debug_init(nfc_dev);
-#endif
-
- pr_notice("%s: OK\n", __func__);
- return 0;
-}
-
-static int __devexit pmic8058_nfc_remove(struct platform_device *pdev)
-{
- struct pm8058_nfc_device *nfcdev = platform_get_drvdata(pdev);
-
-#if defined(CONFIG_DEBUG_FS)
- debugfs_remove(nfcdev->dent);
-#endif
-
- platform_set_drvdata(pdev, nfcdev->pm_chip);
- kfree(nfcdev);
- return 0;
-}
-
-static struct platform_driver pmic8058_nfc_driver = {
- .probe = pmic8058_nfc_probe,
- .remove = __devexit_p(pmic8058_nfc_remove),
- .driver = {
- .name = "pm8058-nfc",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init pm8058_nfc_init(void)
-{
- return platform_driver_register(&pmic8058_nfc_driver);
-}
-
-static void __exit pm8058_nfc_exit(void)
-{
- platform_driver_unregister(&pmic8058_nfc_driver);
-}
-
-module_init(pm8058_nfc_init);
-module_exit(pm8058_nfc_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PMIC8058 NFC driver");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:pmic8058-nfc");
diff --git a/drivers/misc/pmic8058-pwm.c b/drivers/misc/pmic8058-pwm.c
index ad03b88..33407b7 100644
--- a/drivers/misc/pmic8058-pwm.c
+++ b/drivers/misc/pmic8058-pwm.c
@@ -19,11 +19,11 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/err.h>
#include <linux/pwm.h>
-#include <linux/mfd/pmic8058.h>
+#include <linux/mfd/pm8xxx/core.h>
#include <linux/pmic8058-pwm.h>
-#include <linux/slab.h>
#define PM8058_LPG_BANKS 8
#define PM8058_PWM_CHANNELS PM8058_LPG_BANKS /* MAX=8 */
@@ -179,6 +179,7 @@
struct pm8058_pwm_chip;
struct pwm_device {
+ struct device *dev;
int pwm_id; /* = bank/channel id */
int in_use;
const char *label;
@@ -188,14 +189,13 @@
int use_lut; /* Use LUT to output PWM */
u8 pwm_ctl[PM8058_LPG_CTL_REGS];
int irq;
- struct pm8058_pwm_chip *chip;
+ struct pm8058_pwm_chip *chip;
};
struct pm8058_pwm_chip {
struct pwm_device pwm_dev[PM8058_PWM_CHANNELS];
u8 bank_mask;
struct mutex pwm_mutex;
- struct pm8058_chip *pm_chip;
struct pm8058_pwm_pdata *pdata;
};
@@ -244,9 +244,10 @@
else
reg = chip->bank_mask & ~(1 << pwm->pwm_id);
- rc = pm8058_write(chip->pm_chip, SSBI_REG_ADDR_LPG_BANK_EN, ®, 1);
+ rc = pm8xxx_writeb(pwm->dev->parent,
+ SSBI_REG_ADDR_LPG_BANK_EN, reg);
if (rc) {
- pr_err("pm8058_write(): rc=%d (Enable LPG Bank)\n", rc);
+ pr_err("pm8xxx_write(): rc=%d (Enable LPG Bank)\n", rc);
goto bail_out;
}
chip->bank_mask = reg;
@@ -261,10 +262,10 @@
u8 reg;
reg = pwm->pwm_id;
- rc = pm8058_write(pwm->chip->pm_chip, SSBI_REG_ADDR_LPG_BANK_SEL,
- ®, 1);
+ rc = pm8xxx_writeb(pwm->dev->parent,
+ SSBI_REG_ADDR_LPG_BANK_SEL, reg);
if (rc)
- pr_err("pm8058_write(): rc=%d (Select PWM Bank)\n", rc);
+ pr_err("pm8xxx_write(): rc=%d (Select PWM Bank)\n", rc);
return rc;
}
@@ -284,10 +285,10 @@
reg &= ~PM8058_PWM_RAMP_GEN_START;
}
- rc = pm8058_write(pwm->chip->pm_chip, SSBI_REG_ADDR_LPG_CTL(0),
- ®, 1);
+ rc = pm8xxx_writeb(pwm->dev->parent, SSBI_REG_ADDR_LPG_CTL(0),
+ reg);
if (rc)
- pr_err("pm8058_write(): rc=%d (Enable PWM Ctl 0)\n", rc);
+ pr_err("pm8xxx_write(): rc=%d (Enable PWM Ctl 0)\n", rc);
else
pwm->pwm_ctl[0] = reg;
return rc;
@@ -415,15 +416,13 @@
cfg1 = (pwm_value >> 1) & 0x80;
cfg1 |= start_idx + i;
- rc = pm8058_write(pwm->chip->pm_chip,
- SSBI_REG_ADDR_LPG_LUT_CFG0,
- &cfg0, 1);
+ rc = pm8xxx_writeb(pwm->dev->parent,
+ SSBI_REG_ADDR_LPG_LUT_CFG0, cfg0);
if (rc)
break;
- rc = pm8058_write(pwm->chip->pm_chip,
- SSBI_REG_ADDR_LPG_LUT_CFG1,
- &cfg1, 1);
+ rc = pm8xxx_writeb(pwm->dev->parent,
+ SSBI_REG_ADDR_LPG_LUT_CFG1, cfg1);
if (rc)
break;
}
@@ -539,11 +538,11 @@
/* Write in reverse way so 0 would be the last */
for (i = end - 1; i >= start; i--) {
- rc = pm8058_write(pwm->chip->pm_chip,
+ rc = pm8xxx_writeb(pwm->dev->parent,
SSBI_REG_ADDR_LPG_CTL(i),
- &pwm->pwm_ctl[i], 1);
+ pwm->pwm_ctl[i]);
if (rc) {
- pr_err("pm8058_write(): rc=%d (PWM Ctl[%d])\n", rc, i);
+ pr_err("pm8xxx_write(): rc=%d (PWM Ctl[%d])\n", rc, i);
return rc;
}
}
@@ -957,8 +956,8 @@
case PM_PWM_LED_2:
conf = mode & PM8058_LED_MODE_MASK;
conf |= (max_current / 2) << PM8058_LED_CURRENT_SHIFT;
- rc = pm8058_write(pwm->chip->pm_chip,
- SSBI_REG_ADDR_LED(id), &conf, 1);
+ rc = pm8xxx_writeb(pwm->dev->parent,
+ SSBI_REG_ADDR_LED(id), conf);
break;
case PM_PWM_LED_KPD:
@@ -982,8 +981,8 @@
}
conf |= (max_current / 20) << PM8058_FLASH_CURRENT_SHIFT;
id -= PM_PWM_LED_KPD;
- rc = pm8058_write(pwm->chip->pm_chip,
- SSBI_REG_ADDR_FLASH(id), &conf, 1);
+ rc = pm8xxx_writeb(pwm->dev->parent,
+ SSBI_REG_ADDR_FLASH(id), conf);
break;
default:
rc = -EINVAL;
@@ -1012,10 +1011,10 @@
/* Only Test 1 available */
reg |= (1 << PM8058_PWM_DTEST_SHIFT) &
PM8058_PWM_DTEST_MASK;
- rc = pm8058_write(pwm->chip->pm_chip, SSBI_REG_ADDR_LPG_TEST,
- ®, 1);
+ rc = pm8xxx_writeb(pwm->dev->parent,
+ SSBI_REG_ADDR_LPG_TEST, reg);
if (rc)
- pr_err("pm8058_write(DTEST=0x%x): rc=%d\n", reg, rc);
+ pr_err("pm8xxx_write(DTEST=0x%x): rc=%d\n", reg, rc);
}
return rc;
@@ -1024,16 +1023,9 @@
static int __devinit pmic8058_pwm_probe(struct platform_device *pdev)
{
- struct pm8058_chip *pm_chip;
struct pm8058_pwm_chip *chip;
int i;
- pm_chip = dev_get_drvdata(pdev->dev.parent);
- if (pm_chip == NULL) {
- pr_err("no parent data passed in.\n");
- return -EFAULT;
- }
-
chip = kzalloc(sizeof *chip, GFP_KERNEL);
if (chip == NULL) {
pr_err("kzalloc() failed.\n");
@@ -1043,12 +1035,12 @@
for (i = 0; i < PM8058_PWM_CHANNELS; i++) {
chip->pwm_dev[i].pwm_id = i;
chip->pwm_dev[i].chip = chip;
+ chip->pwm_dev[i].dev = &pdev->dev;
}
mutex_init(&chip->pwm_mutex);
chip->pdata = pdev->dev.platform_data;
- chip->pm_chip = pm_chip;
pwm_chip = chip;
platform_set_drvdata(pdev, chip);
diff --git a/drivers/misc/pmic8058-upl.c b/drivers/misc/pmic8058-upl.c
deleted file mode 100644
index ae0abd8..0000000
--- a/drivers/misc/pmic8058-upl.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-/*
- * Qualcomm PMIC8058 UPL driver
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/mfd/pmic8058.h>
-#include <linux/pmic8058-upl.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-
-/* PMIC8058 UPL registers */
-#define SSBI_REG_UPL_CTRL 0x17B
-#define SSBI_REG_UPL_TRUTHTABLE1 0x17C
-#define SSBI_REG_UPL_TRUTHTABLE2 0x17D
-
-struct pm8058_upl_device {
- struct mutex upl_mutex;
- struct pm8058_chip *pm_chip;
-#if defined(CONFIG_DEBUG_FS)
- struct dentry *dent;
-#endif
-};
-static struct pm8058_upl_device *upl_dev;
-
-/* APIs */
-
-/*
- * pm8058_upl_request - request a handle to access UPL device
- */
-struct pm8058_upl_device *pm8058_upl_request(void)
-{
- return upl_dev;
-}
-EXPORT_SYMBOL(pm8058_upl_request);
-
-/*
- * pm8058_upl_read_truthtable - read value currently stored in UPL truth table
- *
- * @upldev: the UPL device
- * @truthtable: value read from UPL truth table
- */
-int pm8058_upl_read_truthtable(struct pm8058_upl_device *upldev,
- u16 *truthtable)
-{
- int rc = 0;
- u8 table[2];
-
- if (upldev == NULL || IS_ERR(upldev))
- return -EINVAL;
- if (upldev->pm_chip == NULL)
- return -ENODEV;
-
- mutex_lock(&upldev->upl_mutex);
-
- rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE1,
- &(table[0]), 1);
- if (rc) {
- pr_err("%s: FAIL pm8058_read(0x%X)=0x%02X: rc=%d\n",
- __func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
- goto upl_read_done;
- }
-
- rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE2,
- &(table[1]), 1);
- if (rc)
- pr_err("%s: FAIL pm8058_read(0x%X)=0x%02X: rc=%d\n",
- __func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
-upl_read_done:
- mutex_unlock(&upldev->upl_mutex);
- *truthtable = (((u16)table[1]) << 8) | table[0];
- return rc;
-}
-EXPORT_SYMBOL(pm8058_upl_read_truthtable);
-
-/*
- * pm8058_upl_writes_truthtable - write value into UPL truth table
- *
- * @upldev: the UPL device
- * @truthtable: value written to UPL truth table
- *
- * Each bit in parameter "truthtable" corresponds to the UPL output for a given
- * set of input pin values. For example, if the input pins have the following
- * values: A=1, B=1, C=1, D=0, then the UPL would output the value of bit 14
- * (0b1110) in parameter "truthtable".
- */
-int pm8058_upl_write_truthtable(struct pm8058_upl_device *upldev,
- u16 truthtable)
-{
- int rc = 0;
- u8 table[2];
-
- if (upldev == NULL || IS_ERR(upldev))
- return -EINVAL;
- if (upldev->pm_chip == NULL)
- return -ENODEV;
-
- table[0] = truthtable & 0xFF;
- table[1] = (truthtable >> 8) & 0xFF;
-
- mutex_lock(&upldev->upl_mutex);
-
- rc = pm8058_write(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE1,
- &(table[0]), 1);
- if (rc) {
- pr_err("%s: FAIL pm8058_write(0x%X)=0x%04X: rc=%d\n",
- __func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
- goto upl_write_done;
- }
-
- rc = pm8058_write(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE2,
- &(table[1]), 1);
- if (rc)
- pr_err("%s: FAIL pm8058_write(0x%X)=0x%04X: rc=%d\n",
- __func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
-upl_write_done:
- mutex_unlock(&upldev->upl_mutex);
- return rc;
-}
-EXPORT_SYMBOL(pm8058_upl_write_truthtable);
-
-/*
- * pm8058_upl_config - configure UPL I/O settings and UPL enable/disable
- *
- * @upldev: the UPL device
- * @mask: setting mask to configure
- * @flags: setting flags
- */
-int pm8058_upl_config(struct pm8058_upl_device *upldev, u32 mask, u32 flags)
-{
- int rc;
- u8 upl_ctrl, m, f;
-
- if (upldev == NULL || IS_ERR(upldev))
- return -EINVAL;
- if (upldev->pm_chip == NULL)
- return -ENODEV;
-
- mutex_lock(&upldev->upl_mutex);
-
- rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_CTRL, &upl_ctrl, 1);
- if (rc) {
- pr_err("%s: FAIL pm8058_read(0x%X)=0x%02X: rc=%d\n",
- __func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
- goto upl_config_done;
- }
-
- m = mask & 0x00ff;
- f = flags & 0x00ff;
- upl_ctrl &= ~m;
- upl_ctrl |= m & f;
-
- rc = pm8058_write(upldev->pm_chip, SSBI_REG_UPL_CTRL, &upl_ctrl, 1);
- if (rc)
- pr_err("%s: FAIL pm8058_write(0x%X)=0x%02X: rc=%d\n",
- __func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
-upl_config_done:
- mutex_unlock(&upldev->upl_mutex);
- return rc;
-}
-EXPORT_SYMBOL(pm8058_upl_config);
-
-#if defined(CONFIG_DEBUG_FS)
-
-static int truthtable_set(void *data, u64 val)
-{
- int rc;
-
- rc = pm8058_upl_write_truthtable(data, val);
- if (rc)
- pr_err("%s: pm8058_upl_write_truthtable: rc=%d, "
- "truthtable=0x%llX\n", __func__, rc, val);
- return rc;
-}
-
-static int truthtable_get(void *data, u64 *val)
-{
- int rc;
- u16 truthtable;
-
- rc = pm8058_upl_read_truthtable(data, &truthtable);
- if (rc)
- pr_err("%s: pm8058_upl_read_truthtable: rc=%d, "
- "truthtable=0x%X\n", __func__, rc, truthtable);
- if (val)
- *val = truthtable;
-
- return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(upl_truthtable_fops, truthtable_get,
- truthtable_set, "0x%04llX\n");
-
-/* enter values as 0xMMMMFFFF where MMMM is the mask and FFFF is the flags */
-static int control_set(void *data, u64 val)
-{
- u8 mask, flags;
- int rc;
-
- flags = val & 0xFFFF;
- mask = (val >> 16) & 0xFFFF;
-
- rc = pm8058_upl_config(data, mask, flags);
- if (rc)
- pr_err("%s: pm8058_upl_config: rc=%d, mask = 0x%X, "
- "flags = 0x%X\n", __func__, rc, mask, flags);
- return rc;
-}
-
-static int control_get(void *data, u64 *val)
-{
- struct pm8058_upl_device *upldev;
- int rc = 0;
- u8 ctrl;
-
- upldev = data;
-
- mutex_lock(&upldev->upl_mutex);
-
- rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_CTRL, &ctrl, 1);
- if (rc)
- pr_err("%s: FAIL pm8058_read(): rc=%d (ctrl=0x%02X)\n",
- __func__, rc, ctrl);
-
- mutex_unlock(&upldev->upl_mutex);
-
- *val = ctrl;
-
- return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(upl_control_fops, control_get,
- control_set, "0x%02llX\n");
-
-static int pm8058_upl_debug_init(struct pm8058_upl_device *upldev)
-{
- struct dentry *dent;
- struct dentry *temp;
-
- dent = debugfs_create_dir("pm8058-upl", NULL);
- if (dent == NULL || IS_ERR(dent)) {
- pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
- __func__, (unsigned)dent);
- return -ENOMEM;
- }
-
- temp = debugfs_create_file("truthtable", S_IRUSR | S_IWUSR, dent,
- upldev, &upl_truthtable_fops);
- if (temp == NULL || IS_ERR(temp)) {
- pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
- __func__, (unsigned)dent);
- goto debug_error;
- }
-
- temp = debugfs_create_file("control", S_IRUSR | S_IWUSR, dent,
- upldev, &upl_control_fops);
- if (temp == NULL || IS_ERR(temp)) {
- pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
- __func__, (unsigned)dent);
- goto debug_error;
- }
-
- upldev->dent = dent;
- return 0;
-
-debug_error:
- debugfs_remove_recursive(dent);
- return -ENOMEM;
-}
-
-static int __devexit pm8058_upl_debug_remove(struct pm8058_upl_device *upldev)
-{
- debugfs_remove_recursive(upldev->dent);
- return 0;
-}
-
-#endif /* CONFIG_DEBUG_FS */
-
-static int __devinit pmic8058_upl_probe(struct platform_device *pdev)
-{
- struct pm8058_chip *pm_chip;
- struct pm8058_upl_device *upldev;
-
- pm_chip = dev_get_drvdata(pdev->dev.parent);
- if (pm_chip == NULL) {
- pr_err("%s: no parent data passed in.\n", __func__);
- return -EFAULT;
- }
-
- upldev = kzalloc(sizeof *upldev, GFP_KERNEL);
- if (upldev == NULL) {
- pr_err("%s: kzalloc() failed.\n", __func__);
- return -ENOMEM;
- }
-
- mutex_init(&upldev->upl_mutex);
-
- upldev->pm_chip = pm_chip;
- upl_dev = upldev;
- platform_set_drvdata(pdev, upldev);
-
-#if defined(CONFIG_DEBUG_FS)
- pm8058_upl_debug_init(upl_dev);
-#endif
- pr_notice("%s: OK\n", __func__);
- return 0;
-}
-
-static int __devexit pmic8058_upl_remove(struct platform_device *pdev)
-{
- struct pm8058_upl_device *upldev = platform_get_drvdata(pdev);
-
-#if defined(CONFIG_DEBUG_FS)
- pm8058_upl_debug_remove(upldev);
-#endif
-
- platform_set_drvdata(pdev, upldev->pm_chip);
- kfree(upldev);
- pr_notice("%s: OK\n", __func__);
-
- return 0;
-}
-
-static struct platform_driver pmic8058_upl_driver = {
- .probe = pmic8058_upl_probe,
- .remove = __devexit_p(pmic8058_upl_remove),
- .driver = {
- .name = "pm8058-upl",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init pm8058_upl_init(void)
-{
- return platform_driver_register(&pmic8058_upl_driver);
-}
-
-static void __exit pm8058_upl_exit(void)
-{
- platform_driver_unregister(&pmic8058_upl_driver);
-}
-
-module_init(pm8058_upl_init);
-module_exit(pm8058_upl_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PMIC8058 UPL driver");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:pmic8058-upl");
diff --git a/drivers/misc/pmic8058-xoadc.c b/drivers/misc/pmic8058-xoadc.c
index b63800c..14b790f 100644
--- a/drivers/misc/pmic8058-xoadc.c
+++ b/drivers/misc/pmic8058-xoadc.c
@@ -17,7 +17,7 @@
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/msm_adc.h>
-#include <linux/pmic8058-xoadc.h>
+#include <linux/mfd/pm8xxx/core.h>
#include <linux/mfd/pmic8058.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
@@ -54,8 +54,8 @@
#define ADC_ARB_USRP_DATA1 0x19C
struct pmic8058_adc {
+ struct device *dev;
struct xoadc_platform_data *pdata;
- struct pm8058_chip *pm_chip;
struct adc_properties *adc_prop;
struct xoadc_conv_state conv[2];
int xoadc_queue_count;
@@ -144,8 +144,8 @@
/* Write twice to the CNTRL register for the arbiter settings
to take into effect */
for (i = 0; i < 2; i++) {
- rc = pm8058_write(adc_pmic->pm_chip, ADC_ARB_USRP_CNTRL,
- &data_arb_cntrl, 1);
+ rc = pm8xxx_writeb(adc_pmic->dev->parent, ADC_ARB_USRP_CNTRL,
+ data_arb_cntrl);
if (rc < 0) {
pr_debug("%s: PM8058 write failed\n", __func__);
return rc;
@@ -165,8 +165,8 @@
{
struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
- u8 data_arb_cntrl, data_amux_chan, data_arb_rsv, data_ana_param;
- u8 data_dig_param, data_ana_param2;
+ u8 data_arb_cntrl = 0, data_amux_chan = 0, data_arb_rsv = 0;
+ u8 data_dig_param = 0, data_ana_param2 = 0, data_ana_param = 0;
int rc;
rc = pm8058_xoadc_arb_cntrl(1, adc_instance, slot->chan_path);
@@ -307,15 +307,15 @@
break;
}
- rc = pm8058_write(adc_pmic->pm_chip,
- ADC_ARB_USRP_AMUX_CNTRL, &data_amux_chan, 1);
+ rc = pm8xxx_writeb(adc_pmic->dev->parent,
+ ADC_ARB_USRP_AMUX_CNTRL, data_amux_chan);
if (rc < 0) {
pr_debug("%s: PM8058 write failed\n", __func__);
return rc;
}
- rc = pm8058_write(adc_pmic->pm_chip,
- ADC_ARB_USRP_RSV, &data_arb_rsv, 1);
+ rc = pm8xxx_writeb(adc_pmic->dev->parent,
+ ADC_ARB_USRP_RSV, data_arb_rsv);
if (rc < 0) {
pr_debug("%s: PM8058 write failed\n", __func__);
return rc;
@@ -341,22 +341,22 @@
break;
}
- rc = pm8058_write(adc_pmic->pm_chip,
- ADC_ARB_USRP_ANA_PARAM, &data_ana_param, 1);
+ rc = pm8xxx_writeb(adc_pmic->dev->parent,
+ ADC_ARB_USRP_ANA_PARAM, data_ana_param);
if (rc < 0) {
pr_debug("%s: PM8058 write failed\n", __func__);
return rc;
}
- rc = pm8058_write(adc_pmic->pm_chip,
- ADC_ARB_USRP_DIG_PARAM, &data_dig_param, 1);
+ rc = pm8xxx_writeb(adc_pmic->dev->parent,
+ ADC_ARB_USRP_DIG_PARAM, data_dig_param);
if (rc < 0) {
pr_debug("%s: PM8058 write failed\n", __func__);
return rc;
}
- rc = pm8058_write(adc_pmic->pm_chip,
- ADC_ARB_USRP_ANA_PARAM, &data_ana_param2, 1);
+ rc = pm8xxx_writeb(adc_pmic->dev->parent,
+ ADC_ARB_USRP_ANA_PARAM, data_ana_param2);
if (rc < 0) {
pr_debug("%s: PM8058 write failed\n", __func__);
return rc;
@@ -364,8 +364,8 @@
enable_irq(adc_pmic->adc_irq);
- rc = pm8058_write(adc_pmic->pm_chip,
- ADC_ARB_USRP_CNTRL, &data_arb_cntrl, 1);
+ rc = pm8xxx_writeb(adc_pmic->dev->parent,
+ ADC_ARB_USRP_CNTRL, data_arb_cntrl);
if (rc < 0) {
pr_debug("%s: PM8058 write failed\n", __func__);
return rc;
@@ -434,13 +434,15 @@
if (!xoadc_initialized)
return -ENODEV;
- rc = pm8058_read(adc_pmic->pm_chip, ADC_ARB_USRP_DATA0, &rslt_lsb, 1);
+ rc = pm8xxx_readb(adc_pmic->dev->parent, ADC_ARB_USRP_DATA0,
+ &rslt_lsb);
if (rc < 0) {
pr_debug("%s: PM8058 read failed\n", __func__);
return rc;
}
- rc = pm8058_read(adc_pmic->pm_chip, ADC_ARB_USRP_DATA1, &rslt_msb, 1);
+ rc = pm8xxx_readb(adc_pmic->dev->parent, ADC_ARB_USRP_DATA1,
+ &rslt_msb);
if (rc < 0) {
pr_debug("%s: PM8058 read failed\n", __func__);
return rc;
@@ -657,7 +659,7 @@
wake_lock_destroy(&adc_pmic->adc_wakelock);
msm_xo_put(adc_pmic->adc_voter);
- platform_set_drvdata(pdev, adc_pmic->pm_chip);
+ platform_set_drvdata(pdev, NULL);
device_init_wakeup(&pdev->dev, 0);
kfree(adc_pmic);
xoadc_initialized = false;
@@ -668,16 +670,9 @@
static int __devinit pm8058_xoadc_probe(struct platform_device *pdev)
{
struct xoadc_platform_data *pdata = pdev->dev.platform_data;
- struct pm8058_chip *pm_chip;
struct pmic8058_adc *adc_pmic;
int i, rc = 0;
- pm_chip = dev_get_drvdata(pdev->dev.parent);
- if (pm_chip == NULL) {
- dev_err(&pdev->dev, "no parent data passed in\n");
- return -EFAULT;
- }
-
if (!pdata) {
dev_err(&pdev->dev, "no platform data?\n");
return -EINVAL;
@@ -689,7 +684,7 @@
return -ENOMEM;
}
- adc_pmic->pm_chip = pm_chip;
+ adc_pmic->dev = &pdev->dev;
adc_pmic->adc_prop = pdata->xoadc_prop;
adc_pmic->xoadc_num = pdata->xoadc_num;
adc_pmic->xoadc_queue_count = 0;
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index cca1035..3590e6d 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -244,7 +244,7 @@
config BATTERY_MSM8X60
tristate "MSM8X60 battery"
- select PMIC8058_BATTALARM
+ select PMIC8XXX_BATTALARM
help
Some MSM boards have dual charging paths to charge the battery.
Say Y to enable support for the battery charging in
diff --git a/drivers/power/pmic8058-charger.c b/drivers/power/pmic8058-charger.c
index a3ce54d..70b5d59 100644
--- a/drivers/power/pmic8058-charger.c
+++ b/drivers/power/pmic8058-charger.c
@@ -15,7 +15,6 @@
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/errno.h>
-#include <linux/mfd/pmic8058.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/bitops.h>
@@ -25,8 +24,10 @@
#include <linux/slab.h>
#include <linux/msm_adc.h>
#include <linux/notifier.h>
-#include <linux/pmic8058-batt-alarm.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pmic8058.h>
#include <linux/pmic8058-charger.h>
+#include <linux/mfd/pm8xxx/batt-alarm.h>
#include <mach/msm_xo.h>
#include <mach/msm_hsusb.h>
@@ -177,7 +178,6 @@
struct pm8058_charger {
struct pmic_charger_pdata *pdata;
- struct pm8058_chip *pm_chip;
struct device *dev;
int pmic_chg_irq[PMIC_CHG_MAX_INTS];
@@ -228,7 +228,11 @@
if (rc)
goto out;
- rc = pm8058_batt_alarm_threshold_set(resume_mv, 4300);
+ rc = pm8xxx_batt_alarm_threshold_set(
+ PM8XXX_BATT_ALARM_LOWER_COMPARATOR, resume_mv);
+ if (!rc)
+ rc = pm8xxx_batt_alarm_threshold_set(
+ PM8XXX_BATT_ALARM_UPPER_COMPARATOR, 4300);
out:
mutex_unlock(&batt_alarm_lock);
@@ -255,15 +259,9 @@
static int pm_chg_get_rt_status(int irq)
{
- int count = 3;
int ret;
- while ((ret =
- pm8058_irq_get_rt_status(pm8058_chg.pm_chip, irq)) == -EAGAIN
- && count--) {
- dev_info(pm8058_chg.dev, "%s trycount=%d\n", __func__, count);
- cpu_relax();
- }
+ ret = pm8xxx_read_irq_stat(pm8058_chg.dev->parent, irq);
if (ret == -EAGAIN)
return 0;
else
@@ -281,53 +279,53 @@
u8 temp;
int temp2;
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL_2 = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_VMAX_SEL, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_VMAX_SEL, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_VMAX_SEL = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_VBAT_DET, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_VBAT_DET, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_VBAT_DET = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_IMAX, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_IMAX, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_IMAX = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TRICKLE, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TRICKLE, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_TRICKLE = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_ITERM, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_ITERM, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_ITERM = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TTRKL_MAX, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TTRKL_MAX, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_TTRKL_MAX = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TCHG_MAX, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TCHG_MAX, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_TCHG_MAX = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEMP_THRESH, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEMP_THRESH, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_THRESH = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEMP_REG, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEMP_REG, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_REG = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_PULSE, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_PULSE, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_PULSE = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_1,
- &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_1,
+ &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_1 = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_3,
- &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_3,
+ &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_3 = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_10,
- &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_10,
+ &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_10 = 0x%x\n",
temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_11,
- &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_11,
+ &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_11 = 0x%x\n",
temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_1, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_1, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_1 = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_3, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_3, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_3 = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_10, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_10, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_10 = 0x%x\n", temp);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_11, &temp, 1);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_11, &temp);
dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_11 = 0x%x\n", temp);
temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGVAL_IRQ]);
@@ -405,7 +403,7 @@
u8 temp;
int ret;
- ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+ ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
if (ret)
return ret;
if (value)
@@ -413,7 +411,7 @@
else
temp &= ~BIT(CHG_USB_SUSPEND);
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
}
static int pm_chg_auto_disable(int value)
@@ -421,7 +419,7 @@
u8 temp;
int ret;
- ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+ ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
if (ret)
return ret;
if (value)
@@ -429,7 +427,7 @@
else
temp &= ~BIT(CHARGE_AUTO_DIS);
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
}
static int pm_chg_batt_temp_disable(int value)
@@ -437,7 +435,7 @@
u8 temp;
int ret;
- ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+ ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
if (ret)
return ret;
if (value)
@@ -445,7 +443,7 @@
else
temp &= ~BIT(CHG_BATT_TEMP_DIS);
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
}
static int pm_chg_vbatdet_set(int voltage)
@@ -463,7 +461,7 @@
temp = diff / PM8058_CHG_V_STEP_MV;
dev_dbg(pm8058_chg.dev, "%s voltage=%d setting %02x\n", __func__,
voltage, temp);
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_VBAT_DET, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_VBAT_DET, temp);
}
static int pm_chg_imaxsel_set(int chg_current)
@@ -484,7 +482,7 @@
__func__, chg_current);
temp = 31;
}
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_IMAX, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_IMAX, temp);
}
#define PM8058_CHG_VMAX_MIN 3300
@@ -501,7 +499,7 @@
temp = (voltage - PM8058_CHG_V_MIN_MV) / PM8058_CHG_V_STEP_MV;
dev_dbg(pm8058_chg.dev, "%s mV=%d setting %02x\n", __func__, voltage,
temp);
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_VMAX_SEL, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_VMAX_SEL, temp);
}
static int pm_chg_failed_clear(int value)
@@ -509,14 +507,14 @@
u8 temp;
int ret;
- ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+ ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
if (ret)
return ret;
if (value)
temp |= BIT(CHG_FAILED_CLEAR);
else
temp &= ~BIT(CHG_FAILED_CLEAR);
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
}
static int pm_chg_iterm_set(int chg_current)
@@ -524,7 +522,7 @@
u8 temp;
temp = (chg_current / PM8058_CHG_I_TERM_STEP_MA) - 1;
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_ITERM, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_ITERM, temp);
}
static int pm_chg_tchg_set(int minutes)
@@ -532,7 +530,7 @@
u8 temp;
temp = (minutes >> PM8058_CHG_T_TCHG_SHIFT) - 1;
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TCHG_MAX, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TCHG_MAX, temp);
}
static int pm_chg_ttrkl_set(int minutes)
@@ -540,7 +538,8 @@
u8 temp;
temp = minutes - 1;
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TTRKL_MAX, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TTRKL_MAX,
+ temp);
}
static int pm_chg_enum_done_enable(int value)
@@ -548,7 +547,7 @@
u8 temp;
int ret;
- ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+ ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
if (ret)
return ret;
if (value)
@@ -556,7 +555,7 @@
else
temp &= ~BIT(ENUM_DONE);
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
}
static uint32_t get_fsm_state(void)
@@ -564,8 +563,8 @@
u8 temp;
temp = 0x00;
- pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
+ pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, temp);
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, &temp);
return (uint32_t)temp;
}
@@ -590,7 +589,7 @@
u8 temp;
int ret;
- ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+ ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
if (ret)
return ret;
if (value)
@@ -598,7 +597,7 @@
else
temp &= ~BIT(CHG_CHARGE_DIS);
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
}
static void pm8058_start_system_current(struct msm_hardware_charger *hw_chg,
@@ -734,7 +733,11 @@
case PMIC8058_CHG_STATE_ATC:
case PMIC8058_CHG_STATE_FAST_CHG:
case PMIC8058_CHG_STATE_TRKL_CHG:
- rc = pm8058_batt_alarm_state_set(0, 0);
+ rc = pm8xxx_batt_alarm_disable(
+ PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+ if (!rc)
+ rc = pm8xxx_batt_alarm_disable(
+ PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
if (rc)
dev_err(pm8058_chg.dev,
"%s: unable to set alarm state\n", __func__);
@@ -863,25 +866,25 @@
}
} else {
if (pm8058_chg.present) {
- ret = pm8058_read(pm8058_chg.pm_chip,
+ ret = pm8xxx_readb(pm8058_chg.dev->parent,
PM8058_OVP_TEST_REG,
- &old, 1);
+ &old);
temp = old | BIT(FORCE_OVP_OFF);
- ret = pm8058_write(pm8058_chg.pm_chip,
+ ret = pm8xxx_writeb(pm8058_chg.dev->parent,
PM8058_OVP_TEST_REG,
- &temp, 1);
+ temp);
temp = 0xFC;
- ret = pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST,
- &temp, 1);
+ ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+ PM8058_CHG_TEST, temp);
/* 10 ms sleep is for the VCHG to discharge */
msleep(10);
temp = 0xF0;
- ret = pm8058_write(pm8058_chg.pm_chip,
+ ret = pm8xxx_writeb(pm8058_chg.dev->parent,
PM8058_CHG_TEST,
- &temp, 1);
- ret = pm8058_write(pm8058_chg.pm_chip,
+ temp);
+ ret = pm8xxx_writeb(pm8058_chg.dev->parent,
PM8058_OVP_TEST_REG,
- &old, 1);
+ old);
pm_chg_enum_done_enable(0);
pm_chg_auto_disable(1);
@@ -904,21 +907,21 @@
pm_chg_enum_done_enable(0);
pm_chg_auto_disable(1);
- ret = pm8058_read(pm8058_chg.pm_chip,
- PM8058_OVP_TEST_REG, &old, 1);
+ ret = pm8xxx_readb(pm8058_chg.dev->parent,
+ PM8058_OVP_TEST_REG, &old);
temp = old | BIT(FORCE_OVP_OFF);
- ret = pm8058_write(pm8058_chg.pm_chip,
- PM8058_OVP_TEST_REG, &temp, 1);
+ ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+ PM8058_OVP_TEST_REG, temp);
temp = 0xFC;
- ret = pm8058_write(pm8058_chg.pm_chip,
- PM8058_CHG_TEST, &temp, 1);
+ ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+ PM8058_CHG_TEST, temp);
/* 10 ms sleep is for the VCHG to discharge */
msleep(10);
temp = 0xF0;
- ret = pm8058_write(pm8058_chg.pm_chip,
- PM8058_CHG_TEST, &temp, 1);
- ret = pm8058_write(pm8058_chg.pm_chip,
- PM8058_OVP_TEST_REG, &old, 1);
+ ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+ PM8058_CHG_TEST, temp);
+ ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+ PM8058_OVP_TEST_REG, old);
if (!is_chg_plugged_in()) {
msm_charger_notify_event(&usb_hw_chg,
@@ -983,8 +986,8 @@
u8 temp;
temp = 0x00;
- if (!pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1)) {
- pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
+ if (!pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, temp)) {
+ pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, &temp);
dev_dbg(pm8058_chg.dev, "%s state=%d\n", __func__, temp);
}
return IRQ_HANDLED;
@@ -1187,7 +1190,7 @@
"%s:couldnt find resource AUTO_CHGDONE\n", __func__);
goto err_out;
} else {
- ret = request_threaded_irq(res->start, NULL,
+ ret = request_irq(res->start,
pm8058_chg_auto_chgdone_handler,
IRQF_TRIGGER_RISING,
res->name, NULL);
@@ -1208,7 +1211,7 @@
"%s:couldnt find resource AUTO_CHGFAIL\n", __func__);
goto err_out;
} else {
- ret = request_threaded_irq(res->start, NULL,
+ ret = request_irq(res->start,
pm8058_chg_auto_chgfail_handler,
IRQF_TRIGGER_RISING, res->name, NULL);
if (ret < 0) {
@@ -1227,7 +1230,7 @@
"%s:couldnt find resource CHGSTATE\n", __func__);
goto err_out;
} else {
- ret = request_threaded_irq(res->start, NULL,
+ ret = request_irq(res->start,
pm8058_chg_chgstate_handler,
IRQF_TRIGGER_RISING, res->name, NULL);
if (ret < 0) {
@@ -1246,7 +1249,7 @@
"%s:couldnt find resource FASTCHG\n", __func__);
goto err_out;
} else {
- ret = request_threaded_irq(res->start, NULL,
+ ret = request_irq(res->start,
pm8058_chg_fastchg_handler,
IRQF_TRIGGER_RISING, res->name, NULL);
if (ret < 0) {
@@ -1265,7 +1268,7 @@
"%s:couldnt find resource CHG_END\n", __func__);
goto err_out;
} else {
- ret = request_threaded_irq(res->start, NULL,
+ ret = request_irq(res->start,
pm8058_chg_batttemp_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
res->name, NULL);
@@ -1286,7 +1289,7 @@
"%s:couldnt find resource BATT_REPLACE\n", __func__);
goto err_out;
} else {
- ret = request_threaded_irq(res->start, NULL,
+ ret = request_irq(res->start,
pm8058_chg_batt_replace_handler,
IRQF_TRIGGER_RISING, res->name, NULL);
if (ret < 0) {
@@ -1305,7 +1308,7 @@
"%s:couldnt find resource BATTCONNECT\n", __func__);
goto err_out;
} else {
- ret = request_threaded_irq(res->start, NULL,
+ ret = request_irq(res->start,
pm8058_chg_battconnect_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
res->name, NULL);
@@ -1351,7 +1354,7 @@
u8 temp;
int rc;
- rc = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+ rc = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
if (rc)
return rc;
@@ -1367,7 +1370,7 @@
u8 temp;
int rc;
- rc = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+ rc = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
if (rc)
return rc;
if (on)
@@ -1375,7 +1378,7 @@
else
temp &= ~BIT(CHG_CHARGE_BAT);
- return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+ return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
}
EXPORT_SYMBOL(pm8058_set_charge_batt);
@@ -1496,12 +1499,12 @@
u8 temp;
temp = 0xA3;
- pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
+ pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
temp = 0x84;
- pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
+ pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
msleep(2);
temp = 0x80;
- pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
+ pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
return 0;
}
@@ -1511,7 +1514,7 @@
int ret;
u8 temp;
- ret = pm8058_read(pm8058_chg.pm_chip, i, &temp, 1);
+ ret = pm8xxx_readb(pm8058_chg.dev->parent, i, &temp);
if (ret)
return -EAGAIN;
*val = temp;
@@ -1525,7 +1528,7 @@
u8 temp;
temp = (u8) val;
- ret = pm8058_write(pm8058_chg.pm_chip, i, &temp, 1);
+ ret = pm8xxx_writeb(pm8058_chg.dev->parent, i, temp);
mb();
if (ret)
return -EAGAIN;
@@ -1821,7 +1824,11 @@
break;
/* expected case - trip of low threshold */
case 1:
- rc = pm8058_batt_alarm_state_set(0, 0);
+ rc = pm8xxx_batt_alarm_disable(
+ PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+ if (!rc)
+ rc = pm8xxx_batt_alarm_disable(
+ PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
if (rc)
dev_err(pm8058_chg.dev,
"%s: unable to set alarm state\n", __func__);
@@ -1841,8 +1848,15 @@
static int pm8058_monitor_for_recharging(void)
{
+ int rc;
/* enable low comparator */
- return pm8058_batt_alarm_state_set(1, 0);
+ rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+ if (!rc)
+ return pm8xxx_batt_alarm_enable(
+ PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+
+ return rc;
+
}
static struct msm_battery_gauge pm8058_batt_gauge = {
@@ -1860,33 +1874,30 @@
int ret = 0;
temp = 0x10;
- ret |= pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST, &temp, 1);
- ret |= pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST, &old, 1);
+ ret |= pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST, temp);
+ ret |= pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST, &old);
old = old & ~BIT(IGNORE_LL);
temp = 0x90 | (0xF & old);
- ret |= pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST, &temp, 1);
+ ret |= pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST, temp);
return ret;
}
static int __devinit pm8058_charger_probe(struct platform_device *pdev)
{
- struct pm8058_chip *pm_chip;
struct pmic8058_charger_data *pdata;
int rc = 0;
- pm_chip = dev_get_drvdata(pdev->dev.parent);
- if (pm_chip == NULL) {
- pr_err("%s:no parent data passed in.\n", __func__);
- return -EFAULT;
- }
-
- pm8058_chg.pm_chip = pm_chip;
pm8058_chg.pdata = pdev->dev.platform_data;
pm8058_chg.dev = &pdev->dev;
pdata = (struct pmic8058_charger_data *) pm8058_chg.pdata;
- if (pdata) {
+ if (pdata == NULL) {
+ pr_err("%s: pdata not present\n", __func__);
+ return -EINVAL;
+ }
+
+ if (pdata->charger_data_valid) {
usb_hw_chg.type = pdata->charger_type;
chg_data.charger_type = pdata->charger_type;
chg_data.max_source_current = pdata->max_source_current;
@@ -1928,7 +1939,10 @@
pm8058_chg_enable_irq(BATTTEMP_IRQ);
pm8058_chg_enable_irq(BATTCONNECT_IRQ);
- rc = pm8058_batt_alarm_state_set(0, 0);
+ rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+ if (!rc)
+ rc = pm8xxx_batt_alarm_disable(
+ PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
if (rc) {
pr_err("%s: unable to set batt alarm state\n", __func__);
goto free_irq;
@@ -1938,26 +1952,31 @@
* The batt-alarm driver requires sane values for both min / max,
* regardless of whether they're both activated.
*/
- rc = pm8058_batt_alarm_threshold_set(resume_mv, 4300);
+ rc = pm8xxx_batt_alarm_threshold_set(
+ PM8XXX_BATT_ALARM_LOWER_COMPARATOR, resume_mv);
+ if (!rc)
+ rc = pm8xxx_batt_alarm_threshold_set(
+ PM8XXX_BATT_ALARM_UPPER_COMPARATOR, 4300);
if (rc) {
pr_err("%s: unable to set batt alarm threshold\n", __func__);
goto free_irq;
}
- rc = pm8058_batt_alarm_hold_time_set(PM8058_BATT_ALARM_HOLD_TIME_16_MS);
+ rc = pm8xxx_batt_alarm_hold_time_set(
+ PM8XXX_BATT_ALARM_HOLD_TIME_16_MS);
if (rc) {
pr_err("%s: unable to set batt alarm hold time\n", __func__);
goto free_irq;
}
/* PWM enabled at 2Hz */
- rc = pm8058_batt_alarm_pwm_rate_set(1, 7, 4);
+ rc = pm8xxx_batt_alarm_pwm_rate_set(1, 7, 4);
if (rc) {
pr_err("%s: unable to set batt alarm pwm rate\n", __func__);
goto free_irq;
}
- rc = pm8058_batt_alarm_register_notifier(&alarm_notifier);
+ rc = pm8xxx_batt_alarm_register_notifier(&alarm_notifier);
if (rc) {
pr_err("%s: unable to register alarm notifier\n", __func__);
goto free_irq;
@@ -1987,11 +2006,14 @@
remove_debugfs_entries();
kfree(chip);
- rc = pm8058_batt_alarm_state_set(0, 0);
+ rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+ if (!rc)
+ rc = pm8xxx_batt_alarm_disable(
+ PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
if (rc)
pr_err("%s: unable to set batt alarm state\n", __func__);
- rc |= pm8058_batt_alarm_unregister_notifier(&alarm_notifier);
+ rc |= pm8xxx_batt_alarm_unregister_notifier(&alarm_notifier);
if (rc)
pr_err("%s: unable to register alarm notifier\n", __func__);
return rc;
diff --git a/drivers/regulator/pm8058-xo.c b/drivers/regulator/pm8058-xo.c
index 581e228..b778660 100644
--- a/drivers/regulator/pm8058-xo.c
+++ b/drivers/regulator/pm8058-xo.c
@@ -19,6 +19,7 @@
#include <linux/bitops.h>
#include <linux/mfd/pmic8058.h>
#include <linux/regulator/driver.h>
+#include <linux/mfd/pm8xxx/core.h>
#include <linux/regulator/pm8058-xo.h>
/* XO buffer masks and values */
@@ -39,6 +40,7 @@
#define XO_DISABLE (XO_MODE_MANUAL | XO_BUFFER_DISABLE)
struct pm8058_xo_buffer {
+ struct device *dev;
struct pm8058_xo_pdata *pdata;
struct regulator_dev *rdev;
u16 ctrl_addr;
@@ -55,7 +57,7 @@
XO_BUFFER(A1, 0x186),
};
-static int pm8058_xo_buffer_write(struct pm8058_chip *chip,
+static int pm8058_xo_buffer_write(struct pm8058_xo_buffer *xo,
u16 addr, u8 val, u8 mask, u8 *reg_save)
{
u8 reg;
@@ -63,10 +65,10 @@
reg = (*reg_save & ~mask) | (val & mask);
if (reg != *reg_save)
- rc = pm8058_write(chip, addr, ®, 1);
+ rc = pm8xxx_writeb(xo->dev->parent, addr, reg);
if (rc)
- pr_err("FAIL: pm8058_write: rc=%d\n", rc);
+ pr_err("FAIL: pm8xxx_write: rc=%d\n", rc);
else
*reg_save = reg;
return rc;
@@ -75,10 +77,9 @@
static int pm8058_xo_buffer_enable(struct regulator_dev *dev)
{
struct pm8058_xo_buffer *xo = rdev_get_drvdata(dev);
- struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
int rc;
- rc = pm8058_xo_buffer_write(chip, xo->ctrl_addr, XO_ENABLE,
+ rc = pm8058_xo_buffer_write(xo, xo->ctrl_addr, XO_ENABLE,
XO_ENABLE_MASK, &xo->ctrl_reg);
if (rc)
pr_err("FAIL: pm8058_xo_buffer_write: rc=%d\n", rc);
@@ -99,10 +100,9 @@
static int pm8058_xo_buffer_disable(struct regulator_dev *dev)
{
struct pm8058_xo_buffer *xo = rdev_get_drvdata(dev);
- struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
int rc;
- rc = pm8058_xo_buffer_write(chip, xo->ctrl_addr, XO_DISABLE,
+ rc = pm8058_xo_buffer_write(xo, xo->ctrl_addr, XO_DISABLE,
XO_ENABLE_MASK, &xo->ctrl_reg);
if (rc)
pr_err("FAIL: pm8058_xo_buffer_write: rc=%d\n", rc);
@@ -130,23 +130,21 @@
VREG_DESCRIP(PM8058_XO_ID_A1, "8058_xo_a1", &pm8058_xo_ops),
};
-static int pm8058_init_xo_buffer(struct pm8058_chip *chip,
- struct pm8058_xo_buffer *xo)
+static int pm8058_init_xo_buffer(struct pm8058_xo_buffer *xo)
{
int rc;
/* Save the current control register state */
- rc = pm8058_read(chip, xo->ctrl_addr, &xo->ctrl_reg, 1);
+ rc = pm8xxx_readb(xo->dev->parent, xo->ctrl_addr, &xo->ctrl_reg);
if (rc)
- pr_err("FAIL: pm8058_read: rc=%d\n", rc);
+ pr_err("FAIL: pm8xxx_read: rc=%d\n", rc);
return rc;
}
static int __devinit pm8058_xo_buffer_probe(struct platform_device *pdev)
{
struct regulator_desc *rdesc;
- struct pm8058_chip *chip;
struct pm8058_xo_buffer *xo;
int rc = 0;
@@ -154,16 +152,15 @@
return -EINVAL;
if (pdev->id >= 0 && pdev->id < PM8058_XO_ID_MAX) {
- chip = dev_get_drvdata(pdev->dev.parent);
rdesc = &pm8058_xo_buffer_desc[pdev->id];
xo = &pm8058_xo_buffer[pdev->id];
xo->pdata = pdev->dev.platform_data;
+ xo->dev = &pdev->dev;
- rc = pm8058_init_xo_buffer(chip, xo);
+ rc = pm8058_init_xo_buffer(xo);
if (rc)
goto bail;
- platform_set_drvdata(pdev, chip);
xo->rdev = regulator_register(rdesc, &pdev->dev,
&xo->pdata->init_data, xo);
if (IS_ERR(xo->rdev)) {
diff --git a/drivers/regulator/pmic8058-regulator.c b/drivers/regulator/pmic8058-regulator.c
index c11f32b..e137b0f 100644
--- a/drivers/regulator/pmic8058-regulator.c
+++ b/drivers/regulator/pmic8058-regulator.c
@@ -18,6 +18,7 @@
#include <linux/mfd/pmic8058.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
+#include <linux/mfd/pm8xxx/core.h>
#include <linux/regulator/pmic8058-regulator.h>
/* Regulator types */
@@ -205,6 +206,7 @@
};
struct pm8058_vreg {
+ struct device *dev;
struct pm8058_vreg_pdata *pdata;
struct regulator_dev *rdev;
struct pm8058_enable *global_enable[GLOBAL_ENABLE_MAX];
@@ -375,11 +377,9 @@
NCP(NCP, 0x090, 0x0EC),
};
-static int pm8058_smps_set_voltage_advanced(struct pm8058_vreg *vreg,
- struct pm8058_chip *chip, int uV,
+static int pm8058_smps_set_voltage_advanced(struct pm8058_vreg *vreg, int uV,
int force_on);
-static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg,
- struct pm8058_chip *chip, int uV);
+static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg, int uV);
static int _pm8058_vreg_is_enabled(struct pm8058_vreg *vreg);
static unsigned int pm8058_vreg_get_mode(struct regulator_dev *dev);
@@ -387,7 +387,7 @@
static void print_write_error(struct pm8058_vreg *vreg, int rc,
const char *func);
-static int pm8058_vreg_write(struct pm8058_chip *chip,
+static int pm8058_vreg_write(struct pm8058_vreg *vreg,
u16 addr, u8 val, u8 mask, u8 *reg_save)
{
int rc = 0;
@@ -395,9 +395,9 @@
reg = (*reg_save & ~mask) | (val & mask);
if (reg != *reg_save)
- rc = pm8058_write(chip, addr, ®, 1);
+ rc = pm8xxx_writeb(vreg->dev->parent, addr, reg);
if (rc)
- pr_err("%s: pm8058_write failed, rc=%d\n", __func__, rc);
+ pr_err("%s: pm8xxx_write failed, rc=%d\n", __func__, rc);
else
*reg_save = reg;
return rc;
@@ -416,14 +416,13 @@
}
-static int pm8058_vreg_set_global_enable(struct pm8058_vreg *vreg,
- struct pm8058_chip *chip, int on)
+static int pm8058_vreg_set_global_enable(struct pm8058_vreg *vreg, int on)
{
int rc = 0, i;
for (i = 0;
(i < GLOBAL_ENABLE_MAX) && !rc && vreg->global_enable[i]; i++)
- rc = pm8058_vreg_write(chip, vreg->global_enable[i]->addr,
+ rc = pm8058_vreg_write(vreg, vreg->global_enable[i]->addr,
(on ? vreg->global_enable_mask[i] : 0),
vreg->global_enable_mask[i],
&vreg->global_enable[i]->reg);
@@ -452,8 +451,7 @@
return ret;
}
-static int pm8058_vreg_set_pin_ctrl(struct pm8058_vreg *vreg,
- struct pm8058_chip *chip, int on)
+static int pm8058_vreg_set_pin_ctrl(struct pm8058_vreg *vreg, int on)
{
int rc = 0, bank;
u8 val = 0, mask;
@@ -473,7 +471,7 @@
val |= LDO_TEST_PIN_CTRL_EN3;
bank = (pf == PM8058_VREG_PIN_FN_ENABLE ? 5 : 6);
- rc = pm8058_vreg_write(chip, vreg->test_addr,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr,
val | REGULATOR_BANK_SEL(bank)
| REGULATOR_BANK_WRITE,
LDO_TEST_PIN_CTRL_MASK | REGULATOR_BANK_MASK,
@@ -484,26 +482,25 @@
val = LDO_TEST_LPM_SEL_CTRL | REGULATOR_BANK_WRITE
| REGULATOR_BANK_SEL(0);
mask = LDO_TEST_LPM_MASK | REGULATOR_BANK_MASK;
- rc = pm8058_vreg_write(chip, vreg->test_addr, val, mask,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr, val, mask,
&vreg->test_reg[0]);
if (rc)
goto bail;
if (pf == PM8058_VREG_PIN_FN_ENABLE) {
/* Pin control ON/OFF */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
LDO_CTRL_PM_HPM,
LDO_ENABLE_MASK | LDO_CTRL_PM_MASK,
&vreg->ctrl_reg);
if (rc)
goto bail;
- rc = pm8058_vreg_set_global_enable(vreg, chip,
- 0);
+ rc = pm8058_vreg_set_global_enable(vreg, 0);
if (rc)
goto bail;
} else {
/* Pin control LPM/HPM */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
LDO_ENABLE | LDO_CTRL_PM_LPM,
LDO_ENABLE_MASK | LDO_CTRL_PM_MASK,
&vreg->ctrl_reg);
@@ -512,14 +509,14 @@
}
} else {
/* Pin control off */
- rc = pm8058_vreg_write(chip, vreg->test_addr,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr,
REGULATOR_BANK_SEL(5) | REGULATOR_BANK_WRITE,
LDO_TEST_PIN_CTRL_MASK | REGULATOR_BANK_MASK,
&vreg->test_reg[5]);
if (rc)
goto bail;
- rc = pm8058_vreg_write(chip, vreg->test_addr,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr,
REGULATOR_BANK_SEL(6) | REGULATOR_BANK_WRITE,
LDO_TEST_PIN_CTRL_MASK | REGULATOR_BANK_MASK,
&vreg->test_reg[6]);
@@ -551,29 +548,29 @@
if (pc & PM8058_VREG_PIN_CTRL_A1)
val |= SMPS_PIN_CTRL_LPM_A1;
}
- rc = pm8058_vreg_set_global_enable(vreg, chip, 0);
+ rc = pm8058_vreg_set_global_enable(vreg, 0);
if (rc)
goto bail;
- rc = pm8058_smps_set_voltage_legacy(vreg, chip,
+ rc = pm8058_smps_set_voltage_legacy(vreg,
vreg->save_uV);
if (rc)
goto bail;
- rc = pm8058_vreg_write(chip, vreg->sleep_ctrl_addr, val,
+ rc = pm8058_vreg_write(vreg, vreg->sleep_ctrl_addr, val,
SMPS_PIN_CTRL_MASK | SMPS_PIN_CTRL_LPM_MASK,
&vreg->sleep_ctrl_reg);
if (rc)
goto bail;
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
(pf == PM8058_VREG_PIN_FN_ENABLE
? 0 : SMPS_LEGACY_ENABLE),
SMPS_LEGACY_ENABLE, &vreg->ctrl_reg);
if (rc)
goto bail;
- rc = pm8058_vreg_write(chip, vreg->clk_ctrl_addr,
+ rc = pm8058_vreg_write(vreg, vreg->clk_ctrl_addr,
(pf == PM8058_VREG_PIN_FN_ENABLE
? SMPS_CLK_CTRL_PWM : SMPS_CLK_CTRL_PFM),
SMPS_CLK_CTRL_MASK, &vreg->clk_ctrl_reg);
@@ -584,20 +581,20 @@
if (!SMPS_IN_ADVANCED_MODE(vreg)) {
if (_pm8058_vreg_is_enabled(vreg))
val = SMPS_LEGACY_ENABLE;
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
val, SMPS_LEGACY_ENABLE,
&vreg->ctrl_reg);
if (rc)
goto bail;
}
- rc = pm8058_vreg_write(chip, vreg->sleep_ctrl_addr, 0,
+ rc = pm8058_vreg_write(vreg, vreg->sleep_ctrl_addr, 0,
SMPS_PIN_CTRL_MASK | SMPS_PIN_CTRL_LPM_MASK,
&vreg->sleep_ctrl_reg);
if (rc)
goto bail;
- rc = pm8058_smps_set_voltage_advanced(vreg, chip,
+ rc = pm8058_smps_set_voltage_advanced(vreg,
vreg->save_uV, 0);
if (rc)
goto bail;
@@ -615,13 +612,13 @@
if (pc & PM8058_VREG_PIN_CTRL_A1)
val |= LVS_PIN_CTRL_EN3;
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val,
LVS_PIN_CTRL_MASK | LVS_ENABLE_MASK,
&vreg->ctrl_reg);
if (rc)
goto bail;
- rc = pm8058_vreg_set_global_enable(vreg, chip, 0);
+ rc = pm8058_vreg_set_global_enable(vreg, 0);
if (rc)
goto bail;
} else {
@@ -629,7 +626,7 @@
if (_pm8058_vreg_is_enabled(vreg))
val = LVS_ENABLE;
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val,
LVS_ENABLE_MASK | LVS_PIN_CTRL_MASK,
&vreg->ctrl_reg);
if (rc)
@@ -649,7 +646,6 @@
static int pm8058_vreg_enable(struct regulator_dev *dev)
{
struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
int mode;
int rc = 0;
@@ -657,16 +653,15 @@
if (mode == REGULATOR_MODE_IDLE) {
/* Turn on pin control. */
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
if (rc)
goto bail;
return rc;
}
if (vreg->type == REGULATOR_TYPE_SMPS && SMPS_IN_ADVANCED_MODE(vreg))
- rc = pm8058_smps_set_voltage_advanced(vreg, chip,
- vreg->save_uV, 1);
+ rc = pm8058_smps_set_voltage_advanced(vreg, vreg->save_uV, 1);
else
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, REGULATOR_EN_MASK,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, REGULATOR_EN_MASK,
REGULATOR_EN_MASK, &vreg->ctrl_reg);
bail:
if (rc)
@@ -706,26 +701,25 @@
static int pm8058_vreg_disable(struct regulator_dev *dev)
{
struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
int rc = 0;
/* Disable in global control register. */
- rc = pm8058_vreg_set_global_enable(vreg, chip, 0);
+ rc = pm8058_vreg_set_global_enable(vreg, 0);
if (rc)
goto bail;
/* Turn off pin control. */
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
if (rc)
goto bail;
/* Disable in local control register. */
if (vreg->type == REGULATOR_TYPE_SMPS && SMPS_IN_ADVANCED_MODE(vreg))
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
SMPS_ADVANCED_BAND_OFF, SMPS_ADVANCED_BAND_MASK,
&vreg->ctrl_reg);
else
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, 0,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, 0,
REGULATOR_EN_MASK, &vreg->ctrl_reg);
bail:
@@ -735,8 +729,7 @@
return rc;
}
-static int pm8058_pldo_set_voltage(struct pm8058_chip *chip,
- struct pm8058_vreg *vreg, int uV)
+static int pm8058_pldo_set_voltage(struct pm8058_vreg *vreg, int uV)
{
int vmin, rc = 0;
unsigned vprog, fine_step;
@@ -775,7 +768,7 @@
|| ((range_sel ^ vreg->test_reg[2]) & LDO_TEST_RANGE_SEL_MASK)
|| ((fine_step_reg ^ vreg->test_reg[2])
& LDO_TEST_FINE_STEP_MASK))) {
- rc = pm8058_vreg_write(chip, vreg->test_addr,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr,
REGULATOR_BANK_SEL(2) | REGULATOR_BANK_WRITE,
REGULATOR_BANK_MASK | LDO_TEST_VPROG_UPDATE_MASK,
&vreg->test_reg[2]);
@@ -784,13 +777,13 @@
}
/* Write new voltage. */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, vprog,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, vprog,
LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
if (rc)
goto bail;
/* Write range extension. */
- rc = pm8058_vreg_write(chip, vreg->test_addr,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr,
range_ext | REGULATOR_BANK_SEL(4)
| REGULATOR_BANK_WRITE,
LDO_TEST_RANGE_EXT_MASK | REGULATOR_BANK_MASK,
@@ -799,7 +792,7 @@
goto bail;
/* Write fine step, range select and program voltage update. */
- rc = pm8058_vreg_write(chip, vreg->test_addr,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr,
fine_step_reg | range_sel | REGULATOR_BANK_SEL(2)
| REGULATOR_BANK_WRITE | LDO_TEST_VPROG_UPDATE_MASK,
LDO_TEST_FINE_STEP_MASK | LDO_TEST_RANGE_SEL_MASK
@@ -812,8 +805,7 @@
return rc;
}
-static int pm8058_nldo_set_voltage(struct pm8058_chip *chip,
- struct pm8058_vreg *vreg, int uV)
+static int pm8058_nldo_set_voltage(struct pm8058_vreg *vreg, int uV)
{
unsigned vprog, fine_step_reg;
int rc;
@@ -826,13 +818,13 @@
vprog >>= 1;
/* Write new voltage. */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, vprog,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, vprog,
LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
if (rc)
goto bail;
/* Write fine step. */
- rc = pm8058_vreg_write(chip, vreg->test_addr,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr,
fine_step_reg | REGULATOR_BANK_SEL(2)
| REGULATOR_BANK_WRITE | LDO_TEST_VPROG_UPDATE_MASK,
LDO_TEST_FINE_STEP_MASK | REGULATOR_BANK_MASK
@@ -849,12 +841,11 @@
int min_uV, int max_uV, unsigned *selector)
{
struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
if (vreg->is_nmos)
- return pm8058_nldo_set_voltage(chip, vreg, min_uV);
+ return pm8058_nldo_set_voltage(vreg, min_uV);
else
- return pm8058_pldo_set_voltage(chip, vreg, min_uV);
+ return pm8058_pldo_set_voltage(vreg, min_uV);
}
static int pm8058_pldo_get_voltage(struct pm8058_vreg *vreg)
@@ -967,8 +958,7 @@
}
static int pm8058_smps_set_voltage_advanced(struct pm8058_vreg *vreg,
- struct pm8058_chip *chip, int uV,
- int force_on)
+ int uV, int force_on)
{
u8 vprog, band;
int rc, new_uV;
@@ -992,7 +982,7 @@
band = SMPS_ADVANCED_BAND_OFF;
/* Set advanced mode bit to 1. */
- rc = pm8058_vreg_write(chip, vreg->test_addr, SMPS_ADVANCED_MODE
+ rc = pm8058_vreg_write(vreg, vreg->test_addr, SMPS_ADVANCED_MODE
| REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(7),
SMPS_ADVANCED_MODE_MASK | REGULATOR_BANK_MASK,
&vreg->test_reg[7]);
@@ -1000,7 +990,7 @@
goto bail;
/* Set voltage and voltage band. */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, band | vprog,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, band | vprog,
SMPS_ADVANCED_BAND_MASK | SMPS_ADVANCED_VPROG_MASK,
&vreg->ctrl_reg);
if (rc)
@@ -1012,8 +1002,7 @@
return rc;
}
-static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg,
- struct pm8058_chip *chip, int uV)
+static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg, int uV)
{
u8 vlow, vref, vprog, pd, en;
int rc;
@@ -1033,7 +1022,7 @@
}
/* set vlow bit for ultra low voltage mode */
- rc = pm8058_vreg_write(chip, vreg->test_addr,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr,
vlow | REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(1),
REGULATOR_BANK_MASK | SMPS_LEGACY_VLOW_SEL_MASK,
&vreg->test_reg[1]);
@@ -1041,7 +1030,7 @@
goto bail;
/* Set advanced mode bit to 0. */
- rc = pm8058_vreg_write(chip, vreg->test_addr, SMPS_LEGACY_MODE
+ rc = pm8058_vreg_write(vreg, vreg->test_addr, SMPS_LEGACY_MODE
| REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(7),
SMPS_ADVANCED_MODE_MASK | REGULATOR_BANK_MASK,
&vreg->test_reg[7]);
@@ -1052,7 +1041,7 @@
pd = (vreg->pdata->pull_down_enable ? SMPS_LEGACY_PULL_DOWN_ENABLE : 0);
/* Set voltage (and the rest of the control register). */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, en | pd | vref | vprog,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, en | pd | vref | vprog,
SMPS_LEGACY_ENABLE | SMPS_LEGACY_PULL_DOWN_ENABLE
| SMPS_LEGACY_VREF_SEL_MASK | SMPS_LEGACY_VPROG_MASK,
&vreg->ctrl_reg);
@@ -1067,16 +1056,15 @@
int min_uV, int max_uV, unsigned *selector)
{
struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
int rc = 0;
if (min_uV < SMPS_UV_MIN || min_uV > SMPS_UV_MAX)
return -EINVAL;
if (SMPS_IN_ADVANCED_MODE(vreg))
- rc = pm8058_smps_set_voltage_advanced(vreg, chip, min_uV, 0);
+ rc = pm8058_smps_set_voltage_advanced(vreg, min_uV, 0);
else
- rc = pm8058_smps_set_voltage_legacy(vreg, chip, min_uV);
+ rc = pm8058_smps_set_voltage_legacy(vreg, min_uV);
if (rc)
print_write_error(vreg, rc, __func__);
@@ -1088,7 +1076,6 @@
int min_uV, int max_uV, unsigned *selector)
{
struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
int rc;
u8 val;
@@ -1098,7 +1085,7 @@
val = (min_uV - NCP_UV_MIN) / NCP_UV_STEP;
/* voltage setting */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val, NCP_VPROG_MASK,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val, NCP_VPROG_MASK,
&vreg->ctrl_reg);
if (rc)
print_write_error(vreg, rc, __func__);
@@ -1113,8 +1100,7 @@
return NCP_UV_MIN + vprog * NCP_UV_STEP;
}
-static int pm8058_ldo_set_mode(struct pm8058_vreg *vreg,
- struct pm8058_chip *chip, unsigned int mode)
+static int pm8058_ldo_set_mode(struct pm8058_vreg *vreg, unsigned int mode)
{
int rc = 0;
u8 mask, val;
@@ -1125,13 +1111,13 @@
val = (_pm8058_vreg_is_enabled(vreg) ? LDO_ENABLE : 0)
| LDO_CTRL_PM_HPM;
mask = LDO_ENABLE_MASK | LDO_CTRL_PM_MASK;
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val, mask,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val, mask,
&vreg->ctrl_reg);
if (rc)
goto bail;
if (pm8058_vreg_using_pin_ctrl(vreg))
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
if (rc)
goto bail;
break;
@@ -1141,7 +1127,7 @@
val = (_pm8058_vreg_is_enabled(vreg) ? LDO_ENABLE : 0)
| LDO_CTRL_PM_LPM;
mask = LDO_ENABLE_MASK | LDO_CTRL_PM_MASK;
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val, mask,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val, mask,
&vreg->ctrl_reg);
if (rc)
goto bail;
@@ -1149,13 +1135,13 @@
val = LDO_TEST_LPM_SEL_CTRL | REGULATOR_BANK_WRITE
| REGULATOR_BANK_SEL(0);
mask = LDO_TEST_LPM_MASK | REGULATOR_BANK_MASK;
- rc = pm8058_vreg_write(chip, vreg->test_addr, val, mask,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr, val, mask,
&vreg->test_reg[0]);
if (rc)
goto bail;
if (pm8058_vreg_using_pin_ctrl(vreg))
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
if (rc)
goto bail;
break;
@@ -1163,7 +1149,7 @@
case REGULATOR_MODE_IDLE:
/* Pin Control */
if (_pm8058_vreg_is_enabled(vreg))
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
if (rc)
goto bail;
break;
@@ -1180,8 +1166,7 @@
return rc;
}
-static int pm8058_smps_set_mode(struct pm8058_vreg *vreg,
- struct pm8058_chip *chip, unsigned int mode)
+static int pm8058_smps_set_mode(struct pm8058_vreg *vreg, unsigned int mode)
{
int rc = 0;
u8 mask, val;
@@ -1191,13 +1176,13 @@
/* HPM */
val = SMPS_CLK_CTRL_PWM;
mask = SMPS_CLK_CTRL_MASK;
- rc = pm8058_vreg_write(chip, vreg->clk_ctrl_addr, val, mask,
+ rc = pm8058_vreg_write(vreg, vreg->clk_ctrl_addr, val, mask,
&vreg->clk_ctrl_reg);
if (rc)
goto bail;
if (pm8058_vreg_using_pin_ctrl(vreg))
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
if (rc)
goto bail;
break;
@@ -1206,13 +1191,13 @@
/* LPM */
val = SMPS_CLK_CTRL_PFM;
mask = SMPS_CLK_CTRL_MASK;
- rc = pm8058_vreg_write(chip, vreg->clk_ctrl_addr, val, mask,
+ rc = pm8058_vreg_write(vreg, vreg->clk_ctrl_addr, val, mask,
&vreg->clk_ctrl_reg);
if (rc)
goto bail;
if (pm8058_vreg_using_pin_ctrl(vreg))
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
if (rc)
goto bail;
break;
@@ -1220,7 +1205,7 @@
case REGULATOR_MODE_IDLE:
/* Pin Control */
if (_pm8058_vreg_is_enabled(vreg))
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
if (rc)
goto bail;
break;
@@ -1237,18 +1222,17 @@
return rc;
}
-static int pm8058_lvs_set_mode(struct pm8058_vreg *vreg,
- struct pm8058_chip *chip, unsigned int mode)
+static int pm8058_lvs_set_mode(struct pm8058_vreg *vreg, unsigned int mode)
{
int rc = 0;
if (mode == REGULATOR_MODE_IDLE) {
/* Use pin control. */
if (_pm8058_vreg_is_enabled(vreg))
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
} else {
/* Turn off pin control. */
- rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+ rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
}
return rc;
@@ -1268,7 +1252,6 @@
static int pm8058_vreg_set_mode(struct regulator_dev *dev, unsigned int mode)
{
struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
- struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
unsigned prev_optimum = vreg->optimum;
unsigned prev_pc_vote = vreg->pc_vote;
unsigned prev_mode_initialized = vreg->mode_initialized;
@@ -1320,13 +1303,13 @@
switch (vreg->type) {
case REGULATOR_TYPE_LDO:
- rc = pm8058_ldo_set_mode(vreg, chip, new_mode);
+ rc = pm8058_ldo_set_mode(vreg, new_mode);
break;
case REGULATOR_TYPE_SMPS:
- rc = pm8058_smps_set_mode(vreg, chip, new_mode);
+ rc = pm8058_smps_set_mode(vreg, new_mode);
break;
case REGULATOR_TYPE_LVS:
- rc = pm8058_lvs_set_mode(vreg, chip, new_mode);
+ rc = pm8058_lvs_set_mode(vreg, new_mode);
break;
}
@@ -1499,24 +1482,25 @@
VREG_DESCRIP(PM8058_VREG_ID_NCP, "8058_ncp", &pm8058_ncp_ops),
};
-static int pm8058_master_enable_init(struct pm8058_chip *chip)
+static int pm8058_master_enable_init(struct pm8058_vreg *vreg)
{
int rc = 0, i;
for (i = 0; i < MASTER_ENABLE_COUNT; i++) {
- rc = pm8058_read(chip, m_en[i].addr, &(m_en[i].reg), 1);
+ rc = pm8xxx_readb(vreg->dev->parent, m_en[i].addr,
+ &(m_en[i].reg));
if (rc)
goto bail;
}
bail:
if (rc)
- pr_err("%s: pm8058_read failed, rc=%d\n", __func__, rc);
+ pr_err("%s: pm8xxx_read failed, rc=%d\n", __func__, rc);
return rc;
}
-static int pm8058_init_ldo(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_ldo(struct pm8058_vreg *vreg)
{
int rc = 0, i;
u8 bank;
@@ -1524,11 +1508,12 @@
/* Save the current test register state. */
for (i = 0; i < LDO_TEST_BANKS; i++) {
bank = REGULATOR_BANK_SEL(i);
- rc = pm8058_write(chip, vreg->test_addr, &bank, 1);
+ rc = pm8xxx_writeb(vreg->dev->parent, vreg->test_addr, bank);
if (rc)
goto bail;
- rc = pm8058_read(chip, vreg->test_addr, &vreg->test_reg[i], 1);
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+ &vreg->test_reg[i]);
if (rc)
goto bail;
vreg->test_reg[i] |= REGULATOR_BANK_WRITE;
@@ -1540,14 +1525,14 @@
vreg->optimum = REGULATOR_MODE_FAST;
/* Set pull down enable based on platform data. */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
(vreg->pdata->pull_down_enable ? LDO_PULL_DOWN_ENABLE : 0),
LDO_PULL_DOWN_ENABLE_MASK, &vreg->ctrl_reg);
bail:
return rc;
}
-static int pm8058_init_smps(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_smps(struct pm8058_vreg *vreg)
{
int rc = 0, i;
u8 bank;
@@ -1555,24 +1540,26 @@
/* Save the current test2 register state. */
for (i = 0; i < SMPS_TEST_BANKS; i++) {
bank = REGULATOR_BANK_SEL(i);
- rc = pm8058_write(chip, vreg->test_addr, &bank, 1);
+ rc = pm8xxx_writeb(vreg->dev->parent, vreg->test_addr, bank);
if (rc)
goto bail;
- rc = pm8058_read(chip, vreg->test_addr, &vreg->test_reg[i],
- 1);
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+ &vreg->test_reg[i]);
if (rc)
goto bail;
vreg->test_reg[i] |= REGULATOR_BANK_WRITE;
}
/* Save the current clock control register state. */
- rc = pm8058_read(chip, vreg->clk_ctrl_addr, &vreg->clk_ctrl_reg, 1);
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->clk_ctrl_addr,
+ &vreg->clk_ctrl_reg);
if (rc)
goto bail;
/* Save the current sleep control register state. */
- rc = pm8058_read(chip, vreg->sleep_ctrl_addr, &vreg->sleep_ctrl_reg, 1);
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->sleep_ctrl_addr,
+ &vreg->sleep_ctrl_reg);
if (rc)
goto bail;
@@ -1585,7 +1572,7 @@
vreg->optimum = REGULATOR_MODE_FAST;
/* Set advanced mode pull down enable based on platform data. */
- rc = pm8058_vreg_write(chip, vreg->test_addr,
+ rc = pm8058_vreg_write(vreg, vreg->test_addr,
(vreg->pdata->pull_down_enable
? SMPS_ADVANCED_PULL_DOWN_ENABLE : 0)
| REGULATOR_BANK_SEL(6) | REGULATOR_BANK_WRITE,
@@ -1596,7 +1583,7 @@
if (!SMPS_IN_ADVANCED_MODE(vreg)) {
/* Set legacy mode pull down enable based on platform data. */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
(vreg->pdata->pull_down_enable
? SMPS_LEGACY_PULL_DOWN_ENABLE : 0),
SMPS_LEGACY_PULL_DOWN_ENABLE, &vreg->ctrl_reg);
@@ -1608,26 +1595,27 @@
return rc;
}
-static int pm8058_init_lvs(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_lvs(struct pm8058_vreg *vreg)
{
int rc = 0;
vreg->optimum = REGULATOR_MODE_FAST;
/* Set pull down enable based on platform data. */
- rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+ rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
(vreg->pdata->pull_down_enable
? LVS_PULL_DOWN_ENABLE : LVS_PULL_DOWN_DISABLE),
LVS_PULL_DOWN_ENABLE_MASK, &vreg->ctrl_reg);
return rc;
}
-static int pm8058_init_ncp(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_ncp(struct pm8058_vreg *vreg)
{
int rc = 0;
/* Save the current test1 register state. */
- rc = pm8058_read(chip, vreg->test_addr, &vreg->test_reg[0], 1);
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+ &vreg->test_reg[0]);
if (rc)
goto bail;
@@ -1637,8 +1625,7 @@
return rc;
}
-static int pm8058_init_regulator(struct pm8058_chip *chip,
- struct pm8058_vreg *vreg)
+static int pm8058_init_regulator(struct pm8058_vreg *vreg)
{
static int master_enable_inited;
int rc = 0;
@@ -1646,28 +1633,28 @@
vreg->mode_initialized = 0;
if (!master_enable_inited) {
- rc = pm8058_master_enable_init(chip);
+ rc = pm8058_master_enable_init(vreg);
if (!rc)
master_enable_inited = 1;
}
/* save the current control register state */
- rc = pm8058_read(chip, vreg->ctrl_addr, &vreg->ctrl_reg, 1);
+ rc = pm8xxx_readb(vreg->dev->parent, vreg->ctrl_addr, &vreg->ctrl_reg);
if (rc)
goto bail;
switch (vreg->type) {
case REGULATOR_TYPE_LDO:
- rc = pm8058_init_ldo(chip, vreg);
+ rc = pm8058_init_ldo(vreg);
break;
case REGULATOR_TYPE_SMPS:
- rc = pm8058_init_smps(chip, vreg);
+ rc = pm8058_init_smps(vreg);
break;
case REGULATOR_TYPE_LVS:
- rc = pm8058_init_lvs(chip, vreg);
+ rc = pm8058_init_lvs(vreg);
break;
case REGULATOR_TYPE_NCP:
- rc = pm8058_init_ncp(chip, vreg);
+ rc = pm8058_init_ncp(vreg);
break;
}
@@ -1681,7 +1668,6 @@
static int __devinit pm8058_vreg_probe(struct platform_device *pdev)
{
struct regulator_desc *rdesc;
- struct pm8058_chip *chip;
struct pm8058_vreg *vreg;
const char *reg_name = NULL;
int rc = 0;
@@ -1690,13 +1676,13 @@
return -EINVAL;
if (pdev->id >= 0 && pdev->id < PM8058_VREG_MAX) {
- chip = dev_get_drvdata(pdev->dev.parent);
rdesc = &pm8058_vreg_descrip[pdev->id];
vreg = &pm8058_vreg[pdev->id];
vreg->pdata = pdev->dev.platform_data;
reg_name = pm8058_vreg_descrip[pdev->id].name;
+ vreg->dev = &pdev->dev;
- rc = pm8058_init_regulator(chip, vreg);
+ rc = pm8058_init_regulator(vreg);
if (rc)
goto bail;
@@ -1705,7 +1691,6 @@
vreg->pdata->init_data.constraints.valid_modes_mask
&= ~(REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE);
- platform_set_drvdata(pdev, chip);
vreg->rdev = regulator_register(rdesc, &pdev->dev,
&vreg->pdata->init_data, vreg);
if (IS_ERR(vreg->rdev)) {
diff --git a/drivers/thermal/pm8xxx-tm.c b/drivers/thermal/pm8xxx-tm.c
index d9f9c9e..1d518e3 100644
--- a/drivers/thermal/pm8xxx-tm.c
+++ b/drivers/thermal/pm8xxx-tm.c
@@ -30,6 +30,7 @@
#include <linux/mfd/pm8xxx/tm.h>
#include <linux/completion.h>
#include <linux/mfd/pm8xxx/pm8921-adc.h>
+#include <linux/msm_adc.h>
/* Register TEMP_ALARM_CTRL bits */
#define TEMP_ALARM_CTRL_ST3_SD 0x80
@@ -226,6 +227,43 @@
return 0;
}
+static int pm8xxx_tz_get_temp_pm8058_adc(struct thermal_zone_device *thermal,
+ unsigned long *temp)
+{
+ struct pm8xxx_tm_chip *chip = thermal->devdata;
+ DECLARE_COMPLETION_ONSTACK(wait);
+ struct adc_chan_result adc_result = {
+ .physical = 0lu,
+ };
+ int rc;
+
+ if (!chip || !temp)
+ return -EINVAL;
+
+ *temp = chip->temp;
+
+ rc = adc_channel_request_conv(chip->adc_handle, &wait);
+ if (rc < 0) {
+ pr_err("%s: adc_channel_request_conv() failed, rc = %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ wait_for_completion(&wait);
+
+ rc = adc_channel_read_result(chip->adc_handle, &adc_result);
+ if (rc < 0) {
+ pr_err("%s: adc_channel_read_result() failed, rc = %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ *temp = adc_result.physical;
+ chip->temp = adc_result.physical;
+
+ return 0;
+}
+
static int pm8xxx_tz_get_temp_pm8921_adc(struct thermal_zone_device *thermal,
unsigned long *temp)
{
@@ -372,6 +410,15 @@
.get_crit_temp = pm8xxx_tz_get_crit_temp,
};
+static struct thermal_zone_device_ops pm8xxx_thermal_zone_ops_pm8058_adc = {
+ .get_temp = pm8xxx_tz_get_temp_pm8058_adc,
+ .get_mode = pm8xxx_tz_get_mode,
+ .set_mode = pm8xxx_tz_set_mode,
+ .get_trip_type = pm8xxx_tz_get_trip_type,
+ .get_trip_temp = pm8xxx_tz_get_trip_temp,
+ .get_crit_temp = pm8xxx_tz_get_crit_temp,
+};
+
static void pm8xxx_tm_work(struct work_struct *work)
{
struct pm8xxx_tm_chip *chip
@@ -465,6 +512,24 @@
return rc;
}
+static int pm8xxx_init_adc(struct pm8xxx_tm_chip *chip, bool enable)
+{
+ int rc = 0;
+
+ if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8058_ADC) {
+ if (enable) {
+ rc = adc_channel_open(chip->cdata.adc_channel,
+ &(chip->adc_handle));
+ if (rc < 0)
+ pr_err("adc_channel_open() failed.\n");
+ } else {
+ adc_channel_close(chip->adc_handle);
+ }
+ }
+
+ return rc;
+}
+
static int __devinit pm8xxx_tm_probe(struct platform_device *pdev)
{
const struct pm8xxx_tm_core_data *cdata = pdev->dev.platform_data;
@@ -505,18 +570,27 @@
goto err_free_chip;
}
+ rc = pm8xxx_init_adc(chip, true);
+ if (rc < 0) {
+ pr_err("Unable to initialize adc\n");
+ goto err_free_chip;
+ }
+
/* Select proper thermal zone ops functions based on ADC type. */
if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8921_ADC)
tz_ops = &pm8xxx_thermal_zone_ops_pm8921_adc;
+ else if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8058_ADC)
+ tz_ops = &pm8xxx_thermal_zone_ops_pm8058_adc;
else
tz_ops = &pm8xxx_thermal_zone_ops_no_adc;
chip->tz_dev = thermal_zone_device_register(chip->cdata.tm_name,
TRIP_NUM, chip, tz_ops, 0, 0, 0, 0);
+
if (chip->tz_dev == NULL) {
pr_err("thermal_zone_device_register() failed.\n");
rc = -ENODEV;
- goto err_free_chip;
+ goto err_fail_adc;
}
rc = pm8xxx_tm_init_reg(chip);
@@ -564,6 +638,8 @@
cancel_work_sync(&chip->irq_work);
err_free_tz:
thermal_zone_device_unregister(chip->tz_dev);
+err_fail_adc:
+ pm8xxx_init_adc(chip, false);
err_free_chip:
kfree(chip);
return rc;
@@ -579,6 +655,7 @@
free_irq(chip->overtemp_irq, chip);
free_irq(chip->tempstat_irq, chip);
pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
+ pm8xxx_init_adc(chip, false);
thermal_zone_device_unregister(chip->tz_dev);
kfree(chip);
}