aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKalle Komierowski <karl.komierowski@gmail.com>2011-03-03 13:10:29 +0100
committerHenrik Öhman <henrik.ohman@stericsson.com>2011-03-15 14:22:56 +0100
commit95564202d60e489e1a494acfb47de2730e153def (patch)
treec6fdd80bdcaf3c67ec2c1518ad559a57d9117d23
parent98a6f2d9459911dd8f8b9fb90e6a434a41cca17e (diff)
mfd: ab8500_gpadc: Added manual batt temp activation for AB8500 3.0
In AB8500 3.0 the pull-up supplying the NTC must be manually activated ST-Ericsson ID: - Change-Id: I88513cff4e064db83f755676468ec0ee44c19c40 Signed-off-by: Kalle Komierowski <karl.komierowski@gmail.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/17511 Tested-by: Karl KOMIEROWSKI <karl.komierowski@stericsson.com> Reviewed-by: Johan PALSSON <johan.palsson@stericsson.com> Reviewed-by: Daniel WILLERUD <daniel.willerud@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
-rw-r--r--drivers/mfd/ab8500-core.c32
-rw-r--r--drivers/mfd/ab8500-gpadc.c34
-rw-r--r--include/linux/mfd/ab8500/ab8500-bm.h5
-rw-r--r--include/linux/mfd/abx500.h7
4 files changed, 56 insertions, 22 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index cb64aadb9e8..212f46c4993 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -243,8 +243,9 @@ static void ab8500_irq_sync_unlock(unsigned int irq)
if (new == old)
continue;
- /* Interrupt register 12 does'nt exist prior to version 0x20 */
- if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20)
+ /* Interrupt register 12 doesn't exist prior to version 2.0 */
+ if (ab8500_irq_regoffset[i] == 11 &&
+ ab8500->chip_id < AB8500_CUT2P0)
continue;
ab8500->oldmask[i] = new;
@@ -295,8 +296,8 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
int status;
u8 value;
- /* Interrupt register 12 does'nt exist prior to version 0x20 */
- if (regoffset == 11 && ab8500->chip_id < 0x20)
+ /* Interrupt register 12 doesn't exist prior to version 2.0 */
+ if (regoffset == 11 && ab8500->chip_id < AB8500_CUT2P0)
continue;
status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
@@ -822,17 +823,15 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
if (ret < 0)
return ret;
- /*
- * 0x0 - Early Drop
- * 0x10 - Cut 1.0
- * 0x11 - Cut 1.1
- * 0x20 - Cut 2.0
- * 0x30 - Cut 3.0
- */
- if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20 ||
- value == 0x30) {
+ switch (value) {
+ case AB8500_CUTEARLY:
+ case AB8500_CUT1P0:
+ case AB8500_CUT1P1:
+ case AB8500_CUT2P0:
+ case AB8500_CUT3P0:
dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
- } else {
+ break;
+ default:
dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value);
return -EINVAL;
}
@@ -861,8 +860,9 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
/* Clear and mask all interrupts */
for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) {
- /* Interrupt register 12 does'nt exist prior to version 0x20 */
- if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20)
+ /* Interrupt register 12 doesn't exist prior to version 2.0 */
+ if (ab8500_irq_regoffset[i] == 11 &&
+ ab8500->chip_id < AB8500_CUT2P0)
continue;
get_register_interruptible(ab8500, AB8500_INTERRUPT,
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
index 8c1404161d6..edb6a2ee242 100644
--- a/drivers/mfd/ab8500-gpadc.c
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -57,6 +57,7 @@
#define SW_AVG_16 0x60
#define ADC_SW_CONV 0x04
#define EN_ICHAR 0x80
+#define BATTEMP_PULLUP 0x04
#define EN_BUF 0x40
#define DIS_ZERO 0x00
#define GPADC_BUSY 0x01
@@ -101,6 +102,7 @@ struct adc_cal_data {
/**
* struct ab8500_gpadc - AB8500 GPADC device information
+ * @chip_id ABB chip id
* @dev: pointer to the struct device
* @node: a list of AB8500 GPADCs, hence prepared for
reentrance
@@ -112,6 +114,7 @@ struct adc_cal_data {
* @cal_data array of ADC calibration data structs
*/
struct ab8500_gpadc {
+ u8 chip_id;
struct device *dev;
struct list_head node;
struct completion ab8500_gpadc_complete;
@@ -270,6 +273,7 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n");
goto out;
}
+
/* Select the input source and set average samples to 16 */
ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16));
@@ -278,9 +282,11 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
"gpadc_conversion: set avg samples failed\n");
goto out;
}
+
/*
* Enable ADC, buffering, select rising edge and enable ADC path
- * charging current sense if it needed
+ * charging current sense if it needed, ABB 3.0 needs some special
+ * treatment too.
*/
switch (input) {
case MAIN_CHARGER_C:
@@ -290,6 +296,23 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
EN_BUF | EN_ICHAR,
EN_BUF | EN_ICHAR);
break;
+ case BTEMP_BALL:
+ if (gpadc->chip_id >= AB8500_CUT3P0) {
+ /* Turn on btemp pull-up on ABB 3.0 */
+ ret = abx500_mask_and_set_register_interruptible(
+ gpadc->dev,
+ AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
+ EN_BUF | BATTEMP_PULLUP,
+ EN_BUF | BATTEMP_PULLUP);
+
+ /*
+ * Delay might be needed for ABB8500 cut 3.0, if not, remove
+ * when hardware will be availible
+ */
+ msleep(1);
+ break;
+ }
+ /* Intentional fallthrough */
default:
ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF);
@@ -300,6 +323,7 @@ int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
"gpadc_conversion: select falling edge failed\n");
goto out;
}
+
ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
AB8500_GPADC, AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV);
if (ret < 0) {
@@ -548,6 +572,14 @@ static int __devinit ab8500_gpadc_probe(struct platform_device *pdev)
goto fail;
}
+ /* Get Chip ID of the ABB ASIC */
+ ret = abx500_get_chip_id(gpadc->dev);
+ if (ret < 0) {
+ dev_err(gpadc->dev, "failed to get chip ID\n");
+ goto fail_irq;
+ }
+ gpadc->chip_id = (u8) ret;
+
/* VTVout LDO used to power up ab8500-GPADC */
gpadc->regu = regulator_get(&pdev->dev, "ab8500-gpadc");
if (IS_ERR(gpadc->regu)) {
diff --git a/include/linux/mfd/ab8500/ab8500-bm.h b/include/linux/mfd/ab8500/ab8500-bm.h
index 2a9f97fdfa0..aacba93b912 100644
--- a/include/linux/mfd/ab8500/ab8500-bm.h
+++ b/include/linux/mfd/ab8500/ab8500-bm.h
@@ -118,11 +118,6 @@
#define ADC_CH_BKBAT_MIN 0
#define ADC_CH_BKBAT_MAX 3200
-/* AB8500 CIDs*/
-#define AB8500_CUT1P0 0x10
-#define AB8500_CUT1P1 0x11
-#define AB8500_CUT2P0 0x20
-
/* Main charge i/p current */
#define MAIN_CH_IP_CUR_0P9A 0x80
#define MAIN_CH_IP_CUR_1P0A 0x90
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index e9840a2b0af..f4e405d8c41 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -34,6 +34,13 @@
#define AB5500_1_1 0x21
#define AB5500_2_0 0x24
+/* AB8500 CIDs*/
+#define AB8500_CUTEARLY 0x00
+#define AB8500_CUT1P0 0x10
+#define AB8500_CUT1P1 0x11
+#define AB8500_CUT2P0 0x20
+#define AB8500_CUT3P0 0x30
+
/*
* AB3100, EVENTA1, A2 and A3 event register flags
* these are catenated into a single 32-bit flag in the code